数値をZeckendorf RepresentationからDecimalに変換する


18

Zeckendorf Representations / Base Fibonacci Numbersについて

これは、フィボナッチ数をベースとして使用する数値システムです。数値は0と1で構成され、各1は数値に対応するフィボナッチ数が含まれることを意味し、0は含まれないことを意味します。

たとえば、10以下のすべての自然数をベースフィボナッチに変換しましょう。

  • 1はフィボナッチ数である1の合計であるため、1になります。

  • 2はフィボナッチ数である2の合計であるため10になります。1は必要ありません。これは既に目的の合計を達成しているためです。

  • 3はフィボナッチ数である3の合計であるため、100になります。目的の合計をすでに達成しているため、2または1は必要ありません。

  • 4は101になります。これは、フィボナッチ数である[3,1]の合計であるためです。
  • 5はフィボナッチ数である5の合計であるため、1000になります。他の数は必要ありません。
  • 6はフィボナッチ数5と1の合計であるため、1001になります。
  • 7はフィボナッチ数5と2の合計であるため、1010になります。
  • 8はフィボナッチ数であるため、10000になります。
  • 9は、フィボナッチ数8と1の合計であるため、10001になります。
  • 10はフィボナッチ数8と2の合計であるため、10010になります。

ランダムなベースフィボナッチ数10101001010を10進数に変換しましょう:最初に、対応するフィボナッチ数を書きます。次に、1の下の数値の合計を計算します。

 1   0   1   0   1   0   0   1   0   1   0
 144 89  55  34  21  13  8   5   3   2   1  -> 144+55+21+5+2 = 227.

ベースフィボナッチ数の詳細:linkには、通常の整数をベースフィボナッチに変換するツールもあります。あなたはそれを試すことができます。

今質問:

あなたの仕事は、Zeckendorf表現で数値を取得し、その10進数値を出力することです。

入力は、0と1のみを含む文字列です(ただし、入力は任意の方法で取得できます)。

1つの数値を10進数で出力します。

テストケース:(入力->出力の形式)

 1001 -> 6
 100101000 -> 73
 1000000000 -> 89
 1001000000100100010 -> 8432
 1010000010001000100001010000 -> 723452

これはコードゴルフなので、バイト単位の最短回答が勝ちです。

注:入力には、先行する0または連続する1は含まれません。


入力をビットのリストとして取得できますか?
小麦ウィザード

たとえば、エンコードされた入力ASCIIを取得し、それをバイナリなどに変換しますか?
ウィンドミルクッキー

4
LSBファーストの順番で入力できますか?
Mego


1
はい@Mego、することができます
風車クッキー

回答:


19

タクシー1987 1927バイト

改行はオプションであると認識されているため、-60バイト。

Go to Post Office:w 1 l 1 r 1 l.Pickup a passenger going to Chop Suey.Go to Chop Suey:n 1 r 1 l 4 r 1 l.[B]Switch to plan C if no one is waiting.Pickup a passenger going to Cyclone.Go to Cyclone:n 1 l 3 l.Pickup a passenger going to Narrow Path Park.Pickup a passenger going to Sunny Skies Park.Go to Zoom Zoom:n.Go to Sunny Skies Park:w 2 l.Go to Narrow Path Park:n 1 r 1 r 1 l 1 r.Go to Chop Suey:e 1 r 1 l 1 r.Switch to plan B.[C]1 is waiting at Starchild Numerology.1 is waiting at Starchild Numerology.Go to Starchild Numerology:n 1 l 3 l 3 l 2 r.Pickup a passenger going to Addition Alley.Pickup a passenger going to Cyclone.Go to Cyclone:w 1 r 4 l.[D]Pickup a passenger going to Addition Alley.Pickup a passenger going to Cyclone.Go to Addition Alley:n 2 r 1 r.Go to Cyclone:n 1 l 1 l.Pickup a passenger going to Multiplication Station.Go to Zoom Zoom:n.Go to Narrow Path Park:w 1 l 1 l 1 r.Switch to plan E if no one is waiting.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:e 1 r.Pickup a passenger going to Multiplication Station.Go to Multiplication Station:n 1 r 2 l.Pickup a passenger going to Joyless Park.Go to Joyless Park:n 2 l 1 r 1 r.Go to Addition Alley:w 1 r 2 l 1 l.Pickup a passenger going to Cyclone.Go to Cyclone:n 1 l 1 l.Pickup a passenger going to Addition Alley.Switch to plan D.[E]Go to Addition Alley:w 1 l 1 r 1 l.Pickup a passenger going to Riverview Bridge.Go to Riverview Bridge:n 1 r.Go to Joyless Park:e 1 r 2 l.Pickup a passenger going to Addition Alley.[F]Switch to plan G if no one is waiting.Pickup a passenger going to Addition Alley.Go to Fueler Up:w 1 l.Go to Addition Alley:n 3 l 1 l.Pickup a passenger going to Addition Alley.Go to Joyless Park:n 1 r 1 r 2 l.Switch to plan F.[G]Go to Addition Alley:w 1 r 2 l 1 l.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:n 1 r 1 r.Pickup a passenger going to Post Office.Go to Post Office:n 1 l 1 r.

