피보나치의 섹스


15

Leonardo da Pisano 일명 피보나치 (Fibonacci)는 힌두-아랍어 숫자 체계를 유럽으로 가져 오는 데 중요한 역할을했습니다. 그 전에 수학자들은 로마 숫자로 60을 기본으로 일했습니다.

예를 들어, 2의 제곱근은 다음 같이 추정됩니다. 육십 육의 부분과 육십 육의 부분과 육십 오의 부분은 문맥에 의해 결정된 스케일링으로 i xxiv li 로 작성 될 수 있습니다. 당시“무 (無)”는 알려져 있었지만 ( 즉, 0),이 숫자 체계에는 표준 표현이 없었습니다.

피보나치가 여행 중에 마주 친이 새로운 십진수를 무시했다면 그는 현재 시스템의 결함을 해결했을 것입니다. 이 개선 된 시스템은 우리가 피보나치의 섹스 심이 라고 부릅니다 .

작업은 ASCII 또는 이진 형식의 부동 소수점 숫자를 사용하여 기본 60 개의 로마 숫자로 출력하는 프로그램, 함수 또는 코드 스 니펫을 작성하는 것입니다. 입력은 파일, 콘솔, 명령 행 또는 함수 인수 일 수 있으며 출력은 파일 또는 콘솔 중 가장 쉬운 것입니다.

출력은 대문자 또는 소문자 일 수 있으며 다음 개선 사항을 포함해야합니다.

  • n 또는 N 을 사용 하여 장소에 값이 없음을 의미하는 null 을 나타냅니다 ( 예 : "제로"(시스템에 문제가 있음)).
  • e 또는 E 를 사용 하여 sexagesimal point에 해당하는 et 를 표시 하십시오 (시스템의 다른 문제)
  • 중간 숫자 또는 별표 *를 사용하여 로마 숫자 그룹을 분리하십시오 (시스템에 다른 문제가 있음).

입력 값이 lix · lix · lix · lix · lix 보다 크지 않은 가수를 가진 부동 소수점이라고 가정합니다 . n · e · n · n · n · i · i 보다 작은 분수 는 무시할 수 있습니다. 따라서 입력에 이러한 제한이 있다면 최대 10 개의 로마 숫자 그룹이 하나의 e 이 출력 될 수 있습니다.

보다 적은 숫자 내가 선두가 있어야 · N E 문맥이 분명하다 보장합니다.

몇 가지 예 : input출력

  • 0n
  • 1
  • 60i · n
  • 0.1n · e · vi
  • 3600i · n · n
  • 10.5x · e · xxx
  • 16777215i · xvii · xl · xx · xv
  • 3.1415926536iii · e · viii · xxix · xliv · n · xlvii

출력은 불필요한 선도 피해야한다 N · 가수 부분에서, 고립 전자 , 또는 후행 N · 출력의 소수 부분이다. 예를 들어 n · n · n · n · i , i · ei · e · n · n · n · n · n1 .

출력에서 플러스 또는 마이너스 n · e · n · n · n · i 의 차이는 허용 오차 내에 있으며 허용 가능합니다.

입력은 선택한 언어로 된 임의의 유효한 부동 소수점이므로 입력이 위에 지정된 범위를 벗어나지 않는 한 양수 또는 음수 지수를 포함 할 수 있습니다.

그리고 마지막으로 로마 숫자 내장 허용됩니다!


1
내가 역사를 좋아하는 한, 피보나치태그 위키 를 바꾸고 싶지 않다면 피보나치 시퀀스를 위해 특별히 예약되어있다 .
Addison Crump

태그는 "Leonardo Fibonacci는 주로 피보나치 수열 (0, 1, 1, 2, 3, 5, 8, 13, ...)로 알려져 있습니다."

나는이 도전에 로마 숫자가 어떻게 작동하고 프로세스가 포함되어 있는지에 대해 약간의 정보가 있어야한다고 생각합니다.
Liam

1
의도 된 용도가 아닙니다. 이것을 반영하기 위해 wiki 발췌 태그를 편집했습니다.
Dennis

답변:


1

파이썬 3, 323 319 320 바이트

이 답변은 Fibonacci의 구분 기호를 사용 *하고 로마 숫자 목록에서 Kolmogorov 복잡성을 고려하지 않고 (지금은 적어도) 구현합니다. 하나의 루프에서 로마 숫자가 생성되는 whileand for루프에 결합 하려고 시도했지만 이러한 시도는 아직 성공하지 못했습니다. 모든 골프 팁과 제안을 환영합니다.

편집 : 버그 수정 및 골프.

편집 : 더 많은 버그 수정.

def f(x):
 v=divmod;f=x%1;n=int(x);d=",I,II,III,IV,V,VI,VII,VIII,IX".split(",");t=",X,XX,XXX,XL,L".split(",");z=["N"];a=f>0;s=z*0**n+["E"]*a
 while n:n,m=v(n,60);j,k=v(m,10);s=[z,[t[j]+d[k]]][m>0]+s
 for i in range(5*a):m,f=v(f*60,1);j,k=v(int(m),10);s+=[z,[t[j]+d[k]]][m>0]
 while s[-1:]==z*a:s.pop()
 return"*".join(s)

언 골프 드 :

def f(x):
    integ = int(x)
    frac = x % 1
    units=",I,II,III,IV,V,VI,VII,VIII,IX".split(",")
    tens=",X,XX,XXX,XL,L".split(",")
    zero = ["N"]
    output = []
    a = frac != 0
    if integ == 0:
        output += z
    if a:
        output += ["E"]
    while integ > 0:
        integ, digit = divmod(integ, 60)
        j, k = divmod(int(digit), 10)
        if digit:
            output += [tens[j], units[k]]
        else:
            output += zero
    for i in range(5*a):
        digit, frac = divmod(frac*60, 1)
        j, k = divmod(int(digit), 10)
        if digit:
            output += [tens[j], units[k]]
        else:
            output += zero
    while output[-1:] == zero * a:
        output.pop()
    return "*".join(output)

