Bạn đang trên chuỗi 8 ngày!


82

Duolingo, ứng dụng học ngôn ngữ, có rất nhiều thứ phù hợp với nó, nhưng có một vấn đề lớn khiến tôi phát điên. Nó cho tôi biết tôi đã sử dụng ứng dụng này bao nhiêu ngày liên tục như một tin nhắn như Bạn đang trên chuỗi 7 ngày! Đặt dấu gạch nối sang một bên và liệu số đó có nên được đánh vần hay không, điều này hoạt động tốt đối với hầu hết các số, nhưng sai lầm không thể chối cãi khi nó nói Bạn đang ở trong chuỗi 8 ngày! Tôi không sử dụng nó để học tiếng Anh nhưng đây vẫn là hành vi đáng tiếc cho một ứng dụng ngôn ngữ.

Bạn sẽ giúp đỡ nhóm Duolingo bằng cách viết một chương trình hoặc chức năng hoàn chỉnh để tìm hiểu xem một số đã cho có nên đi trước một hoặc một . Một số được bắt đầu bằng một nếu phát âm của nó trong tiếng Anh nói bắt đầu bằng một phụ âm hoặc âm bán âm , và trước một phát âm của nó bắt đầu bằng một nguyên âm. Do đó, những con số duy nhất đứng trước một là những người có phát âm bắt đầu bằng tám , mười một , mười tám hoặc tám mươi .

Có lẽ nhóm phát triển Duolingo đã để lại lỗi này vì họ đã hết dung lượng để có thêm mã nguồn trong ứng dụng, vì vậy bạn cần phải tạo mã này càng ngắn càng tốt với hy vọng họ có thể nén nó.

Mã của bạn phải lấy một số nguyên từ 0 đến 2.147.483.647 và đầu ra ahoặc an. Một dòng mới theo dõi là tùy chọn. Đối với mục đích của thử thách này, năm 1863 được đọc là một nghìn tám trăm sáu mươi ba chứ không phải mười tám trăm sáu mươi ba .

Các trường hợp thử nghiệm:

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

31
Đây có phải được chứng thực bởi Duolingo? Nếu không, bạn nên yêu cầu họ trả tiền cho chúng tôi để cải thiện ngôn ngữ trên một trang web học ngôn ngữ.
Arc676

10
1100 (an) mười một trăm hay (a) một nghìn lẻ một trăm ?
user3819867

11
Bilbo sẽ không đồng ý với một số trường hợp thử nghiệm của bạn. :)
Martin Ender

9
@Zaibis: "một" ở đây được phát âm giống như "wun", có âm thanh phụ âm. Do đó, " một nghìn một trăm ngày".
El'endia Starman

31
Có lẽ họ đã để lại lỗi này vì họ nghĩ rằng không ai sẽ đạt được chuỗi 8 ngày.
PNDA

Câu trả lời:


14

Bình thường, 23 byte

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

Điều này chọn có bao nhiêu chữ cái để cắt đi phần cuối của "an"bằng cách kiểm tra xem chữ cái đầu tiên có phải là một 8chữ số không và chữ số đầu tiên của số khi được xem xét trong cơ sở 1000 không phải là 11 hay 18. Boolean kết quả là số lượng ký tự để cắt kết thúc.


3
Rất sáng tạo. Ngoài ra, đáng sợ.
Hellreaver

29

Python 2, 60 byte

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

Một chức năng ẩn danh. Thêm một nnếu:

  • Chữ số đầu tiên là 8
  • Hai chữ số đầu tiên là 11 hoặc 18 và độ dài là 2 modulo 3.

Tôi biết đây là một câu hỏi siêu cũ, nhưng tôi nghĩ `` n> = '8' `` tiết kiệm ba byte.
Lynn

@Lynn Mặc dù vậy sẽ không gây rối?
xnor

Ồ dĩ nhiên rồi! Tôi đã bị đánh lừa bởi bộ thử nghiệm :)
Lynn

12

GNU Sed, 32

Điểm bao gồm +1 cho -Etùy chọn để sed.

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

Hãy thử trực tuyến.

  • Xóa các nhóm gồm 3 chữ số từ cuối mỗi số cho đến khi chỉ còn 1 đến 3 chữ số
  • Khớp bất kỳ số nào bắt đầu bằng 8 hoặc chính xác 11 hoặc 18 và đổi thành an
  • Thay đổi tất cả các số khác thành a

Cảm ơn @ MartinBüttner vì cách tiếp cận võng mạc của anh ấy đã tiết kiệm được 10 byte.


11

Shell + bsd-games, 30

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