オンラインでお試しください!

私は最後にタクシーガレージに戻らないため、上司が私を解雇し、エラーで終了します。


Joyless Park訪問するのに良い場所のようです
aloisdgはReinstate Monicaのことを

まあ、それはより少ない文字ですSunny Skies Park
-JosiahRyanW




4

Haskell、38バイト

f=1:scanl(+)2f
sum.zipWith(*)f.reverse

オンラインでお試しください!

入力を1と0のリストとして受け取ります。

説明


f=1:scanl(+)2f

variableの最初のフィボナッチ数のリストを作成しますf

sum.zipWith(*)f.reverse

入力リストを取得し、reverse各エントリにの対応するエントリを乗算してfからsum、結果を取得します。

Haskell、30バイト

f=1:scanl(+)2f
sum.zipWith(*)f

オンラインでお試しください!

最初に最下位ビットで入力を取得する場合、必要ないreverseため、8バイトを節約できます。



3

Pyth、13バイト

このほとんど(8バイト)は、フィボナッチ数を生成しているだけです。

s*V_m=+Z|~YZ1

このテストスイートで試してみてください!

説明:

s*V_m=+Z|~YZ1QQ     Autofill variables
    m=+Z|~YZ1Q      Generate the first length(input) Fibonacci numbers as follows:
       Z             Start with Z=0
         ~YZ         And Y=[] (update it to Y=Z, return old Y)
        |   1        if Y is [], then replace with 1
      +              Sum Z and Y
     =               Replace Z with sum
    m                Repeat process
             Q       once for each element of the input
   _                Reverse the order of the Fibonacci numbers
 *V                 Vectorize multiplication
s                   Sum


3

J24 14バイト

#.~2+&%&1~#-#\

オンラインでお試しください!

フィボナッチの混合ベースを使用する24バイトバージョンを使い果たしました。

使い方

#.~2+&%&1~#-#\  Example input: y=1 0 0 1 0
          #-#\  Length minus 1-based indices; 4 3 2 1 0
   2     ~      Starting from 2, run the following (4,3,2,1,0) times:
    +&%&1         Given y, compute 1 + 1 / y
                The result is 13/8 8/5 5/3 3/2 2
#.~             Mixed base conversion of y into base above; 2+8=10

J、21バイト

1#.|.*[:+/@(!~#-])\#\

オンラインでお試しください!

Galen Ivanovの25バイトソリューションの改良版。

パスカルの三角形の対角和を使用します。これは二項係数の和に相当します。

Fn=i=0nniCi

使い方

