Cơ sở của bạn thành 1-2-3-Triborie để nhị phân trở lại Cơ sở của bạn


19

Lý lịch

Chuỗi 1-2-3-Triborie

Hãy tưởng tượng trong một giây rằng bạn có thể tạo một chuỗi Wikipedia bằng cách thay thế công thức lặp tiêu chuẩn bằng cách sau:

đường biên

Về cơ bản, thay vì tổng hai số cuối để lấy số tiếp theo, bạn tổng hợp ba số cuối. Đây là cơ sở cho chuỗi 1-2-3-Triborie.

Tiêu chí của Brown

Tiêu chí của Brown cho biết bạn có thể biểu thị bất kỳ giá trị số nguyên nào dưới dạng tổng các thành viên của chuỗi với điều kiện:

  1. x sub n bằng 1

  2. Đối với tất cả nlớn hơn 1,x sub n nhỏ hơn 2 x sub n - 1

Điều này có ý nghĩa gì đối với thử thách

Bạn có thể mô tả bất kỳ số nguyên dương nào dưới dạng tổng các thành viên của chuỗi 1-2-3-Triborie được hình thành bởi các điều kiện ban đầu sau:

điều kiện ban đầu

Điều này được gọi là, đối với mọi giá trị trong chuỗi này, tỷ lệ giữa các thuật ngữ không bao giờ lớn hơn 2 (tỷ lệ trung bình ở khoảng 1.839).

Cách viết trong hệ thống biểu diễn số này

Hãy nói rằng bạn sử dụng một đại diện endian nhỏ. Sắp xếp các thành viên của chuỗi như vậy:

1  2  3  6 11 20 37 68

Sau đó, bạn lấy số của mình để được đại diện (đối với các thử nghiệm của chúng tôi, giả sử là số đó 63) và tìm các giá trị của 1-2-3-Triborie đã cho, tổng bằng 63 (trước tiên sử dụng các giá trị lớn nhất!) . Nếu số là một phần của tổng, đặt 1 dưới nó, 0 nếu không.

1  2  3  6 11 20 37 68
0  0  0  1  0  1  1  0

Bạn có thể làm điều này cho bất kỳ số nguyên cụ thể nào - chỉ cần xác minh rằng bạn sử dụng các giá trị lớn nhất bên dưới đầu vào đã cho trước!

Định nghĩa (cuối cùng)

Viết chương trình hoặc hàm sẽ thực hiện như sau với một số đầu vào số nguyên dương n(được viết bằng bất kỳ cơ sở tiêu chuẩn nào) giữa 1 và giá trị tối đa của ngôn ngữ của bạn:

  1. Chuyển đổi giá trị thành biểu diễn số 1-2-3-Triborie được xác định.
  2. Sử dụng biểu diễn giống như nhị phân này và đọc nó như thể nó là nhị phân. Điều này có nghĩa là các chữ số giữ nguyên, nhưng ý nghĩa của chúng là thay đổi.
  3. Lấy số nhị phân này và chuyển đổi nó thành cơ sở của số ban đầu.
  4. Đầu ra hoặc trả lại số mới này.

Tuy nhiên, miễn là đầu ra hợp lệ, bạn không cần phải làm theo các bước sau. Nếu bạn kỳ diệu tìm thấy một số công thức ngắn hơn (và tương đương về mặt toán học), hãy sử dụng nó.

Ví dụ

Đặt hàm flà hàm được mô tả bởi định nghĩa và để []biểu diễn các bước đã thực hiện (với tư cách là người cuối cùng, mặc dù điều đó không quan trọng) (bạn không cần phải tuân theo quy trình này, đây chỉ là quá trình được mô tả):

>>> f(1)
[1]
[1]
[1]
1

>>> f(5)
[5]
[0, 1, 1]
[6]
6

>>> f(63)
[63]
[0, 0, 0, 1, 0, 1, 1]
[104]
104

Tôi có thể gửi một chương trình riêng mà trong khi không ngắn sẽ giải quyết câu hỏi nhanh hơn không? log (log (n)) + n time trái ngược với log (n) + n time. Đi ma trận điện Nth.
fnɛtɪk

