Du bist auf einer 8-Tage-Serie!

82

Duolingo, die App zum Sprachenlernen, hat eine Menge zu bieten, aber es gibt ein großes Problem, das mich verrückt macht. Es zeigt mir an, wie viele Tage hintereinander ich die App mit einer Meldung verwendet habe, dass Sie sich in einer siebentägigen Phase befinden. Wenn man die Silbentrennung beiseite lässt und festlegt, ob die Zahl richtig geschrieben werden soll, funktioniert dies für die meisten Zahlen gut, ist aber unbestreitbar falsch, wenn es heißt, Sie haben eine 8-Tage-Pause! Ich benutze es nicht, um Englisch zu lernen, aber dies ist immer noch ein unglückliches Verhalten für eine Sprach-App.

Sie helfen dem Duolingo-Team, indem Sie ein komplettes Programm oder eine Funktion schreiben, die herausfindet, ob einer bestimmten Nummer ein oder ein vorangestellt werden sollte . Eine Zahl wird durch voran a , wenn die Aussprache in der gesprochenen Englisch beginnt mit einem Konsonanten oder semivowel Ton und vorangestelltem ein , wenn die Aussprache mit einem Vokallaut beginnt. Daher sind die einzigen Zahlen, denen ein vorangestellt ist, diejenigen, deren Aussprache mit acht , elf , achtzehn oder achtzig beginnt .

Vermutlich hat das Duolingo-Entwicklerteam diesen Fehler behoben, weil in der App nicht mehr genügend Speicherplatz für mehr Quellcode vorhanden ist. Sie müssen diesen Code daher so kurz wie möglich halten, damit sie ihn einschleusen können.

Ihr Code muss eine Ganzzahl von 0 bis 2.147.483.647 annehmen und aoder ausgeben an. Ein abschließender Zeilenumbruch ist optional. Für die Zwecke dieser Herausforderung wird 1863 als eintausendachthundertdreiundsechzig und nicht achtzehnhundertdreiundsechzig gelesen .

Testfälle:

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
quelle
31
Wird dies von Duolingo befürwortet? Wenn nicht, sollten Sie sie bitten, uns für die Verbesserung der Sprache auf einer Sprachlernseite zu bezahlen.
Arc676
10
Ist 1100 (an) elfhundert oder (a) eintausendeinhundert ?
user3819867
11
Bilbo würde mit einigen Ihrer Testfälle nicht einverstanden sein. :)
Martin Ender
9
@Zaibis: "one" wird hier wie "wun" ausgesprochen, was einen konsonanten Klang hat. Daher " eine eintausendeinhunderttägige Serie".
El'endia Starman
31
Sie haben diesen Bug wahrscheinlich verlassen, weil sie dachten, dass niemand eine 8-Tage-Serie erreichen würde.
PNDA

Antworten:

14

Pyth, 23 Bytes

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

Dies wählt aus, wie viele Buchstaben am Ende abgeschnitten werden sollen, "an"indem geprüft wird, ob der erste Buchstabe kein Buchstabe ist 8und ob die erste Ziffer der Zahl in der Basis 1000 weder 11 noch 18 ist. Der resultierende Boolesche Wert gibt die Anzahl der Zeichen an, von denen abgeschnitten werden soll das Ende.

isaacg
quelle
3
Sehr kreativ. Auch erschreckend.
Hellreaver
29

Python 2, 60 Bytes

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

Eine anonyme Funktion. Fügt ein hinzu, nwenn:

  • Die erste Ziffer ist 8
  • Die ersten beiden Ziffern sind 11 oder 18 und die Länge ist 2 Modulo 3.
xnor
quelle
Ich weiß, das ist eine super alte Frage, aber ich denke, `` n> = '8' `` spart drei Bytes.
Lynn
@Lynn Wird das nicht Neuner vermasseln?
xnor
Ah, natürlich! Ich wurde von der Testsuite getäuscht :)
Lynn
12

GNU Sed, 32

Die Punktzahl enthält +1 für die -EOption zu sed.

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

Probieren Sie es online aus.

  • Entfernen Sie 3-stellige Gruppen vom Ende jeder Zahl, bis nur noch 1 bis 3 Stellen übrig sind
  • Ordnen Sie eine beliebige Zahl zu, die mit 8 oder genau 11 oder 18 beginnt, und ändern Sie sie in an
  • Ändern Sie alle anderen Nummern in a

Vielen Dank an @ MartinBüttner für seinen Retina-Ansatz , der 10 Bytes gespart hat.

Digitales Trauma
quelle
11

Shell + BSD-Spiele, 30

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

Eingang von STDIN gelesen.

