Penjumlahan di bawah Representasi Zeckendorf

14

Teorema Zeckendorf menunjukkan bahwa setiap bilangan bulat positif dapat secara unik direpresentasikan sebagai jumlah angka Fibonacci yang tidak berdekatan. Dalam tantangan ini, Anda harus menghitung jumlah dua angka dalam representasi Zeckendorf.


Biarkan F n menjadi nomor Fibonacci ke- n di mana

F 1 = 1,
F 2 = 2 dan
untuk semua k > 2, F k = F k - 1 + F k - 2 .

The Zeckendorf representasi Z ( n ) dari bilangan bulat non-negatif n adalah himpunan bilangan bulat positif sehingga

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

(dalam bahasa prosa: representasi Zeckendorf dari angka n adalah himpunan bilangan bulat positif sehingga angka Fibonacci untuk indeks ini berjumlah hingga n dan tidak ada dua bilangan bulat yang berdekatan adalah bagian dari himpunan itu)

Khususnya, representasi Zeckendorf unik. Berikut adalah beberapa contoh untuk representasi Zeckendorf:

Z (0) = ∅ (set kosong)
Z (1) = {1}
Z (2) = {2}
Z (3) = {3} ({1, 2} bukan representasi Zeckendorf dari 3)
Z (10) = {5, 2}
Z (100) = {3, 5, 10}

Dalam tantangan ini, representasi Zeckendorf dikodekan sebagai set bit di mana bit paling signifikan mewakili jika 1merupakan bagian dari set, dll. Anda dapat mengasumsikan bahwa representasi Zeckendorf dari input dan output cocok menjadi 31 bit.

Tugas Anda adalah menghitung Z ( n + m ) yang diberikan Z ( n ) dan Z ( m ). Solusi dengan panjang terpendek dalam kemenangan oktet.

Anda dapat menemukan implementasi referensi yang ditulis dalam ANSI C di sini . Itu juga dapat digunakan untuk menghasilkan representasi Zeckendorf atau menghitung angka dari representasi Zeckendorf-nya.

Berikut adalah beberapa pasang sampel input dan output, di mana dua kolom pertama berisi input dan kolom ketiga berisi output:

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
FUZxxl
sumber
4
Bisakah Anda menguraikan Input / Output?
flawr
@ flawr Silakan lihat implementasi referensi yang disediakan. Anda dapat menggunakannya untuk menghasilkan input sampel Anda sendiri.
FUZxxl
3
Saya akan senang jika Anda dapat mendokumentasikan apa yang Anda inginkan di sini dan memberikan beberapa contoh, seperti saya, dan mungkin yang lain juga, tidak lancar dalam C.
flawr
Saya tidak setuju dengan argumen keunikan. Karena deret Fibonacci dimulai dengan 1, 1, 2 Anda dapat dengan jelas menguraikan 3 menjadi F0 + F2 = 1 + 2 = 3. F0 dan F2 tidak berdekatan.
orlp
1
@ orlp Urutan Fibonacci yang didefinisikan di sini dimulai dengan F1 = 1 dan F2 = 2. Jadi cara saya membacanya, F0 dari definisi Anda bukan bagian dari urutan yang digunakan di sini.
Reto Koradi

Jawaban:

5

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

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

Cobalah online!

@ Algoritma Bubbler

{ } berfungsi dengan argumen x

64( )/0 lakukan 64 kali, menggunakan 0 sebagai nilai awal:

  • 1, tambahkan 1

  • +': tambahkan setiap sebelumnya (biarkan elemen pertama utuh)

F:ditugaskan Funtuk "Urutan fibonacci"

| balik

(.. ){y!x}\.. dimulai dengan nilai di sebelah kiri, hitung sisa kumulatif (kiri-ke-kanan) untuk daftar di sebelah kanan. nilai di sebelah kiri adalah jumlah sederhana dari input tanpa representasi zeckendorf:

  • 2\xbiner mengkodekan input. ini akan menjadi matriks nbits-by-2

  • | balik

  • +/' jumlahkan masing-masing

  • &dimana 1s? - daftar indeks. jika ada 2s, indeks yang sesuai diulang dua kali.

  • F@ pengindeksan array menjadi F

  • +/ jumlah

<': kurang dari masing-masing sebelumnya (yang pertama hasilnya akan selalu palsu)

2/ decode biner

ngn
sumber
10

CJam, 76 74 70 63 59 byte

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

Cobalah online di juru bahasa CJam atau verifikasi semua kasus uji sekaligus .

Ide

Kita mulai dengan mendefinisikan variasi kecil dari urutan dalam pertanyaan:

G -2 = 0
G -1 = 1
G k = G k-1 + G k-2 setiap kali k adalah bilangan bulat non-negatif

Dengan cara ini, bit 0 (LSB) dari bit array input atau output sesuai dengan angka Fibonacci G 0 dan, secara umum, bit k ke G k .

Sekarang, kami mengganti setiap bit dalam Z (n) dan Z (m) dengan indeks yang dikodekan.

