Descrição do Desafio
Tivemos alguns desafios envolvendo a sequência de dizer e dizer . Lembrete rápido:
- A sequência começa com
1
, - Os termos subsequentes dessa sequência são gerados pela enumeração de cada grupo de dígitos repetidos no termo anterior,
Portanto, os primeiros termos são:
1 "one"
11 "one one" (we look at the previous term)
21 "two ones"
1211 "one two, one one"
111221 "one one, one two, two ones"
312211 "three ones, two twos, one one"
Agora vamos fazer a mesma coisa, mas use algarismos romanos . Começamos com I
e seguimos as mesmas regras (em vez disso, aplicamos a regra de contagem de dígitos aos caracteres, então lemos IVX
como em one one, one five, one ten
vez de one four, one ten
ou de outra maneira):
I "one"
II "one one"
III "two ones" = "II" + "I"
IIII "three ones" = "III" + "I"
IVI "four ones" = "IV" + "I"
IIIVII "one one, one five, one one"
IIIIIVIII "three ones, one five, two ones" = ("III" + "I") + ("I" + "V") + ("II" + "I")
Dado um número inteiro positivo N
:
- Emita os primeiros
N
números desta sequência (qualquer separador razoável é bom, bem como["I", "II", "III", ...]
- Saída
N
th termo desta sequência (pode ser indexado 0).
Lembre-se de tornar seu código o mais curto possível, pois esse é um desafio para o código-golfe !
EDIT: Eu acredito que sempre existe uma maneira padrão / preferida de expressar números inteiros como algarismos romanos (como 95
-> em XCV
vez de VC
). Alguns conversores de números romanos que encontrei on-line corroboram minha opinião. Em caso de dúvida, use um conversor on-line , pois listar todos os possíveis casos extremos e regras específicas para escrever números romanos não é o objetivo desse desafio.
EDIT2: @PeterTaylor e @GregMartin apontou que apenas números menor ou igual a 5
aparecer na seqüência, para que você não precisa se preocupar com a ambigüidade de algarismos romanos (números 1
- 8
são I
, II
, III
, IV
, V
, VI
, VII
, e VIII
)
fonte
4
/IV
/IIII
? Ou95
/XCV
/VC
? Nem sempre pode haver uma maneira única de expressar um número inteiro, mas tenho certeza de que sempre há uma preferida (padrão) - me corrija se estiver errado.Respostas:
Perl, 49 bytes
Inclui +1 para
-p
Execute com o índice baseado em 0 no STDIN, por exemplo
ecce.pl
:Fórmulas mágicas são tão mágicas.
Normalmente, eu usaria
($_=//)x$'
para reduzir o controle de loop em um byte mais curto, mas a pontuação neste site oferece um handicap de 2 para que ele termine 1 byte mais. Em perls mais antigos, você pode eliminar o espaço antesfor
. Algumas versões do perl forçam você a adicionar uma final;
para fechar a transliteração. Mas o que é dado acima é o código que funciona no meu sistema.Explicação
Trabalhando de trás para frente da solução para o código:
As transformações de string que precisamos:
Cada substituição termina com o caractere repetido. Vou obter uma sequência dos mesmos caracteres usando regex
/(.)\1*/
, portanto, isso pode ser feito anexando$1
. A parte antes do->
está em$&
. Com isso eu ainda preciso:Escreva
I
como1
eV
como 9:Ao dividir a parte anterior
->
pelo dígito repetido, isso se torna:Então agora o original repetido
V
não é mais uma exceção. Então, eu quero uma expressão que faça isso acontecer:E isso pode ser feito por um simples módulo 182:
(isso mesmo fica
IIIIII
paraVI
a direita, embora ele não é necessário aqui)Tudo o que resta é inicializar a variável de trabalho
1
para o índice 0, repetir essa transformação em um loop e, no final, substituir1
porI
e9
porV
1
,9
e182
é a única combinação de parâmetros para a qual essa fórmula simples funciona.fonte
Mathematica,
1139083 bytesAgradecemos a Martin Ender pelas sugestões que reduziram o comprimento em mais de 25%!
Exibindo os comandos de alto nível no Mathematica.
Uma função pura, pegando um argumento N e gerando o enésimo elemento dessa sequência (indexada 0), como uma lista de caracteres. Espalhe um pouco:
O externo
Nest
itera a função de quatro linhas do meio, começando{"I"}
N vezes. A linha 4 divide a lista de caracteres do numeral romano de entrada em execuções de caracteres semelhantes, conta cada execução comTally
e coloca as contagens antes dos caracteres que estão contando. A linha 3 renderiza as contagens como algarismos romanos e depois os divide em listas de caracteres. OFlatten
comando reduz a lista de listas inteira para uma lista unidimensional.Aqui está a versão inicial:
fonte
@@@
vez de,/@
poderá usar#
e em#2
vez de#[[1]]
e#[[2]]
. Além disso, listas de caracteres são tipos de sequência aceitáveis, para que você possa trabalhar com elas e evitar o usoCharacters@
.@@@
atalho! Quanto às listas de caracteres que são tipos de seqüência de caracteres aceitáveis (o que eu concordo abreviaria o código): existe algum post neste site que você possa apontar para mim que descreva o (s) padrão (s) da comunidade?Characters
threads automaticamente, para que você possa usar@
,Reverse@#&
é obviamente o mesmo que simplesReverse
, caso em que você também não precisa desses parênteses. E a notação de prefixo (no caso deFlatten
) não salva nada se você precisar adicionar parênteses para fazê-lo funcionar. Combinando tudo isso:Nest[Flatten[Characters@{RomanNumeral@#,#2}&@@@Reverse@@@Tally/@Split@#]&,{"I"},#]&
CJam (
3330 bytes)Demonstração online
A chave para a correção da implementação é o seguinte teorema:
Se a primeira geração for
I
, nenhum comprimento de execução será maior que cincoLema: se a primeira geração é
I
, nenhuma string contémVVV
. A prova é por contradição. Suponha que exista um primeiro índicen
para o qual an
quinta geração contenhaVVV
. Se issoVVV
quebrar como(a)V VV
a conversão da geração anterior é ruim: deveria ter sido(a+5)V
. Assim deve serVV V(d)
, e a geração anterior continhaVVVVV
, contradiz a escolha den
.Agora, suponha que exista um primeiro índice
m
para o qual am
quinta geração contenha...IIIIII...
. Observe que não pode haver dígitos além deI
eV
na sequência, porque nenhuma geração anterior teve uma execução de noveI
ou noveV
s. No máximo quatro dosI
s vêm de uma sequência deI
s na cadeia anterior, portanto a seção correspondente da cadeia anterior deve estar...IIIVV...
fornecendo... IIII IIV ...
. Como aVV
geração inm-1
não vemVVVVV
(consulte o lema), o segundoV
deve ser um dígito de duraçãoI
, portanto, na geraçãom-1
que temos...IIIVVI...
. E já que queremos que as iniciaisI
dêemIIII
e nãoIVI
ouVI
, é precedido pelo início da sequência ou por aV
.Se temos
(...V)?IIIVVI...
em geraçãom-1
, o que temos em geraçãom-2
? Já observamos que oVV
de gen.m-1
deve ser analisado como(a)V V(I)
.Suponha que tomemos
a=2
:(...V)?I IIV VI...
Na verdade deve ser...VI IIV VI...
, embora essa liderançaV
possa fazer parteIV
; então, na geração anterior, temos um(...V)? IIII VV IIIII...
ou outro(...V)? IIIII VV IIIII
. De qualquer maneira, encontramos problemasVVIIIII
: o segundoV
deve ser um comprimento de execução, mas...VI IIII...
requer um par seguinte (comprimento de execução, dígito) com o mesmo dígito.Assim deve ser
a=1
:(...V)?II IV VI...
. Desde que a geraçãom
é a primeira com seisI
s, isso deve ser(...V)? II IV VI...
, de modo que a geraçãom-2
é(...V)? I V IIIII...
....VIVIIIII...
é impossível: no entanto, escolhemos interpretar o segundo emV
que terminamos com dois pares consecutivos (comprimento de execução, dígito) com o mesmo dígito.Portanto, a geração
m-2
deve ser^IVIIIII...
analisada como^IV IIII I(V)...
ou^IV III II(V)...
. Estes dão respectivamente geraçãom-3
como^V III V ...
ou^V II VV...
.Mas se olharmos para o início das strings começando pelo primeiro
V
, começamos um ciclo:e assim nenhuma geração começa com
VIIIV
ouVIIVV
. Devemos concluir que não existem
.Dissecação
fonte
Python 3, 195 bytes
Há muitos bytes desperdiçados nos algarismos romanos; portanto, é provável que haja golfe lá.
Obrigado a @ El'endiaStarman, @ Sherlock9 e @Shooqie
Ideone it!
fonte
for v,i in(5,"V"),(4,"IV"),(1,"I")
for v,i in(5,"V"),(4,"IV"),(1,"I"):a,x=divmod(x,v);r+=i*a
salva um byte.i
(como emfor i in range(...)
). Tentei brincar,exec
mas isso escapou1
no método 'sub' parece estar atrapalhando o código, não consegui encontrar uma solução alternativa.range
R,
110107 bytesas.roman
combinado comrle
facilita isso. Abuso de escopo e comportamento<<-
interno de gato economiza alguns bytes.Recebe N do console. Emite os primeiros 2 a N termos de sequência (que acredito estar dentro das especificações ...)
fonte
JavaScript (ES6), 107
Função recursiva retornando o enésimo termo 0 com base em
Teste
fonte
Perl 6 , 62 bytes
Função anônima que aceita um índice baseado em zero.
Utiliza o fato de que números romanos acima de 5 não são necessários, porque os únicos grupos de dígitos repetidos que podem ocorrer são:
( experimente online )
fonte