R [oman | everse] สัญลักษณ์ของโปแลนด์


11

มันเป็นปี MDLXVII ในโลกที่จักรวรรดิโรมันไม่เคยล้มและการล่มสลายในยุคมืดไม่เคยเกิดขึ้น เนื่องจากช่วงเวลาที่ยาวนานของ Pax Romana ทำให้เสถียรภาพทางเศรษฐกิจของจักรวรรดิเปิดใช้งานเทคโนโลยีเพื่อความก้าวหน้าในอัตราที่รวดเร็ว

ชาวโรมันเริ่มตะลุยกับวงจรไฟฟ้าและคิดค้นเครื่องคิดเลขที่แยบยลซึ่งไม่จำเป็นต้องใช้ปุ่ม "เท่ากับ" พวกเขาเรียกมันว่า "Roman Polish Notation"

ในการคำนวณพวกเขาป้อนตัวถูกดำเนินการก่อนจากนั้นจึงทำการดำเนินการ

ยกตัวอย่างเช่น 100 + 11 * 20 C XI XX * +จะเป็น

นอกจากนี้

ชาวโรมันพบว่าพวกเขามักจะต้องทำการคำนวณหลายอย่างในเวลาเดียวกันและต้องการให้วิธีการคืนค่าทุกค่า "บนสแต็ก" ในโครงสร้างเรียงลำดับอาร์เรย์ / รายการ / ทูเปิลบางประเภท (เช่นX I + X I - CC II +จะส่งคืน [11, 9, 202])


ความท้าทายคือการพัฒนาโปรแกรมเครื่องคิดเลขที่สามารถคำนวณได้

ชี้แจง : จำเป็นต้องมีสัญกรณ์ลบ ฉันไม่ได้ตระหนักว่ามันไม่เป็นที่รู้จักในจักรวรรดิโรมันโบราณ งานจึงคลุมเครือและฉันขอโทษ

แนวทางขั้นต่ำ

  • ผลลัพธ์ของคุณจะเป็นเลขอารบิค
  • คุณต้องแปลงจากตัวเลขโรมันเป็น 5,000
  • คุณจะต้องสนับสนุนการดำเนินงาน +, -, /, * (นอกจากนี้การลบการหารและการคูณ)
  • ไม่ว่าการแบ่งเป็นอิงทศนิยมหรือการใช้จำนวนเต็มเป็นการเจาะจง ใช้ได้กับความท้าทายนี้
  • ผลลัพธ์ของคุณจะต้องรองรับตัวเลขสูงถึง 4 พันล้าน
  • คำตอบที่สั้นที่สุดโดยรวมและในแต่ละภาษาจะชนะ นี่คือการท้าทายของรหัสกอล์ฟ แต่ฉันชอบความหลากหลาย

ในกรณีที่เสมอกันปัจจัยเช่นการสนับสนุนตัวเลขโรมันที่สูงกว่า 5,000 หรือการดำเนินการเพิ่มเติมจะได้รับการพิจารณาการส่งที่เร็วที่สุดจะเป็นผู้ชนะ


1
เราสามารถรับข้อมูลเป็นรายการสตริงได้หรือไม่แต่ละรายการมีหมายเลขโรมันหรือโอเปอเรเตอร์?
user202729

สามารถนำเข้าเป็นตัวพิมพ์เล็กหรือจะต้องเป็นตัวพิมพ์ใหญ่?
dzaima

1
@JesseDanielMitchell เป็นบันทึก ... พยายามที่จะไม่เปลี่ยนแปลงกฎระเบียบและโมฆะมีอยู่คำตอบ นอกจากนี้ (ตามปกติ) ผมขอแนะนำให้โพสต์ในSandbox
user202729

คำตอบ:


6

Python 2 + โรมัน , 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 สาธิต

ในการติดตั้งแพ็คเกจคุณสามารถเรียกใช้สิ่งต่อไปนี้ใน Terminal / Command Line:

pip install roman

2
pyTester/Py.pyಠ_ಠ
totallyhuman

@tallyallyhuman เป็นเพียงโครงการจำลองที่ฉันทำเพื่อสิ่งนี้ ...
Mr. Xcoder

6

Haskell , 217 ไบต์

