Tổng kết dưới Đại diện Zeckendorf


14

Định lý của Zeckendorf cho thấy rằng mọi số nguyên dương có thể được biểu diễn duy nhất dưới dạng tổng của các số Fibonacci không liền kề. Trong thử thách này, bạn phải tính tổng của hai số trong biểu diễn Zeckendorf.


Đặt F n là số Fibonacci thứ n trong đó

F 1 = 1,
F 2 = 2 và
với mọi k > 2, F k = F k - 1 + F k - 2 .

Biểu diễn Zeckendorf Z ( n ) của số nguyên n không âm là tập hợp các số nguyên dương sao cho

n = Σ i ∈ Z ( n ) F i   và
i ∈ Z ( n ) i + 1 ∉ Z ( n ).

(trong prosa: đại diện Zeckendorf của một số n là một tập hợp các số nguyên dương sao cho các số Fibonacci cho các chỉ số này tổng hợp thành n và không có hai số nguyên liền kề nào là một phần của tập hợp đó)

Đáng chú ý, đại diện Zeckendorf là ​​duy nhất. Dưới đây là một số ví dụ cho các đại diện của Zeckendorf:

Z (0) = ∅ (tập hợp trống)
Z (1) = {1}
Z (2) = {2}
Z (3) = {3} ({1, 2} không phải là đại diện Zeckendorf của 3)
Z (10) = {5, 2}
Z (100) = {3, 5, 10}

Trong thử thách này, các biểu diễn Zeckendorf được mã hóa dưới dạng các tập bit trong đó bit đại diện ít quan trọng nhất nếu 1là một phần của tập hợp, v.v. Bạn có thể giả sử rằng các biểu diễn Zeckendorf của cả đầu vào và đầu ra khớp với 31 bit.

Nhiệm vụ của bạn là tính Z ( n + m ) đã cho Z ( n ) và Z ( m ). Giải pháp có độ dài ngắn nhất trong octet thắng.

Bạn có thể tìm thấy một triển khai tham chiếu được viết bằng ANSI C tại đây . Nó cũng có thể được sử dụng để tạo các biểu diễn Zeckendorf hoặc tính một số từ biểu diễn Zeckendorf của nó.

Dưới đây là một số cặp đầu vào và đầu ra mẫu, trong đó hai cột đầu tiên chứa đầu vào và cột thứ ba chứa đầu ra:

73865           9077257         9478805
139808          287648018       287965250
34              279004309       279004425
139940          68437025        69241105
272794768       1051152         273846948
16405           78284865        83888256
9576577         4718601         19013770
269128740       591914          270574722
8410276         2768969         11184785
16384           340             16724

4
Bạn có thể vui lòng xây dựng Đầu vào / Đầu ra?
flawr

@flawr Xin hãy xem triển khai tham khảo được cung cấp. Bạn có thể sử dụng nó để tạo đầu vào mẫu của riêng bạn.
FUZxxl

3
Tôi rất vui nếu bạn có thể ghi lại ở đây chính xác những gì bạn muốn và cung cấp một số ví dụ, như tôi, và có lẽ những người khác cũng vậy, không thông thạo C.
flawr

Tôi không đồng ý với lập luận duy nhất. Vì chuỗi Fibonacci bắt đầu bằng 1, 1, 2, bạn có thể phân tách rõ ràng 3 thành F0 + F2 = 1 + 2 = 3. F0 và F2 không liền kề nhau.
orlp

1
@orlp Chuỗi Fibonacci được xác định ở đây bắt đầu bằng F1 = 1 và F2 = 2. Vì vậy, cách tôi đọc nó, F0 từ định nghĩa của bạn không phải là một phần của chuỗi được sử dụng ở đây.
Reto Koradi

Câu trả lời:


5

K (ngn / k) , 45 43 42 41 byte