numberkonvertiert eine Dezimalzeichenfolge in Wörter. Es ist dann einfach zu entscheiden, ob das Ergebnis mit beginnt oder nicht e.

Digitales Trauma
quelle
2
+1 für die Verwendung von Bsd-Spielen, ich hätte nicht gedacht, dass sie jemals nützlich sein würden :)
ASCIIThenANSI
@ASCIIThenANSI yep, Bsd-Spiele sind hier und da nützlich :)
Digital Trauma
9

Retina , 27 Bytes

Dies unterscheidet sich nicht sehr von der Retina-Antwort von DigitalTrauma, aber sie bestanden darauf, dass ich dies selbst poste.

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

Probieren Sie es online aus.

Der erste reguläre Ausdruck ersetzt alle relevanten Zahlen mit anund der zweite alle verbleibenden Zahlen mit a. Dies funktioniert für die gleichen Bytes:

^8.*|^1[18](...)*$
n
^\d*
a
Martin Ender
quelle
1
+1 Dies ist fast das gleiche Maß an Missbrauch von Regex wie Primalitätstests :)
Katze
1
Und das Gute ist, dass Duolingo tatsächlich in Retina geschrieben ist, so dass es ein Kinderspiel sein sollte, dies zu integrieren. Oder warten Sie, welche Sprache war es?
hörte am
1
@ceasedtoturncounterclockwis Mir wurde gesagt, dass es tatsächlich in Hexagony geschrieben ist, aber sie haben einen Retina-zu-Hexagony-Transpiler geschrieben, also sollte dies kein Problem sein.
Martin Ender
6

C ++, 101

Dies ist meine Herausforderung, daher ist dies keine wettbewerbsfähige Antwort. Ich wollte nur sehen, wie kurz ich es in C ++ bekommen könnte. Zeichenfolgenoperationen sind einfach zu ausführlich, daher wird dies mit Mathematik durchgeführt. Ich habe das Gefühl, dass es eine Möglichkeit geben muss, diesen Zustand zu verringern, aber ich kann es nicht ganz herausfinden.

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
quelle
4

Mathematica, 53 Bytes

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

Eine Lösung mit String-Verarbeitung wäre länger.

LegionMammal978
quelle
3

PostScript, 119 113 Zeichen

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

Mit Testcode:

/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
quelle
3

JavaScript (ES6) 70 61 46 38 Bytes

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

Community-Wiki, weil die aktuelle Lösung so anders ist als mein Original. Vielen Dank an alle!

Demo: http://www.es6fiddle.net/iio40yep/

Scott Kaye
quelle
1
Das macht Sinn. Danke fürs Erklären.
Daniel F
1
@Pavlo Sehr schön, ich habe nach der Entdeckung des evalTricks einzelne Ausdrücke vergessen ! Ich wusste, dass es auch einen besseren regulären Ausdruck geben musste, aber ich konnte nichts herausfinden, was kürzer war. Danke!
Scott
1
@Pavlo Sweet, erneut aktualisiert! Ich habe viel gelernt, vielen Dank :)
Scott
2
URGH! Vergessen 2 Bytes zu rasieren! Hier ist der letzte: n=>/^8|^(?=1[18])..(\d{3})*$/.test(n)?'an':'a'( es6fiddle.net/iiehl1ex ). Es ist 46 Bytes lang.
Ismael Miguel
2
@ScottKaye Der Code ist sehr einfach: Er prüft, ob er mit beginnt 8, ob er mit beginnt 1[18]und ob die Länge der Zahlen ist 2 * (3n). Grundsätzlich handelt es sich um Ihren gesamten Code, jedoch innerhalb eines regulären Ausdrucks.
Ismael Miguel
2

Im Ernst, 43 40 Bytes

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

Die Strategie besteht hier darin, nur die 1, 2 oder 3 höchstwertigen Stellen zu betrachten, indem die Eingabe durch den größten Wert dividiert 10^(3n)wird, der kleiner als die Eingabe ist.

Probieren Sie es online aus

Erläuterung:

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
quelle
2

Perl 6 ,  31   30 Bytes

