Resumo
Os romanos antigos criaram um sistema numérico usando letras latinas, o que lhes serviu bem e ainda é usado pela civilização moderna, embora em um grau muito menor. Na época de seu uso, os romanos precisavam aprender a usar e manipular esses números para serem de grande utilidade para muitas aplicações. Por exemplo, se um homem possuísse 35 bois e ele adquirisse mais 27, como ele saberia o novo total a não ser contar todos? ( Ok, isso e usando um ábaco ... ) Se os romanos pudessem fazê-lo, certamente podemos descobrir também.
Objetivo
Escreva o menor algoritmo / função / programa que adicionará dois algarismos romanos e produza o resultado sem converter a representação em cadeia de uma das entradas em um número.
Regras / restrições
Devido às inconsistências históricas / pré-medievais na formatação, vou descrever algumas regras não-padrão (por uso moderno) para ortografia. Veja o guia de valores abaixo como exemplo.
- As letras I, X, C e M podem ser repetidas até quatro vezes seguidas, mas não mais. D, L e V nunca podem ser repetidos.
- A letra imediatamente à direita de outra letra na representação romana terá o mesmo ou menor valor que a esquerda.
- Em outras palavras,
VIIII == 9
masIX != 9
e é inválido / não permitido.
- Em outras palavras,
- Todos os valores de entrada serão 2.000 (MM) ou menos; nenhuma representação para números maiores que M é necessária.
- Todos os valores de entrada serão um número romano válido, de acordo com as regras acima.
- Você não pode converter nenhum número em decimal, binário ou qualquer outro sistema de números como parte de sua solução (você pode usar esse método para VERIFICAR seus resultados).
- Isso é código de golfe, então o código mais curto vence.
Guia de Valor
Symbol Value
I 1
II 2
III 3
IIII 4
V 5
VIIII 9
X 10
XIIII 14
XXXXIIII 44
L 50
LXXXXVIIII 99
C 100
D 500
M 1,000
Exemplos
XII + VIII = XX (12 + 8 = 20)
MCCXXII + MCCXXII = MMCCCCXXXXIIII (1,222 + 1,222 = 2,444)
XXIIII + XXXXII = LXVI (24 + 42 = 66)
Se precisar de mais esclarecimentos, pergunte.
fonte
Respostas:
APL (
5956)Entrada em uma linha (ou seja
XII + XII
, embora+
não seja necessário).Edit: shift alterado para girar para salvar três caracteres - só importa quando a resposta for ≥ 5000, o que nunca deve acontecer, pois a pergunta diz que os valores de entrada sempre serão ≤ 2000. O único efeito é que agora "transborda" em 5000, dando 5000 = 1, 5001 = 2, etc.
(Eu realmente não acho que os romanos fizeram dessa maneira ... APL é mais uma coisa para os egípcios antigos, eu acho :))
Explicação:
⍞
: obter entrada do usuário(N←'MDCLXVI')∘=¨
: armazene 'MDCLXVI' em N. Retorne, para cada caractere da sequência de entrada, um vetor com 1 no local em que o caractere corresponde a um dos 'MDCLXVI' e 0 caso contrário.⊃+/
: Soma os vetores e desencapsule. Agora temos um vetor com informações sobre quantos números romanos temos. Ou seja, se a entrada foiXXII XIIII
, agora temos:{
...:
...⋄
...}
é uma função com uma construção if-else.D←7⍴5 2
:D
é o vetor5 2 5 2 5 2 5
. É assim que um número romano não é permitido. Ou seja, se você tem 5I
s, isso é demais, e se você tem 2V
s, também é demais. Esse vetor também é o fator de multiplicação para cada numeral romano, ou seja, aV
vale 5I
s eX
2 vale 2V
s.∨/K←⍵≥D
:K
é o vetor em que existe um 1 se tivermos muitos algarismos romanos de um determinado tipo.∨/
ORs esse vetor juntos.K×D
: Multiplique K por D. Esse vetor tem zeros onde não temos muitos algarismos romanos e a quantidade de algarismos romanos onde temos.⍵+(1⌽K)
: Gire K para a esquerda por 1 e adicione-o à entrada. Para cada número romano que temos em excesso, isso adicionará um do próximo número mais alto.⍵+(1⌽K)-K×D
: Subtraia isso do outro vetor. O efeito é que, por exemplo, se você tiver 6I
s, ele adicionará umV
e removerá 4I
s.∇
: Recurso.⋄⍵
: Mas seK
foram todos os zeros, ⍵ representa um numeral romano válido, então retorne ⍵.N⍴⍨¨
: Para cada elemento do vetor resultante, crie muitos dos números romanos correspondentes.,/
: Junte esses vetores para se livrar dos espaços feios na saída.fonte
Python, 100
Toma uma string da entrada (por exemplo,
VIII + XII
ouVIII + XII =
).fonte
Perl, 132 caracteres
Declara a função
s
que pega qualquer número de argumentos e os soma. Bem direto: acrescenta a entrada, reduz tudo aI
se repõe imediatamente os algarismos romanos. (Espero que isso não conte como usar o sistema de número unário!)fonte
Ruby,
8582 caracteresEsta versão recebe a entrada STDIN como uma única sequência (por exemplo
XXIIII + XXXXII
) e imprime a saída em STDOUT.O segundo é uma implementação como uma função. Pega duas (ou mais) seqüências e retorna os valores somados. Uso:
fonte
GNU Sed, 131 caracteres
fonte
Python, 174 caracteres
Um algoritmo muito simples - conte cada loop de dígito para manipular o estouro para o próximo, imprima.
Lê da entrada padrão. Algo como
XVI + CXX
funcionaria (ignora qualquer coisa, exceto números, portanto+
não é realmente necessário).fonte
Scala 150
invocação:
Versão não destruída:
fonte
JavaScript
195179Meu sistema é bastante rudimentar, reduza todos os números romanos a uma série de
I
ambos os números, junte-os e inverta o processo transformando certos blocosI
em suas respectivas versões maiores ...Iteração 1
a="IIIII0VV0XXXXX0LL0CCCCC0DD0M".split(0);d=b=>x.replace(g=RegExp((c=z)>b?a[c][0]:a[c],"g"),c>b?a[b]:a[b][0]);x=prompt().replace("+","");for(z=6;0<z;z--)x=d(z-1);for(z=0;6>z;z++)x=d(z+1);alert(x)
Iteração 2
a="IIIII0VV0XXXXX0LL0CCCCC0DD0M".split(0);x=prompt().replace("+","");for(z=-6;6>z;z++)b=0>z?-z:z,c=0>z?~z:z+1,x=x.replace(g=RegExp(b>c?a[b][0]:a[b],"g"),b>c?a[c]:a[c][0]);alert(x)
Recursos:
A entrada é inserida via prompt na forma de
<first roman number>+<second roman number>
(sem espaços) e a saída na forma de um alerta.por exemplo
fonte
VBA, 187 caracteres
fonte
o
só é usado uma vez, você latas salvar 3 bytes, removendo a atribuição e avaliação do mesmo e ligarn Mod r
diretamente para aString(
chamada de funçãoJavaScript, 190
Colocar algumas instruções dentro do terceiro slot do
for
operador, deixe-me economizar alguns pontos e vírgulas!Quando a entrada solicita, você insere os dois números (os
+
espaços e não são necessários, mas se você os colocar, não receberá um erro). Em seguida, o alerta mostra a soma.fonte
C ++, 319 caracteres
fonte
PHP, 136 bytes
Experimente online!
fonte