R [oman | everse]ポーランド記法


11

それは、ローマ帝国が陥落せず、暗黒時代への崩壊が起こらなかった世界でMDLXVIIの年です。パックスロマナの長期化により、帝国の経済的安定により、テクノロジーは急速に進歩しました。

ローマ人は回路に手を出すようになり、「等しい」ボタンの使用を必要としない独創的な計算機を発明しました。彼らはそれを「ローマ・ポーランド記法」と呼びます

計算を行うには、まずオペランドを入力してから、演算を入力します。

たとえば、100 + 11 * 20はになりますC XI XX * +

さらに

ローマ人は、複数の計算を同時に行う必要がある場合が多く、メソッドが何らかの配列/リスト/タプルのような構造で「スタック上の」すべての値を返すことを望んでいます。(たとえばX I + X I - CC II +、[11、9、202]を返します)


課題は、これらの計算を行うことができる電卓プログラムを開発することです。

明確化:減算表記が必要です。私はそれが古代ローマ帝国の特徴として認識されていないことに気づかなかった。したがって、このタスクはあいまいであり、謝罪します。

最小ガイドライン

  • 出力はアラビア数字になります。
  • 5000までのローマ数字から変換する必要があるだけです。
  • +、-、/、*演算(加算、減算、除算、乗算)をサポートする必要があります。
  • 除算が浮動小数点ベースか整数ベースかは実装固有です。どちらもこの課題に対応します。
  • 出力は40億までの数値をサポートする必要があります。
  • 全体的に最も短い答え、そして各言語での勝ちです。これはコードゴルフチャレンジですが、私はその種類が大好きです。

同点の場合は、5000を超えるローマ数字のサポートや追加の演算などの要素が、最も早い提出が勝つと見なされます。


1
入力を文字列のリストとして受け取ることができます。各文字列にはローマ数字または演算子がありますか?
user202729 2017

入力は小文字で取得できますか、それとも大文字である必要がありますか?
dzaima 2017

1
@JesseDanielMitchell注:ルールを変更せず、既存の回答を無効にしてください。また、(いつものように)サンドボックスに投稿することをお勧めします。
user202729 2018年

回答:


6

Python 2 + roman、118バイト

from roman import*
s=[]
for i in input().split():s+=[eval(s.pop(-2)+i+s.pop())if i in"+-/*"else`fromRoman(i)`]
print s

デモ

使用するモジュールのため、オンラインでテストすることはできませんが、ここでこれを実行する方法を見ることができます(STDINからの入力を受け入れる完全なプログラム(引用符付きの式)およびリストの形式でSTDOUTへの出力を印刷) 、スタック)。わずかに古いバージョンを使用します。これは、数バイトのみの新しいGIFを作成する必要がないためです。

デモGIF

パッケージをインストールするには、ターミナル/コマンドラインで次のコマンドを実行します。

pip install roman

2
pyTester/Py.pyಠ_ಠ
totallyhuman

@totallyhumanこれは、私がこれのために作成したダミープロジェクトにすぎません...
Xcoder氏、2017

6

Haskell、217バイト

Bruce Forteのおかげで-13バイト。ØrjanJohansenのおかげで-73バイト。

foldl(!)[].words
s@ ~(x:y:z)!n=last$(a n:s):[y`f`x:z|(f,c)<-zip[(+),(-),(*),(/)]"+-*/",n==[c]]
a s=last$0:[n+a(drop(length x)s)|(n,x)<-zip l$words"I IV V IX X XL L XC C CD D CM M",x<=s,x++"Y">s]
l=[1,4,5,9]++map(10*)l

オンラインでお試しください!

手動で実装しました。


2
私はそれを少し削減しました(新しいPythonのものを打ち負かすのに非常に近い...)オンラインで試してみてください!
Ørjanヨハンセン

1
Python 1も削減されました。しかし、減法表記をサポートする必要がないという彼の主張が支持されれば、ここでもより多くの節約があります。
Ørjanヨハンセン

1
いずれの場合も、でさらに3バイトオフl=1:4:5:9:map(10*)l
'2017

ローマ数字を変換するときに見つけた残りのトリックを思い出しました。これは自動的に減算を処理します。オンラインでお試しください!
Ørjanヨハンセン


2

JavaScript(ノード)+ romans + stk-lang、74バイト

