การรวมภายใต้การเป็นตัวแทนของ Zeckendorf


14

ทฤษฎีบทของ Zeckendorfแสดงให้เห็นว่าจำนวนเต็มบวกทุกตัวสามารถแสดงอย่างไม่ซ้ำกันได้ว่าเป็นผลรวมของตัวเลขฟีโบนักชีที่ไม่ได้อยู่ติดกัน ในการท้าทายนี้คุณต้องคำนวณผลรวมของตัวเลขสองตัวในการเป็นตัวแทนของ Zeckendorf


ให้ F nเป็นหมายเลข Fibonacci ที่n

F 1 = 1,
F 2 = 2 และ
สำหรับทุกk > 2, F k = F k - 1 + F k - 2

การแทน Zeckendorf Z ( n ) ของจำนวนเต็มไม่เป็นลบnคือชุดของจำนวนเต็มบวกเช่นนั้น

n = Σ ฉัน ∈ Z ( n ) F ฉัน   และ
ฉัน ∈ Z ( n ) ฉัน + 1 ∉ Z ( n )

(ใน prosa: การแทน Zeckendorf ของจำนวนnเป็นชุดของจำนวนเต็มบวกเช่นนั้นตัวเลข Fibonacci สำหรับดัชนีเหล่านี้รวมถึงnและไม่มีจำนวนเต็มสองตัวติดกันเป็นส่วนหนึ่งของชุดนั้น)

ยวดตัวแทน Zeckendorf เป็นเอกลักษณ์ นี่คือตัวอย่างของการเป็นตัวแทนของ Zeckendorf:

Z (0) = ∅ (ชุดว่าง)
Z (1) = {1}
Z (2) = {2}
Z (3) = {3} ({1, 2} ไม่ใช่ตัวแทน Zeckendorf ของ 3)
Z (10) = {5, 2}
Z (100) = {3, 5, 10}

ในความท้าทายนี้การแทน Zeckendorf ถูกเข้ารหัสเป็นชุดบิตซึ่งบิตที่มีนัยสำคัญน้อยที่สุดแสดงว่า1เป็นส่วนหนึ่งของชุด ฯลฯ คุณอาจคิดว่าการแทน Zeckendorf ของทั้งอินพุตและเอาต์พุตพอดีกับบิต 31 บิต

งานของคุณคือการคำนวณ Z ( n + m ) ให้ Z ( n ) และ Z ( m ) โซลูชันที่มีความยาวสั้นที่สุดใน octet ชนะ

คุณสามารถค้นหาดำเนินการอ้างอิงที่เขียนใน ANSI C ที่นี่ นอกจากนี้ยังสามารถใช้เพื่อสร้างการรับรอง Zeckendorf หรือคำนวณตัวเลขจากการเป็นตัวแทน Zeckendorf

นี่คือตัวอย่างอินพุตและเอาต์พุตตัวอย่างบางคู่ที่สองคอลัมน์แรกมีอินพุตและคอลัมน์ที่สามมีเอาต์พุต:

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
คุณช่วยอธิบายเพิ่มเติมอินพุต / เอาท์พุตได้ไหม?
ข้อบกพร่อง

@flawr โปรดดูการดำเนินการอ้างอิงที่ให้ไว้ คุณสามารถใช้มันเพื่อสร้างอินพุตตัวอย่างของคุณเอง
FUZxxl

3
ฉันจะมีความสุขถ้าคุณสามารถทำเอกสารที่นี่สิ่งที่คุณต้องการและให้ตัวอย่างเช่นฉันและบางทีคนอื่นเกินไปไม่คล่องใน C.
ข้อบกพร่อง

ฉันไม่เห็นด้วยกับข้อโต้แย้งที่เป็นเอกลักษณ์ เนื่องจากลำดับ Fibonacci เริ่มต้นด้วย 1, 1, 2 คุณสามารถแยก 3 ออกเป็น F0 + F2 = 1 + 2 = 3 F0 และ F2 ไม่ได้ติดกัน
orlp