{2/<':(+/F@&+/'|2\x){y!x}\|F:64(+':1,)/0}

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

Thuật toán @ Bubbler's

{ } chức năng với đối số x

64( )/0 làm 64 lần, sử dụng 0 làm giá trị ban đầu:

  • 1, trả trước 1

  • +': thêm từng cái trước (giữ nguyên phần tử đầu tiên)

F:gán Fcho "Chuỗi trình tự"

| đảo ngược

(.. ){y!x}\.. bắt đầu bằng giá trị bên trái, tính toán phần dư tích lũy (từ trái sang phải) cho danh sách bên phải. giá trị bên trái là tổng đơn vị của các đầu vào không có đại diện zeckendorf:

  • 2\xmã hóa nhị phân đầu vào. đây sẽ là ma trận nbits-by-2

  • | đảo ngược

  • +/' tổng hợp từng

  • &1s ở đâu? - danh sách các chỉ số. nếu có 2 giây, chỉ số tương ứng được lặp lại hai lần.

  • F@ lập chỉ mục mảng vào F

  • +/ Tổng

<': ít hơn mỗi lần trước (kết quả đầu tiên sẽ luôn là falsey)

2/ giải mã nhị phân


10

CJam, 76 74 70 63 59 byte

2q~{32{2\#I&},}fI+32_,*{WUer$Kf-[UU]/[-2X]*2,/2a*Kf+}fKf#1b

Hãy thử trực tuyến trong trình thông dịch CJam hoặc xác minh tất cả các trường hợp thử nghiệm cùng một lúc .

Ý tưởng

Chúng tôi bắt đầu bằng cách xác định một biến thể nhỏ của chuỗi trong câu hỏi:

G -2 = 0
G -1 = 1
G k = G k - 1 + G k - 2 bất cứ khi nào k là số nguyên không âm

Theo cách này, bit 0 (LSB) của đầu vào hoặc đầu ra của mảng bit tương ứng với số Fibonacci G 0 và nói chung, bit k đến G k .

Bây giờ, chúng ta thay thế từng bit được đặt trong Z (n)Z (m) bằng chỉ mục mà nó mã hóa.

Ví dụ: đầu vào 532 10 = 1000010100 2 được chuyển thành [2 4 9] .

Điều này mang lại hai mảng số nguyên, mà chúng ta có thể ghép để tạo thành một số nguyên.

Ví dụ: nếu n = m = 100 , kết quả là A: = [2 4 9 2 4 9] .

Nếu chúng ta thay thế từng k trong A bằng G k và thêm kết quả, chúng ta thu được n + m = 200 , vì vậy Amột cách để phân tách 200 thành các số Fibonacci, nhưng chắc chắn không phải là một trong định lý của Zeckendorf.

Hãy nhớ rằng G k + G k + 1 = G k + 2G k + G k = G k + G k - 1 + G k - 2 = G k + 1 + G k - 2 , chúng ta có thể thay thế liên tiếp và các chỉ mục trùng lặp bởi những người khác (cụ thể là (k, k + 1) bởi k + 2(k, k) bởi (k + 1, k - 2) ), lặp đi lặp lại những thay thế đó cho đến khi đạt được đại diện Zeckendorf. 1

Trường hợp đặc biệt phải được thực hiện cho các chỉ số tiêu cực. Vì G -2 = 0 , chỉ số -2 có thể bị bỏ qua. Ngoài ra, G -1 = 0 = G 0 , do đó, mọi kết quả -1 phải được thay thế bằng 0 .

Đối với ví dụ A của chúng tôi, chúng tôi có được các đại diện (được sắp xếp) sau đây, cuối cùng là đại diện Zeckendorf.

[2 2 4 4 9 9] → [0 3 4 4 9 9] → [0 5 4 9 9] → [0 6 9 9] → [0 6 7 10] → [0 8 10]

Cuối cùng, chúng tôi chuyển đổi trở lại từ mảng số nguyên sang mảng bit.

2             e# Push a 2 we'll need later.
q~            e# Read and evaluate the input.
{             e# For each integer I in the input:
  32{         e#   Filter [0 ... 31]; for each J:
    2\#       e#     Compute 2**J.
    I&        e#     Compute its logical AND with I.
  },          e#   Keep J if the result in truthy (non-zero).
}fI           e#
+             e# Concatenate the resulting arrays.
32_,*         e# Repeat [0 ... 31] 32 times.
{             e# For each K:
  WUer        e#   Replace -1's with 0's.
  $           e#   Sort.
  Kf-         e#   Subtract K from each element.
  [UU]/[-2X]* e#   Replace subarrays [0 0] with [-2 1].
  2,/2a*      e#   Replace subarrays [0 1] with [2].
  Kf+         e#   Add K to each element.
}fK           e#
f#            e# Replace each K with 2**K.
1b            e# Cast all to integer (discards 2**-2) and sum.

1 Việc triển khai cố gắng thay thế 32 lần và không kiểm tra xem có đạt được đại diện Zeckendorf hay không. Tôi không có bằng chứng chính thức rằng điều này là đủ, nhưng tôi đã kiểm tra tất cả các khoản tiền có thể có của các biểu diễn 15 bit (các biểu diễn của tổng yêu cầu tối đa 17 bit) và 6 lần lặp lại là đủ cho tất cả chúng. Trong mọi trường hợp, có thể tăng số lần lặp lại lên 99 mà không cần tăng số byte, nhưng nó sẽ làm tê liệt hiệu năng.


10

APL (Dyalog Extended) , 39 byte

1↓⍧|/⌽(+/g[⍸⌽+/⊤⎕]),↑,\⌽g←(2+/,)⍣38⍨⍳2

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

Đã thay đổi thành một chương trình đầy đủ lấy một đối số có độ dài 2 và cũng thay đổi trình tạo Fibonacci. Cảm ơn @ngn vì rất nhiều ý tưởng.

Sử dụng ⎕IO←0để ⍳2đánh giá 0 1.

Trình tạo Fibonacci (mới)

Lưu ý rằng hai số cuối không chính xác, nhưng nó không thay đổi đầu ra của chương trình.

(2+/,)⍣38⍨⍳2
 0 1 ((2+/,)⍣38) 0 1

Step 1
0 1 (2+/,) 0 1
 2+/ 0 1 0 1
 (0+1) (1+0) (0+1)  2+/ evaluates sums for moving window of length 2
 1 1 1

Step 2
0 1 (2+/,) 1 1 1
 2+/ 0 1 1 1 1
 1 2 2 2

Step 3
0 1 (2+/,) 1 2 2 2
 2+/ 0 1 1 2 2 2
 1 2 3 4 4

Zeckendorf để đơn giản (một phần)

⍸⌽+/⊤⎕
        Take input from stdin, must be an array of 2 numbers
        Convert each number to base 2; each number is mapped to a column
  +/     Sum in row direction; add up the counts at each digit position
        Reverse
        Convert each number n at index i to n copies of i

APL (Dyalog Extended) , 47 byte

g1↓(1,+\⍤,)⍣201
{⊥1↓⍧|/⌽⍵,↑,\⌽g}+⍥{+/g[⍸⌽⊤⍵]}

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

Đã thay đổi Phần 1 của câu trả lời trước để sử dụng lại các số Fibonacci. Ngoài ra, thả bản sao 1 để lưu một số byte ở những nơi khác.

Phần 1 (mới)

{+/g[⍸⌽⊤⍵]}
       ⊤⍵     Argument to binary digits
     ⍸⌽       Reverse and convert to indices of ones
   g[    ]    Index into the Fibonacci array of 1,2,3,5,...
 +/           Sum

APL (Dyalog Extended) , 52 byte

{⊥1↓¯1↓⍧|/⌽⍵,↑,\⌽(1,+\⍤,)⍣201}+⍥({+∘÷⍣(⌽⍳≢⊤⍵)⍨1}⊥⊤)

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

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

Không có thuật toán ưa thích nào để thực hiện bổ sung trong Zeckendorf vì APL không được biết đến để hoạt động trên các phần tử riêng lẻ trong một mảng. Thay vào đó, tôi đã đi trước để chuyển đổi hai đầu vào từ Zeckendorf sang số nguyên đơn giản, thêm chúng và chuyển đổi lại.

Phần 1: Zeckendorf thành số nguyên

{+∘÷⍣(⌽⍳≢⊤⍵)⍨1}⊥⊤   Zeckendorf to plain integer
                   Convert the input to array of binary digits (X)
{    (  ≢⊤⍵)  }     Take the length L of the binary digits and
      ⌽⍳              generate 1,2..L backwards, so L..2,1
{+∘÷⍣(     )⍨1}     Apply "Inverse and add 1" L..2,1 times to 1
                    The result looks like ..8÷5 5÷3 3÷2 2 (Y)
                   Mixed base conversion of X into base Y

Base |             Digit value
-------------------------------
13÷8 | (8÷5)×(5÷3)×(3÷22 = 8
 8÷5 |       (5÷3)×(3÷22 = 5
 5÷3 |             (3÷22 = 3
 3÷2 |                   2 = 2
 2÷1 |                   1 = 1

Phần 2: Thêm hai số nguyên đơn giản

+⍥z2i   Given left and right arguments,
          apply z2i to each of them and add the two

Phần 3: Chuyển đổi tổng trở lại Zeckendorf

"Bạn có thể giả sử rằng các biểu diễn Zeckendorf của cả đầu vào và đầu ra khớp với 31 bit" khá tiện dụng.

{⊥1↓¯1↓⍧|/⌽⍵,↑,\⌽(1,+\⍤,)⍣201}   Convert plain integer N to Zeckendorf
                 (1,+\⍤,)⍣201    First 41 Fibonacci numbers starting with two 1's
                ⌽                ⍝ Reverse
             ↑,\                 ⍝ Matrix of prefixes, filling empty spaces with 0's
          ⌽⍵,                     Prepend N to each row and reverse horizontally
        |/                        Reduce by | (residue) on each row (see below)
                                 Nub sieve; 1 at first appearance of each number, 0 otherwise
  1↓¯1                           Remove first and last item
                                 Convert from binary digits to integer

Trình tạo Fibonacci

(1,+\⍤,)⍣201
 1 ((1,+\⍤,)⍣20) 1   Expand 
 Apply 1 (1,+\⍤,) x 20 times to 1

First iteration
1(1,+\⍤,)1
 1,+\1,1   Expand the train
 1,1 2     +\ is cumulative sum
 1 1 2     First three Fibonacci numbers

Second iteration
1(1,+\⍤,)1 1 2
 1,+\1,1 1 2   Expand the train
 1 1 2 3 5     First five Fibonacci numbers

20   ... Repeat 20 times

Điều này xuất phát từ thuộc tính của các số Fibonacci: nếu Fibonacci được định nghĩa là

F0=F1=1;n0,Fn+2=Fn+1+Fn

sau đó

n0,i=0nFi=Fn+21

1,F0,,FnF1,,Fn+2

Các chữ số Fibonacci đến Zeckendorf

Input: 7, Fibonacci: 1 1 2 3 5 8 13

Matrix
0 0 0 0 0 0 13 7
0 0 0 0 0 8 13 7
0 0 0 0 5 8 13 7
0 0 0 3 5 8 13 7
0 0 2 3 5 8 13 7
0 1 2 3 5 8 13 7
1 1 2 3 5 8 13 7

Reduction by residue (|/)
- Right side always binds first.
- x|y is equivalent to y%x in other languages.
- 0|y is defined as y, so leading zeros are ignored.
- So we're effectively doing cumulative scan from the right.
0 0 0 0 0 0 13 7 → 13|7 = 7
0 0 0 0 0 8 13 7 →  8|7 = 7
0 0 0 0 5 8 13 7 →  5|7 = 2
0 0 0 3 5 8 13 7 →  3|2 = 2
0 0 2 3 5 8 13 7 →  2|2 = 0
0 1 2 3 5 8 13 7 →  1|0 = 0
1 1 2 3 5 8 13 7 →  1|0 = 0
Result: 7 7 2 2 0 0 0

Nub sieve (⍧): 1 0 1 0 1 0 0
1's in the middle are produced when divisor  dividend
(so it contributes to a Zeckendorf digit).
But the first 1 and last 0 are meaningless.

Drop first and last (1↓¯1↓): 0 1 0 1 0
Finally, we apply base 2 to integer (⊥) to match the output format.

6

Haskell, 325 396 byte

EDIT: phiên bản mới:

s f[]=[]
s f l=f l
x((a:b):(c:d):(e:r))=x(b:d:(a:e):r)
x(a:b:((c:d:e):r))=x((c:a):b:e:((d:s head r):s tail r))
x[]=[]
x(a:r)=a:x r
w l|x l/=l=w.x$l|True=l
l=length
t n x=take n$repeat x
j 0=[]
j n=t(mod(n)2)1:j(div(n)2)
i n=[[],[]]++j n++t(32-(l$j n))[]
u[]=0
u(a:r)=2*u r+l a
o(_:a:r)=u r+l a
z a b=o$w$zipWith(++)(i a)(i b)

z Làm công việc.


Một số nội dung có thể được rút ngắn ngay lập tức - ví dụ chức năng có quyền ưu tiên cao nhất, vì vậy bạn có thể loại bỏ cha mẹ xung quanh các ứng dụng chức năng, và cả những người bảo vệ cũng không cần cha mẹ - bảo vệ dừng lại ở đó =, vì vậy cha mẹ không cần thiết , vân vân và vân vân, và lưu ý rằng :liên kết ở bên phải và bạn có thể cắt một số ở đó. Nhưng, dù sao đi nữa, chúc mừng! Trông rất phức tạp. Không thể chờ đợi để tìm hiểu làm thế nào điều này hoạt động!
tự hào

@proudhaskeller Mặc dù vậy, vô cùng phức tạp, hãy xem bản chỉnh sửa của tôi. Tôi sẽ giải thích ý tưởng cơ bản? Nó có thể là một cách khác tốt hơn, nhưng tôi đã cố gắng thực hiện càng nhiều khớp mẫu càng tốt. À, bởi cha mẹ, ý bạn là dấu ngoặc đơn: golf'd đó!
Leif Willerts

chillax, đó là lần đầu tiên của bạn ở đây. Nếu bạn ở lại lâu, bạn sẽ phát triển tốt hơn nhiều. Hãy chắc chắn kiểm tra câu hỏi mẹo chơi gôn Haskell cho một số codegolf.stackexchange.com/questions/19255/ mẹo
kỵ sĩ kiêu hãnh

@proudhaskeller chỉnh sửa đã đến ...
Leif Willerts

4

ES6, 130 byte

(n,m)=>{for(a={},s=0,i=x=y=1;i<<1;i+=i,z=y,y=x,x+=z)s+=((n&i)+(m&i))/i*(a[i]=x);for(r=0;i;i>>>=1)s>=a[i]?(s-=a[i],r|=i):0;return r}

Ban đầu, tôi đã cố gắng tính tổng tại chỗ (có hiệu quả dọc theo các dòng của việc triển khai CJam) nhưng tôi đã hết thời gian, vì vậy tôi chỉ chuyển đổi các số sang và lấy lại từ các số nguyên thực.

(Có, tôi có thể có thể lưu một byte bằng cách sử dụng eval.)


1

Ruby , 85 73 65 byte

->*a{r=(0..2*a.sum).select{|r|r^r*2==r*3};r[a.sum{|w|r.index w}]}

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

Làm sao?

Trước tiên, lấy giới hạn trên cho tổng được mã hóa: (a + b) * 2 là ok.

Bây giờ lọc ra tất cả các số không phải zeckendorf từ (0..limit).

Chúng tôi có một bảng tra cứu, nó xuống dốc từ đây.


1

Python 3, 207 byte

def s(n):
 p=1
 while n>=2*p:
  p*=2
 return n if n<=p else s(n+p//2)if n>=3*p/2 else s(m)if (m:=s(n-p)+p)!= n else n
a=lambda n,m:(b:=n&m)>-1 and s(a(a(a(s((n|m)-b%4),b//4*2),b//4),b%4*2+b%4//2))if m else n

Hãy thử trực tuyến! (Xác minh tất cả các trường hợp thử nghiệm)

Giải trình

Chương trình này trực tiếp thao tác các bản dịch nhị phân của các đại diện Zeckendorf. Hàm a(n,m)thực hiện các phép tính chính và s(n)là hàm trợ giúp loại bỏ các số liền kề có trong biểu diễn Zeckendorf.

Hãy bắt đầu với chức năng s(n)(mở rộng cho rõ ràng):

def s(n): 
    p=1                  #This finds the highest digit of the binary form of n.
    while n>=2*p:
        p*=2
    if n<=p:             #If n is a power of two (i.e, our number is already a Fibonnaci number)...
        return n         #Then return it normally.  This also works for zero. (A)
    if n>=3*p/2:         #If n's first digit is followed by a 1 (i.e, it starts with 11X)
        return s(n+p//2) #Then replace that with 100X (B)
    m = s(n-p)+p         #Otherwise, apply s to the rest of the number (C)
    if m==n:             #If this is out final result, we're done! (D)
        return n
    return s(m)          #Otherwise, reapply it. (E)

Ví dụ: số 107 ( 1101011ở dạng nhị phân, đại diện cho 1 + 2 + 5 + 13 + 21 = 42), trải qua quá trình sau:

1+2+5+13+21 [1101011] -> 1+2+5+34 [10001011] (B)
1+2+5+34 [10001011] (C)
 1+2+5 [1011] (C)
  1+2 [11] -> 3 [100] (B)
 ->3+5 [1100] (A/E)
 (E):  3+5 [1100] -> 8 [10000] (B)
->8+34 [10010000] (A/E)
(E): 8+34 [10010000] (C)
->8+34 [10010000] (A/E)

Hãy thử trực tuyến! (s với đầu ra chi tiết)

Đây là phiên bản mở rộng của a(n,m):

def a(n,m):
    if m==0:
        return n
    b=n&m
    t=s((n|m)-b%4)              #(A)
    t=a(t,b//4*2)               #(B)
    t=a(t,b//4)                 #(C)
    return s(a(t,b%4*2+b%4//2)) #(D)

Hàm này chuyển đổi hai biểu diễn Zeckendorf thành bốn số nhị phân dễ kết hợp hơn. Dòng (A) là bit OR HOẶC của hai biểu diễn Zeckendorf nhị phân - chúng tương ứng với một bản sao của mỗi số Fibonacci trong một trong hai nhóm. (B) và (C) lần lượt là AND của hai số lần lượt dịch phải 1 và 2 lần. Chúng ta biết rằng khi các số Fibonacci tương ứng cho (B) và (C) được cộng lại với nhau, chúng sẽ tương đương với bitwise AND của chúng ta nmvì F (n) = F (n-1) + F (n-2) .

Ví dụ: giả sử rằng chúng ta có các số nhị phân n = 101001 (tương ứng với 1 + 5 + 13) và m = 110110 (2 + 3 + 8 + 13). Sau đó, chúng ta sẽ có (A) = 111111 (1 + 2 + 3 + 5 + 8 + 13), được chuyển đổi thành 1010100 (3 + 8 + 21) theo chức năng của chúng tôi s, (B) = 10000 (8) và ( C) = 1000 (5). Chúng ta có thể kiểm tra xem (1 + 5 + 13) + (2 + 3 + 8 + 13) = (3 + 8 + 21) + (8) + (5) = 45. Quá trình này lặp lại với ((3 + 8 + 21) + (8)) + (5) = ((3 + 8 + 21) + (5) + (3)) + (5), v.v.

Một khó khăn với hệ thống này là nó không hoạt động đối với các số Fibonacci 1 và 2, vì chúng không tuân theo thuộc tính F(n)=F(n-1)+F(n-2)(chúng là hai số thấp nhất)! Do đó, bất cứ khi nào 1 hoặc 2 được chứa trong cả hai nm, chúng sẽ bị xóa khỏi A, B và C, sau đó tổng của chúng được đặt trong D dưới thuộc tính rằng 1 + 1 = 2 và 2 + 2 = 1 + 3. Ví dụ: nếu chúng ta thêm 1 + 3 (101) + 1 + 3 + 5 (1101), chúng ta sẽ nhận được:

(A): 3 + 5 (1100) = 8 (10000)

(B): 2 (10)

(C): 1 (1)

(D): 2 (10)

Lưu ý rằng 3 và 5 được đặt vào A, 3 trùng lặp được chia thành 2 + 1 trong B và C, và các bản sao 1 được xóa khỏi A, B và C, được thêm vào và thêm vào D. Tương tự, nếu chúng ta thêm 2 + 3 (110) + 2 + 3 + 5 (1110), chúng tôi nhận được:

(A): 3 + 5 (1100) = 8 (10000)

(B): 2 (10)

(C): 1 (1)

(D): 1 + 3 (101)

Hãy thử trực tuyến! (một đầu ra chi tiết)


0

Ngôn ngữ Wolfram (Mathicala) , 218 byte

Fold[#+##&,Total@PadLeft@IntegerDigits[#,2]//.{{p=n_/;n>1,r=y___}:>{0,n,y},{q=x___,i_,p,j_,k_,r}:>{x,i+1,n-2,j,k+1,y},{q,i_,p,j_}:>{x,i+1,n-2,j+1},{q,i_,p}:>{x,i+1,n-2},{1,1,r}:>{1,0,0,y},{q,i_,1,1,r}:>{x,i+1,0,0,y}}]&

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

Đơn giản chỉ cần khớp mẫu.

Ung dung:

FromDigits[Total@PadLeft@IntegerDigits[#, 2] //.
   {{n_ /; n > 1, y___} :> {0, n, y},
    {x___, i_, n_ /; n > 1, j_, k_, y___} :> {x, i + 1, n - 2, j, k + 1, y},
    {x___, i_, n_ /; n > 1, j_} :> {x, i + 1, n - 2, j + 1},
    {x___, i_, n_ /; n > 1} :> {x, i + 1, n - 2},
    {1, 1, y___} :> {1, 0, 0, y},
    {x___, i_, 1, 1, y___} :> {x, i + 1, 0, 0, y}}, 2] &
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.