s=>(R=require)("stk-lang")(s.replace(/\w+/g,R("romans").deromanize)).stack

bigintegersのリストを返します。

実行

以下を実行します。

npm install romans
npm install stk-lang
node

次に、関数を貼り付けます。例:

C:\Users\conorob\Programming\golf-new\roman
λ npm install romans
npm WARN saveError ENOENT: no such file or directory, open 'C:\Users\conorob\Programming\package.json'
npm WARN enoent ENOENT: no such file or directory, open 'C:\Users\conorob\Programming\package.json'
npm WARN Programming No description
npm WARN Programming No repository field.
npm WARN Programming No README data
npm WARN Programming No license field.

+ romans@1.0.0
added 1 package in 0.801s

C:\Users\conorob\Programming\golf-new\roman
λ npm install stk-lang
npm WARN saveError ENOENT: no such file or directory, open 'C:\Users\conorob\Programming\package.json'
npm WARN enoent ENOENT: no such file or directory, open 'C:\Users\conorob\Programming\package.json'
npm WARN Programming No description
npm WARN Programming No repository field.
npm WARN Programming No README data
npm WARN Programming No license field.

+ stk-lang@1.0.0
added 1 package in 0.847s

C:\Users\conorob\Programming\golf-new\roman
λ node
> s=>(R=require)("stk-lang")(s.replace(/\w+/g,R("romans").deromanize)).stack
[Function]
> f=_
[Function]
> f("X I + X I - CC II +").map(e => e.toString())
[ '11', '9', '202' ]
> f("C XI XX * +").map(e => e.toString())
[ '320' ]
> f("MMMM M I - +").map(e => e.toString())
[ '4999' ]

プロンプトとしてラムダを何人使用しますか?
Stan Strum

@StanStrumそれのようなI、そして、それはのような端末のデフォルトだcmder
コナー・オブライエン

それを知りませんでした。$とから逸脱したことがないと思います>。正直なところ、私はそれが好きです
Stan Strum

2

Dyalog APL、93バイト

CY'dfns'
a←⍬⋄{0::{a,←⍵}roman⍵⋄f←⍎'+-÷×'⌷⍨'+-/*'⍳⍵⋄rf2aa↓⍨←¯2a,←r}¨{1↓¨⍵⊂⍨⍵∊' '}' ',⍞⋄a

オンラインでお試しください!

romanが組み込まれていない116バイト


ああ、これまでゴルフで変更された割り当てを見たことがない
ザカロ

ザカリー@それは私がそれはので、そのDFNSスコープ外の変数を変更するために知っている唯一の方法だ持っていた、ここで使用されます。
dzaima 2017

私の無知を許してください、しかし変更された割り当てとは何ですか?
caird coinheringaahing

@cairdcoinheringaahing- var fn←arrと同等var ← var fn arrです。ここでa,←⍵、変数に追加する場所として、複数の場所で使用されていますa
dzaima

1

Pythonの3280の 206バイト

N=dict(I=1,V=5,X=10,L=50,C=100,D=500,M=1000)
def d(s):
	n=0
	for v in map(N.get,s):n+=v-n%v*2
	return n
def c(w):
	s=[]
	for t in w.split():s+=[str(d(t)if t[0]in N else eval(s.pop(-2)+t+s.pop()))]
	return s

オンラインでお試しください!

今回は減法表記をサポートします。メソッドcはメインのエントリポイントです。もう1つはサポートです。

ログを編集:


ifとの後のインデントブロックは必要ありませんelse
Ørjanヨハンセン

見つかったら、実際に、私はあなたにこのトリックIを提供してみましょう:n+=v-n%v*2
Ørjanヨハンセン

1
2つのstr用途を組み合わせることもできます。オンラインでお試しください!
Ørjanヨハンセン

0

JavaScipt(ES6)、152 151バイト

user202729のおかげで1バイト節約

p=>p.split` `.map(c=>s.push(eval("+-/*".indexOf(c)+1?(T=s.pop(),s.pop())+c+T:c.replace(/./g,c=>"+"+{I:1,V:5,X:10,L:50,C:100,D:500,M:1e3}[c]))),s=[])&&s

テストケース

説明(ゴルフが少ない)

