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

11

Это год MDLXVII в мире, в котором никогда не пала Римская империя, и никогда не происходил крах в темные века. Из-за длительного периода Pax Romana, экономическая стабильность империи позволила технологии развиваться быстрыми темпами.

Римляне начали увлекаться схемотехникой и изобрели оригинальный калькулятор, который не требует использования кнопки «равно». Они называют это "римско-польской нотацией"

Чтобы сделать расчет, они сначала вводят свои операнды, а затем операцию.

Например, 100 + 11 * 20 будет C XI XX * +.

Дополнительно

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


Задача состоит в том, чтобы разработать программу-калькулятор, способную выполнять эти вычисления.

Пояснение : требуется вычитание. Я не осознавал, что это не было признано в древнеримской империи. Задача была поэтому неоднозначной, и я прошу прощения.

Минимальные рекомендации

  • Ваш вывод будет в арабских цифрах.
  • Вам нужно только конвертировать из римских цифр до 5000.
  • Вам нужно будет поддерживать операции +, -, /, * (сложение, вычитание, деление и умножение).
  • Будет ли деление основано на числах с плавающей запятой или на целых числах, зависит от реализации. Либо работает для этого вызова.
  • Ваш вывод должен поддерживать номера до 4 миллиардов.
  • Самый короткий ответ в целом, И на каждом языке выигрывает. Это Code Golf Challenge, но я люблю разнообразие.

В случае ничьей такие факторы, как поддержка римских цифр выше 5000 или дополнительные операции, будут считаться наиболее ранними.

Джесси Даниэль Митчелл
источник
1
Можем ли мы принять ввод как список строк, каждая из которых имеет римское число или оператор?
user202729
Можно ли вводить строчные буквы или они должны быть прописными?
Дзайма
1
@JesseDanielMitchell Как заметка ... старайтесь не менять правила и лишать законной силы существующие ответы . Также (как обычно) предлагаю разместить в Песочнице .
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

Чтобы установить пакет, вы можете запустить следующее в терминале / командной строке:

pip install roman
Мистер Xcoder
источник
2
pyTester/Py.pyಠ_ಠ
полностью человек
@totallyhuman Это просто фиктивный проект, который я сделал только для этого ...
Mr. 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

Попробуйте онлайн!

Ручная реализация, ууу!

totallyhuman
источник
2
Я сократил это немного (так близко к победе над новым Python) ... Попробуйте онлайн!
Орджан Йохансен
1
Питон тоже был вырублен. Но если его аргумент о том, что субтрактивная нотация не нуждается в поддержке, подтверждается, то и здесь есть большая экономия.
Орджан Йохансен
1
В любом случае, еще 3 байта с l=1:4:5:9:map(10*)l.
ბიმო
Я вспомнил трюк с остатками, который я когда-то нашел для преобразования римских чисел, который автоматически выполняет вычитание. Попробуйте онлайн!
Орджан Йохансен
2

JavaScript (узел) + романы + 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

Дьялог АПЛ , 93 байта

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

Попробуйте онлайн!

116 байт без римской встроенной

dzaima
источник
Вау, никогда не видел измененного задания в гольфе раньше
Захари
@ Zacharý это единственный известный мне способ изменить переменную вне ее области действия dfns, поэтому ее пришлось использовать здесь.
Дзайма
Прости мое невежество, но что такое измененное задание?
января 18
@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.
Орджан Йохансен
На самом деле, позвольте мне предложить вам этот трюк, который я однажды нашел:n+=v-n%v*2
Орджан Йохансен
1
Вы также можете объединить два strиспользования. Попробуйте онлайн!
Орджан Йохансен
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также работает и экономит некоторые байты.
user202729
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]

user202729
источник
-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

Попробуйте онлайн!

Потому что оно появилось в комментариях как к вопросу, так и к этому ответу и, вероятно, привело к отрицательному голосованию: это представление не поддерживает субтрактивную запись. Обоснование: Субтрактивная запись редко использовалась в Римской империи и только популяризировалась позже (см. Subtractive Notation , параграф 3, последнее предложение). Задача предполагает Римскую империю, которая разработала программируемые интегральные схемы, а не ту, которая претерпела те же культурные изменения, что и Европа 13-го века. В описании не упоминаются субтрактивные обозначения, и ни один из примеров не использует их.

Дэвид Фёрстер
источник
Хм ... ты не поддерживаешь числа типа CIV(104).
Орджан Йохансен
... не могу обвинить вашу логику там. : P
Орджан Йохансен
2
Ах, ты был прав. Я не думал о возможной двусмысленности, я не знал, что вычитание не было обычной чертой в древнеримской империи.
Джесси Даниэль Митчелл
1
На самом деле я подумал о том, чтобы спросить о вычитающей записи в ОП (и заметил отсутствие примера), но отвлекся. Если вы думаете о двусмысленности определения в будущих задачах, не стесняйтесь, просто спросите (ответ с предостережением и ссылка на ваш комментарий следует сделать, если вы хотите опубликовать). Теперь есть решение, которое вы должны попытаться исправить :)
Джонатан Аллан