1
@orlp ลำดับ Fibonacci กำหนดไว้ที่นี่เริ่มต้นด้วย F1 = 1 และ F2 = 2 ดังนั้นวิธีที่ฉันอ่าน F0 จากนิยามของคุณไม่ใช่ส่วนหนึ่งของลำดับที่ใช้ที่นี่
Reto Koradi

คำตอบ:


5

K (ngn / k) , 45 43 42 41 ไบต์

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

ลองออนไลน์!

อัลกอริทึมของ @ Bubbler

{ } ฟังก์ชั่นที่มีข้อโต้แย้ง x

64( )/0 ทำ 64 ครั้งโดยใช้ 0 เป็นค่าเริ่มต้น:

  • 1, เสริม 1

  • +': เพิ่มก่อนหน้านี้ (ปล่อยองค์ประกอบแรกเหมือนเดิม)

F:มอบหมายให้Fสำหรับ "ลำดับฟีโบนักชี"

| ถอยหลัง

(.. ){y!x}\.. เริ่มต้นด้วยค่าทางด้านซ้ายคำนวณส่วนที่เหลือสะสม (จากซ้ายไปขวา) สำหรับรายการทางด้านขวา ค่าทางด้านซ้ายคือผลรวมล้วนของอินพุตโดยไม่มีการแสดง zeckendorf

  • 2\xไบนารีเข้ารหัสอินพุต นี่จะเป็นเมทริกซ์ nbits-by-2

  • | ถอยหลัง

  • +/' รวมกัน

  • &1s อยู่ที่ไหน - รายการดัชนี หากมี 2 วินาทีดัชนีที่เกี่ยวข้องนั้นจะถูกทำซ้ำสองครั้ง

  • F@ การจัดทำดัชนีอาร์เรย์ลงใน F

  • +/ รวม

<': น้อยกว่าก่อนหน้า (ผลลัพธ์แรกจะเป็นเท็จเสมอ)

2/ ถอดรหัสไบนารี


10

CJam, 76 74 70 63 59 ไบต์

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

ลองใช้ออนไลน์ในล่าม CJamหรือตรวจสอบกรณีทดสอบทั้งหมดในครั้งเดียว

ความคิด

เราเริ่มต้นด้วยการกำหนดความผันแปรเล็กน้อยของลำดับในคำถาม:

G -2 = 0
G -1 = 1
G k = G k-1 + G k-2เมื่อใดก็ตามที่kเป็นจำนวนเต็มที่ไม่เป็นลบ

วิธีนี้บิต0 (LSB) ของการป้อนข้อมูลบิตอาร์เรย์หรือการส่งออกสอดคล้องกับจำนวนฟีโบนักชีG 0และโดยทั่วไปบิตkเพื่อG k

ตอนนี้เราแทนที่แต่ละบิตที่ตั้งไว้ในZ (n)และZ (m)ด้วยดัชนีที่เข้ารหัส

ยกตัวอย่างเช่นการป้อนข้อมูล532 10 = 1000010100 2ได้รับการเปลี่ยนเป็น[2 4 9]

นี่ให้จำนวนเต็มสองอาร์เรย์ซึ่งเราสามารถต่อกันเป็นรูปแบบเดียว

ตัวอย่างเช่นถ้าn = m = 100ผลที่ได้คือA: = [2 4 9 2 4 9]

ถ้าเราเปลี่ยนแต่ละkในโดยG kและเพิ่มผลที่เราได้รับ+ m n = 200ดังนั้นเป็นวิธีในการย่อยสลาย200เป็นตัวเลข Fibonacci แต่ก็ไม่ได้เป็นหนึ่งจากทฤษฎีบท Zeckendorf ของ

โปรดทราบว่าG k + G k + 1 = G k + 2และG k + G k = G k + G k-1 + G k-2 = G k + 1 + G k-2เราสามารถทดแทนกันได้ และดัชนีที่ซ้ำกันโดยผู้อื่น (กล่าวคือ(k, k + 1)โดยk + 2และ(k, k)โดย(k + 1, k - 2) ), ทำซ้ำการแทนที่เหล่านั้นซ้ำแล้วซ้ำอีกจนกว่าจะถึงตัวแทน Zeckendorf 1

