Escreva um programa ou uma função que produza uma determinada sequência em forma de escada, escrevendo cada parte de uma palavra que comece com uma vogal uma linha abaixo da parte anterior.
Por exemplo:
Input: Programming Puzzles and Code Golf
Output: Pr P C G
ogr uzzl and od olf
amm es e
ing
Entrada
Uma string contendo nada além de letras e espaços.
A cadeia pode ser passada através de STDIN
argumentos de função ou algo equivalente.
As letras podem ser minúsculas ou maiúsculas.
As entradas sempre são assumidas para seguir essas regras; você não precisa verificar se há entradas incorretas.
Saída
Cada vez que uma vogal (isto é, a
, e
, i
, o
, u
ou y
) é encontrado em uma palavra, você deve emitir o resto da palavra na próxima linha (a vogal encontrou incluído), na posição horizontal correta. Essa regra é recursiva, o que significa que, se houver n vogais na palavra, ela será escrita em n + 1 linhas.
A vogal deve ser escrita no início da próxima linha e não no final da linha anterior quando uma for encontrada.
Cada palavra começa na primeira linha e, portanto, deve ser formatada independentemente de outras palavras. Duas palavras são separadas por um espaço.
Se uma palavra começa com uma vogal, você deve escrevê-la começando na segunda linha.
Casos de teste
- Entrada:
Programming Puzzles and Code Golf
Saída:
Pr P C G
ogr uzzl and od olf
amm es e
ing
- Entrada:
The quick brown fox jumps over the lazy dog
Saída:
Th q br f j th l d
e u own ox umps ov e az og
ick er y
- Entrada:
aeiouy
Saída:
a
e
i
o
u
y
- Entrada:
YEAh UppErcAsE VOwEls
Saída:
V
Y Upp Ow
E Erc Els
Ah As
E
- Entrada:
If you only knew the power of the Dark Side
Saída:
kn th p th D S
If y onl ew e ow of e ark id
o y er e
u
Pontuação
Isso é código-golfe , então o código mais curto vence.
The vowel should be written at the beginning of the next line, and not at the end of the previous line when one is encountered.
Depois de pensar um pouco, entendo que isso significa que a mudança para a próxima linha deve ocorrer antes da impressão da vogal, não depois, mas pode valer a pena redigir isso de uma maneira que seja instantaneamente compreensível - demorei um pouco.Respostas:
Retina ,
504434(+10)3230 bytesAgradecemos a Dennis por salvar 14 bytes usando caracteres de controle reais.
Com base nesta resposta , estou usando códigos de escape ANSI para mover o cursor do terminal verticalmente. O
<ESC>
deve ser substituído pelo caractere de controle 0x1B e<VT>
pela guia vertical0x0B
. Para testes mais simples, você também pode substituir<ESC>
por\e
,<VT>
com\v
e alimentar a saídaprintf
.Para fins de contagem, cada linha entra em um arquivo separado. No entanto, por conveniência, é mais simples colar o código em um único arquivo e chamar Retina com a
-s
opçãoA primeira substituição envolve cada vogal
\v...#
, onde\v
o cursor#
é deslocado para baixo e é um marcador para o segundo passo. Ai`
é a notação de Retina para a correspondência de maiúsculas e minúsculas.O segundo passo, em seguida, repetidamente (
+`
) remove a#
de uma palavra e coloca ae\[A
no final da palavra que move o cursor para cima. Isso para quando a string parar de mudar, ou seja, quando não houver mais#
marcadores na string.fonte
printf
. Apenas substitua\e
pelo byte ESC (0x1b).CJam,
3936 bytesO acima é um despejo xxd reversível, pois o código-fonte contém o caractere não imprimível VT (ponto de código 0x0b) e ESC (ponto de código 0x1b).
Como esta resposta , ele usa guias verticais e seqüências de escape ANSI .
Isso requer um terminal de texto de vídeo de suporte, que inclui a maioria dos emuladores de terminal não Windows.
Execução de teste
Antes de executar o código real, desativaremos o prompt e limparemos a tela.
Isso garante que a saída seja mostrada corretamente.
Para restaurar o prompt, execute o seguinte:
Como funciona
Nós inserimos uma guia vertical antes de cada vogal para mover o cursor para baixo e cópias suficientes da sequência de bytes 1b 5b 41 (
"\e[A"
) após cada espaço para mover o cursor de volta para a primeira linha.fonte
unset PS1save
depois.Java, 428 bytes
Eu sei, é horrível. Provavelmente existem alguns caracteres que podem ser raspados, mas tenho preguiça de fazer isso.
fonte
int
variáveis (ou sejai
,r
,p
,o
, ex
), onde você inicializarl
em
uma vez que vai ser dada valores posteriormente. Você também pode fazerString v="...",a[]=...;
e fazer o mesmo que acimaString u
. Isso deve diminuir bastante sua pontuação.x++-~-p
Perl, 31 bytes
O acima é um despejo xxd reversível, pois o código-fonte contém o caractere não imprimível VT (ponto de código 0x0b) e ESC (ponto de código 0x1b).
O código tem 27 bytes e requer as opções
040p
(4 bytes).O programa requer um terminal de texto de vídeo que suporte guias verticais e seqüências de escape ANSI , que incluem a maioria dos emuladores de terminal não Windows.
Execução de teste
Antes de executar o código real, desativaremos o prompt e limparemos a tela.
Isso garante que a saída seja mostrada corretamente.
Para restaurar o prompt, execute o seguinte:
Como funciona
perl -040p
lê automaticamente a entrada como tokens separados por espaço (-040
), salva cada token em$_
(-p
) e executa o programa.s/[aeiouy]/.$&/gi
realiza uma pesquisa global sem distinção entre maiúsculas e minúsculas$_
e substitui cada vogal pelo caractere de controle VT (move o cursor para baixo), seguido pela própria vogal.s
retorna o número de substituições feitas e$\=".[A"x s...
salva várias cópias da sequência de bytes 1b 5b 41 (move o cursor para cima)$\
, uma para cada vogal.No final do programa, o Perl imprime automaticamente
"$_$\"
, devido à-p
troca.fonte
C,
200190 bytesUngolfed:
Aloca um buffer retangular (na verdade quadrado), preenche-o com espaços e novas linhas e, em seguida, percorre a sequência especificada. No final, ele adiciona um caractere nulo para evitar novas linhas.
Tecnicamente, não é uma função, pois contém globais; na verdade, não pode ser chamado mais de uma vez (
j
el
deve ser 0 no início). Para estar em conformidade,i,j,k,l,M;
pode ser movido paraint i,j=0,k,l=0,M;
no início da função.fonte
char*t=malloc(M*M);
->char t[M*M];
andfor(i=0;i<M*M;++i)
->for(;i<M*M;++i)
char t[M*M]
?CJam, 47
Sim, é um pouco longo, mas não está "trapaceando" com códigos ANSI :)
Experimente online
A idéia é calcular um número de linha para cada caractere (começando em 0, aumentando em vogais e pulando de volta para 0 no espaço) e, em seguida, para cada linha, repita a sequência, mas substitua os caracteres que têm um número de linha diferente por um espaço .
fonte
K,
81727066 bytesBem, é um começo:
Exemplos de uso:
Editar 1:
Melhor. Foram feitas algumas melhorias no nível da superfície:
Notavelmente, inverti os argumentos para
?
quando realizo a pesquisa por vogal e, assim, eliminei a necessidade de uma lambda, fiz a mesma inversão com_
em que dividi as palavras no espaço em branco e percebi que~{" "?x}'x
é uma maneira muito tola e complicada de dizer" "=x
.Edição 2:
Outro nível de superfície é alterado
s
antes de aplicá-lo ao lambda, salvando parênteses no interior:Edição 3:
OK, vamos adotar uma abordagem diferente para calcular o deslocamento de cada caractere. Em vez de dividir a sequência em espaços e calcular uma soma contínua (
+\
) das posições das vogais, podemos operar toda a cadeia de entrada de uma só vez, multiplicando a soma contínua por 0 sempre que encontrarmos um espaço. Preciso da negação dessa sequência, para que eu possa subtrair em vez de adicionar à medida que digitalizo e uso número de distintos (#?
) em vez de max (|/
) ao calcular a quantidade de preenchimento vertical.Isso economiza outros 4 caracteres. Ufa!
fonte
Ruby:
135131124115112 caracteresExemplo de execução:
fonte
/(?=[aeiouy ])/i
.C, 192 bytes
Isso percorre a string, apagando os caracteres à medida que os imprime. Ele se repete até que não haja caracteres que não sejam espaços para imprimir. É C portátil, sem fazer suposições sobre a codificação de caracteres.
Versão legível
fonte
' '
->32
ef(char*s){int l=0,r=1,v,c;
->l,r=1,v,c;f(char*s){
' '
pode ser32
, mas depende da codificação de caracteres, e como eu disse, fiz esse C. portátil. Largar o explícitoint
é ótimo, no entanto - não sei por que esqueci isso!Python 3,
265207202185177 caracteresIsso é terrível e não tenho orgulho. Sei que isso pode ser mais curto, mas pensei em publicar de qualquer maneira.
Inspirado na versão C, ele cria uma lista que é preenchida enquanto percorre a string de entrada.
fonte
GNU Sed, 151 + 1
(+1 porque precisa da
-r
bandeira)Eu pensei que o sed seria a ferramenta para este trabalho, mas achei surpreendentemente difícil.
Versão legível:
fonte
p
, portanto, não gera nada. Um pequeno problema é que as saídas começam com um espaço extra. Um grande problema é que o primeiro pedaço de texto que começa com vogal desaparece.c
, devido à linha pouco antestx
. Restabeleci uma versão anterior com seu loop semelhante e tentarei mais tarde.Python 2,
145142 bytesProvavelmente não é tão competitivo quanto alguns outros métodos, mas achei que essa era uma maneira legal de usar o regex.
A regex
(?!([^aeiouy ]*[aeiouy]){N}[^aeiouy]* ).
corresponde a qualquer caractere único que não esteja no N-ésimo grupo de letras do final de uma palavra. Como conta desde o fim do mundo, inverto a string antes e depois, e também tenho que adicionar um espaço no final, mas depois disso se torna uma simples questão de usarre.sub
para substituir todas as instâncias desses caracteres por um espaço. Faz isso para todos os valores de N até que a cadeia esteja vazia.fonte
re.I
, você pode salvar 3 bytes substituindo o valor de flag apropriado, ou seja2
.Oitava,
132129 caracteresTeste
Entrada:
"YEAh UppErcAsE VOwEls"
Saída:
fonte
Gema :
5348 caracteresObserve que
^[
(x1b) e^K
(x0b) são caracteres únicos. (Na amostra abaixo, eu uso as cópias e pastas compatíveis\e
e\v
equivalentes, caso você queira experimentá-las.)Exemplo de execução:
fonte
Gelatina , 42 bytes (não concorrente?)
Experimente online!
Por que Jelly, por que? :-(
fonte