Richard Dawkins dans son livre The Blind Watchmaker décrit un programme Weasel . L'algorithme peut être décrit comme suit:
Commencez avec une chaîne aléatoire de 28 caractères. Les caractères valides sont toutes les lettres majuscules et l'espace.
Faites 100 copies de cette chaîne, avec une chance de 5% par caractère de ce caractère remplacé par un caractère aléatoire.
Comparez chaque nouvelle chaîne avec la cible "METHINKS, C’EST COMME UNE WEASEL", et attribuez à chacun un score en fonction du nombre de lettres de la chaîne qui sont correctes et dans la bonne position.
Si l’une des nouvelles chaînes a un score parfait (28), arrêtez-vous.
Choisissez la chaîne qui obtient le meilleur score à l’étape 3. Vous pouvez choisir une cravate, mais une seule chaîne peut être choisie. Prenez la chaîne choisie et passez à l'étape 2.
Le gagnant sera l'extrait de code le plus court permettant d'obtenir la réponse correcte tout en imprimant la chaîne de score le plus élevé de chaque génération dans le format suivant:
Si les gens pouvaient aider en vérifiant les réponses des autres, ce serait très utile!
Réponses:
APL (143)
Explication:
0{
...}⊃∘(C←27↑⎕A)¨?28/27
: réglerC
sur les 27 premières lettres majuscules. Il n'y en a que 26, donc le 27ème élément sera un espace. Sélectionnez 28 éléments aléatoires à partir deC
. Ce sera le premier⍵
. La première⍺
(génération) sera0
.⍵≢T←'METHINKS IT IS LIKE A WEASEL
: misT
à la chaîne'METHINKS IT IS LIKE A WEASEL'
. Tant que⍵
n'est pas égal àT
:{
...}¨100⍴⊂⍵
: Faites 100 copies de⍵
. Pour chacun de ces ...9≠?28/20
: sélectionnez 28 nombres aléatoires de 1 à 20. Créez un masque binaire où chacun1
signifie que le nombre aléatoire n’est pas égal à9
. (Cela signifie 5% de chance de a0
).⍵{⍵:⍺⋄C[?27]}¨
: pour chaque lettre entrée⍵
, si le bit correspondant était1
, conservez cette lettre, sinon remplacez-la par un élément choisi aléatoirement dansC
.c←
: stocke les 100 chaînes mutées dansc
.G←{+/⍵=T}¨c
: pour chaque élément dec
, calculer le score (nombre de caractères qui correspondentT
) et stocker les scores dansG
.s←⌈/G
: trouver le score maximum et le stocker danss
.c←⊃c/⍨G=s
: sélectionnez le premier élémentc
dont le score est égal às
(le maximum), puis enregistrez-le àc
nouveau.⎕←(⍕⍺),':'c'-- score:',s
: affiche la génération dans le format indiqué (⍺
la génération actuelle,c
la meilleure chaîne actuelle, les
score)c∇⍨1+⍺
: Incrémente la génération et réexécute la mutation en utilisant la meilleure chaîne actuelle (c
) comme entrée.la source
Mathematica -
238236225Exemple de sortie
la source
Python (273)
la source
K,
173167/
la source
Python: 282 caractères sans point-virgule
278 avec:
la source
JavaScript,
277246(requiert la prise en charge de la fonction flèche; indentation ajoutée uniquement pour la lisibilité)
Ne hésitez pas à changer
alert
deconsole.log
si vous voulez une expérience d'exécution plus agréable.Il y a quelques astuces golfy ici:
La fonction
c
renvoie un caractère aléatoire de la chaîne de l'alphabet" ABC..."
. La fonction prend un argument à utiliser comme limite supérieure pour la sélection d'index aléatoire. Lors de la génération de la chaîne de base, nous utilisons27
, donc la fonction se comporte normalement.Cependant, nous abusons de ce comportement en demandant une limite supérieure aléatoire de 540 po
h = c(540) || h
. Enc
réalité, seuls 5% du temps retournent une chaîne (car 540 * .05 = 27); Les autres 95% du temps, l'index choisi au hasard tombe au-delà de la longueur de la chaîne, donc la fonction retourneundefined
. Cette valeur falsey provoque une cascade logique-OUc(540) || h
, lamap
valeur d' origineh
est donc utilisée (aucun remplacement ne se produit).L'opération de totalisation de score fait
f+=h=="METHINKS IT IS LIKE A WEASEL"[p]
, qui dit "ajoutertrue
àf
si lemap
caractère actuelh
correspond aup
ème caractère de la chaîne WEASEL". L'addition nombre-plus-booléens force le résultat booléen à0
ou1
, ce qui signifie qu'ilf
est incrémenté uniquement lorsqu'il y a une correspondance avec la chaîne WEASEL cible.la source
v
indiqué dans le code? Ce n'est mentionné nulle part ailleurs. Vous pouvez vous enregistrer 2 caractères.?v
est un argument à la fonction de flèche stockée dansc
:c = (v => ...)
. Si vous voulez définir une fonction de flèche sans arguments, cela coûte deux caractères()=>...
, au lieu d'un,v=>...
il est donc préférable d'avoir simplement un argument non utilisé.k=s=[28]
et++
, je n'en avais aucune idée!R (
245239238 caractères)Donne:
...
la source
0: ...
si la première fois que vous appelezcat
vous augmentezc
à 1? (+1 néanmoins comme j'essaye depuis une heure de faire quelque chose de plus court et que je ne peux toujours pas :))ifelse(…,h(f,1),…)
remplace toutes les positions sélectionnées par le même caractère aléatoire. Vous pouvez interpréter les règles dans cette direction, mais comme on les plie, je voudrais au moins en parler. Deuxièmement, vous remplacezs=z
dans la1:100
boucle, de sorte que vous ne faites pas 100 copies de la même chaîne, mais parfois des copies d'une copie. Cela ressemble à enfreindre une règle, pas seulement à la plier.C 256
Trois simples boucles, initialisation, génération de nouvelles chaînes à partir du parent et score calculé par la même instruction. Ce n'est pas très lisible, même avec l'indentation.
C 252
Une boucle, avec un tableau contenant les 101 chaînes.
Cette deuxième version rompt les règles car elle imprime la chaîne de (l’équivalent de) l’étape 1, mais c’est la raison ou non pour imprimer la dernière chaîne. Je suis perplexe sur la façon de le réparer sans exploser de taille. Je le poste quand même pour l'inspiration.
C 256
Une approche différente, au lieu de créer un tableau contenant 101 chaînes, il suffit de régénérer la chaîne 100 fois et d’utiliser l’affectation de structure pour une copie facile. L'initialisation est effectuée en démarrant le compteur "répéter 100 fois" à -1 et en le manipulant avec soin par post-incrémentation choisie de manière stratégique. Malgré une approche très différente, le résultat est identique à celui de la première tentative: 256 caractères.
la source
C # - 436
la source
Lua 5.1 (502)
La version minimisée:
et la version la plus facile à lire (avec des commentaires!):
Pour être honnête, même si cela ne va certainement pas gagner, j'étais heureux de trouver et de minimiser une solution relativement courte pour résoudre ce problème! (mettant l'accent sur raisonnablement): p
la source
SAS - 374
->
Avec sauts de ligne / retrait / commentaires:
la source
C
361331Pas aussi bon que la solution d'Art, mais voici ma tentative (novice) d'une solution en C. 361 caractères si vous supprimez les nouvelles lignes et les onglets.
Edit: s'est débarrassé de la boucle imbriquée et a utilisé un tableau 1D. J'espérais que cela ferait une plus grande différence, mais cela ne m'a sauvé que 30 caractères. Voici le code:
Edit: Ceci est le code original non-goli, pour ceux qui sont intéressés à savoir comment le "golf" a été fait. Le code ne produit aucun avertissement lorsqu'il est compilé avec GCC avec -Wall et C99 activés. Peut-être que vous êtes un débutant en golf comme moi ou un débutant en C comme moi, ou peut-être êtes-vous simplement curieux. :) https://gist.github.com/cpx/97edbce4db3cb30c306a
la source
Scala,
347341337 caractères:=>
la source
println("%2d: %s -- score: %d".format(i,a,s(a))
peut changer àprintln(f"$i%2d: $a%s -- score: ${s(a)}%d")
, en sauvant 4 caractères!def c=(' '+:('A'to'Z'))(r(27))
me donneerror: type mismatch; found : Int required: scala.collection.generic.CanBuildFrom[scala.collection.immutable.IndexedSeq[Char],Char,?]
PHP 442
Lisiblement:
la source
if\for
, il est à 436. Vous pouvez également$n>90
rechercher un autre personnager()
et voss()
fonctions. Voici les changements avec les commentaires: ideone.com/4ecZQc%s
est toujours la même longueur et le%d
est justifié à gauche, vous pouvez donc utiliser ce qui suit:printf("%2d: $s -- score: $l\n",$i);
Java (632)
Java est un langage aussi prolixe .. :(
la source
Python (
330321)Version lisible:
Exemple de sortie:
edit: suppression de quelques caractères basés sur les réponses AMK et Timtech
la source
sum(1for c in range(28)if n[c]==t[c])
peut être raccourci àsum(n[c]==t[c] for c in range(28))
(-3 caractères)import random as r
pourfrom random import*
puis retirer les trois instances der.
S
? Le défi nécessite de commencer avec une chaîne de caractères aléatoires.PHP (
381 397 323 319312):Version lisible:
Crédits d'optimisation (319):
Crédits d'optimisation (312):
la source
for
pour$f=N;while($f--){
des 3 car chacun. et pour un autre personnage:$n=rand(0,26);[...]chr($n?$n+64:32)
Ruby, 218
exemple couru
la source
Ruby -
225202203198 caractèresJusqu'à présent, Ruby semble sous-représentée dans ce défi, alors j'ai décidé de l'essayer! Les améliorations sont les bienvenues.
la source
1
mais la question est spécifiée0
. Si vous init avecg=-1
alors c'est bien. Il y a peut-être un moyen plus intelligent mais je l'ai fait de cette façon. Cordialement, 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,
206200199La première ligne est tout simplement une façon élégante de définir
q=-2
,i=-1
etR=(0..27).to_a
. Tout le travail est fait dans la 2ème ligne:la source
Japt v2.0a0,
112108 octetsEssayez-le en ligne!
-4 octets grâce à @ETHproductions.
Déballé et comment ça marche
la source
Japt
-R
, 94 octetsUne approche différente mais légèrement inspirée de la solution de Bubbler .
Testez-le (ou essayez-le en ligne )
Explication
Ligne 1
Le résultat est affecté à la variable
U
.Ligne 2
Le résultat est affecté à la variable
V
.Ligne 3
Le résultat de cette ligne est implicitement associé aux nouvelles lignes et à la sortie.
la source
Perl 5 , 219 octets
Essayez-le en ligne!
la source
Rubis - 410
Edit * Il échoue actuellement (pour une raison quelconque, un [any] est défini sur 0 (type => fixnum)). Cependant, la conception actuelle est correcte, je dois juste trouver le bogue à l'origine de ce problème (c'est très mystérieux)
la source
Python 284
la source
JavaScript - 312
Il existe déjà une solution JS plus courte ci-dessus, mais elle utilise des fonctions de pointeur expérimentales. J'ai donc pensé intégrer une autre solution fonctionnant dans n'importe quel environnement JS:
la source
Java:
557534Non emballé:
la source
PHP
429426421415joli imprimé
J'aurai besoin d'une langue moins verbeuse la prochaine fois
la source
Python 2.7 - 319 octets
Bien sûr, ce n’est pas le plus petit, mais c’était amusant de programmer.
Utilise une fonction récursive, de sorte qu'elle peut atteindre la profondeur de récursion maximale s'il existe une sorte de dévolution étrange avec la chaîne.
Merci à Sp3000 pour son aide au golf.
la source
Julia, 281 octets
Golfé:
L'algorithme lui-même n'est pas très intelligent, mais il contient quelques éléments intéressants. La combinaison d' une plage de caractères avec un autre personnage, puis l' indexation en elle:
['A':'Z',' '][rand(1:27,n)]
et en prenant la somme d'un tableau de booléens (communes, mais je l' aime toujours l'idée):sum(a.=="METHINKS IT IS LIKE A WEASEL".data)
. Content d'avoir moins de 300 ans!Ungolfed:
la source