Vous êtes sur une série de 8 jours!

82

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 aou 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
Luke
la source
31
Est-ce que cela est approuvé par Duolingo? Si ce n'est pas le cas, vous devriez leur demander de nous payer pour l'amélioration de la langue sur un site d'apprentissage linguistique.
Arc676
10
Est-ce que 1100 (an) onze cents ou (a) mille et cent ?
user3819867
11
Bilbo serait en désaccord avec certains de vos cas de test. :)
Martin Ender
9
@Zaibis: "on" se prononce ici comme "wun", qui a un son de consonne. Par conséquent, " une série de mille et cent jours".
El'endia Starman
31
Ils ont probablement quitté ce virus car ils pensaient que personne ne pourrait atteindre une série de 8 jours.
PNDA

Réponses:

14

Pyth, 23 octets

<>n\8hz}hjsz^T3,hT18"an

Ceci sélectionne le nombre de lettres à trancher à la fin de "an"en vérifiant si la première lettre n'est pas un 8et 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.

isaacg
la source
3
Très créatif. Aussi, terrifiant.
Hellreaver
29

Python 2, 60 octets

lambda n:'a'+'n'[:`n`[0]=='8'or`n`[:2]in len(`n`)%3/2*'118']

Une fonction anonyme. Ajoute un nsi si:

  • Le premier chiffre est 8
  • Les deux premiers chiffres sont 11 ou 18 et la longueur est 2 modulo 3.
