⊥1↓⍧|/⌽(+/g[⍸⌽+/⊤⎕]),↑,\⌽g←(2+/,)⍣38⍨⍳2
Probieren Sie es online aus!
In ein vollständiges Programm mit einem Argument der Länge 2 geändert und auch der Fibonacci-Generator geändert. Vielen Dank an @ngn für viele Ideen.
Verwendet ⎕IO←0
so, dass ⍳2
ausgewertet wird 0 1
.
Fibonacci-Generator (neu)
Beachten Sie, dass die letzten beiden Zahlen ungenau sind, die Ausgabe des Programms jedoch nicht geändert wird.
(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 zu schlicht (teilweise)
⍸⌽+/⊤⎕
⎕ ⍝ 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[⍸⌽⊤⍵]}
Probieren Sie es online aus!
Teil 1 der vorherigen Antwort wurde geändert, um die Fibonacci-Zahlen wiederzuverwenden. Löschen Sie außerdem das Duplikat 1, um einige Bytes an anderen Stellen zu speichern.
Teil 1 (neu)
{+/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}⊥⊤)
Probieren Sie es online aus!
Wie es funktioniert
Kein ausgefallener Algorithmus zum Hinzufügen in Zeckendorf, da APL nicht für die Operation einzelner Elemente in einem Array bekannt ist. Stattdessen habe ich die beiden Eingaben von Zeckendorf in einfache Ganzzahlen konvertiert, hinzugefügt und zurückkonvertiert.
Teil 1: Zeckendorf zur einfachen ganzen Zahl
{+∘÷⍣(⌽⍳≢⊤⍵)⍨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
Teil 2: Fügen Sie zwei einfache Ganzzahlen hinzu
+⍥z2i ⍝ Given left and right arguments,
⍝ apply z2i to each of them and add the two
Teil 3: Wandle die Summe zurück nach Zeckendorf
"Sie können davon ausgehen, dass die Zeckendorf-Darstellungen von Eingabe und Ausgabe in 31 Bit passen" war ziemlich praktisch.
{⊥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
Der Fibonacci-Generator
(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
Dies folgt aus der Eigenschaft von Fibonacci-Zahlen: wenn Fibonacci definiert ist als
F.0= F.1= 1 ; ∀ n ≥ 0 , F.n + 2= F.n + 1+ F.n
dann
∀ n ≥ 0 , ∑i = 0nF.ich= F.n + 2- 1
1 , F.0, ⋯ , F.nF.1, ⋯ , F.n + 2
Fibonacci nach Zeckendorf Ziffern
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.