{'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 wird [ ]in regulären Ausdrücken für Nichterfassung ( )und <[ ]>für Zeichensätze verwendet.)

Verwendungszweck:

# 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
quelle
2

PostScript, 109 Bytes

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

Der Code überprüft, ob die Nummer mit bestimmten Präfixen beginnt. Das Präfix 8wird immer geprüft ( acht , achtzig etwas , acht-hundert-und ), aber 11und 18( elf und achtzehn ) überprüft nur , wenn die Anzahl der Ziffern ist ein Vielfaches von 3 plus 2.

Wir beginnen mit einem vorläufigen Ergebnis von aund wenn ein Präfix gefunden wird, wird das Ergebnis durch ersetzt an.anchorsearchwird verwendet, um zu vermeiden, dass ein Präfix aus der Zeichenfolge extrahiert wird. Selbst wenn eine Übereinstimmung gefunden wird, werden die restlichen Präfixe überprüft. Warum 5 Byte für die verschwenden  exit? -, aber da die ursprüngliche Zeichenfolge durch ersetzt wird, werden awir mit Sicherheit keine falsch positiven Ergebnisse erhalten.

Rückgabe der a -oder anErgebnis auf dem Operandenstapel , anstatt es zu drucken, entfernen Sie den nacheilenden  =(resultierende Länge: 107 Bytes).

Testcode:

/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
sackt ab
quelle
2

PostScript (mit binären Token), 63 Bytes

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

Das sind Bytes mit dem Wert 146 (dezimal),¥ ist ein 165 und $ist ein 3. Alle anderen sind druckbare 7-Bit-ASCII-Zeichen.

Dies ist dasselbe wie meine PostScript-Version [pure ASCII], verwendet jedoch binäre Token, mit denen sich die Gesamtlänge verringern lässt. Ich poste es aus 3 Gründen separat:

  • Im Allgemeinen ist eine Implementierung, die den ASCII-Code minimiert, nicht unbedingt dieselbe wie die, die die Binärversion minimiert. Ein längerer Teil des ASCII-PostScript-Codes könnte besser komprimiert werden als ein anderer und die entsprechende Binärversion könnte kürzer sein.
  • Binärcode ist nicht überall geeignet, daher kann eine reine ASCII-Antwort auch dann bevorzugt werden, wenn sie länger dauert.
  • Es wäre nicht fair, die Länge einer reinen ASCII-PostScript-Antwort mit einer binären Codierung zu vergleichen.
sackt ab
quelle
1

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

Hier ist eine lange, aber eine einfache.

Edit: Korrigiert mit dank isaacg . Nach den Vergleichen wurden einige Leerzeichen gespeichert. Viele Bytes gespart dank Timwi , Mego , Benpop und Alissa .

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

oder für die gleiche Anzahl von Bytes.

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
quelle
Dies ist falsch in der Eingabe 843"achthundertdreiundvierzig", die sein sollte an.
Isaacg
@isaacg Du hast nicht nur Recht, sondern dies vereinfacht meinen Code immens. Vielen Dank! Es stellte sich heraus, dass ich nur acht, achttausend, acht Millionen betrachtete und Fälle wie achtundachtzighundert ignorierte.
Sherlock9
Warum (-~len(n)%3)<1statt len(n)%3==2?
Timwi
Könnte (n[:2]=="11"or n[:2]=="18")auf gekürzt werden "118".contains(n[:2])?
Timwi
Oder sogar n[:2]in"118"?
Timwi
1

Java 10, 102 Bytes

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

Probieren Sie es online aus.

Erläuterung:

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
quelle
1

Japt , 28 27 Bytes

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

Probieren Sie es online!

Ausgepackt und wie es funktioniert

'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
Bubbler
quelle
Sie können 1e3mit
Oliver
1

GNU sed -r+ BSD number, 34 Bytes

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

Zuerst konvertieren wir in englische Zahlen. Löschen Sie dann alles außer einem möglichen Anfangsbuchstaben eund setzen Sie das Präfix auf a. Dann konvertieren Sie die e(falls vorhanden) zu n. Der einzige Trick beim Golfen ist es, den optionalen zu findene in der ersten Auswechslung zuzuordnen, damit wir das Muster in der folgenden Zeile wiederverwenden können.

Demo

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
quelle
0

TeaScript , 35 Bytes

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

Probieren Sie es hier aus.

Erläuterung

               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
quelle
0

Python 2.7, 66

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

Offensichtlich nicht so kurz wie der lambdaeine.

janrn
quelle
0

05AB1E , 26 Bytes

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

Kann wahrscheinlich ein bisschen mehr golfen werden, aber es funktioniert.

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

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
quelle
0

Stax , 25 Bytes

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

Führen Sie es aus und debuggen Sie es

Ausgepackt, ungolfed und kommentiert sieht es so aus.

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"

Führen Sie dieses aus

rekursiv
quelle
0

Leerzeichen , 243 Bytes

[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]

Buchstaben S(Leerzeichen), T(Tabulator) und (Zeilenvorschub) werden Nnur als Hervorhebung hinzugefügt.
[..._some_action]nur als Erklärung hinzugefügt.

Probieren Sie es online aus (nur mit Leerzeichen, Tabulatoren und Zeilenumbrüchen).
Programm stoppt mit Fehler: Kein Exit gefunden.

Erklärung im Pseudocode:

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
quelle
0

C ++, 80 79 Bytes

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

Es stellte sich heraus, dass 4 Bytes kürzer sind, um explizit gegen 8xx und 8x zu testen, als eine andere /=10Schleife zu haben :

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

Demo

#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
quelle
Ich kenne C ++ nicht so gut, kann i/=1000es aber sein i/=1e3und kann es alles &&werden &?
Kevin Cruijssen
Es scheint in der Tat zu funktionieren: Probieren Sie es online.
Kevin Cruijssen
1
@ Kevin - Ich hatte an einem Punkt 1e3 dort; Ich habe es während des Debuggens geändert und vergessen, es zurück zu ändern. Das &&kann nicht alles sein &, denn Subtraktion liefert ganze Zahlen und keine Booleschen Werte - zB 19-11ist 8 und 19-18ist 1; siehe, das 8 && 1ist wahr, aber 8 & 1falsch. Wir könnten verwenden , &aber wir müssen sich ändern -zu !=und auch Klammern hinzuzufügen.
Toby Speight
Ah, natürlich ... &funktioniert hier tatsächlich nicht, mein Schlimmes. Übrigens, warum fügst du deiner Antwort nicht auch einen TIO-Link hinzu?
Kevin Cruijssen
-1

Perl, 71 55 49 Bytes

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

Ich wusste, dass der ternäre Operator eines Tages helfen würde ...

Lass mich das zusammenfassen.

  • $_=<> akzeptiert eine Zahl als Eingabe.
  • Der große $_=...Block setzt den Wert von, $_nachdem er verwendet wurde.
    • ...?...:...ist der ternäre Operator. Wenn die Bedingung (erstes Argument) wahr ist, gibt sie das zweite Argument zurück. Andernfalls wird der dritte zurückgegeben.
    • /^8/||(/^1[18]/&&length%3==2) prüft, ob die Zahl mit 8 beginnt oder mit 11 oder 18 beginnt (1[18] akzeptiert entweder) und eine Länge mod 3 von 2 hat.
    • Wenn das stimmt, $_steht auf an. Ansonsten ist es auf eingestellt a.
  • Anschließend wird der Inhalt von $_(entweder aoder an) mit ausgedruckt say.

Änderungen

  • 16 Bytes dank msh210 gespart.
  • 6 Bytes gespart, indem Parens entfernt und Standardeinstellungen verwendet wurden.
ASCIIThenANSI
quelle
$_=<>;$_=(/^8/)||/^1[18]/&&length($_)%3==1?'an':'a';sayspart ein paar Bytes. (Obwohl die zu vergleichende Zahl davon abhängt, was Ihr Zeilenvorschubzeichen ist, ändert dies nichts an der Anzahl der Bytes.)
msh210
@ msh210 Das sind anscheinend nur 55 Bytes, was bedeutet, dass 16 Bytes eingespart werden. Ich werde das hinzufügen. Danke!
ASCIIThenANSI
Bitte. Oh, und du kannst die ersten Parens fallen lassen (ich nehme an. Ich habe nicht getestet). Ich würde denken , dass Sie auch ändern könnte length($_)zu length(oder die Pars zumindest fallen) , aber das funktioniert nicht aus irgendeinem Grund für mich.
msh210
@ msh210 Ja, du kannst die parens löschen und ($_)bekommen $_=<>;$_=/^8/||/^1[18]/&&length%3==1?'an':'a';say, das sind nur 49 Bytes.
ASCIIThenANSI
Sie können mit ein paar Bytes speichern -pstatt $_=<>und say, y///cstatt length, und Ablegen der Anführungszeichen aund an: perl -pe'$_=/^8/||/^1[18]/&&y///c%3==2?an:a'(34 Bytes + 1 für -p). Beachten Sie, dass die Eingabe nicht mit einer Neuen - Zeile enden: echo -n 11 | perl -pe'...'. Dies behebt auch einen Fehler: length%3==2Wird analysiert als length(%3)==2, nicht als length($_)%3==2, und gibt immer false zurück.
ThisSuitIsBlackNot
-1

Pyth, 29 31

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

Kehrt die Zeichenfolge um, teilt sie in Dreierabschnitte auf, kehrt sie erneut um und wählt dann die entsprechende Endung aus.

Elch
quelle
5
Dies ist falsch in der Eingabe 111- es gibtan
isaacg
Du hast recht. Fest.
Elch