Perl 69 bytes
s;.;y/XVI60-9/CLXVIX/dfor$a[$_].="32e$&"%72726;gefor 1..100;print"@a"
Funciona por meio de fórmula mágica. A expressão "32e$&"%72726
transforma cada dígito da seguinte maneira:
0⇒32, 1⇒320, 2⇒3200, 3⇒32000, 4⇒29096, 5⇒56, 6⇒560, 7⇒5600, 8⇒56000, 9⇒50918
Depois de aplicar a tradução y/016/IXV/
, temos o seguinte:
0⇒32, 1⇒32 I , 2⇒32 II , 3⇒32 III , 4⇒29 I 9 V , 5⇒5 V , 6⇒5 VI , 7⇒5 VII , 8⇒5 VIII , 9⇒5 I 9 X 8
O restante dos dígitos ( 2-57-9
) é removido. Observe que isso pode ser melhorado em um byte usando uma fórmula que traduz em 012
vez de 016
, simplificando /XVI60-9/
para /XVI0-9/
. Não consegui encontrar um, mas talvez você tenha mais sorte.
Depois que um dígito é transformado dessa maneira, o processo se repete para o próximo dígito, acrescentando o resultado e convertendo os XVI
s anteriores para CLX
ao mesmo tempo em que ocorre a tradução para o novo dígito.
Atualizar
Pesquisa exaustiva não revelou nada mais curto. No entanto, encontrei uma solução alternativa de 69 bytes:
s;.;y/XVI0-9/CLXIXV/dfor$a[$_].="57e$&"%474976;gefor 1..100;print"@a"
Este usa uma 0-2
substituição para IXV
, mas possui um módulo com um dígito a mais.
Atualização: 66 65 bytes
Esta versão é notavelmente diferente, então eu provavelmente deveria dizer algumas palavras sobre ela. A fórmula usada é na verdade um byte a mais!
Incapaz de encurtar a fórmula mais do que é, decidi jogar golfe o que tinha. Não demorou muito até eu lembrar do meu velho amigo $\
. Quando uma print
declaração é emitida, ela $\
é automaticamente anexada ao final da saída. Consegui me livrar da $a[$_]
construção estranha de uma melhoria de dois bytes:
s;.;y/XVI60-9/CLXVIX/dfor$\.="32e$&"%72726;ge,$\=!print$"for 1..100
Muito melhor, mas isso $\=!print$"
ainda parecia um pouco detalhado. Lembrei-me de uma fórmula alternativa de igual comprimento que encontrei que não continha o número 3
em nenhuma de suas transformações de dígitos. Portanto, deve ser possível usá-lo $\=2+print
e substituir o resultante 3
por um espaço:
s;.;y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535;ge,$\=2+print for 1..100
Também 67 bytes, devido ao espaço em branco necessário entre print
e for
.
Editar : Isso pode ser melhorado em um byte, movendo o print
para a frente:
$\=2+print!s;.;y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535;gefor 1..100
Como a substituição precisa avaliar completamente antes de print
, a atribuição a$\
ainda ocorrerá por último. A remoção do espaço em branco entre ge
e for
emitirá um aviso de reprovação, mas é válido.
Mas, se houvesse uma fórmula que não usasse um 1
em qualquer lugar, $\=2+print
torna-se $\=print
por mais dois bytes valor de poupança. Mesmo se fosse um byte mais longo, ainda seria uma melhoria.
Acontece que essa fórmula existe, mas é um byte mais longo que o original, resultando em uma pontuação final de 65 bytes :
$\=print!s;.;y/XVI60-9/CLXXI V/dfor$\.="37e$&"%97366;gefor 1..100
Metodologia
A pergunta foi feita sobre como alguém poderia encontrar essa fórmula. Em geral, encontrar uma fórmula mágica para generalizar qualquer conjunto de dados é uma questão de probabilidade. Ou seja, você deseja escolher um formulário com a maior probabilidade possível de produzir algo semelhante ao resultado desejado.
Examinando os primeiros algarismos romanos:
0:
1: I
2: II
3: III
4: IV
5: V
6: VI
7: VII
8: VIII
9: IX
há alguma regularidade a ser vista. Especificamente, de 0 a 3 e, novamente, de 5 a 8 , cada termo sucessivo aumenta de comprimento em um numeral. Se quisermos criar um mapeamento de dígitos para numerais, gostaríamos de ter uma expressão que também aumente em um dígito para cada termo sucessivo. Uma escolha lógica é k • 10 d, em que d é o dígito correspondente ek é qualquer constante inteira.
Isso funciona para 0-3 , mas 4 precisa quebrar o padrão. O que podemos fazer aqui é aderir a um módulo:
k • 10 d % m , onde m está em algum lugar entre k • 10 3 e k • 10 4 . Isso deixará o intervalo de 0 a 3 intocado e modificará 4 para que não contenha quatro I
s. Se restringirmos adicionalmente nosso algoritmo de pesquisa, de modo que o resíduo modular de 5 , vamos chamá-lo de j , seja menor que m / 1000 , isso garantirá que também tenhamos regularidade de 5 a 8 também. O resultado é algo como isto:
0: k
1: k0
2: k00
3: k000
4: ????
5: j
6: j0
7: j00
8: j000
9: ????
Como você pode ver, se substituirmos 0
por I
, 0-3 e 5-8 têm a garantia de serem mapeados corretamente! Os valores para 4 e 9 precisam ser forçados brutalmente. Especificamente, 4 precisa conter um 0
e um j
(nessa ordem) e 9 precisa conter um0
, seguido por outro dígito que não apareça em nenhum outro lugar. Certamente, existem várias outras fórmulas que, por alguma coincidência, podem produzir o resultado desejado. Alguns deles podem até ser mais curtos. Mas não creio que exista alguém com tanta probabilidade de sucesso como este.
Também experimentei várias substituições I
e / ou V
com algum sucesso. Mas, infelizmente, nada menor do que o que eu já tinha. Aqui está uma lista das soluções mais curtas que encontrei (o número de soluções de 1 a 2 bytes mais pesadas são muitas para listar):
y/XVI60-9/CLXVIX/dfor$\.="32e$&"%72726
y/XVI0-9/CLXIXV/dfor$\.="57e$&"%474976
y/XVI0-9/CLXIVXI/dfor$\.="49e$&"%87971
y/XVI0-9/CLXIIXIV/dfor$\.="7e$&"%10606 #
y/XVI0-9/CLXIIXIV/dfor$\.="7e$&"%15909 # These are all essentially the same
y/XVI0-9/CLXIIXIV/dfor$\.="7e$&"%31818 #
y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535 # Doesn't contain 3 anywhere
y/XVI60-9/CLXXI V/dfor$\.="37e$&"%97366 # Doesn't contain 1 anywhere