Misalnya, input 532 10 = 1000010100 2 ditransformasikan menjadi [2 4 9] .

Ini menghasilkan dua array integer, yang dapat kita gabungkan untuk membentuk satu array.

Misalnya, jika n = m = 100 , hasilnya adalah A: = [2 4 9 2 4 9] .

Jika kita mengganti setiap k di A dengan G k dan menambahkan hasil, kita memperoleh n + m = 200 , sehingga A adalah suatu cara untuk menguraikan 200 menjadi angka Fibonacci, tetapi tentu bukan satu dari teorema Zeckendorf ini.

Perlu diingat bahwa G k + G k + 1 = G k + 2 dan G k + G k = G k + G k-1 + G k-2 = G k + 1 + G k-2 , kita bisa mengganti berturut-turut dan indeks yang digandakan oleh orang lain (yaitu, (k, k + 1) oleh k + 2 dan (k, k) oleh (k + 1, k - 2) ), mengulangi pergantian-pergantian itu berulang-ulang sampai perwakilan Zeckendorf tercapai. 1

Kasus khusus harus diambil untuk menghasilkan indeks negatif. Karena G -2 = 0 , indeks -2 dapat diabaikan begitu saja. Juga, G -1 = 0 = G 0 , jadi setiap -1 yang dihasilkan harus diganti dengan 0 .

Sebagai contoh kami A , kami mendapatkan representasi (diurutkan) berikut, yang terakhir adalah representasi 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]

Akhirnya, kami mengkonversi kembali dari array integer ke array bit.

Kode

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 Implementasi mencoba menggantikan 32 kali dan tidak memeriksa apakah representasi Zeckendorf telah tercapai. Saya tidak memiliki bukti formal bahwa ini sudah cukup, tetapi saya sudah menguji semua kemungkinan jumlah representasi 15-bit (yang jumlah penjumlahannya membutuhkan hingga 17 bit) dan 6 pengulangan sudah cukup untuk semuanya. Dalam kasus apa pun, menambah jumlah pengulangan ke 99 dimungkinkan tanpa menambah jumlah byte, tetapi itu akan melumpuhkan kinerja.

Dennis
sumber
10

APL (Dyalog Extended) , 39 byte

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

Cobalah online!

Berubah menjadi program lengkap yang mengambil satu argumen dengan panjang 2, dan juga mengubah generator Fibonacci. Terima kasih kepada @ngn untuk banyak ide.

Digunakan ⎕IO←0sehingga ⍳2dievaluasi menjadi 0 1.

Generator Fibonacci (baru)

Perhatikan bahwa dua angka terakhir tidak akurat, tetapi tidak mengubah output program.

(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 ke polos (sebagian)

⍸⌽+/⊤⎕
        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[⍸⌽⊤⍵]}

Cobalah online!

Mengubah Bagian 1 dari jawaban sebelumnya untuk menggunakan kembali angka Fibonacci. Juga, letakkan duplikat 1 untuk menyimpan beberapa byte di tempat lain.

Bagian 1 (baru)

{+/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}⊥⊤)

Cobalah online!

Bagaimana itu bekerja

Tidak ada algoritma yang bagus untuk melakukan penambahan di Zeckendorf karena APL tidak dikenal untuk operasi pada elemen individu dalam sebuah array. Sebagai gantinya, saya melanjutkan untuk mengubah dua input dari Zeckendorf ke integer polos, menambahkannya, dan mengubahnya kembali.

Bagian 1: Zeckendorf to plain integer

{+∘÷⍣(⌽⍳≢⊤⍵)⍨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

Bagian 2: Tambahkan dua bilangan bulat polos

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

Bagian 3: Konversi jumlah kembali ke Zeckendorf

"Anda dapat berasumsi bahwa representasi Zeckendorf dari input dan output cocok menjadi 31 bit" cukup berguna.

{⊥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

Generator 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

Ini mengikuti dari properti nomor Fibonacci: jika Fibonacci didefinisikan sebagai

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

kemudian

n0,saya=0nFsaya=Fn+2-1

1,F0,,FnF1,,Fn+2

Digit Fibonacci ke 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.
Bubbler
sumber
6

Haskell, 325 396 byte

EDIT: versi baru:

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 melakukan pekerjaan.

Leif Willerts
sumber
Beberapa hal dapat langsung dipersingkat - misalnya fungsi memiliki prioritas tertinggi, sehingga Anda dapat membasmi orang tua di sekitar aplikasi fungsi, dan juga penjaga tidak memerlukan orang tua juga - penjaga berhenti di mana saja =, sehingga orang tua di sana tidak diperlukan , dan seterusnya dan seterusnya, dan perhatikan bahwa :mengaitkan ke kanan dan Anda dapat memotong beberapa di sana. Tapi, selamat, selamat! Terlihat sangat rumit. Tidak sabar untuk mencari tahu bagaimana ini bekerja!
haskeller bangga
@proudhaskeller Tidak ada yang rumit, lihat edit saya. Haruskah saya menjelaskan ide dasarnya? Mungkin lebih baik cara lain, tetapi saya mencoba melakukan pencocokan pola sebanyak mungkin pada awalnya. Ah, yang Anda maksud orang tua adalah tanda kurung: golf'd that!
Leif Willerts
chillax, ada di kali pertama Anda di sini. Jika Anda tinggal lama, Anda akan tumbuh jauh lebih baik. Pastikan untuk memeriksa pertanyaan kiat bermain golf Haskell untuk mengetahui codegolf.stackexchange.com/questions/19255/…
haskeller bangga
sunting @proudhaskeller tiba ...
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}

Saya awalnya mencoba menghitung jumlah di tempat (efektif sepanjang garis implementasi CJam) tetapi saya terus kehabisan sementara, jadi saya hanya mengkonversi angka ke dan kembali dari bilangan bulat nyata.

(Ya, saya mungkin bisa menyimpan byte dengan menggunakan eval.)

Neil
sumber
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}]}

