Giới tính của Fibonacci


15

Leonardo da Pisano hay còn gọi là Fibonacci là công cụ đưa hệ thống chữ số Hindu-Ả Rập vào châu Âu. Trước đó, các nhà toán học ở đó đã làm việc trong cơ sở sáu mươi với các chữ số La Mã.

Ví dụ, căn bậc hai của hai có thể xấp xỉ là: một và hai mươi bốn phần của sáu mươi và năm mươi mốt phần ba nghìn sáu trăm , và được viết là: i xxiv li , với tỷ lệ được xác định theo ngữ cảnh. Vào thời điểm đó, không có gì khác, đã được biết đến ( tức là số 0), nhưng không có đại diện tiêu chuẩn trong hệ thống số này.

Nếu Fibonacci bỏ qua những chữ số thập phân có răng cưa mới mà anh gặp phải trong các chuyến đi của mình, anh chắc chắn sẽ giải quyết được những thiếu sót trong hệ thống hiện tại. Hệ thống được cải tiến này, chúng tôi sẽ gọi giới tính của Fibonacci .

Nhiệm vụ của bạn là viết một chương trình, hàm hoặc đoạn mã lấy số dấu phẩy động ở định dạng ASCII hoặc định dạng nhị phân và xuất ra bằng sáu mươi chữ số La Mã cơ sở. Đầu vào có thể là tệp, bàn điều khiển, dòng lệnh hoặc đối số chức năng và đầu ra có thể là tệp hoặc bàn điều khiển, tùy theo cái nào là dễ nhất.

Đầu ra có thể là chữ hoa hoặc chữ thường và phải bao gồm các cải tiến sau:

  • sử dụng n hoặc N để biểu thị null có nghĩa là một địa điểm không có giá trị, nghĩa là Số 0 không (vấn đề với hệ thống)
  • sử dụng e hoặc E để chỉ et tương ứng với điểm giới tính (một vấn đề khác với hệ thống)
  • sử dụng dấu chấm giữa · hoặc dấu hoa thị * để phân tách các nhóm chữ số La Mã (một vấn đề khác với hệ thống)

Giả sử đầu vào sẽ là dấu phẩy động với mantissa không lớn hơn lix · lix · lix · lix · lix . Phân số nhỏ hơn n · e · n · n · n · n · tôi có thể bỏ qua. Vì vậy, với điều kiện đầu vào có những hạn chế này, nhiều nhất là mười nhóm chữ số La Mã với một e có thể xuất ra.

Số ít hơn tôi phải có n · e hàng đầu để đảm bảo bối cảnh rõ ràng.

Một số ví dụ: inputđầu ra

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

Đầu ra phải tránh n · không cần thiết trong phần mantissa, e bị cô lập hoặc trailing · n trong phần phân số của đầu ra. Vì vậy, ví dụ, n · n · n · n · i , i · ei · e · n · n · n · n · n là đầu ra không chính xác cho đầu vào của 1.

Sự khác biệt của cộng hoặc trừ n · e · n · n · n · n · i trong đầu ra nằm trong dung sai và chấp nhận được.

Đầu vào là bất kỳ điểm nổi hợp pháp nào trong ngôn ngữ bạn chọn, do đó, có thể bao gồm các số mũ dương hoặc âm miễn là đầu vào không nằm ngoài phạm vi được chỉ định ở trên.

Và cuối cùng, chữ số La Mã tích hợp được cho phép!


1
Tôi yêu thích lịch sử nhiều như vậy, Dailymotion được dành riêng cho chuỗi Wikipedia , trừ khi bạn muốn thay đổi thẻ wiki ...
Addison Crump

Thẻ dành cho "Leonardo Fibonacci hầu hết được biết đến với chuỗi Wikipedia (0, 1, 1, 2, 3, 5, 8, 13, ...).", Vì vậy sẽ nói nó có ý nghĩa với người đó.

Tôi nghĩ rằng thách thức này nên có một chút thông tin về cách các chữ số La Mã hoạt động và quá trình liên quan, chỉ để được khép kín.
Liam

1
Đó không phải là mục đích sử dụng. Tôi đã chỉnh sửa đoạn trích wiki để phản ánh điều này.
Dennis

Câu trả lời:


1

Python 3, 323 319 320 byte

Câu trả lời này thực hiện các giới tính của Fibonacci với dấu phân cách *và không liên quan đến độ phức tạp Kolmogorov trong danh sách các chữ số La Mã (ít nhất là bây giờ). Các nỗ lực đã được thực hiện để tham gia whileforvòng lặp theo đó các chữ số La Mã được tạo ra theo một vòng lặp, nhưng những nỗ lực đó vẫn chưa đạt được thành công. Bất kỳ lời khuyên và đề nghị chơi golf đều được chào đón và đánh giá cao.

Chỉnh sửa: Sửa lỗi và chơi gôn.

Chỉnh sửa: Sửa lỗi nhiều hơn.

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)

Ung dung:

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 byte

Không cạnh tranh (rõ ràng), nhưng để phục vụ như là nguồn cảm hứng:

#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;}

Lưu dưới dạng fs.c, xây dựng với gcc -o fs fs.c -lmvà chạy như./fs <arg> .

Các trường hợp thử nghiệm:

$ ./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

Bọ ngựa lớn nhất và phân số:

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

Tôi đang sử dụng doublelàm loại làm việc, do đó phần lớn nhất và phần kết hợp vượt quá độ chính xác tự nhiên của loại đó. Nếu tôi sử dụng long doublethay thế nó có thể xử lý nó.


int mainkhông phải quay lại 0.
Zacharý

0

Haskell ( 333 322 315 byte)

Tôi không rõ liệu chữ số giới tính cuối cùng có được làm tròn khi tôi thực hiện hay không cho phép cắt ngắn; cắt ngắn này, tôi nghĩ rằng Python3 có thể quá?

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 byte, nhờ H.PWiz ! -2 byte bằng cách loại bỏ wherecho (\->)$, -5 hơn bằng cách phát minh này dchức năng và chơi golfa++"."++x đến a++'.':x.)

Ung dung:


-- 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))

Phương pháp chuyển đổi số nguyên thành chữ số La Mã đã bị đánh cắp một cách đáng xấu hổ từ Thomas Ahle trên StackOverflow và chỉ chơi gôn một chút.


["l","xl","x","ix","v","iv","i"]có thểwords"l xl x ix v iv i"
H.PWiz

@ H.PWiz cảm ơn, kết hợp!
CR Drost
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.