3

C – 584 바이트

비 경쟁적 (분명히)이지만 영감을주는 것 :

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
char*f(int z){static char r[8];char*l[]={"","I","II","III","IV","V","VI","VII","VIII","IX"},*h[]={"","X","XX","XXX","XL","L"};if(!z)return"N";sprintf(r,"%s%s",h[z/10],l[z%10]);return r;}int main(int c,char**v){char*s="";int i,j,z[10],k=60;long x;double d,y;y=modf(atof(v[1]),&d);x=d;for(i=4;i>=0;i--){z[i]=x%k;x/=k;}for(i=5;i<=9;i++){z[i]=(y*=k);y-=z[i];}for(i=0;!z[i]&&i<4;i++);for(;i<5;i++){printf("%s%s",s,f(z[i]));s="*";}for(j=9;!z[j]&&j>=i;j--);if(i<=j)printf("*E");for(;i<=j;i++)printf("*%s",f(z[i]));printf("\n");return 0;}

로 저장하고 fs.c로 빌드 gcc -o fs fs.c -lm하고로 실행하십시오 ./fs <arg>.

테스트 사례 :

$ ./fs 0
N
$ ./fs 1
I
$ ./fs 60
I*N
$ ./fs 0.1
N*E*VI
$ ./fs 3600
I*N*N
$ ./fs 10.5
X*E*XXX
$ ./fs 16777215
I*XVII*XL*XX*XV
$ ./fs 3.1415926536
III*E*VIII*XXIX*XLIV*N*XLVII

가장 큰 가수와 분수 :

$ ./fs 777599999
LIX*LIX*LIX*LIX*LIX
$ ./fs 0.999999998713992
N*E*LIX*LIX*LIX*LIX*LIX

내가 사용하고 double결합 된 최대 규모의 가수와 분수가 해당 유형의 기본 정확도를 초과하므로, 작업 유형으로. 내가 사용하는 경우 long double대신 그것을 처리 할 수 있습니다.


int main돌아올 필요가 없습니다 0.
Zacharý

0

하스켈 ( 333 322 315 바이트)

마지막 sexagesimal 자리가 반올림되어야하는지 또는 잘림이 허용되는지는 확실하지 않습니다. 이것은 잘립니다 .Python3도 마찬가지일까요?

d n f 0=n;d n f x=f x
x!n=60*(x-fromInteger n)
f 0=[];f x=(\n->n:f(x!n))$floor x
l 0=[];l x=(\(d,m)->l d++[m])$divMod x 60
v=[50,40,10,9,5,4,1]
n&i|n==0=""|n>=v!!i=words"l xl x ix v iv i"!!i++(n-v!!i)&i|True=n&(i+1)
q=foldl1(\a x->a++'.':x).map(d"n"(&0))
p x=(\n->d"n"(q.l)n++d""((".e."++).q.take 5.f)(x!n))$floor x

(-9 바이트, H.PWiz 덕분에 ! 2 바이트를 제거 하여이 기능 을 발명 하고을 (where(\->)$) 사용하여 -5를 더 제거 했습니다 .)da++"."++xa++'.':x

언 골프 드 :


-- this function gets called `d` for default
onZero :: (Eq n, Num n) => z -> (n -> z) -> n -> z
onZero def f x 
 | x == 0    = def
 | otherwise = f x 

-- this function gets called `f`
fracPart :: RealFrac a => a -> [Integer]
fracPart x
  | x == 0    = [] 
  | otherwise = n : fracPart (60 * (x - fromInteger n))
    where n = floor x

-- this function gets called `l`
leadPart :: Integral n => n -> [Integer]
leadPart x
  | x == 0    = [] 
  | otherwise = leadPart div ++ [ mod ]
    where (div, mod) = x `divMod` 60

-- these get called `v`
romanValues :: [Integer]
romanValues = [50, 40, 10, 9, 5, 4, 1]

-- these get inlined with `words`, and correspond to the values above
romanLetters :: [String]
romanLetters = ["l", "xl", "x", "ix", "v", "iv", "i"]

-- this becomes (&)
romanNumeralLoop :: Integer -> Int -> String
romanNumeralLoop n i
 | n == 0                  = "" 
 | n >= (romanValues !! i) = (romanLetters !! i) ++ romanNumeralLoop (n - (romanValues !! i)) i
 | otherwise               = romanNumeralLoop n (i + 1)

-- this becomes `q`
concatRomanWithDots :: [Integer] -> String
concatRomanWithDots numbers = concatWithDots (map toRoman numbers)
  where 
    toRoman = onZero "n" (\x -> romanNumeralLoop x 0)
    concatWithDots = foldl1 concatDot
    concatDot acc item = acc ++ "." ++ item

-- this becomes `p`
solve x = onZero "n" elseRomanizeLeadPart n ++ onZero "" elseRomanizeFracPart f
  where
    n = floor x
    f = 60 * (x - fromInteger n) 
    elseRomanizeLeadPart l = concatRomanWithDots (leadPart l)
    elseRomanizeFracPart f = ".e." ++ concatRomanWithDots (take 5 (fracPart f))

정수를 로마 숫자로 변환하는 방법은 StackOverflow의 Thomas Ahle에서 부끄럽게 도난 당했으며 약간의 골프를 쳤습니다.


["l","xl","x","ix","v","iv","i"]할 수 있습니다words"l xl x ix v iv i"
H.PWiz에게

@ H.PWiz 감사합니다!
CR Drost 2018 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.