Objetivo:
Escreva uma função que aceite um número como entrada e retorne um número romano abreviado para esse número como saída.
Símbolos de números romanos:
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1,000
Para um exemplo do que quero dizer quando digo "numerais romanos com letras curtas", vamos considerar encontrar um numeral romano para representar 1983, porque esse é o ano em que nasci. Uma opção é fazer isso da maneira normal (10 letras):
1983 = MCMLXXXIII = (1000 - 100 + 1000 + 50 + 30 + 3)
A outra opção é fazê-lo da maneira abreviada (6 caracteres):
1983 = MXVIIM = (1000 - (10 + 10) + 1000 + 3)
Você sabe o que isso significa?!?!!?? Se eu fosse romano, poderia ter salvo quatro caracteres toda vez que escrevi minha data de nascimento! Woot Woot !!
No entanto, antes de me excitar, tenho uma pergunta a escrever, por isso provavelmente devo definir as regras dos números romanos abreviados para que todos fiquemos na mesma página:
Regras do numeral romano de mão curta:
- Sempre considere os símbolos da esquerda para a direita até que não haja mais caracteres a serem considerados.
- Se não houver símbolos de valor mais alto à direita do símbolo atual:
- Adicione o valor do símbolo atual ao total atual deste numeral romano.
- Se houver símbolos de valor mais alto à direita do símbolo, você está considerando:
- Localize o símbolo de maior valor à direita, à direita do símbolo atual
- Considere todos os caracteres até esse símbolo como um numeral romano
- Calcule o valor desse numeral romano usando estas etapas
- Subtraia o valor desse numeral romano do total corrente desse numeral romano.
- Vá para o próximo símbolo após o grupo que você acabou de considerar
- Cada numeral romano deve ter pelo menos 1 símbolo.
- É isso aí! Qualquer coisa que siga estas regras será aceita!
Exemplos:
IIIIV = (-(1+1+1+1)+5) = 1 //Don't ask me why you'd want to do this!
VVX = (-(5+5) + 10) = 0 //Who said you couldn't represent 0 with roman numerals?!!?
VVXM = (-(-(5+5) + 10) + 1000) = 1000 //Again...don't ask me why you'd want to do this!
MXIIXMI = (1000-(10-(1+1)+10)+1000+1) = 1983 //Ahhh...such a great year :)
Regras da pergunta:
Faça uma função que use um número único como entrada e retorne um número romano para esse número como saída usando as regras acima. Calcule o codeGolfScore dessa função.
example input: 2011 example possible output: MMXI another possible output: MMVVIVV //(2000 + 10 - 4 + 5)
Usando sua função da regra 1, gere os algarismos romanos entre -1000 (isso é certo, NEGATIVO mil) e 3000. Em seguida, some o tamanho dos caracteres desses algarismos romanos para obter seu totalCharacterCount . Aqui estão alguns pseudocódigo para esclarecer:
totalCharacterCount = 0; for(currentNumber = -1000; currentNumber <= 3000; currentNumber++){ totalCharacterCount += getRomanNumeral(currentNumber).length; } return totalCharacterCount;
finalScore = codeGolfScore + totalCharacterCount
- Menor pontuação final ganha!
Nota: Como a contagem total de caracteres estará entre os dez mil +, o algoritmo de comprimento de caractere deve ser a principal prioridade. As pontuações de código de golfe são apenas o desempate, caso vários usuários encontrem o algoritmo ideal ou algoritmos que estão próximos um do outro.
Boa sorte e divirta-se nas suas celebrações MMXII amanhã à noite !!!
fonte
DDDDM
representam-1000
?""
permitido zero ou temos que usarVVX
ou algo equivalente?IXV = -(-1 + 10) + 5 = -4
(vitórias à direita) ouIXV = -1 + 10 + 5 = 14
(vitórias com maior valor)?Respostas:
Haskell, 25637 (= 268 + 25369)
26045 (= 222 + 25823)para ser usado como por exemplo
Você pode avaliar a soma do comprimento com o método
O que leva algo na ordem de um minuto.
fonte
C ++, 345 caracteres do código, 25021 algarismos romanos = 25366
um pouco ofuscado, com um driver:
V
calcula o valor numérico de uma determinada sequência numérica romanas
de comprimentoL
. As strings são codificadas na base 7 (o primeiro dígito é s% 7, o segundo dígito é s / 7% 7, ...). Cada dígito é codificado com I = 0, V = 1, ..., M = 6.f
faz uma enumeração de força bruta de possíveis seqüências de números romanos para encontrar uma queV
avalien
.O número total de dígitos numéricos romanos é ideal. O maior número romano necessário para [-1000,3000] é de 11 dígitos (por exemplo, -827 = CMDDMLXXIII), o que leva cerca de 5 minutos na minha máquina.
fonte
LMCLXXIII
como resposta-777
. Eu li isso como se fosse-50+1000-100+50+10+10+3 = 923 ≠ -777
apenas " avaliado mais à direita " em vez de " mais alto "-777
. Mas foi exatamente o que você pediu nos comentários!VVVXI
para-4
quandoIXVX
é realmente mais curto, como eu notei) - mas isso é perfeitamente legal.Ruby, 25987 (= 164 + 25823)
Você pode ligar
r
diretamente para obter os resultados. A soma acima do intervalo especificado geraque é a soma ideal, como nas outras soluções.
fonte
C # 23537 (639 caracteres do código + 22898 caracteres da saída)
Calcular:
Enumerable.Range(-1000, 3000).Sum(i => M.R(i).Length);
fonte