フィボナッチの六十進法


15

レオナルドダピサーノ(別名フィボナッチ)は、ヒンドゥーアラビア数字システムをヨーロッパに持ち込むことに貢献しました。その前に、そこの数学者はローマ数字で60を底に働いた。

たとえば、2の平方根は次のように概算できます:60分の1から24の部分、360分の51の部分、およびi xxiv liとして記述されます。スケーリングはコンテキストによって決定されます。当時、「無」は知られていました(つまりゼロ)が、この数体系には標準的な表現がありませんでした。

フィボナッチが旅行中に出会ったこれらの新しい小数の数字を無視していたなら、彼は確かに現在のシステムの欠陥に対処していたでしょう。この改善されたシステムを、フィボナッチの六十進数と呼びます。

あなたの仕事は、ASCII形式またはバイナリ形式の浮動小数点数を取り、60を基数とするローマ数字で出力するプログラム、関数、またはコードスニペットを記述することです。入力はファイル、コンソール、コマンドライン、または関数の引数であり、出力はファイルまたはコンソールのいずれか最も簡単なものです。

出力は大文字でも小文字でもかまいませんが、これらの改善を含める必要があります。

  • nまたはNを使用して、場所に値がない、つまり「ゼロ」(システムの問題)を意味するnullを示します。
  • eまたはEを使用して、六十進点に対応するetを示します(システムの別の問題)
  • 中央のドット・またはアスタリスク*を使用して、ローマ数字のグループを区切ります(システムの別の問題)

入力がlix・lix・lix・lix・lix以下の仮数を持つ浮動小数点になると仮定します。n・e・n・n・n・n・i未満の分数は無視できます。したがって、入力にこれらの制限がある場合、1つのeを持つローマ数字のグループを最大10個出力できます。

コンテキストが明確になるように、iより小さい数字には先頭にn・eが必要です。

いくつかの例:input出力

  • 0n
  • 1i
  • 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・、孤立e、または出力の小数部の末尾・nを避ける必要があります。そのため、たとえば、n・n・n・n・ii・e、およびi・e・n・n・n・n・nは、の入力に対して誤った出力です1

出力のプラスまたはマイナスn・e・n・n・n・n・iの差は許容範囲内で許容範囲内です。

入力は、選択した言語の正当な浮動小数点であるため、入力が上記で指定した範囲外にない限り、正または負の指数を含めることができます。

そして最後に、ローマ数字の組み込み許可されています!


1
限り、私は歴史を愛するように、フィボナッチを変更したい場合を除き、特にフィボナッチ数列のために予約されているタグのwikiを ...
アディソンCrumpの

タグは、「レオナルドフィボナッチはフィボナッチ数列(0、1、1、2、3、5、8、13、...)でよく知られています。」という意味です。

この課題には、ローマ数字がどのように機能するのか、関連するプロセスに関する情報が少し含まれている必要があると思います。
リアム

1
それは意図した用途ではありません。これを反映するために、タグwikiの抜粋を編集しました。
デニス

回答:


1

Python 3、323 319 320バイト

この回答は、フィボナッチの六十進法を区切り文字で実装し、*ローマ数字のリストのコルモゴロフの複雑さに関係なく(少なくとも今のところ)。1つのループでローマ数字が生成される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
ザカリー

0

Haskell(333 322 315バイト)

最後の六十進数字を丸めるときに切り捨てられるかどうか、または切り捨てが許可されるかどうかはわかりません。これは切り捨てられます、私は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に感謝しますwherefor を排除して-2バイト、(\->)$このd関数を発明し、ゴルフa++"."++xをすることでさらに-5 バイトa++'.':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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.