1#.|.*[:+/@(!~#-])\#\
                       Example input: 1 0 0 1 0
                   #\  Generate 1-based index; 1 2 3 4 5
      [:          \    For each prefix of above... (ex. 1 2 3)
              #-]        Subtract each element from the length (ex. 2 1 0)
           (!~   )       Compute binomial coefficient (ex. 3C0 + 2C1 + 1C2)
        +/@              Sum
                       The result is Fibonacci numbers; 1 2 3 5 8
   |.*                 Multiply with mirrored self; 0 2 0 0 8
1#.                    Sum; 10

J、24バイト

3 :'y#.~|.(1+%)^:(<#y)2'

オンラインでお試しください!

モナドの明示的な動詞。フィボナッチベースを表す混合ベースを生成し、ベース変換にフィードし#.ます。

使い方

y#.~|.(1+%)^:(<#y)2  Explicit verb, input: y = Fibonacci digit array, n = length of y
      (1+%)          x -> 1 + 1/x
           ^:(<#y)2  Apply the above 0..n-1 times to 2
                     The result looks like 2/1, 3/2, 5/3, 8/5, 13/8, ...
    |.               Reverse
                     Now, if it is fed into #. on the left, the digit values become
                     ...(8/5 * 5/3 * 3/2 * 2/1), (5/3 * 3/2 * 2/1), (3/2 * 2/1), 2/1, 1
                     which is ... 8 5 3 2 1 (Yes, it's Fibonacci.)
y#.~                 Convert y to a number using Fibonacci base

代替案

J、27バイト

}.@(+#{.3#{.)^:(<:@#)@(,&0)

オンラインでお試しください!

アイデア:

 1  0  0  1  0  1
-1 +1 +1
------------------
    1  1  1  0  1
   -1 +1 +1
------------------
       2  2  0  1
      -2 +2 +2
------------------
          4  2  1
         -4 +4 +4
------------------
             6  5
            -6 +6 +6 <- Add an imaginary digit that has value 1
---------------------
               11  6
              -11+11
---------------------
                  17 <- the answer

J、30バイト

0.5<.@+(%:5)%~(-:>:%:5)#.,&0 0

オンラインでお試しください!

これは、構築に最も労力を要しました。丸めトリックで閉じた形式の式を使用します。式では、0番目と1番目の値はそれぞれ0と1であるため、実際の桁数は2で始まる必要があります。

0.5<.@+(%:5)%~(-:>:%:5)#.,&0 0  Tacit verb.
                         ,&0 0  Add two zeroes at the end
              (-:>:%:5)#.       Convert to a number using base phi (golden ratio)
       (%:5)%~                  Divide by sqrt(5)
0.5<.@+                         Round to nearest integer

エラー(((1-sqrt(5))/2)^n項)が蓄積される可能性がありますが、0.5を超えることはないため、丸めトリックは無限に機能します。数学的に:

max(|error|)=151(152)2n=150(152)n=5125<12


いい解決策!暗黙の解決策を破る明確な動詞を見ることができてうれしいです。
ガレンイワノフ

より短い暗黙の解決策を見つけようとしていますが、成功していません。今のところ25バイト。パスカルの三角形を使用します。
ガレンイワノフ

@GalenIvanov 1年後に挑戦を再訪して、私は新しい、非常に短い暗黙の解決策を得ました:)
バブラー

それは素晴らしいことです!すぐに詳細を見ていきます。
ガレンイワノフ

2

MathGolf8 6バイト

{î)f*+

オンラインでお試しください!

説明

{        Start block (foreach in this case)
 î)      Push loop index (1-based) and increment by 1
   f     Get fibonacci number of that index
    *    Multiply with the array value (0 or 1)
     +   Add top two elements of stack. This implicitly pops the loop index the first iteration, which makes the addition become 0+a, where a is the top of the stack.

JoKingのおかげで1バイト、LSBの順序付けでもう1バイト節約しました。


LSB注文は実際に許可されています。また、-1バイト
ジョーキング

@JoKingもちろん、先週暗黙的な追加も実装しました...いい感じです。MathGolfが1位になりました!
maxb

2

05AB1E11 9 8バイト

vyiNÌÅfO

オンラインでお試しください!

説明:

v             : For each character in input string (implicit) in LSB order
  yi          : If the current character is truthy (1)
    NÌ        : Add 2 to the current index
       ÅfO    : Add the fibonacci of this number to the stack
  • -2バイト:このコードを短くする小さな方法を指摘してくれた@KevinCruijssenに感謝します!
  • -1バイト:入力のLSB順序を指摘してくれた@JonathanAllanに感謝します!

1
を削除できΘます。105AB1Eではすでに真実です。:)また、2+することができますÌ
ケビンCruijssen

1
入力をリトルエンディアン形式で(つまり逆に)取り、1バイト(または2つ?)節約します。
ジョナサンアラン






1

C(gcc)、63バイト

入力を、配列の長さとともに、10の配列として受け取ります。このソリューションは、かなり単純な逆方向ループです。

f(_,l,a,b,t)int*_;{a=b=1;for(t=0;l--;b=(a+=b)-b)t+=a*_[l];_=t;}

オンラインでお試しください!



0

Retina 0.8.2、23バイト

0?
;
+`1;(1*);
;1$1;1
1

オンラインでお試しください!リンクには、より高速なテストケースが含まれています。説明:

0?
;

あらゆる場所にセパレータを挿入し、ゼロを削除します。たとえば、に1001なり;1;;;1;ます。

+`1;(1*);
;1$1;1

それらの値の合計が元の値と等しいため、次の2つの場所のそれぞれで、それぞれ1を繰り返しa 1に置き換えます11sしたがって、移行して、最後の2つの場所に達するまで蓄積されます(最後に追加されたセパレータにより)1

1

1sを数えます。




0

実際には、8バイト

;r⌐@░♂FΣ

オンラインでお試しください!

入力は、LSBファーストのビットのリストとして取得されます。

説明:

;r⌐@░♂FΣ
;r        range(0, len(input))
  ⌐       add 2 to every element in range (range(2, len(input)+2))
   @░     filter: take values in range that correspond to 1s in input
     ♂F   Fibonacci number at index of each element in list (Actually uses the F(0)=F(1)=1 definition, which is why we needed to add 2 earlier)
       Σ  sum

0

Powershell、68バイト

param($s)$b=1
$s[$s.Length..0]|%{$a,$b=$b,($a+$b)
$x+=($_-48)*$b}
$x

テストスクリプト:

$f = {
param($s)$b=1
$s[$s.Length..0]|%{$a,$b=$b,($a+$b)
$x+=($_-48)*$b}
$x
}

@(
    ,("1001", 6)
    ,("100101000", 73)
    ,("1000000000", 89)
    ,("1001000000100100010", 8432)
    ,("1010000010001000100001010000", 723452)
) | % {
    $s,$e = $_
    $r = &$f $s
    "$($r-eq$e): $r"
}

出力:

True: 6
True: 73
True: 89
True: 8432
True: 723452

0

Java(OpenJDK 8)、65バイト

Javaの答えとしてはかなり小さいので、満足しています。入力をLSBファーストのint配列として受け取ります。

d->{int s=0,f=1,h=1;for(int i:d){s+=i>0?f:0;f=h+(h=f);}return s;}

オンラインでお試しください!

非ゴルフ

d->{                        // Lambda function that takes array of ints
    int s=0,f=1,h=1;        // Initialise sum and fibonacci vars
    for(int i:d){           // Loop through each input integer
        s+=i>0?f:0;         // If it's 1 add current fibonacci number to sum
        f=h+(h=f);          // Increase fibonacci number 
    }return s;              // return sum
}

0

Z80Golf、34バイト

00000000: dde1 f1b7 2819 fe30 2812 4504 aff5 3cf5  ....(..0(.E...<.
00000010: d1f1 82d5 f510 f9c1 f17c 8067 2c18 e3dd  .........|.g,...
00000020: e5c9                                     ..

入力1001の例:オンラインで試してください!

入力100101000の例-オンラインで試してください!

アセンブリ:

zeck:		; input=push on stack in MSB order (eg top is LSB) output=reg h
pop ix		; save return addr in ix
f:
pop af		; get next digit
or a
jr z, return	; if current digit==0, return
cp 0x30
jr z, skip	; if current digit=='0' (e.g. not '1'), skip loop
ld b, l		; find fib of counter
fib:
	inc b	; 1-indexing for func to work
	xor a	; set a to 0 (1st fibo num)
	push af
	inc a	; set a to 1 (2nd fibo num)
	push af
	fib_loop:
		pop de
		pop af
		add d
		push de
		push af
		djnz fib_loop
pop bc		; get the fibo num just calculated
pop af		; pop just to reset stack frame
ld a, h
add b		; add current fibo number to sum
ld h, a
skip:
inc l		; increment counter reg
jr f		; repeat loop
return:
push ix		; push the return addr to ret to it
ret
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.