R [oman | everse] Notasi Polandia

11

Ini adalah tahun MDLXVII di dunia di mana Kekaisaran Romawi tidak pernah jatuh, dan keruntuhan ke zaman kegelapan tidak pernah terjadi. Karena periode Pax Romana yang diperpanjang, stabilitas ekonomi kekaisaran memungkinkan teknologi untuk maju dengan kecepatan tinggi.

Orang-orang Romawi mulai mencoba-coba dengan sirkuit, dan telah menemukan kalkulator cerdas yang tidak memerlukan penggunaan tombol "sama dengan". Mereka menyebutnya "Notasi Romawi Polandia"

Untuk membuat perhitungan, mereka memasukkan operan mereka terlebih dahulu, kemudian operasi.

Misalnya, 100 + 11 * 20 akan menjadi C XI XX * +.

Selain itu

Bangsa Romawi telah menemukan bahwa mereka sering perlu membuat banyak perhitungan pada waktu yang bersamaan, dan akan lebih memilih metode untuk mengembalikan setiap nilai "pada tumpukan" dalam semacam susunan / daftar / struktur seperti tuple. (mis. X I + X I - CC II +akan kembali [11, 9, 202])


Tantangannya adalah mengembangkan program kalkulator yang mampu membuat perhitungan ini.

Klarifikasi : Notasi Subtraktif diperlukan. Saya tidak menyadari itu tidak dikenal fitur di kekaisaran Romawi Kuno. Karena itu tugasnya ambigu, dan saya minta maaf.

Pedoman Minimum

  • Output Anda akan dalam Angka Arab.
  • Anda hanya perlu mengonversi dari Angka Romawi hingga 5000.
  • Anda perlu mendukung operasi +, -, /, * (penambahan, pengurangan, pembagian, dan penggandaan).
  • Apakah divisi berbasis floating point atau integer didasarkan pada implementasi spesifik. Baik berhasil untuk tantangan ini.
  • Output Anda perlu mendukung angka hingga 4 Miliar.
  • Jawaban terpendek secara keseluruhan, DAN dalam setiap bahasa menang. Ini adalah Tantangan Golf Code tapi saya suka varietasnya.

Dalam hal terjadi seri, faktor-faktor seperti dukungan untuk angka romawi di atas 5000 atau operasi tambahan akan dianggap pengajuan paling awal akan menang.

Jesse Daniel Mitchell
sumber
1
Bisakah kita mengambil input sebagai daftar string, masing-masing memiliki nomor Romawi atau operator?
user202729
dapatkah input diambil dalam huruf kecil, atau harus huruf besar?
dzaima
1
@JesseDanielMitchell Sebagai catatan ... cobalah untuk tidak mengubah aturan dan membatalkan jawaban yang ada . Juga, (seperti biasa) saya sarankan memposting di Sandbox .
user202729

Jawaban:

6

Python 2 + roman , 118 byte

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

Demo

Itu tidak dapat diuji secara online karena modul yang digunakannya, tetapi Anda dapat melihat bagaimana menjalankan ini di sini (program lengkap menerima input dari STDIN - ekspresi dengan tanda kutip - dan mencetak output ke STDOUT - dalam bentuk daftar , tumpukan). Menggunakan versi yang sedikit lebih lama, karena saya tidak akan repot-repot membuat GIF baru hanya dengan beberapa byte:

Demo GIF

Untuk menginstal paket, Anda dapat menjalankan yang berikut ini di Terminal / Command Line:

pip install roman
Tuan Xcoder
sumber
2
pyTester/Py.pyಠ_ಠ
totallyhuman
@totallyhuman Ini hanya proyek tiruan yang saya buat hanya untuk ini ...
Tn. Xcoder
6

Haskell , 217 byte

-13 byte terima kasih kepada Bruce Forte. -73 byte berkat Ørjan Johansen.

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

Cobalah online!

Implementasi manual, yay!

benar-benar manusiawi
sumber
2
Saya mengurangi itu sedikit (sangat dekat dengan mengalahkan Python yang baru ...) Cobalah online!
Ørjan Johansen
1
Yang Python juga ditebang. Tetapi jika argumennya bahwa notasi subtraktif tidak perlu didukung didukung, maka ada lebih banyak penghematan di sini juga.
Ørjan Johansen
1
Dalam hal apa pun, 3 byte lagi mati bersama l=1:4:5:9:map(10*)l.
ბიმო
Saya ingat trik sisa yang pernah saya temukan untuk mengonversi angka Romawi, yang menangani pengurangan secara otomatis. Cobalah online!
Ørjan Johansen
2

