O quebra-cabeça
Um pequeno quebra-cabeça que ouvi quando estava no colégio foi mais ou menos assim ...
- O questionador pedia que eu desse um número;
- Ao ouvir o número, o questionador faria algum tipo de transformação nele repetidamente (por exemplo, ele poderia dizer que dez é três ) até finalmente chegar ao número 4 (nesse ponto ele terminaria com quatro é mágico ).
- Qualquer número parece ser transformável em quatro eventualmente, não importa o quê.
O objetivo era tentar descobrir a função de transformação e, então, ser capaz de supervisionar esse quebra-cabeça de maneira confiável.
A solução
A função de transformação em qualquer etapa era
- Pegue o número em questão,
- Conte o número de letras em sua representação de palavra em inglês, ignorando um hífen ou espaços ou "e" (por exemplo, "dez" tem 3 letras, "trinta e quatro" tem 10 letras, "cento e quarenta e três" tem 20 letras).
- Retorne aquele número de letras.
Para todos os números que já me preocupei em testar, isso converge para 4. Como "quatro" também tem quatro letras, haveria um loop infinito aqui; em vez disso, é apenas referido como mágica por convenção para encerrar a sequência.
O desafio
Seu desafio é criar um pedaço de código que lerá um número do usuário e então imprimirá linhas mostrando a função de transformação sendo aplicada repetidamente até que "quatro é mágico" seja alcançado.
Especificamente:
- As soluções devem ser programas completos por si mesmas. Eles não podem ser meramente funções que recebem um número - fator na entrada.
- A entrada deve ser lida a partir da entrada padrão. (Canalizar de "echo" ou usar redirecionamento de entrada é bom, pois também vai de stdin)
- A entrada deve ser em formato numérico.
- Para cada aplicação da função de transformação, uma linha deve ser impressa:,
a is b.
onde a e b são as formas numéricas dos números na transformação. - Paradas completas (períodos) SÃO obrigatórios!
- A última linha deve naturalmente dizer
4 is magic.
,. - O código deve produzir uma saída correta para todos os números de 0 a 99 .
Exemplos:
> 4
4 is magic.
> 12
12 is 6.
6 is 3.
3 is 5.
5 is 4.
4 is magic.
> 42
42 is 8.
8 is 5.
5 is 4.
4 is magic.
> 0
0 is 4.
4 is magic.
> 99
99 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.
O vencedor é o envio mais curto por contagem de caracteres do código-fonte, que também está correto .
BÔNUS
Você também pode tentar escrever uma versão do código que imprima os NOMES EM INGLÊS para os números com cada aplicação da função de transformação. A entrada original ainda é numérica, mas as linhas de saída devem ter a forma de palavra do número.
(Bônus duplo para desenhar formas com seu código)
(EDIT) Alguns esclarecimentos:
- Eu quero que a palavra apareça em ambos os lados em todos os casos aplicáveis, por exemplo
Nine is four. Four is magic.
- Não me importo com letras maiúsculas, no entanto. E eu não me importo como você separa as palavras tokens, embora elas devam ser separadas:
ninety-nine
está certo,ninety nine
está certo,ninetynine
não está certo.
Estou considerando isso como uma categoria separada para competição de bônus no que diz respeito ao desafio, então, se você for para isso, não se preocupe com o seu código ser mais longo do que a versão numérica.
Sinta-se à vontade para enviar uma solução para cada versão.
fonte
Respostas:
GolfScript -
10196939291909486 bytes90 → 94
: Saída fixa para múltiplos de 1094 → 86
.: Código reestruturado. Usando base 100 para remover caracteres não imprimíveis.86 → 85
: Shorter cast para string.fonte
"magic."
, ele basicamente resume tudo.d
é extraída pelo)
que100
e é utilizado como a raiz para a conversão de base.Perl, cerca de 147 char
Vagamente baseado na solução Platinum Azure:
fonte
pop
, sem nenhum argumento. Fora de uma sub-rotinapop
remove e retorna o último valor do@ARGV
qual é a lista de argumentos para o programa Perl. Ele poderia ser facilmente substituído porshift
, mas isso adiciona outros 2 caracteres. Veja: p3rl.org/pop'.'
, que é 2 para\n
ou 1 se você estiver contando espaços em branco no'. '
(espaço sendo o literal de nova linha)Common Lisp 157 Chars
Nova versão mais conforme, agora lendo a entrada padrão do formulário e ignorando espaços e hifens:
Em forma legível:
E alguns testes são executados:
E a versão bônus, em 165 caracteres:
Dando
fonte
Python 2.x, 144
150154166charsIsso separa o número em dezenas e unidades e soma-os. A propriedade indesejável do operador pseudo-ternário
a and b or c
quec
é retornado seb
for 0 está sendo abusada aqui.A versão ingênua anterior (150 caracteres). Apenas codifique todos os comprimentos como um inteiro.
fonte
n,"is",p,"."
? Eu acho que você ainda economiza alguns caracteres se estou contando direito).
.int()
, dizer algo fora dos módulosstruct
oubase64
...C - com palavras numéricas
445431427421399386371359 *356354 †348347 caracteresÉ isso aí. Eu não acho que posso tornar isso mais curto.
Todas as novas linhas são legíveis e podem ser removidas:
Abaixo, está um pouco não reduzido, mas ainda muito difícil de ler. Veja abaixo uma versão mais legível.
Expandido e comentado:
Sobre a string codificada perto do início
Os nomes dos números são compactados usando um esquema muito simples. Subcadeias de caracteres usadas com frequência são substituídas por índices de um caractere na matriz de nomes. Uma "tabela de pesquisa" de entradas de nomes extras é adicionada ao final para substrings não usadas em sua totalidade no primeiro conjunto. As pesquisas são recursivas: as entradas podem referir-se a outras entradas.
Por exemplo, o nome compactado para 11 é
elM
. Aprint()
função produz os caracterese
el
('L' minúsculo, não o número '1') literalmente, mas depois encontra oM
, então se chama com o índice da entrada 29 (ASCII 'M' - ASCII '0') na tabela de pesquisa. Essa string éevL
, portanto, ela produze
ev
, em seguida, chama a si mesma novamente com o índice da 28ª entrada na tabela de pesquisa, que éen
, e é gerada literalmente. Isso é útil porqueen
também é usado emeL
paraeen
(usado apóseight
emeighteen
), que é usado emtO
parateen
(usado para todos os outros-teen
nomes).Este esquema resulta em uma compressão bastante significativa dos nomes dos números, enquanto requer apenas uma pequena quantidade de código para descompactar.
As vírgulas no início e no final da string representam a maneira simplista como as substrings são encontradas nessa string. Adicionar dois caracteres aqui salva mais caracteres posteriormente.
Sobre o abuso de
main()
argv
é ignorado (e, portanto, não declarado na versão compactada), o valor de argc é ignorado, mas o armazenamento é reutilizado para conter o número atual. Isso apenas me salva de ter que declarar uma variável extra.Sobre a falta de
#include
Alguns reclamarão que omitir
#include <stdio.h>
é trapacear. Não é de todo. O dado é um programa C completamente legal que irá compilar corretamente em qualquer compilador C que eu conheço (embora com avisos). Na falta de protótipos para as funções stdio, o compilador assumirá que são funções cdecl retornandoint
e confiará que você sabe quais argumentos passar. Os valores de retorno são ignorados neste programa, de qualquer maneira, e são todas funções cdecl (convenção de chamada "C") e realmente sabemos quais argumentos passar.Resultado
O resultado é o esperado:
* A versão anterior errou o alvo em duas partes da especificação: não manipulava zero e recebia entrada na linha de comando em vez de stdin. O tratamento de zeros adicionando caracteres, mas usando stdin em vez de argumentos de linha de comando, bem como algumas outras otimizações salvou o mesmo número de caracteres, resultando em uma lavagem.
† Os requisitos foram alterados para deixar claro que a palavra numérica deve ser impressa em ambos os lados de "é". Esta nova versão atende a esse requisito e implementa mais algumas otimizações para (mais de) considerar o tamanho extra necessário.
fonte
J, 107
112caracteres(Nova linha apenas para legibilidade)
Uso e saída:
fonte
T-SQL, 413
451499caracteres(Não que eu esteja realmente sugerindo que você faça isso ... na verdade, eu só queria escrever um CTE)
Usar:
Devoluções
fonte
CREATE FUNCTION d(@ int) RETURNS int AS BEGIN Declare @l char(9),@s char(50) Select @l='066555766',@s='03354435543668877987' if @=0 return 4 if @<20 return 0+substring(@s,@+1,1)return 0+substring(@l,@/10,1)+substring(@s,@%10+1,1)END
Java (com clichê),
308290286282280 caracteresTenho certeza de que o Groovy se livraria de grande parte disso.
Explicação e formatação (todos os comentários, novas linhas e espaços em branco iniciais / finais removidos na contagem):
Razoavelmente direto, mas
Editar: Não use mais hex, isso significa menos pressionamentos de tecla
fonte
String[]a
vez deString[] a
.Windows PowerShell: 152
153184bytescom base na solução anterior, com mais influência de outras soluções
fonte
$input
precisam permanecer, já que você não pode lançar um enumerador diretamente paraint
; funciona ao passar pelastring
primeira vez :-)C, 158 caracteres
(originalmente baseado no código Python de Vlad, peguei emprestado um truque da solução C ++ de Tom Sirgedas para espremer mais alguns caracteres)
versão expandida:
fonte
Python, 129
133137148charsComo aquecimento, aqui está minha primeira versão (melhora alguns caracteres em relação ao melhor Python anterior).
PS. Depois de algumas redações, agora é cerca de vinte caracteres mais curto:
fonte
C #: 210 caracteres.
Esmagado:
Expandido:
Truques que essa abordagem usa:
Console.
paraC.
?:
) em vez deif/else
.\n
comWrite
código de escape em vez deWriteLine
Write
chamada de funçãofonte
int[] z
seria mais curto, pois não precisa donew[]
"magic"
paraobject
, seria implicitamente chamarToString()
emy
adicionando""
. Mas, porque+
tem precedência maior do que?:
, você tem que colocá-lo na verdade parte em vez da falsa parte:x!=4?y+"":"magic"
.Perl: 148 caracteres
(Perl:
233181212206200199198185179149148 caracteres)r
é desnecessária, cortou um pouco mais.Vamos fazer a bola rolar com uma tentativa modesta em Perl.
Truques:
Muitos!
fonte
@u=split$x,'43350435543668877988';
suas vírgulas usam 19 caracteres desnecessários, dividindo-undef
se em divisões a cada caractere, eu uso$x
como uma variável indefinida para tomar o lugar de `undef` - total economia: 11 caracteres. Além disso, remova om
emchomp
e você terá um outro personagem rapou a sua pontuação.sub r
totalmente - você só usa isso uma vez e pode substituir tudo por um único ternário aninhado sem parênteses. Minha versão agora é 144 caracteres: gist.github.com/473289JavaScript 1.8 (SpiderMonkey) - 153 caracteres
Uso:
echo 42 | js golf.js
Resultado:
Com bônus - 364 caracteres
Resultado:
fonte
Haskell, 224
270caracteresE um pouco mais legível -
fonte
Versão C ++ Stdio, reduzida: 196 caracteres
Versão C ++ Iostreams, reduzida: 195 caracteres
Original, sem redução: 344 caracteres
fonte
#define
seria ainda mais curto, pois poderia substituir vários tokens.printf("is magic".\n)
=>puts
.printf("%d",p)
=>puts(atoi(p))
. Não apenas mais curto, mas também mais rápido.while(p!=4)
poderia ser abreviado parawhile(p-4)
. Um personagem inteiro, eu sei, mas ainda assim. :-)Delphi: 329 caracteres
Versão de linha única:
Formado:
Provavelmente espaço para mais apertos ... :-P
fonte
C #
314286283274289273252 chars.Esmagado:
Normal:
Editar Dykam: Fez algumas inserções e alterações cuidadosas:
object
destring
"magic"
.o
, para que pudesse mover parabreak
fora dofor
loop, ou seja, resultando em ado-while
.o
atribuição, assim como av
atribuição, continuando a inserir o cálculo del
nos argumentos da função por completo, eliminando a necessidade del
. Também incluiu a atribuição dem
.int[] x
, tambémint[]x
é legítimo.using System.Linq
era demais para fazer disso uma melhoria.Editar 2 Dykam Alterado o array int para um array / string char, adicionado aritmia apropriada para corrigir isso.
fonte
Lua, 176 caracteres
ou
fonte
C - sem palavras numéricas
180175*172167 caracteresTodas as novas linhas são legíveis e podem ser removidas:
Ligeiramente reduzido:
* A versão anterior errou o alvo em duas partes da especificação: não manipulava zero e recebia entrada na linha de comando em vez de stdin. Lidar com zero caracteres adicionados, mas usar stdin em vez de argumentos de linha de comando economizou ainda mais, resultando em uma economia líquida.
fonte
perl,
123122 caracteresAcabei de perceber que não há requisitos para a saída em STDOUT, então a saída em STDERR em vez disso e eliminar outro caractere.
E, uma versão que retorna números detalhados:
279278276280 caracteresEmbora atenda às especificações, não está 100% bem formatado. Ele retorna um espaço extra após os números que terminam em zero. A especificação diz:
Isso é uma espécie de doninha. Uma versão mais correta em
282281279283 caracteresfonte
Pitão:
fonte
N = input()
(ouraw_input()
) e eliminar assys
coisas.she-bang
em uma resposta de código de golfe ;-)C ++, 171 caracteres (#include omitido)
fonte
#include
porque as funções serão apenas assumidas para receberint
parâmetros. Você pode até salvar um traço fazendo omain
retornoint
.Ruby, 164 caracteres
decodificado:
fonte
Lua
185190199pontos adicionados, adicionado io.read, removido () na última impressão
com quebras de linha
fonte
n=io.read()
(+11 caracteres) para cumprir a regra de leitura do número da entrada padrão. Mudarprint('4 is magic.')
paraprint'4 is magic.'
salvará 2 caracteres. Remover;
depois)
salvará 1 caractere. Oprint
uso de vírgulas parece trapaça, mas as especificações não são claras. Pode muito bem mudar paraprint(n,'is',m,'.')
para salvar 2 caracteres.Código PhP
//////////// testing //////////////////
////// Resultados /////////
fonte
$l='4335443554366887798866555766';for($b=(int)fgets(fopen('php://stdin','r'));($a=$b)-4;){$b=$a<20?$l[$a]:$l[18+$a/10]+($a%10?$l[$a%10]:0);echo"$a is $b.\n";}echo"4 is magic.\n";
Perl - 130 caracteres
5.12.1 (130 caracteres)
1211231321361405.10.1 (134 caracteres)
125127136140144Histórico de mudanças:
20100714:2223
- reverti a mudança com a atenção do mobrule , mas($_%10&&$u[$_%10])
→(($_%=10)&&$u[$_])
, que é o mesmo # de caracteres, mas fiz isso no caso de alguém ver uma maneira de melhorar20100714:0041
-split//,'...'
→'...'=~/./g
20100714:0025
-($_%10&&$u[$_%10])
→$u[$_%10]
20100713:2340
-while$_
→until/\D/
+ removeu parênteses desnecessários20100713:xxxx
-$=<>;chop;
→$_=pop;
- cortesia para mobruleNota: Eu estava cansado de melhorar as respostas dos outros nos comentários, então agora estou sendo ganancioso e posso apenas adicionar minhas alterações aqui :) Esta é uma divisão da resposta do Platinum Azure - crédito em parte para Hobbs , mobrule e Platinum Azure .
fonte
$_%10&&...
construção, quebrou a especificação das entradas 20,30,40, ...ARGV
, que é preenchido porSTDIN
:) ou ..echo bar | xargs perl foo.pl
, tecnicamente canalizado de echo para args para perl :)Shameless Perl com palavras numéricas (329 caracteres)
Adaptado diretamente do código C de P Daddy, com alguns ajustes para
p()
fazê-lo fazer a mesma coisa usando primitivos Perl em vez de C, e um mainloop quase reescrito. Veja a explicação dele. As novas linhas são opcionais.Nota lateral: é uma pena que o perl
print
apenas retorne verdadeiro / falso; se retornasse uma contagem, economizaria 7 golpes.fonte
Ruby, 141 caracteres:
fonte
fonte