Zeckendorf Representation에서 Decimal로 숫자 변환


18

Zeckendorf 표현 /베이스 피보나치 번호 정보

이것은 피보나치 수를 기본으로 사용하는 수 시스템입니다. 숫자는 0과 1로 구성되며 각 1은 숫자에 해당 피보나치 숫자가 포함되어 있음을 의미하고 0은 그렇지 않습니다.

예를 들어, 모든 자연수 <= 10을 기본 피보나치로 변환 해 봅시다.

  • 1은 피보나치 수인 1의 합이므로 1이됩니다.

  • 2는 피보나치 수인 2의 합이므로 10이됩니다. 이미 원하는 합을 달성 했으므로 1이 필요하지 않습니다.

  • 3은 100이됩니다. 3의 합은 피보나치 수이며 이미 원하는 합을 얻었으므로 2 또는 1이 필요하지 않습니다.

  • 4는 [3,1]의 합계이기 때문에 101이됩니다. 둘 다 피보나치 수입니다.
  • 5는 피보나치 수인 5의 합이므로 1000이됩니다. 다른 숫자는 필요하지 않습니다.
  • 6은 피보나치 수 5와 1의 합이므로 1001이됩니다.
  • 7은 피보나치 수 5와 2의 합이므로 1010이됩니다.
  • 피보나치 수이기 때문에 8은 10000이됩니다.
  • 9는 피보나치 수 8과 1의 합이므로 10001이됩니다.
  • 피보나치 수 8과 2의 합이므로 10은 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 Representation에서 숫자를 받아서 10 진수 값을 출력하는 것입니다.

입력은 0과 1 만 포함하는 문자열입니다 (원하는 방식으로 입력 할 수 있음).

하나의 숫자를 10 진수로 출력합니다.

테스트 사례 : (입력-> 출력 형식)

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

이것은 코드 골프이므로 바이트 단위의 최단 답변이 이깁니다.

참고 : 입력에는 선행 0 또는 연속 1이 포함되지 않습니다.


비트리스트로 입력을받을 수 있습니까?
밀 마법사

마찬가지로 입력 ASCII를 인코딩 한 다음 바이너리 또는 이와 유사한 것으로 변환합니까?
Windmill Cookies

4
LSB-first order로 입력을받을 수 있습니까 ?
Mego


1
@Mego 네, 가능합니다
Windmill Cookies

답변:


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

11

펄 6 , 28 23 바이트

{[+] (1,2,*+*...*)Z*$_}

온라인으로 사용해보십시오!

LSB 순서에서 1s 및 0s 목록을 가져와 숫자를 반환하는 익명 코드 블록입니다 .

설명:

{                     }   # Anonymous codeblock
 [+]                      # The sum of
     (1,2,*+*...*)        # The infinite Fibonacci sequence starting from 1,2
                  Z*      # Zip multiplied by
                    $_    # The input list in LSB form



4

하스켈 , 38 바이트

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

온라인으로 사용해보십시오!

1과 0의 목록으로 입력을받습니다.

설명


f=1:scanl(+)2f

변수에서 피보나치 수의 목록을 첫 번째로 만듭니다 f.

sum.zipWith(*)f.reverse

입력 목록에서 reverse각 항목에의 해당 항목을 곱한 f다음 sum결과를 가져옵니다.

하스켈 , 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

J , 24 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'

온라인으로 사용해보십시오!

Monadic 명백한 동사. 피보나치 염기를 나타내는 혼합 염기를 생성 한 다음 염기 변환에 투입합니다 #..

작동 원리

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


좋은 해결책! 암묵적 인 솔루션을 치는 명백한 동사를 보게되어 기쁩니다.
Galen Ivanov

더 짧은 암묵적 해결책을 찾으려고 노력하고 있지만 성공하지 못했습니다. 지금은 25 바이트입니다 . 나는 파스칼의 삼각을 사용합니다.
Galen Ivanov

@GalenIvanov 1 년 후의 도전에 다시 도전하면서 새로운 초 속속 암묵적 솔루션을 얻었습니다.
Bubbler

대단해! 좀 더 자세히 살펴 보겠습니다.
Galen Ivanov

2

MathGolf , 8 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 순서로 다른 바이트를 절약했습니다.


LSB 주문은 실제로 허용됩니다. 또한, -1 바이트
조 왕

@JoKing 물론, 나는 지난주에 암시 적 추가를 구현했습니다 ... 멋진 터치, 이제 MathGolf는 첫 번째 자리에 있습니다!
maxb

2

05AB1E , 11 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 bytes :이 코드를 줄이는 작은 방법을 지적한 @KevinCruijssen에게 감사합니다!
  • -1 byte : 입력을위한 LSB 순서를 지적한 @JonathanAllan에게 감사합니다!

1
를 제거 할 수 있습니다 Θ. 105AB1E는 이미 진실입니다. :) 또한 2+가능합니다 Ì.
Kevin Cruijssen

1
Little-endian 형식 (즉, 반대로)으로 입력을 받아 바이트 (또는 2?)를 저장해야합니다.
Jonathan Allan




1

Stax , 6 바이트

çéC◘0â

실행 및 디버깅

:1F^|5+           #Full program, unpacked, implicit input as array    
:1                #Get indicies of truthy
  F               #Use rest of program to loop through elements
   ^              #Increment current element
    |5+           #Get n-th fib and Add

꽤 직설적 인. LSB 주문.



1

C (gcc) , 63 바이트

배열의 길이와 함께 1및 의 배열로 입력을 0받습니다. 이 솔루션은 다소 직접적인 역방향 루프입니다.

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

온라인으로 사용해보십시오!



0

레티 나 0.8.2 , 23 바이트

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

온라인으로 사용해보십시오! 링크에는 더 빠른 테스트 사례가 포함됩니다. 설명:

0?
;

사방에 구분 기호를 삽입하고 0을 삭제하십시오. 예를 들어 1001됩니다 ;1;;;1;.

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

반복적으로 각각 교체 1A를 1그 값의 합이 원래의 값과 동일로, 다음 두 곳의 각을 1. 1따라서 새로 추가 된 구분 기호로 인해 마지막 두 위치에 도달 할 때까지 마이그레이션 및 누적 1됩니다.

1

1s를 세십시오 .




0

실제로 8 바이트

;r⌐@░♂FΣ

온라인으로 사용해보십시오!

LSB-first order에서 비트리스트로 입력됩니다.

설명:

;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

파워 쉘, 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

자바 (OpenJDK 8) , 65 바이트

Java에 대한 답변은 꽤 작습니다. LSB-first-ordered 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.