Đầu vào đọc từ STDIN.

numberchuyển đổi một chuỗi thập phân thành các từ. Đó là một vấn đề đơn giản để quyết định xem kết quả có bắt đầu hay không e.


2
+1 khi sử dụng các trò chơi bsd, tôi thực sự không nghĩ rằng chúng sẽ hữu ích :)
ASCIIThenANSI

@ASCIIThenANSI yep, bsd-games rất hữu ích ở đâyđó :)
Chấn thương kỹ thuật số

9

Võng mạc , 27 byte

Điều này không khác lắm với câu trả lời Retina của DigitalTrauma, nhưng họ khăng khăng tôi tự đăng bài này.

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

Hãy thử trực tuyến.

Regex đầu tiên thay thế tất cả các số có liên quan bằng anvà thứ hai thay thế tất cả các số còn lại bằng a. Điều này hoạt động cho cùng một byte:

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

1
+1 đây gần như là mức độ lạm dụng regex tương tự như thử nghiệm nguyên thủy :)
con mèo

1
Và điều tốt là, Duolingo thực sự được viết bằng Retina nên sẽ rất dễ dàng để tích hợp điều này. Hay chờ đợi, ngôn ngữ là gì?
đã ngừng quay ngược chiều

1
@ceasetoturncountclockwis Tôi được cho biết nó thực sự được viết bằng Hexagony, nhưng họ đã viết một bộ chuyển mã Retina-to-Hexagony, vì vậy đây không phải là vấn đề.
Martin Ender

6

C ++, 101

Đây là thách thức của tôi, vì vậy đây không có nghĩa là một câu trả lời cạnh tranh. Chỉ muốn xem tôi có thể lấy nó trong C ++ ngắn đến mức nào. Các phép toán chuỗi quá dài dòng vì vậy điều này được thực hiện với toán học. Tôi cảm thấy như phải có một cách để làm cho tình trạng đó nhỏ hơn nhưng tôi không thể tìm ra nó.

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";}

4

Toán học, 53 byte

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

Một giải pháp sử dụng xử lý chuỗi sẽ thực sự dài hơn.


3

PostScript, 119 113 ký tự

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

Với mã kiểm tra:

/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

3

JavaScript (ES6) 70 61 46 38 byte

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

Wiki cộng đồng vì giải pháp hiện tại quá khác so với bản gốc của tôi. Cảm ơn mọi người!

Bản trình diễn: http://www.es6fiddle.net/iio40yep/


1
Điều đó có ý nghĩa. Cảm ơn vì đã giải thích.
Daniel F

1
@Pavlo Rất hay, tôi quên mất những biểu hiện đơn lẻ sau khi phát hiện ra evalmánh khóe! Tôi biết rằng cũng phải có một biểu hiện thường xuyên tốt hơn, nhưng tôi không thể tìm ra bất cứ điều gì ngắn hơn. Cảm ơn bạn!
Scott

1
@Pavlo Ngọt ngào, cập nhật lại! Học nhiều, cảm ơn bạn rất nhiều :)
Scott

2
ĐÔ LA! Quên cạo 2 byte! Đây là cái cuối cùng: n=>/^8|^(?=1[18])..(\d{3})*$/.test(n)?'an':'a'( es6fiddle.net/iiehl1ex ). Nó dài 46 byte.
Ismael Miguel

2
@ScottKaye Mã rất đơn giản: Nó kiểm tra nếu nó bắt đầu bằng 8, nếu nó bắt đầu bằng 1[18]và nếu độ dài của các số là 2 * (3n). Về cơ bản, nó là toàn bộ mã của bạn, nhưng trong một biểu thức chính quy.
Ismael Miguel

2

Nghiêm túc, 43 40 byte

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

Chiến lược ở đây là chỉ nhìn vào 1, 2 hoặc 3 chữ số có nghĩa nhất, bằng cách chia số nguyên cho đầu vào cho giá trị lớn nhất 10^(3n)nhỏ hơn đầu vào.

Dùng thử trực tuyến

Giải trình:

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


2

Perl 6 ,  31   30 byte

