Masz 8-dniową passę!

82

Duolingo, aplikacja do nauki języków, ma wiele rzeczy do zrobienia, ale jest jeden poważny problem, który doprowadza mnie do szału. Mówi mi, ile dni z rzędu korzystałem z aplikacji z komunikatem „ Jesteś w 7-dniowej serii”! Pomijając dzielenie wyrazów i to, czy należy przeliterować liczbę, działa to dobrze w przypadku większości liczb, ale jest bezsprzecznie błędne, gdy mówi, że masz 8-dniową passę! Nie używam go do nauki angielskiego, ale nadal jest to niefortunne zachowanie w przypadku aplikacji językowej.

Pomożesz zespołowi Duolingo, pisząc kompletny program lub funkcję, która określa, czy dana liczba powinna być poprzedzona znakiem a lub an . Liczba jest poprzedzona znakiem „ if” w mówionym języku angielskim, który rozpoczyna się od dźwięku spółgłoskowego lub półpełkowego , a poprzedzona jest znakiem „if”, który rozpoczyna się od dźwięku samogłoski. Zatem jedyne numery poprzedzone to te, których wymowa zaczyna się osiem , jedenaście , osiemnaście , czy osiemdziesięciu .

Prawdopodobnie zespół deweloperów Duolingo zostawił ten błąd, ponieważ zabrakło miejsca na więcej kodu źródłowego w aplikacji, więc musisz go skrócić tak krótko, jak to możliwe, w nadziei, że mogą go wcisnąć.

Twój kod musi przyjmować liczbę całkowitą od 0 do 2 147 483 647 i dane wyjściowe alub an. Końcowy znak nowej linii jest opcjonalny. Dla celów tego wyzwania rok 1863 jest odczytywany jako tysiąc osiemset sześćdziesiąt trzy , a nie osiemset sześćdziesiąt trzy .

Przypadki testowe:

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
Łukasz
źródło
31
Czy jest to zatwierdzone przez Duolingo? Jeśli nie, należy poprosić ich o zapłacenie nam za ulepszenie języka na stronie do nauki języków.
Arc676,
10
Czy 1100 (an) tysiące sto albo (a) jeden tysięcy sto ?
user3819867,
11
Bilbo nie zgodziłby się z niektórymi z twoich przypadków testowych. :)
Martin Ender,
9
@Zaibis: „jeden” jest tutaj wymawiany jak „wun”, który ma dźwięk spółgłoski. Stąd „ 1 tysięcy sto dzień smuga”.
El'endia Starman,
31
Prawdopodobnie zostawili ten błąd, ponieważ sądzili, że nikt nie osiągnie 8-dniowej serii.
PNDA

Odpowiedzi:

14

Pyth, 23 bajty

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

Wybiera liczbę liter do odcięcia na końcu "an", sprawdzając, czy pierwsza litera nie jest 8cyfrą, i czy pierwsza cyfra liczby rozpatrywana w bazie 1000 nie jest ani 11, ani 18. Wynikowa wartość logiczna to liczba znaków do wycięcia koniec.

isaacg
źródło
3
Bardzo kreatywne. Przerażające.
Hellreaver,
29

Python 2, 60 bajtów

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

Anonimowa funkcja. Dodaje njeśli:

  • Pierwsza cyfra to 8
  • Pierwsze dwie cyfry to 11 lub 18, a długość to 2 modulo 3.
xnor
źródło
Wiem, że to bardzo stare pytanie, ale myślę, że `` n> = '8' '`` oszczędza trzy bajty.
Lynn
@ Lynn Czy to jednak nie zepsuje dziewiątek?
xnor
Och, oczywiście! Oszukiwał mnie zestaw testowy :)
Lynn
12

GNU Sed, 32

Wynik obejmuje +1 za -Eopcję sed.

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

Wypróbuj online.

  • Usuń grupy 3 cyfr z końca każdego numeru, aż pozostanie tylko 1 do 3 cyfr
  • Dopasuj dowolną liczbę, zaczynając od 8 lub dokładnie 11 lub 18 i zmień na an
  • Zmień wszystkie inne liczby na a

Dzięki @ MartinBüttner za jego podejście do siatkówki, które pozwoliło zaoszczędzić 10 bajtów.

Cyfrowa trauma
źródło
11

Shell + bsd-games, 30

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

Wejście odczytane ze STDIN.