JavaScript (Node) + romans + stk-lang , 74 byte

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

Mengembalikan daftar bigintegers.

Eksekusi

Jalankan yang berikut ini:

npm install romans
npm install stk-lang
node

Kemudian tempel fungsinya. Contoh:

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.

+ [email protected]
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.

+ [email protected]
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' ]
Conor O'Brien
sumber
Berapa banyak orang yang menggunakan lambda sebagai konfirmasi?
Stan Strum
@StanStrum Saya menyukainya, dan ini adalah default untuk terminal seperti cmder
Conor O'Brien
Tidak tahu itu. Kira saya tidak pernah menyimpang dari $dan >. Jujur, saya suka itu
Stan Strum
2

Dyalog APL , 93 byte

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

Cobalah online!

116 byte tanpa built-in roman

dzaima
sumber
Woah, tidak pernah melihat tugas yang dimodifikasi di golf sebelumnya
Zacharý
@ Zachary itu satu-satunya cara yang saya tahu untuk memodifikasi variabel keluar dari ruang lingkup dfns nya, sehingga harus digunakan di sini.
dzaima
Maafkan ketidaktahuan saya, tapi apa tugas yang dimodifikasi?
caird coinheringaahing
@cairdcoinheringaahing var fn←arr- setara dengan var ← var fn arr. Ini digunakan di banyak tempat, a,←⍵menjadi salah satu yang ditambahkan ke variabela
dzaima
1

Python 3 , 280 206 byte

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

Cobalah online!

Kali ini dengan dukungan notasi yang kurang. metodec adalah titik masuk utama; yang lainnya adalah dukungan.

Edit log:

David Foerster
sumber
Anda tidak perlu blok lekukan setelah ifdan else.
Ørjan Johansen
Sebenarnya, izinkan saya menawarkan trik ini yang pernah saya temukan:n+=v-n%v*2
Ørjan Johansen
1
Anda juga dapat menggabungkan kedua strkegunaan. Cobalah online!
Ørjan Johansen
0

JavaScipt (ES6), 152 151 byte

Disimpan 1 byte berkat pengguna202729

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

Uji kasus

Penjelasan (kurang golf)

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
Herman L.
sumber
Saya cukup yakin itu 1e3juga berfungsi dan menyimpan beberapa byte.
user202729
0

Jelly , 82 byte

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

Cobalah online!

Awalnya diposting di obrolan .


Penjelasan:

Karena Jelly tidak memiliki tumpukan, saya memasukkan tumpukan itu ke dalam register.

Ketika program dimulai, nilai register ®adalah 0, yang diperlakukan sebagai [0]untuk keperluan program ini.


ị“+-×÷”;”/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]

pengguna202729
sumber
-1

Python 3 , 216 187 byte

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

Cobalah online!

Karena muncul di komentar baik pertanyaan dan jawaban ini dan kemungkinan menyebabkan suara turun: pengajuan ini tidak mendukung notasi subtraktif.Dasar Pemikiran: Notasi subtraktif jarang digunakan di Kekaisaran Romawi dan hanya dipopulerkan kemudian (lihat Subtractive Notation , paragraf 3, kalimat terakhir). Tugas ini menganggap Kekaisaran Romawi yang mengembangkan sirkuit terpadu yang dapat diprogram, bukan yang mengalami perubahan budaya yang sama seperti Eropa abad ke-13. Deskripsi tidak menyebutkan notasi subtraktif dan tidak ada contoh yang menggunakannya.

David Foerster
sumber
Hm ... Anda tidak mendukung angka seperti CIV(104).
Ørjan Johansen
... tidak dapat menyalahkan logika Anda di sana. : P
Ørjan Johansen
2
Agh, kamu benar. Saya belum memikirkan kemungkinan ambiguitas, saya tidak menyadari notasi subtraktif bukan fitur umum di kekaisaran Romawi Kuno.
Jesse Daniel Mitchell
1
Saya benar-benar mempertimbangkan untuk bertanya tentang notasi subtraktif di bawah OP (dan memperhatikan kurangnya contoh), tetapi menjadi terganggu. Jika Anda berpikir tentang ambiguitas definisi dalam tantangan di masa depan, jangan ragu, tanyakan saja (menjawab dengan peringatan dan tautan ke komentar Anda harus dilakukan jika Anda ingin memposting). Sekarang keputusan ada di Anda harus berusaha untuk memperbaikinya :)
Jonathan Allan