V={I:1,V:5,X:10,L:50,C:100,D:500,M:1e3}     // Values of the roman numerals
p=>(
 s=[],                                      // Initialize the stack
 p.split` `.map(c=>                         // For every part in the input:
  "+-/*".indexOf(c)+1?                      //   If the input is an operator:
   s.push(eval((T=s.pop(),s.pop())+c+T))    //     Evaluate the operator on the top of the stack
  :                                         //   Else (if it is a roman numeral):
   s.push(eval(c.replace(/./g,c=>"+"+V[c])))//     Push the sum of the characters' values
 ),s)                                       // return the stack

1e3もそれが機能し、いくつかのバイトを節約すると確信しています。
user202729 2017

0

ゼリー、82バイト

ị“+-×÷”;”/v®ṫ-¤®ṖṖ¤;©
4Ḷ⁵*p1,5P€
“IVXLCDM”iЀị¢µIN‘Ṡæ.µ®;©
Ḳµ“+-*/”W€i⁸Ñ⁸Ǥ¹?µ€ṛ®Ḋ

オンラインでお試しください!

もともとチャットで投稿


説明:

ジェリーにはスタックがないので、スタックをレジスターに入れました。

プログラムの開始時、レジスター値®0であり[0]、このプログラムの目的と同様に扱われます。


ị“+-×÷”;”/v®ṫ-¤®ṖṖ¤;©       Link 1: Given an operator index (an
                            integer in range 1..4), apply it.

ị“+-×÷”                     Index to the string "+-×÷"
       ;”/                  Concatenate with the character "/",
                            which is Jelly splat operator.
          v   ¤             Evaluate with parameter...
           ®                  the register's
            ṫ                 tail
             -                from -1. (2 last items)
               ®  ¤;        Concatenate with the register value,
                ṖṖ            pop twice.
                    ©       Store the result to register.

4Ḷ⁵*p1,5P€          Link 2: Niladic, generate [1,5,10,50,...]
4Ḷ                  Lowered range of 4, gives [0,1,2,3].
  ⁵*                Raise to power of 10. Value = 1,10,100,1000.
    p1,5            Calculate Cartesian product with [1,5].
                      Value = [1,1],[1,5],[10,1],[10,5],...
        P€          Calculate product of each item.

Alternatively, ×þ1,5F would also work instead of p1,5P€.

“IVXLCDM”iЀị¢µIN‘Ṡæ.µ®;©   Link 3: Given roman number, push it
                            to the stack (register).
         i                  Find index of ...
          Ѐ                  each character ...
“IVXLCDM”                     in "IVXLCDM".
            ị¢              Index to last link. (link 2)
              µ             With that value, (consider LIX ->
                            [50,1,10] for example)
               I             
Ḳµ“+-*/”W€i⁸Ñ⁸Ǥ¹?µ€ṛ®Ḋ

[TODO complete explanation]


-1

Pythonの3216の 187バイト

from operator import*
N=dict(I=1,V=5,X=10,L=50,C=100,D=500,M=1000)
def f(w):
	s=[]
	for t in w.split():s+=[str(sum(map(N.get,t)))if t[0]in N else str(eval(s.pop(-2)+t+s.pop()))]
	return s

オンラインでお試しください!

それは質問とこの回答の両方のコメントで出てきて、おそらく反対票につながったからです。この提出は減法表記をサポートしていません。理論的根拠:減算表記法は、ローマ帝国ではめったに使用されず、後に普及しただけです(減算表記法、段落3、最後の文を参照)。タスクは、13世紀のヨーロッパと同じ文化的変化を受けたものではなく、プログラム可能な集積回路を開発したローマ帝国を想定しています。説明では減法表記については触れられておらず、どの例でもそれを使用していません。


うーん...あなたはCIV(104)のような数をサポートしていません。
Ørjanヨハンセン

...そこでロジックを失敗させることはできません。:P
Ørjanヨハンセン

2
ああ、あなたは正しかった。あいまいさの可能性については考えていませんでした。減算表記法が古代ローマ帝国では一般的な機能ではないことを知りませんでした。
ジェシーダニエルミッチェル

1
私は実際にはOPでの減算表記について尋ねることを検討しました(そして例の欠如に気づきました)が、気が散りました。将来の課題における定義のあいまいさについて考える場合は、ためらわずに質問してください(投稿したい場合は、警告とコメントへのリンクで答えてください)。判決が出ているので、修正を試みるべきです:)
Jonathan Allan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.