Xnor
la source
Je sais que c’est une très vieille question, mais je pense que `>> n= '8'` `enregistre trois octets.
Lynn
@ Lynn Est-ce que ça ne va pas gâcher les neuf?
xnor
Oh bien sûr! J'ai été dupé par la suite de tests :)
Lynn
12

GNU Sed, 32

Le score inclut +1 pour l' -Eoption sed.

s/^8.*|^1[18](...)*$/an/
t
ca
:

Essayez-le en ligne.

  • Supprimez les groupes de 3 chiffres de la fin de chaque numéro jusqu'à ce qu'il ne reste que 1 à 3 chiffres
  • Correspond à tout nombre commençant par 8 ou exactement 11 ou 18 et changer à an
  • Changer tous les autres numéros en a

Merci à @ MartinBüttner pour son approche de la rétine qui a permis d’économiser 10 octets.

Trauma numérique
la source
11

Shell + bsd-jeux, 30

number -l|sed '/^e/{can
q};ca'

Entrée lue depuis STDIN.

numberconvertit une chaîne décimale en mots. Il est alors simple de décider si le résultat commence ou non e.

Trauma numérique
la source
2
+1 pour l'utilisation de bsd-games, je ne pensais pas qu'ils seraient utiles :)
ASCIIThenANSI
@ASCIIThenANSI Oui, bsd-games sont utiles ici et :)
Digital Trauma
9

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.

^8.*|^1[18](...)*$
an
\d+
a

Essayez-le en ligne.

La première expression rationnelle remplace tous les nombres pertinents par an, et la seconde remplace tous les nombres restants par a. Cela fonctionne pour les mêmes octets:

^8.*|^1[18](...)*$
n
^\d*
a
Martin Ender
la source
1
+1 c'est presque le même niveau d'abus de regex que le test de primalité :)
Cat
1
Et le point positif est que Duolingo est en fait écrit en rétine, il devrait donc être facile de l’intégrer. Ou attendez, quelle langue était-ce?
cessé de tourner dans le sens antihoraire
1
@ceasedtoturncounterclockwis On me dit que c'est écrit en hexagone, mais ils ont écrit un transpiler rétine en hexagone, donc cela ne devrait pas être un problème.
Martin Ender
6

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.

const char*f(int i){int n=0,d=0;for(;i;(!(d++%3)&(i==18|i==11))|i==8?n=1:0,i/=10);return n?"an":"a";}
Luke
la source
4

Mathematica, 53 octets

If[#~IntegerName~"Words"~StringStartsQ~"e","an","a"]&

Une solution utilisant le traitement de chaîne finirait par être plus longue.

LegionMammal978
la source
3

PostScript, 119 113 caractères

10 string cvs dup 0 get 56 eq exch dup length 3 mod 2 eq{0 2 getinterval dup(11)eq exch(18)eq or or}{pop}ifelse

Avec code de test:

/An
{
    10 string cvs dup 0 get 56 eq exch dup length 3 mod 2 eq{0 2 getinterval dup(11)eq exch(18)eq or or}{pop}ifelse
} def

/ShouldBeFalse [ 0 110 1111 1863 110000 180000 1141592 1897932 ] def
/ShouldBeTrue [ 8 11 18 84 843 8192 11000 18000 11234567 18675309 ] def

() = (ShouldBeFalse) = ShouldBeFalse {An =} forall
() = (ShouldBeTrue)  = ShouldBeTrue  {An =} forall
jdaw1
la source
3

JavaScript (ES6) 70 61 46 38 octets

n=>/^8|^1[18](...)*$/.test(n)?'an':'a'

Wiki 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/

Scott Kaye
la source
1
ça a du sens. Merci de m'avoir expliqué.
Daniel F
1
@Pavlo Très sympa, j'ai oublié les expressions simples après avoir découvert le evaltour! 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!
Scott
1
@Pavlo Sweet, mis à jour à nouveau! Apprentissage beaucoup, merci beaucoup :)
Scott
2
URGH! Oublié de raser 2 octets! Voici le dernier: n=>/^8|^(?=1[18])..(\d{3})*$/.test(n)?'an':'a'( es6fiddle.net/iiehl1ex ). C'est 46 octets de long.
Ismael Miguel
2
@ScottKaye Le code est très simple: il vérifie s'il commence par 8, s'il commence par 1[18]et si la longueur des nombres est 2 * (3n). En gros, il s’agit de tout votre code, mais au sein d’une expression régulière.
Ismael Miguel
2

Sérieusement, 43 40 octets

9⌐9τk,;;$l3@\3*╤@\(íub)$#p'8=)XkΣ'n*'a+

La 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:

9⌐9τk,;;$l3@\3*╤@\(íub)$#p'8=)XkΣ'n*'a+
9⌐9τk                                    push [11, 18]
     ,;;                                 push 3 copies of input (n)
        $l                               get length of n as string (effectively floor(log(n,10)))
          3@\3*╤                         get largest 10^(3n) less than the length
                @\                       get most significant digits of n (x)
                  (í                     bring list from back, push the index of x in the list or -1 if not in list
                    ub)                  increment by 1, convert to boolean, shove to bottom
                       $#p               push first digit from n (as string)
                          '8=            push 1 if "8" else 0
                             )X          shove to bottom of stack, discard remaining digits
                               kΣ'n*     push sum of stack, push a string containing that many "n"s
                                    'a+  push "a", concatenate
Mego
la source
2

Perl 6 ,  31   30 octets

{'a'~'n'x?/^8|^1<[18]>[...]*$/} # 31 bytes
{<a an>[?/^8|^1<[18]>[...]*$/]} # 31 bytes
{<a an>[?/^8|^[11|18][...]*$/]} # 31 bytes

{'a'~'n'x?/^8|^1[1|8][...]*$/} # 30 bytes
{<a an>[?/^8|^1[1|8][...]*$/]} # 30 bytes

(Perl 6 utilise [ ]dans les expressions rationnelles pour ne pas capturer ( ), et utilise <[ ]>pour les jeux de caractères)

Usage:

# store it in a lexical code variable for ease of use
my &code = {...}

my @a  = <0 110 1111 1863 110000 180000 1141592 1897932>;
my @an = <8 11 18 843 8192 11000 18000 11234567 18675309>;

say @a.map: &code;
say @an.map: &code;
(a a a a a a a a)
(an an an an an an an an an)
Brad Gilbert b2gills
la source
2

PostScript, 109 octets

(a)exch 10 string cvs dup[exch length 3 mod 2 eq{(11)(18)}if(8)]{anchorsearch{pop pop(an)exch}if}forall pop =

Le code vérifie si le numéro commence par certains préfixes. Le préfixe 8est toujours vérifié ( huit , quatre-vingts quelque chose , huit cents et plus ), mais 11et 18( 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 aet lorsqu'un préfixe est trouvé, le résultat est remplacé par an. anchorsearchest 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 le  exit? -, mais parce que la chaîne d'origine est remplacée par, anous sommes sûrs de ne pas obtenir de faux positifs.

Pour ramener le a-ou- anrésultat sur la pile d'opérandes au lieu d'imprimer, retirer la queue  =(résultant longueur: 107 octets).

Code de test:

/DO {
    ... the code above ...
} def

(Should be "a"s:)  = {0 110 1111 1863 110000 180000 1141592 1897932}     { DO } forall
(Should be "an"s:) = {8 11 18 84 843 8192 11000 18000 11234567 18675309} { DO } forall
flush
affaissements
la source
2

PostScript (avec jetons binaires), 63 octets

(a)’>10’¥’1’8[’>’b3’j2’={(11)(18)}if(8)]{’${’u’u(an)’>}if}’I’u=

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:

  • Dans le cas général, une implémentation qui minimise le code ASCII n'est pas nécessairement identique à celle qui minimise la version binaire. Un morceau de code PostScript ASCII plus long pourrait se compresser mieux qu'un autre et sa version binaire correspondante serait plus courte.
  • Le code binaire ne convenant pas partout, une réponse ASCII pure peut être préférable même si elle est plus longue.
  • Il ne serait pas juste de comparer la longueur d’une réponse PostScript ASCII pure à une réponse utilisant des codages binaires.
affaissements
la source
1

Python 3, 110 93 91 76 74 70 65 64 octets

En 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 .

n=input();print("a"+"n"*(len(n)%3>1and n[:2]in"118"or"8"==n[0]))

ou pour le même nombre d'octets.

n=input();print("a"+"n"[:len(n)%3>1and n[:2]in"118"or"8"==n[0]])

Ungolfed:

def a():
    n=input()
    if "8"==n[:1]:
        a = "n"
    elif len(n)%3 == 2 and (n[:2] in ["11", "18"]):
        a = "n"
    else:
        a = ""
    return "a"+a
Sherlock9
la source
Ceci est incorrect sur l'entrée 843"huit cent quarante-trois", ce qui devrait être an.
isaacg
@isaacg Non seulement vous avez raison, mais cela simplifie énormément mon code. Merci! Il s'avère que je ne visais que huit, huit mille huit millions, sans tenir compte des cas comme quatre-vingts et huit cents.
Sherlock9
Pourquoi (-~len(n)%3)<1au lieu de len(n)%3==2?
Timwi
Pourrait (n[:2]=="11"or n[:2]=="18")être raccourci à "118".contains(n[:2])?
Timwi
Ou même n[:2]in"118"?
Timwi
1

Java 10, 102 octets

n->{var N=n+"";return(n>9&&"118".contains(N.substring(0,2))&N.length()%3>1)|N.charAt(0)==56?"an":"a";}

Essayez-le en ligne.

Explication:

n->{                  // Method with integer parameter and String return-type
  var N=n+"";         //  Input integer as String
  return(n>9&&        //  If the input has at least two digits,
    "118".contains(N.substring(0,2))
                      //  and the first two digits are "11" or "18",
    &N.length()%3>1)  //  and the length modulo-3 is 2
   |N.charAt(0)==56?  //  Or if the first digit is an '8':
     "an"             //   Return "an"
   :                  //  Else:
     "a";}            //   Return "a"
Kevin Cruijssen
la source
1

Japt , 28 27 octets

'a+'npUì v ¥8ª[B18]d¥UìA³ v

Essayez-le en ligne!

Déballé et comment ça marche

'a+'npUì v ==8||[B18]d==UìAp3  v

'a+'np  "a" + "n".repeat(...)
Uì v ==8    First digit in decimal == 8
||          or...
[B18]d      [11,18].some(...)
==UìAp3  v  == First digit in base 10**3
Barboteur
la source
Vous pouvez remplacer 1e3par
Oliver
1

GNU sed -r+ BSD number, 34 octets

s/(e?).*/number &/e
s//a\1/
y/e/n/

Nous convertissons d'abord en nombre anglais. Puis supprimez tout sauf une initiale possible eet préfixez avec a. Puis convertissez le e(si présent) en n. Le seul truc pour jouer au golf consiste à faire correspondre les options edans la première substitution afin de pouvoir réutiliser le modèle dans la ligne suivante.

Démo

for i in 0 8 11 18 84 110 843 1111 1863 8192 \
    11000 18000 110000 180000 1141592 1897932 11234567 18675309
do printf "%'10d → %s\n" $i $(./66841.sed <<<$i)
done
         0 → a
         8 → an
        11 → an
        18 → an
        84 → an
       110 → a
       843 → an
     1,111 → a
     1,863 → a
     8,192 → an
    11,000 → an
    18,000 → an
   110,000 → a
   180,000 → a
 1,141,592 → a
 1,897,932 → a
11,234,567 → an
18,675,309 → an
Toby Speight
la source
0

TeaScript , 35 octets

[18,11,8,80]I(+xh(x.n%3¶3©?'an':'a'

Essayez ici.

Explication

               xh(x.n%3¶3           get the relevant digits from the input
                                    xh compiles to x.head which returns the
                                    first n chars of x (implicit input)
                                    ¶ ('\xb6') compiles to ||
              +                     cast the result to an integer since
                                    .includes does a strict comparison
                         ©          ('\xa9') compiles to ))
[18,11,8,80]                        array of the special cases
            I(                      I( is an alias for .includes( which
                                    returns true if the array contains the
                                    argument
                          ?'an':'a' finally, return 'an' if the array
                                    contains the number, 'a' otherwise
Dom Hastings
la source
0

Python 2.7, 66

s=`input()`
print['a','an'][s[:1]=='8'or s[:2]in len(s)%3/2*'118']

Évidemment pas aussi court que celui- lambdalà.

janvier
la source
0

05AB1E , 26 octets

g3%ô¬D11Qs18Q+I1£8Q+>„ans∍

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:

g3%                  # Length of the input, modulo-3
                     #  11234567 → 8 → 2
                     #  110000 → 6 → 0
   ô                 # Split the input into chunks of that size
                     #  11234567 and 2 → ['11', '23', '45', '67']
                     #  110000 and 0 → ['110000']
    ¬                # Take the Head (first element)
                     #  ['11', '23', '45', '67'] → '11'
                     #  ['110000'] → '110000'
     D11Q            # Does it equal 11?
                     #  '11' and 11 → 1
                     #  '110000' and 11 → 0
     s18Q            # Or does it equal 18?
                     #  '11' and 18 → 0
                     #  '110000' and 18 → 0
         +           # Add them together (if it was either 11 or 18, this becomes 1)
                     #  1 and 0 → 1
                     #  0 and 0 → 0
I1£                  # Get the first character of the input
                     #  11234567 → '1'
                     #  110000 → '1'
   8Q                # Does it equal 8?
                     #  '1' and 8 → 0
          +          # Add them together
                     #  1 and 0 → 1
                     #  0 and 0 → 0
           >         # Increase it by 1
                     #  1 → 2
                     #  0 → 1
            „ans∍    # Push "an", and shorten it to a size equal to the result above
                     #  "an" and 2 → "an"
                     #  "an" and 1 → "a"
Kevin Cruijssen
la source
0

Stax , 25 octets

â-x▬♪°∞▄'δL|÷æ╪║>₧4¢ÿ·7åR

Exécuter et déboguer

Déballé, non golfé et commenté, cela ressemble à ceci.

Vk|Eh       get the first "digit" after converting to base 1000
AJ|Eh       get the first "digit" after converting to base 100
c20>9*^/    if the result is greater than 20, divide it by 10 again
"AMj"!#     is the result one of [8, 11, 18]?
^           increment by 1
.an(        keep that many characters of the string "an"

Exécuter celui-ci

récursif
la source
0

Espaces blancs , 243 octets

[S S S T    T   S S S S T   N
_Push_97_a][T   N
S S _Print_as_character][S S S T    N
_Push_1][S N
S _Duplicate_1][S N
S _Duplicate_1][T   N
T   T   _Read_STDIN_as_integer][T   T   T   _Retrieve_input][N
S S S T N
_Create_Label_LOOP][S N
T   _Swap_top_two][S S S T  N
_Push_1][T  S S S _Add][S N
T   _Swap_top_two][S N
S _Duplicate][S S S T   T   S S T   S S N
_Push_100][T    S S T   _Subtract][N
T   T   T   N
_If_negative_jump_to_Label_TWO_DIGITS][S S S T  S ST    S N
_Push_10][T S T S _Integer_division][N
S N
S T N
_Jump_to_Label_LOOP][N
S S T   N
_Create_Label_TWO_DIGITS][S N
S _Duplicate][S S S T   S S S N
_Push_8][T  S S T   _Subtract][N
T   S S S N
_If_zero_jump_to_Label_PRINT_n][S N
S _Duplicate][S S S T   S T T   N
_Push_11][T S S T   _Subtract][N
T   S S N
_If_0_jump_to_Label_2_MOD_3][S N
S _Duplicate][S S S T   S S T   S N
_Push_18][T S S T   _Subtract][N
T   S S N
_If_0_jump_to_Label_2_MOD_3][S S S T    S ST    S N
_Push_10][T S T S _Integer_division][S N
S _Duplicate][N
T   S N
_If_0_jump_to_Label_EXIT][N
S N
T   N
_Jump_to_Label_TWO_DIGITS][N
S S S N
_Create_Label_2_MOD_3][S N
T   _Swap_top_two][S S S T  T   N
_Push_3][T  S T T   _Modulo][S S S T    S M
_Push_2][T  S S T   _Subtract][N
T   T   N
_If_negative_jump_to_Label_EXIT][N
S S S S N
_Create_Label_PRINT_n][S S S T  T   S T T   T   S N
_Push_110_n][T  N
S S _Print_as_character][N
S S N
_Create_Label_EXIT]

Lettres S(espace), T(tabulation) et N(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:

Print "a"
Integer input = STDIN as integer
Integer counter = 1
Start LOOP:
  counter = counter + 1
  If(input < 100)
    Jump to function TWO_DIGITS
  input = input integer-divided by 10
  Go to next iteration of LOOP

function TWO_DIGITS:
  If(input == 8)
    Jump to function PRINT_n
  If(input == 11 or input == 18)
    Jump to function 2_MOD_3
  input = input integer-divided by 10
  If(input == 0)
    Exit program
  Recursive call to TWO_DIGITS

function 2_MOD_3:
  If(counter modulo-3 != 2)
    Exit program
  Jump to function PRINT_n

function PRINT_n:
  Print "n"
  Exit program
Kevin Cruijssen
la source
0

C ++, 80 79 octets

[](int i){for(;i>999;i/=1e3);return i-11&&i-18&&i/100-8&&i/10-8&&i-8?"a":"an";}

Il s'est avéré que 4 octets étaient plus courts pour tester explicitement 8xx et 8x que d'avoir une autre /=10boucle, comme ceci:

[](int i){for(;i>999;i/=1e3);for(i==11|i==18?i=8:0;i>9;i/=10);return i-8?"a":"an";}

Démo

#include <locale>
#include <cstdio>
int main(int argc, char**argv)
{
    auto const f =
        [](int i){for(;i>999;i/=1e3);return i-11&&i-18&&i/100-8&&i/10-8&&i-8?"a":"an";}
    ;

    std::locale::global(std::locale{""});
    for (int i = 1;  i < argc;  ++i) {
        auto const n = std::stoi(argv[i]);
        printf("%'10d → %s\n", n, f(n));
    }
}
         0 → a
         8 → an
        11 → an
        18 → an
        84 → an
       110 → a
       843 → an
     1,111 → a
     1,863 → a
     8,192 → an
    11,000 → an
    18,000 → an
   110,000 → a
   180,000 → a
 1,141,592 → a
 1,897,932 → a
11,234,567 → an
18,675,309 → an
Toby Speight
la source
Je ne connais pas très bien le C ++, mais peut i/=1000être i/=1e3, et tout peut &&devenir &?
Kevin Cruijssen
Cela semble effectivement fonctionner: essayez-le en ligne.
Kevin Cruijssen
1
@ Kevin - J'avais à un moment donné 1e3 là-bas; Je l'ai changé pendant le débogage et j'ai oublié de le changer. Le &&ne peut pas tous être &, parce que la soustraction donne des nombres entiers et non booléens - par exemple , 19-11est 8 et 19-18est 1; voyez que 8 && 1c'est vrai, mais 8 & 1c'est faux. Nous pourrions utiliser &mais nous avions besoin de changer -pour !=et ajouter entre parenthèses.
Toby Speight
Ah bien sûr .. en &effet ne fonctionne pas ici, mon mauvais. Au fait, pourquoi ne pas ajouter un lien TIO à votre réponse?
Kevin Cruijssen
-1

Perl, 71 55 49 octets

$_=<>;$_=/^8/||/^1[18]/&&length%3==1?'an':'a';say

Je savais que l'opérateur ternaire aiderait un jour ...

Laisse moi décomposer ça.

  • $_=<> accepte un nombre en entrée.
  • Le gros $_=...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.
    • Si c'est vrai, $_est réglé sur an. Sinon, il est réglé sur a.
  • Il affiche ensuite le contenu de $_(ou aou an) avec say.

Changements

  • 16 octets sauvés grâce à msh210.
  • Sauvegardé 6 octets en supprimant les parenthèses et en utilisant les valeurs par défaut.
ASCIIThenANSI
la source
$_=<>;$_=(/^8/)||/^1[18]/&&length($_)%3==1?'an':'a';sayenregistre 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.)
msh210
@ msh210 On dirait que ce n'est que 55 octets, ce qui signifie qu'il enregistre 16 octets. Je vais ajouter ça dans. Merci!
ASCIIThenANSI
Je vous en prie. Oh, et vous pouvez laisser tomber les premiers parents (je suppose. Je n'ai pas testé). Je pense que vous pouvez également changer length($_)à length(ou au moins laisser tomber les parens) , mais qui ne fonctionne pas pour moi pour une raison quelconque.
msh210
@ msh210 Oui, vous pouvez laisser tomber les parens et ($_)obtenir $_=<>;$_=/^8/||/^1[18]/&&length%3==1?'an':'a';say, ce qui ne représente que 49 octets.
ASCIIThenANSI
Vous pouvez enregistrer des octets en utilisant -pplutôt que $_=<>et say, y///cau lieu de length, et en supprimant les guillemets autour de aet an: 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==2est analysé comme length(%3)==2, pas comme length($_)%3==2, donc il retourne toujours faux.
ThisSuitIsBlackNot
-1

Pyth, 29 31

?:_ec_z3"(^18$|^11$|^8)"0"an"\a

Inverse la chaîne, la divise en sections de trois, l’inverse à nouveau, puis choisit la fin appropriée.

élan
la source
5
C'est faux sur l'entrée 111- ça donnean
isaacg
Vous avez raison. Fixé.
Moose