Le puzzle
Un petit casse-tête que j'ai entendu pendant que j'étais au lycée ressemblait à quelque chose comme ça ...
- L'intervenant me demandait de lui donner un numéro;
- En entendant le nombre, le questionneur ferait une sorte de transformation à plusieurs reprises (par exemple, il pourrait dire que dix est trois ) jusqu'à arriver finalement au nombre 4 (à quel point il finirait avec quatre est magique ).
- N'importe quel nombre semble éventuellement transformable en quatre, quoi qu'il arrive.
L'objectif était d'essayer de comprendre la fonction de transformation et de pouvoir ensuite surveiller de manière fiable ce puzzle vous-même.
La solution
La fonction de transformation à chaque étape était de
- Prends le numéro en question,
- Comptez le nombre de lettres dans sa représentation de mot anglais, en ignorant un trait d'union ou des espaces ou "et" (par exemple, "dix" a 3 lettres, "trente-quatre" a 10 lettres, "cent quarante-trois" contient 20 lettres).
- Renvoyez ce nombre de lettres.
Pour tous les nombres que j'ai jamais voulu tester, cela converge vers 4. Puisque "quatre" contient également quatre lettres, il y aurait une boucle infinie ici; au lieu de cela, on parle simplement de magie par convention pour terminer la séquence.
Le défi
Votre défi est de créer un morceau de code qui lira un nombre de l'utilisateur, puis imprimera des lignes montrant la fonction de transformation appliquée à plusieurs reprises jusqu'à ce que «quatre est magique» soit atteint.
Plus précisément:
- Les solutions doivent être des programmes complets en soi. Ils ne peuvent pas être simplement des fonctions qui prennent un nombre - facteur dans l'entrée.
- L'entrée doit être lue à partir de l'entrée standard. (La tuyauterie depuis "echo" ou l'utilisation de la redirection d'entrée est très bien puisque cela va également de stdin)
- L'entrée doit être sous forme numérique.
- Pour chaque application de la fonction de transformation, une ligne doit être imprimée:,
a is b.
où a et b sont des formes numériques des nombres dans la transformation. - Des arrêts complets (périodes) SONT obligatoires!
- La dernière ligne devrait dire naturellement,
4 is magic.
. - Le code doit produire une sortie correcte pour tous les nombres de 0 à 99 .
Exemples:
> 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.
Le gagnant est la soumission la plus courte par nombre de caractères du code source qui est également correct .
PRIME
Vous pouvez également essayer d'écrire une version du code qui imprime les NOMS EN ANGLAIS pour les nombres à chaque application de la fonction de transformation. L'entrée d'origine est toujours numérique, mais les lignes de sortie doivent avoir la forme mot du nombre.
(Double bonus pour dessiner des formes avec votre code)
(EDIT) Quelques clarifications:
- Je veux que le mot apparaisse des deux côtés dans tous les cas applicables, par exemple
Nine is four. Four is magic.
- Je me fiche de la capitalisation, cependant. Et je me fiche de la façon dont vous séparez les mots jetons, même s'ils devraient être séparés:
ninety-nine
c'est bien,ninety nine
c'est bien,ninetynine
n'est pas bien.
Je les considère comme une catégorie distincte pour la compétition de bonus en ce qui concerne le défi, donc si vous optez pour cela, ne vous inquiétez pas que votre code soit plus long que la version numérique.
N'hésitez pas à soumettre une solution pour chaque version.
la source
Réponses:
GolfScript -
10196939291909486 octets90 → 94
: Sortie fixe pour les multiples de 1094 → 86
.: Code restructuré. Utilisation de la base 100 pour supprimer les caractères non imprimables.86 → 85
: Coulée plus courte en corde.la source
"magic."
, cela résume assez bien la situation.d
est extrait par)
as100
et est utilisé comme base pour la conversion de base.Perl, environ 147 caractères
Basée librement sur la solution Platinum Azure:
la source
pop
, sans aucun argument. En dehors d'un sous-programme,pop
supprime et renvoie la dernière valeur@ARGV
dont la liste des arguments du programme Perl. Il pourrait tout aussi bien être remplacé parshift
, mais cela ajoute 2 autres caractères. Voir: p3rl.org/pop'.'
, qui est 2 pour\n
ou 1 si vous comptez les espaces dans le'. '
(l'espace étant le littéral de nouvelle ligne)Common Lisp 157 caractères
Nouvelle version plus conforme, maintenant la lecture de l'entrée standard et ignorant les espaces et les traits d'union:
Sous une forme lisible par l'homme:
Et quelques tests:
Et la version bonus, à 165 caractères:
Donnant
la source
Python 2.x, 144
150154166caractèresCela sépare le nombre en dizaines et unités et les résume. La propriété indésirable de l'opérateur pseudo-ternaire
a and b or c
quic
est retourné sib
est 0 est ici abusée.La version naïve précédente (150 caractères). Encodez simplement toutes les longueurs sous forme d'entier.
la source
n,"is",p,"."
? Je pense que vous enregistrez encore quelques caractères si je compte bien).
.int()
, dites quelque chose en dehors des modulesstruct
oubase64
...C - avec des mots numériques
445431427421399386371359 *356354 †348347 caractèresC'est tout. Je ne pense pas pouvoir raccourcir cela.
Toutes les nouvelles lignes sont destinées à la lisibilité et peuvent être supprimées:
Ci-dessous, il est un peu non réduit, mais toujours assez difficile à lire. Voir ci-dessous pour une version plus lisible.
Développé et commenté:
À propos de la chaîne codée vers le début
Les noms des nombres sont compressés à l'aide d'un schéma très simple. Les sous-chaînes fréquemment utilisées sont remplacées par des index à un caractère dans le tableau de noms. Une «table de recherche» d'entrées de noms supplémentaires est ajoutée à la fin pour les sous-chaînes non utilisées dans leur intégralité dans le premier ensemble. Les recherches sont récursives: les entrées peuvent faire référence à d'autres entrées.
Par exemple, le nom compressé de 11 est
elM
. Laprint()
fonction sort les caractèrese
etl
(minuscule 'L', pas le nombre '1') textuellement, mais ensuite elle trouve leM
, donc elle s'appelle avec l'index de la 29e entrée (ASCII 'M' - ASCII '0') dans la table de recherche. Cette chaîne estevL
, donc elle produite
etv
, puis s'appelle à nouveau avec l'index de la 28e entrée dans la table de recherche, qui esten
et est sortie textuellement. Ceci est utile car ilen
est également utilisé danseL
foreen
(utilisé aprèseight
ineighteen
), qui est utilisé danstO
forteen
(utilisé pour tous les autres-teen
noms).Ce schéma entraîne une compression assez importante des noms de nombres, tout en ne nécessitant qu'une petite quantité de code pour décompresser.
Les virgules au début et à la fin de la chaîne expliquent la manière simpliste dont les sous-chaînes se trouvent dans cette chaîne. L'ajout de deux caractères ici enregistre plus de caractères plus tard.
À propos de l'abus de
main()
argv
est ignoré (et donc non déclaré dans la version compressée), la valeur d'argc est ignorée, mais le stockage est réutilisé pour contenir le numéro actuel. Cela m'évite simplement d'avoir à déclarer une variable supplémentaire.À propos du manque de
#include
Certains se plaindront qu'omettre
#include <stdio.h>
c'est tricher. Ce n'est pas du tout. Le donné est un programme C complètement légal qui se compilera correctement sur n'importe quel compilateur C que je connais (bien qu'avec des avertissements). Faute de protoypes pour les fonctions stdio, le compilateur supposera que ce sont des fonctions cdecl qui retournentint
, et sera sûr que vous savez quels arguments transmettre. Les valeurs de retour sont ignorées dans ce programme, de toute façon, et ce sont toutes des fonctions cdecl (convention d'appel "C"), et nous savons en effet quels arguments passer.Production
La sortie est conforme aux attentes:
* La version précédente manquait la marque sur deux parties de la spécification: elle ne traitait pas zéro, et elle prenait des entrées sur la ligne de commande au lieu de stdin. La gestion des zéros a ajouté des caractères, mais l'utilisation de stdin au lieu d'arguments de ligne de commande, ainsi que quelques autres optimisations ont enregistré le même nombre de caractères, ce qui a entraîné un lavage.
† Les exigences ont été modifiées pour préciser que le mot numérique doit être imprimé des deux côtés de «est». Cette nouvelle version répond à cette exigence et implémente quelques optimisations supplémentaires pour (plus de) tenir compte de la taille supplémentaire nécessaire.
la source
J, 107
112caractères(Newline pour la lisibilité uniquement)
Utilisation et sortie:
la source
T-SQL, 413
451499caractères(Non pas que je suggère sérieusement que vous fassiez ça ... vraiment je voulais juste écrire un CTE)
Utiliser:
Retour
la source
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 (avec boilerplate),
308290286282280 caractèresJe suis sûr que Groovy s'en débarrasserait en grande partie.
Explication et formatage (tous les commentaires, nouvelles lignes et espaces blancs de début / de fin supprimés dans le compte):
Raisonnablement simple, mais
Edit: n'utilisez plus hexadécimal, c'est moins de frappes
la source
String[]a
au lieu deString[] a
.Windows PowerShell: 152
153184octetsbasé sur la solution précédente, avec plus d'influence d'autres solutions
la source
$input
doivent rester car vous ne pouvez pas convertir directement un énumérateurint
; ça marche quand on passe enstring
premier :-)C, 158 caractères
(basé à l'origine sur le code Python de Vlad, emprunté une astuce à la solution C ++ de Tom Sirgedas pour extraire quelques caractères supplémentaires)
version étendue:
la source
Python, 129
133137148caractèresEn guise d'échauffement, voici ma première version (améliore quelques caractères par rapport au meilleur Python précédent).
PS. Après quelques expurgations, il est maintenant plus court d'environ vingt caractères:
la source
C #: 210 caractères.
Écrasé:
Étendu:
Trucs que cette approche utilise:
Console.
deC.
?:
) au lieu deif/else
.\n
avec leWrite
code d'échappement au lieu deWriteLine
Write
appel de fonctionla source
int[] z
serait plus court car il n'a pas besoin denew[]
"magic"
àobject
, serait implicitement appelToString()
ày
en ajoutant""
. Mais, à cause+
a une priorité supérieure?:
, vous devez mettre dans la vraie partie au lieu de la fausse partie:x!=4?y+"":"magic"
.Perl: 148 caractères
(Perl:
233181212206200199198185179149148 caractères)r
est inutile, rasé un peu plus.Lançons ce bal avec une modeste tentative en Perl.
Des trucs:
Trop!
la source
@u=split$x,'43350435543668877988';
vos virgules utilisent 19 caractères inutiles, se divisant sur uneundef
division à chaque caractère, j'utilise$x
comme variable indéfinie pour remplacer `undef` - total économies: 11 caractères. De plus, retirez lem
danschomp
et vous obtenez un autre personnage rasa votre score.sub r
entièrement - vous ne l'utilisez qu'une seule fois et vous pouvez tout remplacer par un seul ternaire imbriqué sans même parenthèse. Ma version est de 144 caractères pour le moment: gist.github.com/473289JavaScript 1.8 (SpiderMonkey) - 153 caractères
Usage:
echo 42 | js golf.js
Production:
Avec bonus - 364 caractères
Production:
la source
Haskell, 224
270caractèresEt un peu plus lisible -
la source
Version C ++ Stdio, minifiée: 196 caractères
Version C ++ Iostreams, minifiée: 195 caractères
Original, non minifié: 344 caractères
la source
#define
serait encore plus court car cela pourrait remplacer plusieurs jetons.printf("is magic".\n)
=>puts
.printf("%d",p)
=>puts(atoi(p))
. Non seulement plus court mais plus rapide aussi.while(p!=4)
pourrait être abrégéwhile(p-4)
. Un personnage entier, je sais, mais quand même. :-)Delphi: 329 caractères
Version à une seule ligne:
Formé:
Probablement de la place pour un peu plus de pression ... :-P
la source
C #
314286283274289273252 car.Écrasé:
Ordinaire:
Edit Dykam: J'ai fait quelques insertions et modifications soigneuses:
object
dustring
"magic"
.o
J'ai créé une variable temporaire pour que je puisse déplacer l'break
extérieur de lafor
boucle, c'est-à-dire créer un fichierdo-while
.o
affectation, ainsi que l'v
affectation, en continuant à insérer le calcul del
dans les arguments de la fonction, supprimant ainsi le besoin del
. Également intégré l'attribution dem
.int[] x
,int[]x
est également légitime.using System.Linq
c'était trop pour en faire une amélioration.Edit 2 Dykam Changement du tableau int en tableau / chaîne de caractères, ajout d'arithmiques appropriées pour corriger cela.
la source
Lua, 176 caractères
ou
la source
C - sans mots numériques
180175*172167 caractèresToutes les nouvelles lignes sont destinées à la lisibilité et peuvent être supprimées:
Légèrement non minimisé:
* La version précédente manquait la marque sur deux parties de la spécification: elle ne traitait pas zéro, et elle prenait des entrées sur la ligne de commande au lieu de stdin. La gestion de zéro caractère ajouté, mais l'utilisation de stdin au lieu d'arguments de ligne de commande enregistre encore plus, ce qui entraîne des économies nettes.
la source
perl,
123122caractèresJe viens de réaliser qu'il n'est pas nécessaire de sortir vers STDOUT, alors sortez plutôt vers STDERR et supprimez un autre caractère.
Et, une version qui renvoie des nombres épelés:
279278276280 caractèresBien que cela respecte les spécifications, il n'est pas bien formaté à 100%. Il renvoie un espace supplémentaire après les nombres se terminant par zéro. La spécification dit:
C'est plutôt farfelu. Une version plus correcte à
282281279283 caractèresla source
Python:
la source
N = input()
(ouraw_input()
) et éliminer lessys
éléments.she-bang
dans une réponse code-golf ;-)C ++, 171 caractères (#include omis)
la source
#include
car les fonctions seront simplement supposées prendre desint
paramètres. Vous pouvez même enregistrer un coup en effectuant unmain
retourint
.Rubis, 164 caractères
décodé:
la source
Lua
185190199points ajoutés, ajout de io.read, suppression de () lors de la dernière impression
avec sauts de ligne
la source
n=io.read()
(+11 caractères) pour se conformer à la règle de lecture du nombre à partir de l'entrée standard. Changerprint('4 is magic.')
enprint'4 is magic.'
économisera 2 caractères. Supprimer;
après)
sauvera 1 caractère. L'print
utilisation de virgules semble tricher, mais les spécifications ne sont pas claires. Autant le changer enprint(n,'is',m,'.')
pour enregistrer 2 caractères.Code PhP
//////////// test ////////////////
////// Résultats /////////
la source
$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 caractères
5.12.1 (130 caractères)
1211231321361405.10.1 (134 caractères)
125127136140144Historique des modifications:
20100714:2223
- annulé le changement à l'attention de mobrule , mais($_%10&&$u[$_%10])
→(($_%=10)&&$u[$_])
, qui est le même nombre de caractères, mais je l'ai fait au cas où quelqu'un verrait un moyen de l'améliorer20100714:0041
-split//,'...'
→'...'=~/./g
20100714:0025
-($_%10&&$u[$_%10])
→$u[$_%10]
20100713:2340
-while$_
→until/\D/
+ suppression des parenthèses inutiles20100713:xxxx
-$=<>;chop;
→$_=pop;
- courtoisie envers mobruleRemarque: J'étais fatigué d'améliorer les réponses des autres dans les commentaires, alors maintenant je suis avide et je peux simplement ajouter mes modifications ici :) Ceci est une scission de la réponse de Platinum Azure - crédit en partie à Hobbs , mobrule et Platine Azure .
la source
$_%10&&...
construction, vous avez cassé les spécifications pour les entrées 20, 30, 40, ...ARGV
, qui est rempli parSTDIN
:) ou ..echo bar | xargs perl foo.pl
, techniquement transféré de l'écho dans les arguments pour perl :)Perl sans vergogne avec mots numériques (329 caractères)
Adapté assez directement du code C de P Daddy, avec quelques ajustements pour
p()
lui faire faire la même chose en utilisant des primitives Perl au lieu de celles C, et une boucle principale en grande partie réécrite. Voir le sien pour une explication. Les nouvelles lignes sont toutes facultatives.Note latérale: c'est dommage que perl
print
renvoie juste vrai / faux; s'il retournait un compte, cela me sauverait 7 coups.la source
Rubis, 141 caractères:
la source
la source