Notação polonesa de R [oman | everse]


11

É o ano MDLXVII em um mundo em que o Império Romano nunca caiu e o colapso na idade das trevas nunca ocorreu. Devido ao longo período de Pax Romana, a estabilidade econômica do império permitiu que a tecnologia progredisse rapidamente.

Os romanos começaram a se interessar por circuitos e inventaram uma calculadora engenhosa que não requer o uso de um botão "igual". Eles chamam de "notação romana polonesa"

Para fazer um cálculo, eles inserem seus operandos primeiro, depois a operação.

Por exemplo, 100 + 11 * 20 seria C XI XX * +.

Além disso

Os romanos descobriram que frequentemente precisam fazer vários cálculos ao mesmo tempo e preferem que o método retorne todos os valores "na pilha" em algum tipo de estrutura semelhante a matriz / lista / tupla. (por exemplo X I + X I - CC II +, retornaria [11, 9, 202])


O desafio é desenvolver um programa de calculadora capaz de fazer esses cálculos.

Esclarecimento : Notação subtrativa é necessária. Eu não tinha percebido que não era uma característica reconhecida no império romano antigo. A tarefa era, portanto, ambígua, e peço desculpas.

Diretrizes mínimas

  • Sua saída será em algarismos arábicos.
  • Você só precisa converter de algarismos romanos para 5000.
  • Você precisará oferecer suporte às operações +, -, /, * (adição, subtração, divisão e multiplicação).
  • Se a divisão é baseada em ponto flutuante ou em número inteiro é específica da implementação. Ou funciona para esse desafio.
  • Sua saída precisará suportar números de até 4 bilhões.
  • Resposta mais curta no geral, E em cada idioma vence. Este é um desafio do Code Golf, mas eu adoro a variedade.

Em caso de empate, fatores como suporte para algarismos romanos acima de 5000 ou operações adicionais serão considerados os primeiros a serem vencidos.


11
Podemos considerar a entrada como uma lista de strings, cada uma com um número romano ou um operador?
user202729

a entrada pode ser feita em minúscula ou precisa ser maiúscula?
Dzaima 31/12/19

11
@JesseDanielMitchell Como observação ... tente não alterar as regras e invalidar as respostas existentes . Além disso, (como sempre), sugiro postar na Sandbox .
User202729 01/01

Respostas:


6

Python 2 + romano , 118 bytes

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

Ele não pode ser testado on-line devido ao módulo usado, mas você pode ver como executá-lo aqui (um programa completo aceitando entrada de STDIN - uma expressão entre aspas) e imprimindo a saída em STDOUT - na forma de uma lista , a pilha). Usa uma versão um pouco mais antiga, porque não vou me preocupar em criar um novo GIF por apenas alguns bytes:

GIF de demonstração

Para instalar o pacote, você pode executar o seguinte no Terminal / Linha de Comando:

pip install roman

2
pyTester/Py.pyTotally_ಠ
totallyhuman

@totallyhuman É apenas um projeto fictício que eu fiz apenas para esta ...
Mr. Xcoder

6

Haskell , 217 bytes

-13 bytes graças a Bruce Forte. -73 bytes graças a Ø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

Experimente online!

Implementação manual, yay!


2
Eu reduzi um pouco isso (tão perto de vencer o novo Python ...) Experimente online!
Ørjan Johansen

11
O Python também foi cortado. Mas se o argumento de que a notação subtrativa não precisa ser apoiada for mantido, também haverá mais economia aqui.
Ørjan Johansen

11
De qualquer forma, outros 3 bytes estão desativados com l=1:4:5:9:map(10*)l.
ბიმო

Lembrei-me de um truque restante que encontrei para converter números romanos, que cuida da subtração automaticamente. Experimente online!
Ørjan Johansen


2

JavaScript (Nó) + romanos + stk-lang , 74 bytes

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

Retorna uma lista de bigintegers.

Execução

Execute o seguinte:

npm install romans
npm install stk-lang
node

Em seguida, cole a função. Exemplo:

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

Quantas pessoas usam um lambda como prompt?
Stan Strum

@StanStrum eu gosto, e é o padrão para os terminais como cmder
Conor O'Brien

Não sabia disso. Acho que nunca me desviei de $e >. Honestamente, eu gosto embora
Stan Strum

2

Dyalog APL , 93 bytes

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

Experimente online!

116 bytes sem o romano embutido


Woah, nunca vi atribuição modificada de golfe antes
Zachary

@ Zacharý é a única maneira que conheço de modificar uma variável fora de seu escopo dfns, então ela teve que ser usada aqui.
dzaima 31/12/19

Perdoe minha ignorância, mas o que é atribuição modificada?
caird coinheringaahing

@cairdcoinheringaahing var fn←arr- é equivalente a var ← var fn arr. Aqui ele é usado em vários lugares, a,←⍵sendo um que acrescenta à variávela
dzaima

1

Python 3 , 280 206 bytes

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

Experimente online!

Desta vez, com suporte a notação subtrativa. O método cé o principal ponto de entrada; o outro é apoio.

Editar log:


Você não precisa dos blocos de indentação depois ife else.
Ørjan Johansen

Na verdade, deixe-me oferecer-lhe este truque uma vez eu encontrei:n+=v-n%v*2
Ørjan Johansen

11
Você também pode combinar os dois strusos. Experimente online!
Ørjan Johansen

0

JavaScipt (ES6), 152 151 bytes

Guardado 1 byte graças a 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

Casos de teste

Explicação (menos golfe)

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

Tenho certeza de que 1e3também funciona e salva alguns bytes.
user202729

0

Geléia , 82 bytes

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

Experimente online!

Originalmente publicado no chat .


Explicação:

Como Jelly não tem uma pilha, coloquei a pilha no registro.

Quando o programa começa, o valor registo ®é 0, que é tratada como [0]para os efeitos deste programa.


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

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

Experimente online!

Porque surgiu nos comentários da pergunta e desta resposta e provavelmente levou a votos negativos: esse envio não suporta notação subtrativa. Fundamentação da petição: A notação subtrativa raramente era usada no Império Romano e popularizada mais tarde (ver Notação subtrativa , parágrafo 3, última frase). A tarefa presume um Império Romano que desenvolveu circuitos integrados programáveis, não aquele que sofreu as mesmas mudanças culturais da Europa do século XIII. A descrição não menciona notação subtrativa e nenhum dos exemplos a utiliza.


Hum ... você não está apoiando números como CIV(104).
Ørjan Johansen

... não pode culpar sua lógica lá. : P
Ørjan Johansen

2
Agh, você estava certo. Eu não tinha pensado na possível ambiguidade, não sabia que a notação subtrativa não era uma característica comum no império romano antigo.
Jesse Daniel Mitchell

11
Na verdade, considerei perguntar sobre a notação subtrativa no OP (e notei a falta de um exemplo), mas me distraí. Se você pensa em ambigüidades de definição em desafios futuros, não hesite, basta perguntar (respondendo com uma ressalva e um link para seu comentário, se você quiser postar). Agora, uma decisão está em que você deve tentar corrigi-la :) #
3113 Jonathan Allan
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.