numberkonwertuje ciąg dziesiętny na słowa. Łatwo jest zatem zdecydować, czy wynik zaczyna się od tego, czy nie e.

Cyfrowa trauma
źródło
2
+1 za korzystanie z gier bsd, tak naprawdę nie sądziłem, że kiedykolwiek się przydadzą :)
ASCIIThenANSI,
@ASCIIThenANSI tak, bsd-gry są przydatne tu i tam :)
Digital Trauma
9

Siatkówka , 27 bajtów

Nie różni się to bardzo od odpowiedzi Retina od DigitalTrauma, ale nalegali, żebym to opublikował.

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

Wypróbuj online.

Pierwszy regex zastępuje wszystkie odpowiednie liczby an, a drugi zastępuje wszystkie pozostałe liczby a. Działa to dla tych samych bajtów:

^8.*|^1[18](...)*$
n
^\d*
a
Martin Ender
źródło
1
+1 to prawie taki sam poziom nadużywania wyrażenia regularnego jak testowanie pierwotności :)
kot
1
Dobrą rzeczą jest to, że Duolingo jest napisane w Retinie, więc integracja tego powinna być prosta. Lub poczekaj, jaki to był język?
przestał się obracać przeciwnie do zegara
1
@ceasedtoturncounterclockwis Powiedziano mi, że tak naprawdę jest napisane w Hexagony, ale napisali transpilator Retina-to-Hexagony, więc nie powinno to stanowić problemu.
Martin Ender,
6

C ++, 101

To jest moje wyzwanie, więc nie jest to konkurencyjna odpowiedź. Chciałem tylko zobaczyć, jak krótko mogę to zrobić w C ++. Operacje na łańcuchach są zbyt szczegółowe, więc odbywa się to za pomocą matematyki. Wydaje mi się, że musi istnieć sposób na zmniejszenie tego stanu, ale nie jestem w stanie tego rozgryźć.

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";}
Łukasz
źródło
4

Mathematica, 53 bajty

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

Rozwiązanie wykorzystujące przetwarzanie ciągów byłoby w rzeczywistości dłuższe.

LegionMammal978
źródło
3

PostScript, 119 113 znaków

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

Z kodem testowym:

/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
źródło
3

JavaScript (ES6) 70 61 46 38 bajtów

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

Społeczność wiki, ponieważ obecne rozwiązanie jest tak różne od mojego oryginalnego. Dziękuję wszystkim!

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

Scott Kaye
źródło
1
to ma sens. Dziękuję za wyjaśnienie.
Daniel F,
1
@Pavlo Bardzo miło, zapomniałem o pojedynczych wyrażeniach po odkryciu evalsztuczki! Wiedziałem, że musi być też lepszy wyraz regularny, ale nie mogłem znaleźć niczego, co byłoby krótsze. Dziękuję Ci!
Scott,
1
@Pavlo Sweet, zaktualizowane ponownie! Dużo się uczę, dziękuję bardzo :)
Scott
2
URGH! Zapomniałem ogolić 2 bajty! Oto ostatni: n=>/^8|^(?=1[18])..(\d{3})*$/.test(n)?'an':'a'( es6fiddle.net/iiehl1ex ). Ma długość 46 bajtów.
Ismael Miguel,
2
@ScottKaye Kod jest bardzo prosty: sprawdza, czy zaczyna się od 8, czy zaczyna się od 1[18]i czy długość liczb jest 2 * (3n). Zasadniczo jest to cały kod, ale w wyrażeniu regularnym.
Ismael Miguel,
2

Poważnie, 43 40 bajtów

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

Strategia polega na tym, aby spojrzeć tylko na 1, 2 lub 3 najbardziej znaczące cyfry, dzieląc liczbę całkowitą przez największą wartość, 10^(3n)która jest mniejsza niż wartość wejściowa.

Wypróbuj online

Wyjaśnienie:

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
źródło
2

Perl 6 ,  31   30 bajtów