-13 ไบต์ขอบคุณ Bruce Forte -73 ไบต์ขอบคุณØ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

ลองออนไลน์!

ดำเนินการด้วยตนเองใช่!


2
ฉันตัดมันลงเล็กน้อย (ใกล้เคียงกับ Python อันใหม่ ... ) ลองออนไลน์!
Ørjan Johansen

1
งูหลามก็ถูกตัดออกเช่นกัน แต่ถ้าการโต้แย้งของเขาที่ไม่จำเป็นต้องได้รับการสนับสนุนเป็นสัญกรณ์ลบสัญกรณ์ก็มีเงินออมที่นี่เช่นกัน
Ørjan Johansen

1
ในกรณีใด ๆ อีก 3 l=1:4:5:9:map(10*)lไบต์ออกด้วย
2560

ฉันจำเคล็ดลับส่วนที่เหลือที่ฉันเคยพบในการแปลงตัวเลขโรมันซึ่งจะจัดการการลบโดยอัตโนมัติ ลองออนไลน์!
Ørjan Johansen


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

@StrumStrum ฉันชอบมันและเป็นค่าเริ่มต้นสำหรับเทอร์มินัลเช่นcmder
Conor O'Brien

ไม่ทราบว่า คิดว่าผมไม่เคยเบี่ยงเบนจากและ$ >สุจริตฉันชอบมัน
Stan Strum

2

Dyalog APL , 93 ไบต์

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

ลองออนไลน์!

116 ไบต์โดยไม่มีโรมันในตัว


Woah ไม่เคยเห็นงานดัดแปลงในสนามกอล์ฟมาก่อน
Zacharý

@ Zachary มันเป็นวิธีเดียวที่ฉันรู้ที่จะปรับเปลี่ยนตัวแปรออกจากขอบเขต dfns ของมันจึงมีที่จะใช้ที่นี่
dzaima

ยกโทษให้ความไม่รู้ของฉัน แต่สิ่งที่ได้รับมอบหมายมีการปรับเปลี่ยน?
caird coinheringaahing

@cairdcoinheringaahing var fn←arr- var ← var fn arrมันเทียบเท่ากับ ที่นี่มีการใช้งานในหลายสถานที่โดยa,←⍵เป็นที่ผนวกกับตัวแปรa
dzaima

1

Python 3 , 280 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เป็นจุดเข้าหลัก อื่น ๆ คือการสนับสนุน

แก้ไขบันทึก:

  • 74 ลงขอบคุณØrjan

คุณไม่จำเป็นต้องบล็อกเยื้องหลังและif else
Ørjan Johansen

ที่จริงแล้วฉันขอเสนอเคล็ดลับนี้ให้คุณเมื่อฉันพบ:n+=v-n%v*2
Ørjan Johansen

1
นอกจากนี้คุณยังสามารถรวมสองstrความหมาย ลองออนไลน์!
Ørjan Johansen

0

JavaScipt (ES6), 152 151 ไบต์

บันทึก 1 ไบต์ขอบคุณ user202729

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

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 3 , 216 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 Johansen

... ไม่ผิดตรรกะของคุณที่นั่น : P
Ørjan Johansen

2
ใช่คุณพูดถูก ฉันไม่ได้คิดเกี่ยวกับความกำกวมที่เป็นไปได้ แต่ฉันไม่ได้ตระหนักถึงสัญกรณ์ลบที่ไม่ได้เป็นคุณลักษณะทั่วไปในจักรวรรดิโรมันโบราณ
Jesse Daniel Mitchell

1
จริง ๆ แล้วฉันได้พิจารณาถามเกี่ยวกับสัญกรณ์หักลบภายใต้ OP (และสังเกตเห็นการขาดตัวอย่าง) แต่ได้ฟุ้งซ่าน หากคุณนึกถึงความคลุมเครือของคำจำกัดความในความท้าทายในอนาคตอย่าลังเลเพียงถาม (ตอบด้วยข้อแม้และลิงก์ไปยังความคิดเห็นของคุณควรทำอย่างไรถ้าคุณต้องการโพสต์) ขณะนี้คดีอยู่ในตัวคุณควรพยายามที่จะแก้ไขได้ขึ้น :)
โจนาธานอัลลัน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.