กรณีพิเศษจะต้องดำเนินการสำหรับดัชนีผลลบ ตั้งแต่G -2 = 0คุณสามารถข้ามดัชนี-2ได้ นอกจากนี้จี-1 = 0 = G 0ดังนั้นใด ๆ ที่เกิด-1จะต้องมีการแทนที่ด้วย0

สำหรับตัวอย่างAเราได้รับการรับรอง (เรียงลำดับ) ต่อไปนี้การเป็นตัวแทน 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]

ในที่สุดเราแปลงกลับจากอาร์เรย์จำนวนเต็มเป็นบิตอาร์เรย์

รหัส

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 การใช้งานพยายามทดแทน 32 ครั้งและไม่ตรวจสอบว่ามีการนำเสนอ Zeckendorf จริงหรือไม่ ฉันไม่มีหลักฐานอย่างเป็นทางการว่านี่เพียงพอ แต่ฉันได้ทดสอบจำนวนเงินที่เป็นไปได้ทั้งหมดของการเป็นตัวแทนแบบ 15 บิต (ซึ่งการแสดงผลรวมต้องใช้จำนวนถึง 17 บิต) และการทำซ้ำ 6 ครั้งก็เพียงพอสำหรับพวกเขาทั้งหมด ไม่ว่าในกรณีใดก็ตามการเพิ่มจำนวนการทำซ้ำเป็น 99 เป็นไปได้โดยไม่ต้องเพิ่มจำนวนไบต์ แต่จะทำให้ประสิทธิภาพการทำงานลดลง


10

APL (Dyalog Extended)ขนาด 39 ไบต์

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

ลองออนไลน์!

เปลี่ยนเป็นโปรแกรมแบบเต็มโดยใช้อาร์กิวเมนต์หนึ่งความยาว 2 และเปลี่ยนตัวสร้าง Fibonacci ขอบคุณ @ngn สำหรับแนวคิดมากมาย

ใช้⎕IO←0เพื่อให้ประเมิน⍳20 1

เครื่องกำเนิดไฟฟ้า Fibonacci (ใหม่)

โปรดทราบว่าตัวเลขสองตัวสุดท้ายนั้นไม่ถูกต้อง แต่จะไม่เปลี่ยนผลลัพธ์ของโปรแกรม