Cobalah online!

Bagaimana?

Pertama, dapatkan batas atas untuk jumlah yang disandikan: (a + b) * 2 ok.

Sekarang filter semua nomor non-zeckendorf dari (0..limit).

Kami memiliki tabel pencarian, itu menurun dari sini.

GB
sumber
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

Cobalah secara Online! (Verifikasi semua kasus uji)

Penjelasan

Program ini secara langsung memanipulasi terjemahan biner dari representasi Zeckendorf. Fungsi a(n,m)melakukan perhitungan utama, dan s(n)merupakan fungsi pembantu yang menghilangkan angka berdekatan yang terdapat dalam representasi Zeckendorf.

Mari kita mulai dengan fungsi s(n)(diperluas untuk kejelasan):

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)

Misalnya, angka 107 ( 1101011dalam biner, mewakili 1 + 2 + 5 + 13 + 21 = 42), mengalami proses berikut:

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)

Cobalah secara Online! (s dengan output terperinci)

Ini adalah versi yang diperluas dari 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)

Fungsi ini mengubah dua representasi Zeckendorf menjadi empat angka biner yang lebih mudah untuk digabungkan. Baris (A) adalah bitwise OR dari dua representasi biner Zeckendorf - ini sesuai dengan satu salinan dari setiap nomor Fibonacci di kedua kelompok. (B) dan (C) adalah bitwise AND dari dua angka yang bergeser-kanan masing-masing 1 dan 2 kali. Kita tahu bahwa ketika angka-angka Fibonacci yang sesuai untuk (B) dan (C) ditambahkan bersama-sama, mereka akan setara dengan bitwise AND dari ndanm karena F (n) = F (n-1) + F (n-2) .

Sebagai contoh, katakanlah kita memiliki angka biner n = 101001 (sesuai dengan 1 + 5 + 13) dan m = 110110 (2 + 3 + 8 + 13). Maka kita akan memiliki (A) = 111111 (1 + 2 + 3 + 5 + 8 + 13), yang dikonversi menjadi 1010100 (3 + 8 + 21) dengan fungsi kami s, (B) = 10000 (8), dan ( C) = 1000 (5). Kita dapat memeriksa bahwa (1 + 5 + 13) + (2 + 3 + 8 + 13) = (3 + 8 + 21) + (8) + (5) = 45. Proses ini berulang dengan ((3 + 8 + 21) + (8)) + (5) = ((3 + 8 + 21) + (5) + (3)) + (5), dll.

Satu kesulitan dengan sistem ini adalah tidak berfungsi untuk angka Fibonacci 1 dan 2, karena mereka tidak mematuhi properti F(n)=F(n-1)+F(n-2)(mereka adalah dua angka terendah)! Karena itu, setiap kali 1 atau 2 terkandung dalam keduanya ndan m, mereka dikeluarkan dari A, B, dan C, maka jumlah mereka ditempatkan di D di bawah properti yang 1 + 1 = 2 dan 2 + 2 = 1 + 3. Misalnya, jika kita menambahkan 1 + 3 (101) + 1 + 3 + 5 (1101), kita mendapatkan:

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

(B): 2 (10)

(C): 1 (1)

(D): 2 (10)

Perhatikan bahwa 3 dan 5 ditempatkan dalam A, duplikat 3 dipecah menjadi 2 + 1 dalam B dan C, dan duplikat 1 dihapus dari A, B, dan C, ditambahkan bersama-sama, dan dimasukkan ke dalam D. Demikian pula, jika kita tambahkan 2 + 3 (110) + 2 + 3 + 5 (1110), kita mendapatkan:

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

(B): 2 (10)

(C): 1 (1)

(D): 1 + 3 (101)

Cobalah online! (a dengan output terperinci)

Madison Silver
sumber
0

Bahasa Wolfram (Mathematica) , 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}}]&

Cobalah online!

Cukup pencocokan pola.

Tidak Disatukan:

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] &
alephalpha
sumber