Richard Dawkins em seu livro The Blind Watchmaker , descreve um programa Weasel . O algoritmo pode ser descrito da seguinte maneira:
Comece com uma sequência aleatória de 28 caracteres. Caracteres válidos são letras maiúsculas e espaço.
Faça 100 cópias dessa sequência, com uma chance de 5% por personagem desse personagem sendo substituída por um caractere aleatório.
Compare cada nova string com o alvo "METHINKS IS LIKE A WEASEL" e dê a cada uma pontuação de acordo com o número de letras na string que estão corretas e na posição correta.
Se alguma das novas strings tiver uma pontuação perfeita (28), pare.
Escolha a sequência de maior pontuação na etapa 3. A decisão de empatar depende de você, mas apenas uma pode ser escolhida. Pegue a corda escolhida e vá para o passo 2.
O vencedor será o snippet de código mais curto para obter a resposta correta enquanto imprime a sequência de maior pontuação de cada geração no seguinte formato:
Se as pessoas pudessem ajudar verificando as respostas de outras pessoas, seria muito útil!
fonte
Respostas:
APL (143)
Explicação:
0{
...}⊃∘(C←27↑⎕A)¨?28/27
: definaC
com as 27 primeiras letras maiúsculas. Como existem apenas 26, o 27º elemento será um espaço. Selecione 28 itens aleatórios deC
. Este será o primeiro⍵
. A primeira⍺
(geração) será0
.⍵≢T←'METHINKS IT IS LIKE A WEASEL
: definidoT
como a sequência'METHINKS IT IS LIKE A WEASEL'
. Contanto que⍵
não seja igual aT
:{
...}¨100⍴⊂⍵
: Faça 100 cópias de⍵
. Para cada um desses ...9≠?28/20
: selecione 28 números aleatórios de 1 a 20. Faça uma máscara de bit onde cada um1
significa que o número aleatório não era igual a9
. (Isso significa 5% de chance de a0
).⍵{⍵:⍺⋄C[?27]}¨
: para cada letra em⍵
, se o bit correspondente foi1
, mantenha essa letra, caso contrário, substitua-a por um elemento escolhido aleatoriamente emC
.c←
: armazena as 100 seqüências mutadas emc
.G←{+/⍵=T}¨c
: para cada elemento emc
, calcule a pontuação (quantidade de caracteres correspondentesT
) e armazene as pontuações emG
.s←⌈/G
: encontre a pontuação máxima e armazene-a ems
.c←⊃c/⍨G=s
: selecione o primeiro itemc
cuja pontuação é igual as
(o máximo) e armazene-oc
novamente.⎕←(⍕⍺),':'c'-- score:',s
: imprime a geração no formato especificado (⍺
é a geração atual,c
é a melhor sequência atual,s
é pontuação)c∇⍨1+⍺
: Incremente a geração e execute a mutação novamente usando a melhor string atual (c
) como entrada.fonte
Mathematica -
238236225Saída de exemplo
fonte
Python (273)
fonte
K,
173167/
fonte
Python: 282 caracteres sem ponto e vírgula
278 com:
fonte
JavaScript,
277246(requer suporte à função de seta; recuo adicionado apenas para facilitar a leitura)
Sinta-se livre para mudar
alert
paraconsole.log
se você quiser uma experiência de execução mais agradável.Existem alguns pedaços bacanas de golfe aqui:
A função
c
retorna um caractere aleatório da sequência do alfabeto" ABC..."
. A função usa um argumento para usar como limite superior para a seleção aleatória do índice. Ao gerar a string base, usamos27
, para que a função se comporte normalmente.No entanto, abusamos desse comportamento solicitando um limite superior aleatório de 540 pol
h = c(540) || h
. Somente 5% do tempoc
realmente retornará uma string (porque 540 * .05 = 27); nos outros 95% do tempo, o índice escolhido aleatoriamente cai além do comprimento da string, então a função retornaundefined
. Esse valor de falsey causa uma cascata lógica OUc(540) || h
, portanto omap
valor originalh
é usado (ou seja, nenhuma substituição ocorre).A operação de soma pontuação faz
f+=h=="METHINKS IT IS LIKE A WEASEL"[p]
, que diz "adicionartrue
aof
se a correntemap
de caracteresh
corresponde aop
th carácter da cadeia WEASEL". A adição de número mais booleano coage o resultado booleano para um0
ou outro1
, o que significa quef
é incrementado apenas quando há uma correspondência com a sequência WEASEL de destino.fonte
v
declarado no código? Não é mencionado em nenhum outro lugar lá. Você pode economizar 2 caracteres.v
é um argumento para a função de seta armazenados emc
:c = (v => ...)
. Se você deseja definir uma função de seta sem argumentos, ela custa dois caracteres()=>...
, em vez de umv=>...
, por isso é melhor simplesmente ter um argumento não utilizado.k=s=[28]
e++
eu não fazia ideia!R (
245239238 caracteres)Dá:
...
fonte
0: ...
se, na primeira vez em que você invocar,cat
aumentarc
para 1? (+1 no entanto, como estou tentando desde uma hora para fazer algo mais curto e eu ainda não pode :))ifelse(…,h(f,1),…)
substitui todas as posições selecionadas pelo mesmo caractere aleatório. Você pode interpretar as regras nessa direção, mas parece dobrá-las, pelo menos eu mencionaria. Segundo, você substituis=z
dentro do1:100
loop, para não fazer 100 cópias da mesma sequência, mas às vezes cópias de uma cópia. Parece que quebrar uma regra para mim, não apenas dobrá-la.C 256
Três loops simples, inicialização, geração de novas strings do pai e pontuação calculada pela mesma instrução. Não é muito legível, mesmo com recuo.
C 252
Um loop, com uma matriz segurando todas as 101 strings.
Esta segunda versão quebra as regras porque imprime a sequência da (o equivalente a) etapa 1, mas era essa ou não a última seqüência de caracteres. Estou perplexo como corrigi-lo sem explodir de tamanho. Estou postando de qualquer maneira para inspiração.
C 256
Abordagem diferente, em vez de criar um array para conter 101 strings, apenas regenere a string 100 vezes e use a atribuição de struct para facilitar a cópia. A inicialização é feita iniciando o contador "repita 100 vezes" em -1 e manipulando-o cuidadosamente pelo pós-incremento estrategicamente escolhido. Apesar de uma abordagem muito diferente, acaba exatamente igual à primeira tentativa - 256 caracteres.
fonte
C # - 436
fonte
Lua 5.1 (502)
A versão minimizada:
e a versão mais fácil de ler (com comentários!):
Para ser sincero, mesmo que isso definitivamente não vença, fiquei feliz em encontrar e minimizar uma solução razoavelmente curta para esse problema! (ênfase razoável): p
fonte
SAS - 374
->
Com quebras de linha / recuo / comentários:
fonte
C
361331Não é tão bom quanto a solução da Art, mas aqui está minha (novata) tentativa de uma solução C. 361 caracteres se você remover novas linhas e guias.
Edit: Se livrou do loop aninhado e usou uma matriz 1D. Esperava que isso fizesse uma diferença maior, mas me salvou apenas 30 caracteres. Aqui está o código:
Edit: Este é o código original, não-destruído, para aqueles que estão interessados em saber como o "golfe" foi feito. O código não produz avisos quando compilado com o GCC com -Wall e C99 ativados. Talvez você seja um novato em golfe como eu, ou um novato em C como eu, ou talvez esteja apenas curioso. :) https://gist.github.com/cpx/97edbce4db3cb30c306a
fonte
Scala,
347341337 caracteres:=>
fonte
println("%2d: %s -- score: %d".format(i,a,s(a))
pode mudar paraprintln(f"$i%2d: $a%s -- score: ${s(a)}%d")
, economizando 4 caracteres!def c=(' '+:('A'to'Z'))(r(27))
me dáerror: type mismatch; found : Int required: scala.collection.generic.CanBuildFrom[scala.collection.immutable.IndexedSeq[Char],Char,?]
PHP 442
Readbly:
fonte
if\for
, é em 436. você também pode procurar$n>90
outro charr()
es()
. Eis as mudanças com comentários: ideone.com/4ecZQc%s
é sempre o mesmo comprimento e o%d
é justificado à esquerda, assim você pode usar o seguinte em vez disso:printf("%2d: $s -- score: $l\n",$i);
Java (632)
Java é uma linguagem tão detalhada .. :(
fonte
Python (
330321)Versão legível:
Exemplo de saída:
edit: removeu alguns caracteres com base nas respostas AMKs e Timtechs
fonte
sum(1for c in range(28)if n[c]==t[c])
pode ser reduzido parasum(n[c]==t[c] for c in range(28))
(-3 caracteres)import random as r
afrom random import*
e remova as três instâncias der.
S
? O desafio requer começar com uma sequência de caracteres aleatórios.PHP (
381 397 323 319312):Versão legível:
Créditos de otimização (319):
Créditos de otimização (312):
fonte
for
para$f=N;while($f--){
para 3 de char cada. e para outro caractere:$n=rand(0,26);[...]chr($n?$n+64:32)
Ruby, 218
exemplo de execução
fonte
Ruby -
225202203198 caracteresRuby parece sub-representado neste desafio até agora, então pensei em tentar! Melhorias são bem-vindas.
fonte
1
mas a pergunta especifica0
. Se você iniciarg=-1
, tudo bem. Pode haver uma maneira mais inteligente, mas eu fiz dessa maneira. Saúde, companheiro RubyGolfer.puts"#{g+=1}: #{$.,s=(0..99).map{n=(r=0..27).map{|i|x=[' ',*?A..?Z].sample;rand<0.05?x:s[i]||=x};[r.count{|i|n[i]=='METHINKS IT IS LIKE A WEASEL'[i]},n*'']}.max;s} -- score: #$."until$.>27
Ruby,
206200199A primeira linha é simplesmente uma maneira extravagante para definir
q=-2
,i=-1
eR=(0..27).to_a
. Todo o trabalho é feito na 2ª linha:fonte
Japt v2.0a0,
112108 bytesExperimente online!
-4 bytes graças a @ETHproductions.
Descompactado e como funciona
fonte
Japonês
-R
, 94 bytesUma abordagem diferente, mas com um pouco de inspiração da solução de Bubbler .
Teste (ou Experimente Online )
Explicação
Linha 1
O resultado é atribuído à variável
U
.Linha 2
O resultado é atribuído à variável
V
.Linha 3
O resultado dessa linha é implicitamente associado a novas linhas e saída.
fonte
Perl 5 , 219 bytes
Experimente online!
fonte
Ruby - 410
Editar * No momento, está falhando (por algum motivo, um [qualquer] está sendo definido como 0 (tipo => fixnum)). No entanto, o design atual está correto, eu só preciso encontrar o bug que está causando isso (é muito misterioso)
fonte
Python 284
fonte
JavaScript - 312
Já existe uma solução JS mais curta acima, mas ela está usando funções experimentais de ponteiro, então pensei em lançar outra solução que esteja sendo executada em qualquer ambiente JS:
fonte
Java:
557534Desembrulhado:
fonte
PHP
429426421415impressão bonita
Vou precisar de uma linguagem menos detalhada da próxima vez
fonte
Python 2.7 - 319 bytes
Claro que não é o menor, mas foi divertido programar.
Usa uma função recorrente, para que ela atinja a profundidade máxima de recursão se houver algum tipo de devolução estranha com a string.
Agradecimentos massivos ao Sp3000 pela ajuda no golfe.
fonte
Julia, 281 bytes
Golfe:
O algoritmo em si não é muito inteligente, mas há alguns bits interessantes aqui. Combinando um intervalo de caracteres com outro personagem, em seguida, a indexação para ele:
['A':'Z',' '][rand(1:27,n)]
e tomando a soma de uma matriz de booleanos (comum, mas eu ainda amo a idéia):sum(a.=="METHINKS IT IS LIKE A WEASEL".data)
. Ainda bem que tenho menos de 300!Ungolfed:
fonte