⊥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
g←1↓(1,+\⍤,)⍣20⍨1
{⊥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
{⊥1↓¯1↓⍧|/⌽⍵,↑,\⌽(1,+\⍤,)⍣20⍨1}+⍥({+∘÷⍣(⌽⍳≢⊤⍵)⍨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÷2)×2 = 8
 8÷5 |       (5÷3)×(3÷2)×2 = 5
 5÷3 |             (3÷2)×2 = 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,+\⍤,)⍣20⍨1}  ⍝ Convert plain integer N to Zeckendorf
                 (1,+\⍤,)⍣20⍨1   ⍝ 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,+\⍤,)⍣20⍨1
→ 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 ; ∀ n ≥ 0 ,Fn + 2=Fn + 1+Fn
แล้วก็
∀ n ≥ 0 ,Σi = 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.