{'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 sử dụng [ ]trong regexes để không bắt ( )và sử dụng <[ ]>cho các bộ ký tự)

Sử dụng:

# 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)

2

PostScript, 109 byte

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

Mã xác minh nếu số bắt đầu với các tiền tố nhất định. Tiền tố 8luôn được kiểm tra ( tám , tám mươi , tám trăm và ), nhưng 1118( mười mộtmười tám ) chỉ được kiểm tra khi số chữ số là bội của 3 cộng 2.

Chúng tôi bắt đầu với một kết quả dự kiến avà khi tìm thấy tiền tố, kết quả sẽ được thay thế bằng an. anchorsearchđược sử dụng để tránh trích xuất một tiền tố từ chuỗi. Ngay cả khi tìm thấy kết quả khớp, chúng tôi vẫn tiếp tục xác minh phần còn lại của các tiền tố - tại sao lại lãng phí 5 byte cho  exit? -, nhưng vì chuỗi gốc được thay thế bằng achúng tôi chắc chắn không nhận được bất kỳ thông báo sai nào.

Để trả về kết quả a-hoặc antrên ngăn toán hạng thay vì in nó, hãy xóa dấu vết  =(chiều dài kết quả: 107 byte).

Mã kiểm tra:

/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

2

PostScript (với mã thông báo nhị phân), 63 byte

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

Các byte có giá trị 146 (thập phân), ¥là 165 và $là 3. Tất cả các byte khác đều có thể in các ký tự ASCII 7 bit.

Đây giống như phiên bản PostScript [thuần ASCII] của tôi, nhưng sử dụng mã thông báo nhị phân trong đó điều này giúp giảm tổng chiều dài. Tôi đăng nó riêng vì 3 lý do:

  • Trong trường hợp chung, việc triển khai tối thiểu hóa mã ASCII không nhất thiết giống như phiên bản thu nhỏ phiên bản nhị phân. Một số đoạn mã ASCII PostScript dài hơn có thể nén tốt hơn mã khác và phiên bản nhị phân tương ứng của nó ngắn hơn.
  • Mã nhị phân không phù hợp ở mọi nơi, vì vậy câu trả lời ASCII thuần túy có thể được ưa thích ngay cả khi lâu hơn.
  • Sẽ không công bằng khi so sánh độ dài của câu trả lời ASCII PostScript thuần túy với câu trả lời bằng cách sử dụng mã hóa nhị phân.

1

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

Đây là một cái dài, nhưng một cái đơn giản.

Chỉnh sửa: Đã sửa với lời cảm ơn đến isaacg . Lưu một số khoảng trắng sau khi so sánh. Nhiều byte được lưu nhờ Timwi , Mego , benpopAlissa .

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

hoặc cho cùng một số byte.

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

Ung dung:

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

Điều này là không chính xác trên đầu vào 843, "tám trăm bốn mươi ba", nên được an.
isaacg

@isaacg Không chỉ bạn đúng mà còn đơn giản hóa mã của tôi vô cùng. Cảm ơn! Hóa ra tôi chỉ nhìn vào tám, tám nghìn, tám triệu, trong khi bỏ qua các trường hợp như tám mươi tám trăm.
Sherlock9

Tại sao (-~len(n)%3)<1thay vì len(n)%3==2?
Timwi

(n[:2]=="11"or n[:2]=="18")thể rút ngắn thành "118".contains(n[:2])?
Timwi

Hay thậm chí n[:2]in"118"?
Timwi

1

Java 10, 102 byte

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

Hãy thử trực tuyến.

Giải trình:

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"

1

Japt , 28 27 byte

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

Hãy thử trực tuyến!

Giải nén & Cách thức hoạt động

'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

Bạn có thể thay thế 1e3bằng
Oliver

1

GNU sed -r+ BSD number, 34 byte

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

Đầu tiên chúng tôi chuyển đổi sang số tiếng Anh. Sau đó xóa mọi thứ trừ một chữ cái đầu tiên có thể evà tiền tố với a. Sau đó chuyển đổi e(nếu có) thành n. Bí quyết chơi gôn duy nhất là khớp với tùy chọn etrong lần thay thế đầu tiên, vì vậy chúng ta có thể sử dụng lại mẫu trong dòng sau.

Bản giới thiệu

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

0

TeaScript , 35 byte

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

Hãy thử nó ở đây.

Giải trình

               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

0

Con trăn 2.7, 66

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

Rõ ràng không ngắn như lambdacái.


0

05AB1E , 26 byte

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

Có thể chơi golf nhiều hơn một chút, nhưng nó hoạt động.

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

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"


0

Stax , 25 byte

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

Chạy và gỡ lỗi nó

Giải nén, không ghi chú và nhận xét, nó trông như thế này.

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"

Chạy cái này


0

Khoảng trắng , 243 byte

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

Chữ cái S(dấu cách), T(tab) và N(dòng mới) được thêm vào dưới dạng chỉ tô sáng.
[..._some_action]chỉ thêm vào giải thích.

Hãy thử trực tuyến (chỉ với không gian thô, tab và dòng mới).
Chương trình dừng với một lỗi: Không tìm thấy lối ra.

Giải thích bằng mã giả:

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

0

C ++, 80 79 byte

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

Hóa ra ngắn hơn 4 byte để kiểm tra rõ ràng so với 8xx và 8x so với việc có một /=10vòng lặp khác , như thế này:

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

Bản giới thiệu

#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

Tôi không biết C ++ quá rõ, nhưng có i/=1000thể i/=1e3, và tất cả có thể &&trở thành &?
Kevin Cruijssen

Nó thực sự có vẻ hiệu quả: Hãy thử trực tuyến.
Kevin Cruijssen

1
@Kevin - Tôi đã làm một lúc có 1e3 ở đó; Tôi đã thay đổi nó trong quá trình gỡ lỗi và quên thay đổi lại. Tất &&cả đều không thể &, bởi vì phép trừ mang lại số nguyên chứ không phải booleans - ví dụ 19-11là 8 và 19-18là 1; thấy đó 8 && 1là đúng, nhưng 8 & 1là sai Chúng ta có thể sử dụng &nhưng chúng tôi cần phải thay đổi -để !=và cũng thêm dấu ngoặc đơn.
Toby Speight

Tất nhiên rồi .. &thực sự không hoạt động ở đây, xấu của tôi. Btw, tại sao bạn không thêm một liên kết TIO vào câu trả lời của bạn?
Kevin Cruijssen


-1

Perl, 71 55 49 byte

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

Tôi biết người điều hành chim nhạn sẽ giúp một ngày ...

Hãy để tôi phá vỡ điều này.

  • $_=<> chấp nhận một số làm đầu vào.
  • Khối lớn $_=...sẽ đặt giá trị $_sau khi sử dụng.
    • ...?...:...là toán tử ternary. Nếu điều kiện (đối số thứ nhất) là đúng, nó sẽ trả về đối số thứ hai. Nếu không, nó trả về cái thứ ba.
    • /^8/||(/^1[18]/&&length%3==2)kiểm tra xem số bắt đầu bằng 8 hay bắt đầu bằng 11 hoặc 18 ( 1[18]chấp nhận một trong hai) và có độ dài mod 3 là 2.
    • Nếu đó là sự thật, $_được đặt thành an. Nếu không, nó được đặt thành a.
  • Sau đó nó in ra nội dung của $_(hoặc ahoặc an) với say.

Thay đổi

  • Đã lưu 16 byte nhờ msh210.
  • Đã lưu 6 byte bằng cách xóa parens và sử dụng mặc định.

$_=<>;$_=(/^8/)||/^1[18]/&&length($_)%3==1?'an':'a';saytiết kiệm một vài byte. (Mặc dù số lượng để so sánh với nó phụ thuộc vào ký tự dòng mới của bạn là gì, nhưng điều đó không thay đổi số byte.)
msh210

@ msh210 Có vẻ như chỉ có 55 byte nghĩa là nó tiết kiệm được 16 byte. Tôi sẽ thêm nó vào. Cảm ơn!
ASCIIThenANSI

Không có gì. Ồ, và bạn có thể bỏ các parens đầu tiên (tôi giả sử. Tôi chưa thử nghiệm). Tôi nghĩ rằng bạn cũng có thể thay đổi length($_)thành length(hoặc ít nhất là bỏ parens) nhưng vì một số lý do không hiệu quả với tôi.
msh210

@ msh210 Yep, bạn có thể thả parens và ($_)để lấy $_=<>;$_=/^8/||/^1[18]/&&length%3==1?'an':'a';say, chỉ có 49 byte.
ASCIIThenANSI

Bạn có thể lưu một số byte bằng cách sử dụng -pthay vì $_=<>say, y///cthay vì lengthvà bỏ các dấu ngoặc kép xung quanh aan: perl -pe'$_=/^8/||/^1[18]/&&y///c%3==2?an:a'(34 byte + 1 cho -p). Lưu ý rằng đầu vào không thể kết thúc bằng một dòng mới : echo -n 11 | perl -pe'...'. Điều này cũng sửa một lỗi: length%3==2được phân tích cú pháp length(%3)==2, không phải là length($_)%3==2, vì vậy nó luôn trả về false.
ThisSuitIsBlackNot

-1

Bình thường, 29 31

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

Đảo ngược chuỗi, chia chuỗi thành ba phần, đảo ngược lại chuỗi, sau đó chọn kết thúc thích hợp.


5
Điều này là sai về đầu vào 111- nó mang lạian
isaacg

Bạn đúng. Đã sửa.
Moose
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.