Duolingo, l'application d'apprentissage des langues, a de nombreux objectifs, mais il y a un problème majeur qui me rend fou. Il me dit combien de jours d'affilée j'ai utilisé l'application avec un message du type " Vous êtes sur une période de 7 jours!" Si on met de côté la césure et si le numéro doit être précisé, cela fonctionne bien pour la plupart des numéros, mais il est incontestablement faux quand il est dit que vous êtes sur une période de 8 jours! Je ne l'utilise pas pour apprendre l'anglais, mais il s'agit toujours d'un comportement malheureux pour une application linguistique.
Vous allez aider l'équipe Duolingo en écrivant un programme complet ou une fonction qui figure si un nombre donné doit être précédée d' un ou une . Un nombre est précédé d' un si sa prononciation en anglais parlé commence par un son de consonne ou semi-vocal , et précédé d' un si sa prononciation commence par un son de voyelle. Ainsi, les seuls numéros précédés d' un sont ceux dont la prononciation commence par huit , onze , dix - huit ou quatre - vingts .
L’équipe de développement de Duolingo a vraisemblablement laissé ce bogue, car elle manquait d’espace pour plus de code source dans l’application; vous devez donc rendre ce code aussi court que possible dans l’espoir de pouvoir le rentrer.
Votre code doit prendre un entier compris entre 0 et 2 147 483 647 et la sortie a
ou an
. Un retour à la ligne est facultatif. Pour les besoins de ce défi, 1863 est lu comme mille huit cent soixante-trois , pas dix-huit cent soixante-trois .
Cas de test:
0 → a
8 → an
11 → an
18 → an
84 → an
110 → a
843 → an
1111 → a
1863 → a
8192 → an
11000 → an
18000 → an
110000 → a
180000 → a
1141592 → a
1897932 → a
11234567 → an
18675309 → an
Réponses:
Pyth, 23 octets
Ceci sélectionne le nombre de lettres à trancher à la fin de
"an"
en vérifiant si la première lettre n'est pas un8
et que le premier chiffre du nombre considéré en base 1000 n'est ni 11 ni 18. Le booléen résultant est le nombre de caractères à trancher la fin.la source
Python 2, 60 octets
Une fonction anonyme. Ajoute un
n
si si:la source
n
= '8'` `enregistre trois octets.GNU Sed, 32
Le score inclut +1 pour l'
-E
option sed.Essayez-le en ligne.
an
a
Merci à @ MartinBüttner pour son approche de la rétine qui a permis d’économiser 10 octets.
la source
Shell + bsd-jeux, 30
Entrée lue depuis STDIN.
number
convertit une chaîne décimale en mots. Il est alors simple de décider si le résultat commence ou none
.la source
Retina , 27 octets
Ce n'est pas très différent de la réponse de DigitalTrauma à la rétine, mais ils ont insisté pour que je poste cela moi-même.
Essayez-le en ligne.
La première expression rationnelle remplace tous les nombres pertinents par
an
, et la seconde remplace tous les nombres restants para
. Cela fonctionne pour les mêmes octets:la source
C ++, 101
C'est mon défi, alors ce n'est pas censé être une réponse compétitive. Je voulais juste voir à quel point je pouvais l'obtenir en C ++. Les opérations sur les chaînes de caractères sont trop verbeuses, c'est donc fait en mathématiques. J'ai le sentiment qu'il doit y avoir un moyen de réduire cette condition, mais je n'arrive pas à comprendre.
la source
Mathematica, 53 octets
Une solution utilisant le traitement de chaîne finirait par être plus longue.
la source
PostScript,
119113 caractèresAvec code de test:
la source
JavaScript (ES6)
70614638 octetsWiki de la communauté car la solution actuelle est tellement différente de celle de mon original. Merci tout le monde!
Démo: http://www.es6fiddle.net/iio40yep/
la source
eval
tour! Je savais qu'il devait y avoir une meilleure expression régulière également, mais je ne pouvais pas comprendre quoi que ce soit qui soit plus court. Je vous remercie!n=>/^8|^(?=1[18])..(\d{3})*$/.test(n)?'an':'a'
( es6fiddle.net/iiehl1ex ). C'est 46 octets de long.8
, s'il commence par1[18]
et si la longueur des nombres est2 * (3n)
. En gros, il s’agit de tout votre code, mais au sein d’une expression régulière.Sérieusement,
4340 octetsLa stratégie consiste ici à ne regarder que les 1, 2 ou 3 chiffres les plus significatifs, en divisant en entier l'entrée par la plus grande valeur
10^(3n)
inférieure à l'entrée.Essayez-le en ligne
Explication:
la source
Rétine , 34 ans
Traduction directe de ma réponse sed :
Essayez-le en ligne.
Un octet enregistré grâce à @Timwi.
la source
Perl 6 ,
3130 octets(Perl 6 utilise
[ ]
dans les expressions rationnelles pour ne pas capturer( )
, et utilise<[ ]>
pour les jeux de caractères)Usage:
la source
PostScript, 109 octets
Le code vérifie si le numéro commence par certains préfixes. Le préfixe
8
est toujours vérifié ( huit , quatre-vingts quelque chose , huit cents et plus ), mais11
et18
( onze et dix - huit ) ne sont cochés que lorsque le nombre de chiffres est un multiple de 3 plus 2.Nous commençons avec un résultat provisoire de
a
et lorsqu'un préfixe est trouvé, le résultat est remplacé paran
.anchorsearch
est utilisé pour éviter d'extraire un préfixe de la chaîne. Même si une correspondance est trouvée, nous continuons à vérifier le reste des préfixes - pourquoi perdre 5 octets pour leexit
? -, mais parce que la chaîne d'origine est remplacée par,a
nous sommes sûrs de ne pas obtenir de faux positifs.Pour ramener le
a
-ou-an
résultat sur la pile d'opérandes au lieu d'imprimer, retirer la queue=
(résultant longueur: 107 octets).Code de test:
la source
PostScript (avec jetons binaires), 63 octets
Les
’
octets avec la valeur 146 (décimal),¥
est un 165 et$
est un 3. Tous les autres sont des caractères imprimables ASCII 7 bits.Ceci est identique à ma version PostScript [ASCII pur], mais utilise des jetons binaires, ce qui permet de réduire la longueur totale. Je le poste séparément pour 3 raisons:
la source
Python 3,
11093917674706564 octetsEn voici un long, mais simple.
Edit: corrigé grâce à isaacg . A sauvé quelques espaces après les comparaisons. Beaucoup d'octets sauvés grâce à Timwi , Mego , Benpop et Alissa .
ou pour le même nombre d'octets.
Ungolfed:
la source
843
"huit cent quarante-trois", ce qui devrait êtrean
.(-~len(n)%3)<1
au lieu delen(n)%3==2
?(n[:2]=="11"or n[:2]=="18")
être raccourci à"118".contains(n[:2])
?n[:2]in"118"
?Java 10, 102 octets
Essayez-le en ligne.
Explication:
la source
Japt ,
2827 octetsEssayez-le en ligne!
Déballé et comment ça marche
la source
1e3
parA³
GNU
sed -r
+ BSDnumber
, 34 octetsNous convertissons d'abord en nombre anglais. Puis supprimez tout sauf une initiale possible
e
et préfixez aveca
. Puis convertissez lee
(si présent) enn
. Le seul truc pour jouer au golf consiste à faire correspondre les optionse
dans la première substitution afin de pouvoir réutiliser le modèle dans la ligne suivante.Démo
la source
TeaScript , 35 octets
Essayez ici.
Explication
la source
Python 2.7, 66
Évidemment pas aussi court que celui-
lambda
là.la source
05AB1E , 26 octets
Peut probablement être joué un peu plus au golf, mais cela fonctionne.
Essayez-le en ligne ou vérifiez tous les cas de test .
Explication:
la source
QuadS , 32 octets
Essayez-le en ligne!
la source
Stax , 25 octets
Exécuter et déboguer
Déballé, non golfé et commenté, cela ressemble à ceci.
Exécuter celui-ci
la source
Espaces blancs , 243 octets
Lettres
S
(espace),T
(tabulation) etN
(nouvelle ligne) ajoutées uniquement en surbrillance.[..._some_action]
ajouté comme explication seulement.Essayez en ligne (avec des espaces premières, des onglets et de nouvelles lignes seulement).
Le programme s’arrête avec une erreur: Aucune sortie trouvée.
Explication en pseudo-code:
la source
C ++,
8079 octetsIl s'est avéré que 4 octets étaient plus courts pour tester explicitement 8xx et 8x que d'avoir une autre
/=10
boucle, comme ceci:Démo
la source
i/=1000
êtrei/=1e3
, et tout peut&&
devenir&
?&&
ne peut pas tous être&
, parce que la soustraction donne des nombres entiers et non booléens - par exemple ,19-11
est 8 et19-18
est 1; voyez que8 && 1
c'est vrai, mais8 & 1
c'est faux. Nous pourrions utiliser&
mais nous avions besoin de changer-
pour!=
et ajouter entre parenthèses.&
effet ne fonctionne pas ici, mon mauvais. Au fait, pourquoi ne pas ajouter un lien TIO à votre réponse?Perl 5
-p
, 26 octetsEssayez-le en ligne!
la source
Perl,
715549 octetsJe savais que l'opérateur ternaire aiderait un jour ...
Laisse moi décomposer ça.
$_=<>
accepte un nombre en entrée.$_=...
bloc définira la valeur$_
après son utilisation....?...:...
est l'opérateur ternaire. Si la condition (premier argument) est vraie, le second argument est renvoyé. Sinon, il retourne le troisième./^8/||(/^1[18]/&&length%3==2)
vérifie si le nombre commence par 8 ou commence par 11 ou 18 (1[18]
accepte l'un ou l'autre) et a une longueur mod 3 de 2.$_
est réglé suran
. Sinon, il est réglé sura
.$_
(oua
ouan
) avecsay
.Changements
la source
$_=<>;$_=(/^8/)||/^1[18]/&&length($_)%3==1?'an':'a';say
enregistre quelques octets. (Bien que le nombre à comparer dépend de la nature de votre caractère de nouvelle ligne, mais cela ne change pas le nombre d'octets.)length($_)
àlength
(ou au moins laisser tomber les parens) , mais qui ne fonctionne pas pour moi pour une raison quelconque.($_)
obtenir$_=<>;$_=/^8/||/^1[18]/&&length%3==1?'an':'a';say
, ce qui ne représente que 49 octets.-p
plutôt que$_=<>
etsay
,y///c
au lieu delength
, et en supprimant les guillemets autour dea
etan
:perl -pe'$_=/^8/||/^1[18]/&&y///c%3==2?an:a'
(34 octets + 1 pour-p
). Notez que l' entrée ne peut pas se terminer par un saut de ligne:echo -n 11 | perl -pe'...'
. Cela corrige aussi un bug:length%3==2
est analysé commelength(%3)==2
, pas commelength($_)%3==2
, donc il retourne toujours faux.Pyth,
2931Inverse la chaîne, la divise en sections de trois, l’inverse à nouveau, puis choisit la fin appropriée.
la source
111
- ça donnean