ローマ数字の線分


10

入力として1..3999の範囲の整数を受け入れ、その整数を標準のローマ数字で表すために必要な線分の数を返すプログラムまたは関数を記述します(したがって、VMではなくXLを使用します)。例:

   1 -> 1
   4 -> 3
   5 -> 2
   9 -> 3
  10 -> 2
  40 -> 4
  50 -> 2
  90 -> 3
 100 -> 1
 400 -> 3
 500 -> 2
 900 -> 5
1000 -> 4

ローマ数字変換のビルトインは許可されていますが、上記のリストから残りの最大数を繰り返し減算することで、ビルトインなしで問題を解決できます。例:1234 = 4 + 1 + 1 + 2 + 2 + 2 + 3 = 15。

これはので、最短のプログラムが勝ちます。


4本ではなく10本の2つの線分がある理由 Xを書く場合、通常は2本の線を書くだけですが、線の交差によって4つのセグメントにならないのですか?
— Alex A.

@AlexA。線分の定義は通常、「2点間の最短経路をたどる一連の点」のようなものです。これに基づいてXをカットする理由は何もないようです。それを定義するために必要なエンドポイントは2セットだけです。(ローマ人が主にユークリッド幾何学について書いたと仮定すると)
— -FryAmTheEggman

@FryAmTheEggmanなるほど。知ってよかった、ありがとう。
— Alex A.

回答:


2

Pyth、92 76 70バイト

KsMc."/9hæ²z³Þ§ªW×Oû[Tnè,O¤"\/WQ=Q-Q=Nef!>TQ%2K aY@KhxKN;sY

ここでお試しください!

私にいくつかのバイトを節約したいくつかの文字列パッキング提案を@FryAmTheEggmanに感謝します!

このリストをエンコードする数学的な方法があるかどうか私はまだ疑問に思っています。何かを理解しようとします。

説明

これは与えられたアルゴリズムを使用します。K番号と対応するラインセグメントの数が交互に指定されたリストを含みます。このリストは、分割にデコードされますパックされた文字列で構成されます0/0/1/1/4/3/5/2/9/3/10/2/40/4/50/2/90/3/100/1/400/3/500/2/900/5/1000/4、上の/整数への各要素をマッピングします。

KsMc。 "..." \ / WQ = QQ = Nef!> TQ%2K aY @ KhxKN; sY#Q =入力

   c。 "..." \ /#/で文字列を分割します
KsM#すべての数値をintにマップし、Kに割り当てます
            WQ#while Q!= 0
                     f%2K#Kの2番目の要素のみを取得し、Tでフィルター
                      !> TQ#T <= Q
                  = Ne#その最後の要素を取り、それをNに割り当てる
              = QQ#Q = Q-N
                                   xKN#Kで最初に出現するNのインデックス
                                  h#ラインセグメントが必要なため、そのインデックスをインクリメントします
                              aA @ K#そのインデックスからラインセグメントを取得し、Yに追加する
                                      ; sY#ループを終了し、すべての線分の合計をYに出力します

3

C、148の 129文字

d,x,n[]={1000,900,500,400,100,90,50,40,10,9,5,4,1,4,5,2,3,1,3,2,4,2,3,2,3,1};f(c){while(d+=(c/n[x])*n[x+13],c%=n[x++]);return d;}

私の最初のコードゴルフ:^)。質問には関数を使用できると記載されているので、メインをいくつかの文字をトリミングする関数に変更しました(最も重要なのは、cをscanfではなくパラメーターとして渡す)。

開梱

d,x,n[]={1000,900,500,400,100,90,50,40,10,9,5,4,1,4,5,2,3,1,3,2,4,2,3,2,3,1};
f(c){
  while(d+=(c/n[x])*n[x+13],
        c%=n[x++]);
  return d;
}

2

Mathematica、80 72バイト

Tr[Characters[#~IntegerString~"Roman"]/.{"I"|"C"->1,"M"->4,_String->2}]&

数値をローマ数字に変換し、各文字をそのセグメントの数で置き換え、合計を取得する無名関数。


2

Retina、128バイト

。+
$ *
1 {1000}
t '
1 {900}
td
1 {500}
d
1 {400}
t
1 {100}
」
1 {90}
t
1 {50}
d
1 {40}
t '
1 {10}
d
1 {9}
t
1 {5}
d
1 {4}
t
1
」
t
d '
d
」
'+
$ .0

交換するものがなくなるまで簡単に交換できます。次にアポストロフィが数えられ、それがラインセグメントの数になります。

単項での入力と出力が許可されている場合、それは115バイトです(だれが1234を入力したいですか?)。

オンラインでお試しください!
オンラインでお試しください!(単項IO)


2

Python 3、95バイト

def f(a,b=0):
 for e in'᝴ᔝ஺ॣəȟĮô>9 ':e=ord(e);d=e//6;b+=a//d*(e%6);a%=d
 return b

Unicode文字列は、コードポイントで構成されています。

6004 5405 3002 2403 601 543 302 244 62 57 32 27 7

その文字列をバイトリテラルに変換する場合は省略できますe=ord(e);
— xsot

私の場合はうまくいかないと思います。私は、Unicode文字列を必要とする:(つまり私は、その文字列ではなく、バイトを超えるコードポイントをループしています。
— リン

1
ああなるほど。文字列の16進ダンプを提供してもよろしいですか。スマートフォンに正しく表示されません。
— xsot 2016年

1

Java、152バイト

知っているので、Java。

n->{int c=0;int[]r={999,4,899,5,499,2,399,3,99,1,89,3,49,2,39,4,9,2,8,3,4,2,3,3,0,1};for(int i=0;i<26;i+=2)while(n>r[i]){n-=r[i]+1;c+=r[i+1];}return c;}

指定されたアルゴリズムの単純なリテラル実装。配列は変換情報をパックします。偶数のインデックスはローマ数字より1少なく、奇数のインデックスはその数字の数です。

これはint/ を取り、返すラムダですInteger。これにはIntUnaryOperatorまたはが含まれUnaryOperator<Integer>ます。


1

JavaScript(ES6)、79バイト

n=>"0123323453"[[,a,b,c,d]=1e4+n+'',d]-(-"0246424683"[c]-"0123323455"[b])+a*4

文字列は、単位の数十、数百桁の線分の数を表します。(千は単に千の桁の4倍です。)この方法は、質問で提案されているアルゴリズムなどの他のオプションよりも短いようです。

編集:@ user81655のおかげで2バイト節約されました。


これはクールなアルゴリズムです。キャストを再配置すると、2つのバイトを保存することができますだけでなく、:n=>"0123323453"[[,a,b,c,d]=1e4+n+'',d]-(-"0246424683"[c]-"0123323455"[b])+a*4
— user81655

@ user81655ああ、それはいいことです。単に+sを-sに変更すると、先頭のを削除できます+が、グループ化すると別のバイトが節約されます。
— Neil、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.