(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 ถึงธรรมดา (บางส่วน)

⍸⌽+/⊤⎕
        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 ไบต์

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

ลองออนไลน์!

เปลี่ยนส่วนที่ 1 ของคำตอบก่อนหน้าเพื่อนำหมายเลข Fibonacci ไปใช้ซ้ำ และปล่อย 1 ที่ซ้ำกันเพื่อบันทึกบางไบต์ในที่อื่น ๆ

ส่วนที่ 1 (ใหม่)

{+/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 ไบต์

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

ลองออนไลน์!

มันทำงานอย่างไร

ไม่มีอัลกอริทึมแฟนซีที่จะเพิ่มใน Zeckendorf เพราะ APL ไม่เป็นที่รู้จักสำหรับการดำเนินการกับแต่ละองค์ประกอบในอาร์เรย์ แต่ฉันไปข้างหน้าเพื่อแปลงอินพุตทั้งสองจาก Zeckendorf เป็นจำนวนเต็มธรรมดาเพิ่มเข้าไปและแปลงกลับ

ส่วนที่ 1: Zeckendorf ถึงจำนวนเต็มธรรมดา

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

ส่วนที่ 2: เพิ่มจำนวนเต็มธรรมดาสองจำนวน

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

ส่วนที่ 3: แปลงผลรวมกลับเป็น Zeckendorf

"คุณอาจคิดว่าการเป็นตัวแทนของ Zeckendorf ของทั้งอินพุตและเอาต์พุตพอดีกับ 31 บิต" ค่อนข้างมีประโยชน์

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

เครื่องกำเนิดไฟฟ้า 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

สิ่งนี้ตามมาจากคุณสมบัติของหมายเลขฟีโบนักชี: ถ้าฟีโบนักชีถูกกำหนดเป็น

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

แล้วก็

n0,Σผม=0nFผม=Fn+2-1

ผลรวมสะสมของ 1,F0,,Fn (อาร์เรย์ฟีโบนักชีต่อท้ายด้วย 1) กลายเป็น F1,,Fn+2. จากนั้นฉันเติม 1 อีกครั้งเพื่อรับอาร์เรย์ Fibonacci ปกติเริ่มต้นด้วยดัชนี 0

ตัวเลข Fibonacci ถึง 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 ไบต์

แก้ไข: รุ่นใหม่:

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 ทำงาน


บางสิ่งสามารถสั้นลงได้ทันที - ตัวอย่างเช่นฟังก์ชั่นมีลำดับความสำคัญสูงสุดดังนั้นคุณสามารถกำจัดผู้ปกครองรอบ ๆ แอปพลิเคชันฟังก์ชันและผู้ปกครองไม่ต้องการผู้ปกครองเช่นกัน - ยามหยุดอยู่ที่ไหน=ดังนั้นไม่จำเป็น และอื่น ๆ และอื่น ๆ และทราบว่า:เชื่อมโยงไปทางขวาและคุณสามารถตัดบางส่วนที่นั่น แต่ยังไงก็ตามขอแสดงความยินดี! ดูซับซ้อนมาก อดใจรอไม่ไหวที่จะทราบว่ามันทำงานอย่างไร!
ภูมิใจ haskeller

@proudhaskeller ซับซ้อนเกินไป แต่ดูการแก้ไขของฉัน ฉันจะอธิบายแนวคิดพื้นฐานได้ไหม มันอาจจะดีกว่าอีกวิธีหนึ่ง แต่ฉันพยายามทำการจับคู่รูปแบบให้มากที่สุดในตอนแรก อืมโดยผู้ปกครองคุณหมายถึงวงเล็บ: golf'd นั่น!
Leif Willerts

chillax มันเป็นครั้งแรกของคุณที่นี่ ถ้าคุณอยู่นานคุณจะเติบโตได้ดีขึ้นมาก ให้แน่ใจว่าได้ตรวจสอบคำถามเคล็ดลับการเล่นกอล์ฟ Haskell สำหรับcodegolf.stackexchange.com/questions/19255/…
ภูมิใจ haskeller

แก้ไข @proudhaskeller แล้ว ...
Leif Willerts

4

ES6, 130 ไบต์

(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}

ตอนแรกฉันพยายามคำนวณผลรวมในสถานที่ (อย่างมีประสิทธิภาพตามแนวของการใช้งาน CJam) แต่ฉันก็หมดเวลาชั่วคราวดังนั้นฉันจึงแปลงตัวเลขไปและกลับจากจำนวนเต็มจริง

(ใช่ฉันอาจบันทึกไบต์ด้วยการใช้ eval)


1

Ruby , 85 73 65 ไบต์

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

ลองออนไลน์!

อย่างไร?

ก่อนอื่นรับขอบเขตบนสำหรับผลรวมที่เข้ารหัส: (a + b) * 2 ก็โอเค

ตอนนี้กรองตัวเลขที่ไม่ใช่ zeckendorf ทั้งหมดจาก (0..limit)

เรามีตารางการค้นหามันตกต่ำจากที่นี่


1

Python 3, 207 ไบต์

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

ลองออนไลน์! (ตรวจสอบกรณีทดสอบทั้งหมด)

คำอธิบาย

โปรแกรมนี้จัดการการแปลแบบไบนารีของการรับรอง Zeckendorf โดยตรง ฟังก์ชั่นa(n,m)ทำการคำนวณหลักและs(n)เป็นฟังก์ชั่นตัวช่วยที่กำจัดจำนวนที่อยู่ติดกันที่มีอยู่ในการเป็นตัวแทนของ Zeckendorf

เริ่มจากฟังก์ชั่นs(n)(ขยายเพื่อความชัดเจน):

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)

ตัวอย่างเช่นหมายเลข 107 (เป็น1101011ไบนารีซึ่งแทน 1 + 2 + 5 + 13 + 21 = 42) ผ่านกระบวนการต่อไปนี้:

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)

