R [oman | everse] польська нотація


11

Це рік MDLXVII у світі, в який Римська імперія ніколи не впадала, а крах у темні віки ніколи не відбувався. Завдяки тривалому періоду Пакс Романа, економічна стабільність імперії дозволила технології прогресувати швидкими темпами.

Римляни почали заплутатися з схемою, і винайшли геніальний калькулятор, який не вимагає використання кнопки "рівний". Вони називають це "Римське польське позначення"

Щоб зробити розрахунок, вони вводять спочатку свої операнди, потім операцію.

Наприклад, 100 + 11 * 20 було б C XI XX * +.

Додатково

Римляни виявили, що їм часто потрібно робити кілька обчислень одночасно, і вважають за краще, щоб метод повертав кожне значення "на стеку" в якійсь структурі масиву / списку / кортежу. (наприклад X I + X I - CC II +, повернеться [11, 9, 202])


Завдання полягає в розробці програми калькулятора, здатної робити ці обчислення.

Уточнення : віднімання обов'язкове. Я не здогадувався, що це не було визнано рисою в Стародавній Римській імперії. Тому завдання було неоднозначним, і я вибачаюся.

Мінімальні вказівки

  • Ваш вихід буде арабськими цифрами.
  • Вам потрібно лише конвертувати з римських чисел до 5000.
  • Вам потрібно буде підтримувати операції +, -, /, * (додавання, віднімання, ділення та множення).
  • Незалежно від того, чи є поділ на основі плаваючої точки чи на ціле число, це специфічна реалізація. Або це працює для цього виклику.
  • Ваш вихід повинен мати підтримку чисел до 4 мільярдів.
  • Найкоротша відповідь в цілому, І в кожній мові виграє. Це Code Golf Challenge, але я люблю різноманітність.

У випадку зрівноваження такі фактори, як підтримка римських цифр вище 5000 або додаткові операції, вважатимуться найвищим виграшем.


1
Чи можемо ми взяти введення як список рядків, кожен з яких має або римський номер, або оператор?
користувач202729

чи можна вводити малі літери або це має бути великими літерами?
dzaima

1
@JesseDanielMitchell Як зауваження ... намагайтеся не змінювати правила та скасовуйте існуючі відповіді . Також (як завжди) пропоную розміщувати в пісочниці .
користувач202729

Відповіді:


6

Пітон 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 Це просто фіктивний проект, який я зробив саме для цього ...
Містер Xcoder

6

Haskell , 217 байт

-13 байт завдяки Брюсу Форте. -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 Johansen

1
Пітон також був скорочений. Але якщо його аргумент про те, що віднімання позначень не потрібно підтримувати, підтримується і тут.
Ørjan Johansen

1
У будь-якому випадку, ще 3 байти відключити за допомогою l=1:4:5:9:map(10*)l.
იმო

Я запам'ятав залишок, який я одного разу знайшов для перетворення римських цифр, який автоматично переймається відніманням. Спробуйте в Інтернеті!
Ørjan Johansen


2

JavaScript (Node) + римляни + stk-lang , 74 байти

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

Повертає список великих цілих чисел.

Виконання

Виконайте наступне:

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' ]

Скільки людей використовують лямбда як підказку?
Стен Струм

@StanStrum Мені це подобається, і це за замовчуванням для таких терміналів, як cmder
Conor O'Brien

Не знав цього. Здогадайтесь, я ніколи не відхилявся від $і >. Чесно кажучи, мені це подобається
Стен Струм

2

Діалог APL , 93 байти

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

Спробуйте в Інтернеті!

116 байт без римської вбудованої


Вуа, ніколи раніше не бачив модифікованих завдань у гольфі
червня

@ Zacharý - це єдиний спосіб, коли я знаю, щоб змінити змінну зі своєї області 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- головна точка входу; інша - підтримка.

Редагувати журнал:


Не потрібні блоки відступу після ifта після else.
Ørjan Johansen

Власне, дозвольте запропонувати вам цю хитрість, яку я одного разу знайшов:n+=v-n%v*2
Ørjan Johansen

1
Ви також можете поєднати два strваріанти використання. Спробуйте в Інтернеті!
Ørjan Johansen

0

JavaScipt (ES6), 152 151 байт

Збережено 1 байт завдяки користувачу202729

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також працює і зберігає деякі байти.
користувач202729

0

Желе , 82 байти

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

Спробуйте в Інтернеті!

Спочатку розміщено у чаті .


Пояснення:

Оскільки у Jelly немає стека, я ставлю їх у реєстр.

Коли програма запускається, значення регістру ®є 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

Пітон 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
Ага, ви мали рацію. Я не замислювався над можливою неоднозначністю, не знав, що віднімання позначень не є загальною рисою в Давньоримській імперії.
Джессі Даніель Мітчелл

1
Я насправді розглядав питання про віднімання позначень в рамках ОП (і помітив відсутність прикладу), але відволікався. Якщо ви думаєте про неоднозначності визначення в майбутніх викликах, не соромтеся, просто запитайте (відповідаючи застереженням та посиланням на ваш коментар, це слід зробити, якщо ви хочете опублікувати). Тепер ухвала у вас, ви повинні спробувати її виправити :)
Джонатан Аллан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.