@LliwTelracs Tôi không thể ngăn bạn đăng giải pháp của bạn. Chỉ cần đặt mục tiêu phương pháp giải pháp đó ngắn gọn theo kiến ​​thức của bạn là có thể để đảm bảo bạn vẫn đang cạnh tranh trong lĩnh vực phù hợp.
Addison Crump

Vâng, sẽ không làm điều này ít nhất. Sự lũy thừa nhanh chóng của ma trận này thật dài dòng
fəˈnɛtɪk

2
@LliwTelracs Có thể chỉ cần thêm nó dưới dạng phụ lục vào bài đăng hiện có của bạn sau đó.
Jonathan Allan

thách thức của bạn là không thể đối với những người không thể hiển thị hình ảnh.
Mindwin

Câu trả lời:


7

Javascript 117 111 byte

Cảm ơn @theonlygusti đã giúp chơi golf 5 byte

x=>{r=0;a=[1,2,3];i=1;while(a[++i]<x)a[i+1]=a[i]+a[i-1]+a[i-2];for(;x;i--)if(x>=a[i]){r+=1<<i;x-=a[i]}return r}

Làm thế nào nó hoạt động

Đầu tiên, hàm tạo ra tất cả các số Triborie cho đến khi nó tìm thấy một số lớn hơn đầu vào

a=[1,2,3];i=1;for(;a[++i]<x;)a[i+1]=a[i]+a[i-1]+a[i-2];

Tiếp theo, nó đảo ngược tìm kiếm danh sách các số. Nếu một số nhỏ hơn đầu vào, nó sẽ thêm 2 ^ (chỉ mục của số đó) vào giá trị trả về và giảm đầu vào theo số đó.

for(;x;i--)if(x>=a[i]){r+=1<<i;x-=a[i]}

Cuối cùng nó trả về kết quả.

Dùng thử trực tuyến


1
Điều gì về a[++i]<xbên trong điều kiện để lưu một byte?
theonlygusti

1
Ngoài ra, bạn có thể thay thế x>0bằng x. Lưu thêm 2 byte.
theonlygusti

Đó là một thuật toán khá tốt. oo
Addison Crump

7

Python 2 , 110 102 byte

-3 byte nhờ Rod (thủ thuật gọn gàng để truyền boolean icho int với +irepr `+i`hoạt động)

n=input()
x=[3,2,1]
r=''
while x[0]<n:x=[sum(x[:3])]+x
for v in x:i=n>=v;n-=v*i;r+=`+i`
print int(r,2)

Hãy thử trực tuyến!


1
bạn có thể thay thế '01'[i]bằng`+i`
Rod

ilà một boolean không phải là một int. Chỉnh sửa - Ohhh +i, gọn gàng.
Jonathan Allan

3
@Rod Đó có phải là mẹo trong Python 2 mẹo và thủ thuật không?
Addison Crump

@VoteToC Đóng Tôi không nghĩ vậy
Rod

7

JavaScript (ES6), 97 93 byte

Ở đây, chúng tôi đang sử dụng reduce()trên một hàm đệ quy. Chúng tôi giả định rằng đầu ra là 31 bit (là số lượng không dấu lớn nhất mà JS có thể dễ dàng làm việc với các hoạt động bitwise dù sao).

n=>[...Array(x=31)].reduce(p=>(c=(F=k=>k<4?k:F(--k)+F(--k)+F(--k))(x--))>n?p:(n-=c,p|1<<x),0)

Hiệu suất khôn ngoan, điều này rõ ràng là không hiệu quả lắm.

Dành cho những người tò mò:

  • Tỷ lệ giữa số lần gọi F()cho các reduce()lần lặp N + 1 so với số lần lặp N nhanh chóng hội tụ về hằng số Triborie (≈ 1.83929). Do đó, mỗi bit bổ sung trong đầu ra có giá gấp khoảng hai lần thời gian trước đó.
  • Với 31 bit, F()chức năng này được gọi là tốt hơn 124 triệu lần.