ลองออนไลน์! (s พร้อมเอาต์พุตรายละเอียด)

นี่คือเวอร์ชันขยายของ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)

ฟังก์ชันนี้แปลงการแทนค่า Zeckendorf สองรายการเป็นเลขฐานสองสี่ตัวซึ่งง่ายต่อการรวม Line (A) คือ bitwise OR ของการแทนค่า Zeckendorf ไบนารีสองรายการซึ่งตรงกับสำเนาหนึ่งของหมายเลขฟีโบนักชีในแต่ละกลุ่ม (B) และ (C) คือค่าบิตและของทั้งสองตัวเลขเลื่อนไปทางขวา 1 และ 2 ครั้งตามลำดับ เรารู้ว่าเมื่อเพิ่มหมายเลขฟีโบนักชีสำหรับ (B) และ (C) เข้าด้วยกันพวกเขาจะเทียบเท่ากับค่าบิตและของเราnและmเพราะ F (n) = F (n-1) + F (n-2) .

ตัวอย่างเช่นสมมติว่าเรามีเลขฐานสอง n = 101001 (ตรงกับ 1 + 5 + 13) และ m = 110110 (2 + 3 + 8 + 13) จากนั้นเราจะมี (A) = 111111 (1 + 2 + 3 + 5 + 8 + 13) ซึ่งถูกแปลงเป็น 1010100 (3 + 8 + 21) โดยฟังก์ชั่นของเราs(B) = 10,000 (8) และ ( C) = 1,000 (5) เราสามารถตรวจสอบได้ว่า (1 + 5 + 13) + (2 + 3 + 8 + 13) = (3 + 8 + 21) + (8) + (5) = 45 กระบวนการนี้ซ้ำกับ ((3 + 8 + 21) + (8)) + (5) = ((3 + 8 + 21) + (5) + (3)) + (5) ฯลฯ

หนึ่งปัญหากับระบบนี้ก็คือว่ามันไม่ทำงานสำหรับตัวเลข Fibonacci ที่ 1 และ 2 เนื่องจากพวกเขาไม่เชื่อฟังทรัพย์สินF(n)=F(n-1)+F(n-2)(พวกเขากำลังต่ำสุดตัวเลขสอง)! เนื่องจากว่าเมื่อใดก็ตามที่มี 1 หรือ 2 อยู่ในทั้งสองnและmพวกเขาจะถูกลบออกจาก A, B และ C จากนั้นผลรวมของพวกเขาใน D ภายใต้คุณสมบัติที่ 1 + 1 = 2 และ 2 + 2 = 1 + 3 ตัวอย่างเช่นถ้าเราเพิ่ม 1 + 3 (101) + 1 + 3 + 5 (1101) เราจะได้รับ:

(A): 3 + 5 (1100) = 8 (10,000)

(B): 2 (10)

(C): 1 (1)

(D): 2 (10)

โปรดสังเกตว่าวาง 3 และ 5 ลงใน A สำเนาที่ซ้ำกันถูกแบ่งออกเป็น 2 + 1 ใน B และ C และลบ 1s ที่ซ้ำกันออกจาก A, B และ C รวมเข้าด้วยกันและนำเข้า D ในทำนองเดียวกันถ้าเรา เพิ่ม 2 + 3 (110) + 2 + 3 + 5 (1110) เราได้รับ:

(A): 3 + 5 (1100) = 8 (10,000)

(B): 2 (10)

(C): 1 (1)

(D): 1 + 3 (101)

ลองออนไลน์! (a พร้อมเอาต์พุตรายละเอียด)


0

ภาษา Wolfram (Mathematica) , 218 ไบต์

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}}]&

ลองออนไลน์!

การจับคู่รูปแบบเพียง

Ungolfed:

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] &
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.