{'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 używa [ ]w wyrażeniach regularnych do przechwytywania ( )i używa <[ ]>do zestawów znaków)

Stosowanie:

# 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
źródło
2

PostScript, 109 bajtów

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

Kod weryfikuje, czy numer zaczyna się od pewnych prefiksów. Prefiks 8jest zawsze sprawdzany ( osiem , osiemdziesiąt coś , osiemset setek i ), ale 11i 18( jedenaście i osiemnaście ) są sprawdzane tylko wtedy, gdy liczba cyfr jest wielokrotnością 3 plus 2.

Zaczynamy od wstępnego wyniku, aa gdy zostanie znaleziony prefiks, wynik zostanie zastąpiony przez an. anchorsearchsłuży do unikania wydobywania przedrostka z łańcucha. Nawet jeśli znaleziono dopasowanie, kontynuujemy weryfikację pozostałych prefiksów - po co marnować 5 bajtów  exit? -, ale ponieważ oryginalny ciąg zostanie zastąpiony przez, z apewnością nie otrzymamy żadnych fałszywych trafień.

Aby zwrócić wynik a-lub- anna stosie operandów zamiast go drukować, usuń końcowy  =(wynikowa długość: 107 bajtów).

Kod testowy:

/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
ugięcia
źródło
2

PostScript (z tokenami binarnymi), 63 bajty

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

to bajty o wartości 146 (dziesiętne), ¥165 i $3. Wszystkie pozostałe są drukowalnymi 7-bitowymi znakami ASCII.

Jest to to samo, co moja wersja PostScript [czysta ASCII], ale używa tokenów binarnych, co pomaga zmniejszyć całkowitą długość. Wysyłam go osobno z 3 powodów:

  • W ogólnym przypadku implementacja minimalizująca kod ASCII niekoniecznie jest taka sama jak implementacja minimalizująca wersję binarną. Niektóre dłuższe fragmenty kodu PostScript ASCII mogą kompresować się lepiej niż inne, a odpowiadająca im wersja binarna może być krótsza.
  • Kod binarny nie jest odpowiedni wszędzie, więc czysta odpowiedź ASCII może być preferowana, nawet jeśli jest dłuższa.
  • Porównywanie długości czystej odpowiedzi ASCII PostScript z odpowiedzią wykorzystującą kodowanie binarne byłoby niesprawiedliwe.
ugięcia
źródło
1

Python 3, 110 93 91 76 74 70 65 64 bajtów

Oto długi, ale prosty.

Edycja: poprawione dzięki isaacg . Zapisano trochę białych znaków po porównaniach. Wiele bajtów zapisywane dzięki Timwi , Mego , benpop i Alissa .

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

lub dla tej samej liczby bajtów.

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

Nie golfowany:

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
źródło
Jest to niepoprawne na wejściu 843„osiemset czterdzieści trzy”, które powinno być an.
isaacg,
@isaacg Nie tylko masz rację, ale to ogromnie upraszcza mój kod. Dzięki! Okazuje się, że patrzyłem tylko na osiem, osiem tysięcy, osiem milionów, ignorując przypadki takie jak osiemdziesiąt i osiemset.
Sherlock9,
Dlaczego (-~len(n)%3)<1zamiast len(n)%3==2?
Timwi,
Można (n[:2]=="11"or n[:2]=="18")to skrócić "118".contains(n[:2])?
Timwi,
A może nawet n[:2]in"118"?
Timwi,
1

Java 10, 102 bajty

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

Wypróbuj online.

Wyjaśnienie:

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
źródło
1

Japt , 28 27 bajtów

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

Wypróbuj online!

Rozpakowane i jak to działa

'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
źródło
Można wymienić 1e3z
Oliver
1

GNU sed -r+ BSD number, 34 bajty

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

Najpierw przekonwertujemy na numer angielski. Następnie usunąć wszystko z wyjątkiem ewentualnego początkowego e, a prefiks ze a. Następnie przekonwertuj e(jeśli jest obecny) na n. Jedyną sztuczką w golfa jest dopasowanie opcjonalnego ew pierwszej zmianie, dzięki czemu możemy ponownie użyć wzorca w następnej linii.

Próbny

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
źródło
0

TeaScript , 35 bajtów

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

Wypróbuj tutaj.

Wyjaśnienie

               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
źródło
0

Python 2.7, 66

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

Oczywiście nie tak krótki jak ten lambda.

janrn
źródło
0

05AB1E , 26 bajtów

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

Prawdopodobnie można grać w golfa jeszcze trochę, ale działa.

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

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
źródło
0

Stax , 25 bajtów

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

Uruchom i debuguj

Rozpakowane, niepolowane i skomentowane, wygląda to tak.

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"

Uruchom ten

rekurencyjny
źródło
0

Biała spacja , 243 bajty

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

Litery S(spacja), T(tab) i N(nowa linia) dodane tylko jako wyróżnienia.
[..._some_action]dodano tylko jako wyjaśnienie.

Wypróbuj online (tylko z surowymi spacjami, tabulatorami i nowymi wierszami).
Program zatrzymuje się z błędem: nie znaleziono wyjścia.

Objaśnienie w pseudo-kodzie:

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
źródło
0

C ++, 80 79 bajtów

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

Okazało się, że 4 bajty są krótsze, aby jawnie przetestować pod kątem 8xx i 8x niż mieć inną /=10pętlę, taką jak ta:

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

Próbny

#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
źródło
Nie znam zbyt dobrze C ++, ale mogę i/=1000być i/=1e3i może &&stać się wszystkim &?
Kevin Cruijssen
Rzeczywiście wydaje się, że działa: Wypróbuj online.
Kevin Cruijssen
1
@Kevin - w pewnym momencie miałem tam 1e3; Zmieniłem go podczas debugowania i zapomniałem go zmienić z powrotem. Nie &&może być wszystko &, ponieważ odejmowanie daje liczby całkowite, a nie boolean - np. Wynosi 19-118, a 19-18wynosi 1; widzę, że 8 && 1to prawda, ale 8 & 1fałsz. Możemy użyć &, ale że musimy zmienić -się !=, a także dodać nawiasów.
Toby Speight
Ach, oczywiście .. &naprawdę nie działa tutaj, mój zły. Przy okazji, dlaczego nie dodasz również linku TIO do swojej odpowiedzi?
Kevin Cruijssen
-1

Perl, 71 55 49 bajtów

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

Wiedziałem, że trójskładnik pomoże kiedyś ...

Pozwól mi to zepsuć.

  • $_=<> akceptuje liczbę jako dane wejściowe.
  • Duży $_=...blok ustawi wartość $_po użyciu.
    • ...?...:...jest operatorem trójskładnikowym. Jeśli warunek (pierwszy argument) jest prawdziwy, zwraca drugi argument. W przeciwnym razie zwraca trzeci.
    • /^8/||(/^1[18]/&&length%3==2)sprawdza, czy liczba zaczyna się od 8 lub od 11 lub 18 ( 1[18]akceptuje albo) i ma mod długości 3 2.
    • Jeśli to prawda, $_jest ustawione na an. W przeciwnym razie jest ustawiony na a.
  • Następnie drukuje zawartość $_(albo aalbo an) przy pomocy say.

Zmiany

  • Zaoszczędzono 16 bajtów dzięki msh210.
  • Zaoszczędzono 6 bajtów, usuwając pareny i używając ustawień domyślnych.
ASCIIThenANSI
źródło
$_=<>;$_=(/^8/)||/^1[18]/&&length($_)%3==1?'an':'a';sayoszczędza kilka bajtów. (Chociaż liczba do porównania zależy od tego, jaki jest twój znak nowej linii, ale to nie zmienia liczby bajtów.)
msh210
@ msh210 Wygląda na to, że to tylko 55 bajtów, co oznacza, że ​​zapisuje 16 bajtów. Dodam to. Dzięki!
ASCIIThenANSI,
Nie ma za co. Aha, i możesz upuścić pierwsze pareny (zakładam. Nie testowałem). Sądzę, że możesz również zmienić length($_)na length(lub przynajmniej upuścić pareny), ale z jakiegoś powodu to nie działa.
msh210,
@ msh210 Tak, możesz upuścić pareny i ($_)dostać $_=<>;$_=/^8/||/^1[18]/&&length%3==1?'an':'a';say, który ma tylko 49 bajtów.
ASCIIThenANSI,
Można zaoszczędzić kilka bajtów używając -pzamiast $_=<>i say, y///czamiast length, i upuszczając w cudzysłowie ai an: perl -pe'$_=/^8/||/^1[18]/&&y///c%3==2?an:a'(34 bajtów + 1 o -p). Należy pamiętać, że wejście nie może kończyć się znakiem nowej linii: echo -n 11 | perl -pe'...'. To także naprawia błąd: length%3==2jest analizowany jako length(%3)==2, a nie jako length($_)%3==2, więc zawsze zwraca false.
ThisSuitIsBlackNot
-1

Pyth, 29 31

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

Odwraca ciąg, dzieli go na trzyosobowe sekcje, odwraca go ponownie, a następnie wybiera odpowiednie zakończenie.

Łoś
źródło
5
Jest to błędne na wejściu 111- dajean
isaacg
Masz rację. Naprawiony.
Łoś