Kiểm tra

NB: Điều này có thể mất 1 hoặc 2 giây để hoàn thành.


Wow, điều đó làm chậm trình duyệt của tôi khi tôi sử dụng nó. xD
Addison Crump

@VoteToC Đóng Hiệu suất khôn ngoan, điều này là không hiệu quả khủng khiếp. :-) Mã kiểm tra không nên trễ quá lâu. Trên hộp của tôi, tôi nhận được khoảng 600ms trong Firefox và 900ms trong Chrome. Là nó chậm hơn nhiều về phía bạn?
Arnauld

Giống như, 5 giây. xD
Addison Crump

@VoteToC Đóng Bây giờ nên nhanh hơn một chút. Lặp lại thứ 32 là vô nghĩa, vì vậy tôi đã giới hạn đầu ra ở một số nguyên 31 bit không dấu.
Arnauld

6

Toán học, 78 74 byte

Fold[#+##&,#~NumberDecompose~Reverse@LinearRecurrence[{1,1,1},{1,2,3},#]]&

LinearRecurrence[{1,1,1},{1,2,3},#]tạo ra một danh sách, có độ dài bằng với đầu vào, của các số 1-2-3. (Đại {1,1,1}diện cho tổng của ba thuật ngữ trước, trong khi {1,2,3}là các giá trị ban đầu.) Sau đó #~NumberDecompose~tìm cách tham lam nhất để viết đầu vào dưới dạng tổng các phần tử của danh sách (đây là cùng một hàm sẽ phân tách một lượng tiền thành bội số của các loại tiền tệ có sẵn, ví dụ). Cuối cùng, Fold[#+##&,...]chuyển đổi danh sách nhị phân kết quả thành số nguyên (cơ số 10).

Trình trước:

Fold[#+##&,#~NumberDecompose~Reverse@Array[If[#<4,#,Tr[#0/@(#-Range@3)]]&,#]]&

Như thường lệ (mặc dù không phải ở trên), phiên bản chơi gôn này siêu chậm với các đầu vào lớn hơn 20 hoặc hơn, vì nó tạo ra (với đệ quy không được tối ưu hóa) một danh sách các bộ lạc có chiều dài là đầu vào; thay thế trận chung kết #bằng một ràng buộc hợp lý hơn như Round[2Log@#+1]kết quả trong hiệu suất tốt hơn nhiều.


Cái gì? Mathematica không có 123Tribonacci[]nội dung?
palsch

1
Không chính xác, mặc dù hóa ra việc sử dụng một nội trang sẽ giúp một chút.
Greg Martin

5

Haskell, 95 byte

(a!b)c=a:(b!c)(a+b+c)
e#(r,c)|c-e<0=(2*r,c)|1<2=(2*r+1,c-e)
f n=fst$foldr(#)(0,n)$take n$(1!2)3

Ví dụ sử dụng: f 63-> 104. Hãy thử trực tuyến! .

Cách thức hoạt động: !xây dựng chuỗi 1-2-3-Triborie. Với 1, 23như các thông số bắt đầu, chúng ta hãy là người đầu tiên nyếu tố của chuỗi. Sau đó chúng tôi gấp từ chức năng đúng #mà trừ phần tử tiếp theo etừ nvà đặt bit trong giá trị trả về rnếu elà cần thiết hoặc cho phép người unset bit. Đặt bit là nhân đôi rvà thêm 1, để cho nó không được đặt chỉ là nhân đôi.


4

Thạch , 31 byte

S=³
3RUµḣ3S;µ<³Ạµ¿µŒPÇÐfṀe@ЀµḄ

Hãy thử trực tuyến!

Tôi gần như chắc chắn có một cách ngắn hơn NHIỀU để đạt được điều này trong Jelly.

Làm sao?

S=³ - Link 1, compare sum to input: list
S   - sum
  ³ - 3rd command line argument which is 1st program argument.
 =  - equal?

3RUµḣ3S;µ<³Ạµ¿µŒPÇÐfṀe@ЀµḄ - Main link: n
3RU                         - range(3) upended -> [3,2,1]
   µ    µ   µ¿              - while
         <³                 - less than input (vectorises)
           Ạ                - all?
    ḣ3S;                    -     head(3), sum, and concatenate
                                  [3,2,1] -> [6,3,2,1] -> [11,6,3,2,1] -> ...
              µ             - monadic chain separation, call the result x
               ŒP           - power set of x - e.g. for [6,3,2,1] -> [[],[6],[3],[2],[1],[6,3],[6,2],[6,1],[3,2],[3,1],[2,1],[6,3,2],[6,3,1],[6,2,1],[3,2,1],[6,3,2,1]]
                  Ðf        - filter keep
                 Ç          -     last link (1) as a monad (those that sum to the input)
                    Ṁ       - maximum (e.g. an input of 63 would yield [[37,20,6],[37,20,3,2,1]], the maximum of which is [37,20,6], the one with the largest numbers used)
                         µ  - monadic chain separation (to have x as the right argument below)
                     e@Ѐ   - exists in with reversed arguments mapped over x (e.g. [37,20,6] with x = [68,37,20,11,6,3,2,1] yields [0,1,1,0,1,0,0,0])
                          Ḅ - convert from binary to integer.        

4

Perl 6 , 93 91 byte

-2 byte nhờ b2gills

{my@f=1,2,3,*+*+*...*>$^n;sum @f».&{$_~~any first *.sum==$n,@f.combinations}Z*(2 X**^∞)}

Làm thế nào nó hoạt động

  • Đầu tiên, nó tạo ra chuỗi 1-2-3-Triborie cho đến phần tử đầu tiên lớn hơn đầu vào:

    my @f = 1, 2, 3, *+*+* ... * > $^n;
  • Dựa vào đó, nó tìm thấy tập hợp con của chuỗi cộng vào đầu vào:

    first *.sum==$n, @f.combinations
  • Dựa vào đó, nó xây dựng một danh sách các booleans xác định xem mỗi phần tử của chuỗi có phải là một phần của tổng hay không:

    @f».&{$_~~any ...}
  • Và cuối cùng, nó diễn giải danh sách các giá trị True = 1, false = 0 làm cơ sở 2 và trả về dưới dạng số (cơ sở 10):

    sum ... Z* (2 X** ^∞)

1
Bạn có thể rút ngắn nó bằng cách sử dụng *>$^n.sum==$n. Ngoài ra, không gian không cần thiết giữa my@f
Brad Gilbert b2gills

3

JavaScript (ES6), 61 60 byte

n=>(g=(x,y,z)=>(n>x&&g(y,z,x+y+z)*2)+!(n<x||![n-=x]))(1,2,3)

Tính các số 1-2-3-Triborie cho đến khi đạt đến số ban đầu, sau đó khi đệ quy thư giãn, cố gắng trừ lần lượt từng số một, nhân đôi kết quả khi nó đi.

Chỉnh sửa: Đã lưu 1 byte nhờ @Arnauld.


Ồ Rất đẹp. Có thể n=>(g=(x,y,z)=>(n>x&&g(y,z,x+y+z)*2)+!(n<x||![n-=x]))(1,2,3)lưu một byte?
Arnauld

@Arnauld Tôi đã tìm kiếm thứ gì đó bằng cách sử dụng n<x||nhưng đó ![]chỉ là thiên tài.
Neil

2

Hàng loạt, 151 148 145 byte

@set/ar=0,n=%1
@call:c 3 2 1
@echo %r%
@exit/b
:c
@set/as=%1+%2+%3
@if %n% gtr %3 call:c %s% %*
@set/ar*=2
@if %n% geq %3 set/an-=%3,r+=1

Cổng câu trả lời JavaScript của tôi. Chỉnh sửa: Đã lưu 3 byte bằng cách chuyển các đối số chương trình con của tôi theo thứ tự ngược lại và 3 byte khác bằng cách sử dụng các @s riêng lẻ trên mỗi dòng thay vì @echo off.


2

Thạch , 19 18 17 byte

Ḣx3+
BÇL¡2ị
²Ç€»ċ

Hãy thử trực tuyến!

Lý lịch

Thay vì cố gắng chuyển đổi một số nguyên thành cơ sở 1,2,3-Triborie, sau đó từ nhị phân sang số nguyên, chúng tôi sẽ làm ngược lại: chuyển đổi số nguyên thành nhị phân, sau đó từ cơ sở 1,2,3-Trionacci thành số nguyên và trả về cái cao nhất phù hợp với đầu vào. Điều này dễ dàng được thực hiện.

Chúng tôi sẽ minh họa quá trình cho đầu vào 63 , đặc biệt là bước thử nghiệm 104 . Trong nhị phân, từ chữ số có nghĩa lớn nhất đến chữ số nhỏ nhất, 104 bằng

 1  1  0  1  0  0  0
37 20 11  6  3  2  1

trong đó hàng thứ hai biểu thị các giá trị vị trí của các chữ số đó.

Chúng ta có thể mở rộng chuỗi 1,2,3-Trib sang bên phải, quan sát rằng các chữ số được thêm vào tuân thủ cùng một công thức đệ quy. Đối với ba chữ số, điều này mang lại

 1  1  0  1  0  0  0  0  0  0
37 20 11  6  3  2  1  0  1  0

Bây giờ, để tính giá trị của số 1,2,3-Trib cơ sở, chúng ta có thể sử dụng công thức đệ quy. Vì mỗi số là tổng của ba số ở bên phải (trong bảng trên), chúng ta có thể xóa chữ số đầu tiên và thêm số này vào ba chữ số đầu tiên của mảng còn lại. Sau 7 bước, tương đương với số chữ số nhị phân là 104 , chúng tôi hiếm khi chỉ còn lại ba chữ số.

 1  1  0  1  0  0  0  0  0  0
37 20 11  6  3  2  1  0  1  0

    2  1  2  0  0  0  0  0  0
   20 11  6  3  2  1  0  1  0

       3  4  2  0  0  0  0  0
      11  6  3  2  1  0  1  0

          7  5  3  0  0  0  0
          6  3  2  1  0  1  0

            12 10  7  0  0  0
             3  2  1  0  1  0

               22 19 12  0  0
                2  1  0  1  0

                  41 34 22  0
                   1  0  1  0

                     75 63 41
                      0  1  0

Bây giờ, vì cả chữ số đầu tiên và cuối cùng còn lại đều có giá trị vị trí 0 , kết quả là chữ số giữa, tức là 63 .

Làm thế nào nó hoạt động

²Ç€»ċ   Main link. Argument: n

²       Yield n². Since 1.839² = 3.381921 > 2, the range [1, ..., n²] will contain
        the answer. Better bounds, at the cost of additional bytes are possible.
 Ç€     Map the the second helper link over [1, ..., n²].
   »    Take the maximum of n and each result.
    ċ   Count the occurrences of n.


BÇL¡2ị  Second helper link. Left argument: k. Right argument: n

B       Convert k to binary. Let's call the result A.
  L     Length; count the number of binary digits. Let's call the result l.
 Ç ¡    Apply the first helper link l times to A.
    2ị  Retrieve the second element.


Ḣ×3+    First helper link. Argument: A (array)

Ḣ       Head; pop and yield the first element of A.
 x3     Repeat it thrice.
   +    Add the result, component by component, to the beheaded A.

2

Thạch ( nĩa ), 17 16 byte

ḣ3S;µ¡
3RṚdzæFṪḄ

Đã lưu 1 byte nhờ @Dennis, người đã chơi gôn mà không cần chạy.

Điều này phụ thuộc vào một nhánh của Jelly, nơi tôi thất vọng khi vẫn đang thực hiện một nguyên tử giải quyết Frobenius hiệu quả. Đối với những người quan tâm, tôi muốn phù hợp với tốc độ của FrobeniusSolveMathistica và may mắn thay, có một lời giải thích về họ Mathistica phương pháp trong bài báo "Tạo sự thay đổi và tìm kiếm các chữ số: Cân bằng một chiếc ba lô" của Daniel Lichtblau.

Giải trình

ḣ3S;µ¡  Helper link. Input: a list
    µ   Create monadic chain
ḣ3        Take the first 3 items
  S       Sum
   ;      Prepend to the list
     ¡  Repeat it n (initial argument from main) times

3RṚdzæFṪḄ  Main link. Input: integer n
3          The constant 3
 R         Range. Makes [1, 2, 3]
  Ṛ        Reverse. Makes [3, 2, 1]
   Ç       Call the helper link on that list.
           Generates the first (n+3) 123-Tribonacci values in reverse
    ³      Get n
     æF    Frobenius solve for n using the first n 123-Tribonacci values in reverse
       Ṫ   Tail. Take the last value. The results of Frobenius solve are ordered
           where the last result uses the least
        Ḅ  Unbinary. Convert digits from base 2 to base 10

3
Bạn biết rằng bạn đang tiến sâu vào môn đánh gôn khi bạn đang sử dụng những chiếc dĩa siêu esolang.
Addison Crump

Sẽ ḣ3S;µ¡¶3RṚdzæFṪḄlàm việc? Tôi chưa cài đặt nĩa của bạn, vì vậy tôi không thể kiểm tra.
Dennis

@Dennis Đó là lấy đầu vào từ stdin không phải đối số, phải không? Tôi đã gặp khó khăn khi sử dụng các đối số và chỉ nhận ra nó hoạt động theo cách khác.
dặm

Không, đó vẫn nên là đối số. ³tham chiếu đối số đầu tiên.
Dennis

@Dennis Nvm, nó hoạt động bằng các đối số, tôi jelly.pyđã có một số thứ khác trong đó sau lần cam kết cuối cùng đó.
dặm

1

dc , 110 102 byte

?se1sa2sb3sc_1sf[laddSdlbdsalcdsb++sclf1+sfle>y]dsyx0sk[lk2lf^+skler-se]sr[Lddle!<rlf1-dsf0!>z]dszxlkp

Chà, có vẻ như những bộ óc vĩ đại cũng nghĩ giống nhau. Rõ ràng, thuật toán mà tôi nghĩ ra để khắc phục những hạn chế của dcnó là trùng khớp chính xác với thuật toán được sử dụng trong câu trả lời của @ LliwTelrac. Hấp dẫn.

Hãy thử trực tuyến!



1

tiện ích bash + BSD (OS X, v.v.), 53 byte

jot $[2#$1**4]|egrep -v '[2-9]|11(1|$)'|sed $[2#$1]!d

tiện ích bash + GNU (cũng hoạt động theo BSD), 59 byte

seq -f2o%.fp $[2#$1**2]|dc|egrep -v '11(1|$)'|sed $[2#$1]!d

Đầu vào và đầu ra trong cả hai ở trên là ở dạng nhị phân.


Hãy thử phiên bản GNU tại TIO. (Ví dụ được liên kết để thể hiện đầu vào của 111111, là 63 ở dạng nhị phân và đầu ra là 1101000, là 104 ở dạng nhị phân.)

Tôi không nghĩ TIO cung cấp tùy chọn BSD, nhưng nếu bạn có sẵn máy Mac, bạn có thể thử cả hai ở ngoài đó. (Chương trình 59-byte là nhiều nhanh hơn so với chương trình 53-byte).


Thật không may, seqđơn giản là không thể bỏ vào giải pháp BSD thay jotvì định dạng đầu ra choseq khác với các đầu ra trên 999999. (Điều này bắt đầu là một vấn đề đối với các đầu vào khoảng 32, kể từ 32 ^ 4> 1000000.)

Bạn có thể thay thế jotở trên seq -f%.fđể làm cho điều này hoạt động với các tiện ích GNU, nhưng với cùng 59 byte, bạn có thể sử dụng giải pháp GNU ở trên, nhanh hơn nhiều.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.