คุณอยู่ในช่วง 8 วัน!


82

Duolingo แอปเรียนรู้ภาษามีหลายสิ่งหลายอย่างที่เป็นไปได้ แต่มีประเด็นสำคัญอย่างหนึ่งที่ทำให้ฉันบ้า มันบอกฉันว่าฉันใช้แอพนี้กี่วันติดต่อกันโดยมีข้อความเหมือนคุณอยู่ในช่วง 7 วัน! หลีกเลี่ยงการใส่ยัติภังค์และควรจะสะกดหมายเลขหรือไม่ซึ่งสามารถใช้งานได้กับตัวเลขส่วนใหญ่ แต่ก็ผิดถ้าคุณบอกว่าคุณอยู่ในช่วง 8 วัน! ฉันไม่ได้ใช้มันเพื่อเรียนรู้ภาษาอังกฤษ แต่นี่ก็เป็นพฤติกรรมที่โชคร้ายสำหรับแอปภาษา

คุณจะช่วยให้ออกจากทีม Duolingo โดยการเขียนโปรแกรมที่สมบูรณ์หรือฟังก์ชั่นที่ตัวเลขออกมาไม่ว่าจะเป็นจำนวนที่กำหนดควรจะนำหน้าด้วยหรือ จำนวนจะนำหน้าด้วยถ้าออกเสียงในการพูดภาษาอังกฤษเริ่มต้นด้วยเสียงพยัญชนะหรือเสียงกึ่งสระและนำหน้าด้วยถ้าออกเสียงเริ่มต้นด้วยเสียงสระ ดังนั้นเฉพาะตัวเลขนำหน้าด้วยคือบรรดาผู้ที่เริ่มต้นด้วยการออกเสียงแปด , สิบเอ็ด , สิบแปดหรือสิบ

สันนิษฐานว่าทีมงาน Duolingo dev ออกจากจุดบกพร่องนี้เนื่องจากพวกเขามีพื้นที่ว่างสำหรับซอร์สโค้ดเพิ่มเติมในแอปดังนั้นคุณต้องทำให้รหัสนี้สั้นที่สุดเท่าที่จะเป็นไปได้โดยหวังว่าพวกเขาจะบีบมันได้

รหัสของคุณจะต้องเป็นจำนวนเต็มจาก 0 ถึง 2,147,483,647 และผลผลิตหรือa anขึ้นบรรทัดใหม่ต่อท้ายเป็นตัวเลือก สำหรับวัตถุประสงค์ของการท้าทายนี้ 1863 จะอ่านเป็น1863ไม่1800 และหกหมื่นสาม

กรณีทดสอบ:

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
สิ่งนี้รับรองโดย Duolingo หรือไม่ ถ้าไม่คุณควรให้พวกเขาจ่ายเงินให้เราเพื่อพัฒนาภาษาในเว็บไซต์การเรียนรู้ภาษา
Arc676

10
คือ1100 (เป็น) พันหนึ่งร้อยหรือ(กได้) พันหนึ่งร้อย ?
user3819867

11
บิลโบจะไม่เห็นด้วยกับกรณีทดสอบของคุณ :)
Martin Ender

9
@Zaibis: "หนึ่ง" ที่นี่ออกเสียงเหมือน "wun" ซึ่งมีเสียงพยัญชนะ ดังนั้น " แนวอย่างใดอย่างหนึ่งพันหนึ่งร้อยวัน"
El'endia Starman

31
พวกเขาอาจออกจากข้อผิดพลาดนี้เพราะพวกเขาคิดว่าจะไม่มีใครไปถึงระยะเวลา 8 วัน
PNDA

คำตอบ:


14

Pyth, 23 ไบต์

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

นี่เป็นการเลือกจำนวนตัวอักษรที่จะตัดออกจากจุดสิ้นสุด"an"โดยการตรวจสอบว่าตัวอักษรตัวแรกไม่ใช่8และตัวเลขตัวแรกของตัวเลขเมื่อพิจารณาในฐาน 1000 ไม่ใช่ 11 หรือ 18 ผลลัพธ์บูลีนคือจำนวนตัวอักษรที่จะแบ่ง ตอนจบ.


3
สร้างสรรค์มาก นอกจากนี้ยังน่ากลัว
Hellreaver

29

Python 2, 60 ไบต์

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

ฟังก์ชั่นที่ไม่ระบุชื่อ เพิ่มnถ้าอย่างใดอย่างหนึ่ง:

  • ตัวเลขแรกคือ 8
  • ตัวเลขสองหลักแรกคือ 11 หรือ 18 และความยาวคือ 2 โมดูโล

ฉันรู้ว่านี่เป็นคำถามที่เก่ามาก แต่ฉันคิดว่า `` n> = '8' '' จะช่วยประหยัดสามไบต์
Lynn

@ ลินน์นั่นจะไม่เลอะเนี้ยใช่ไหม?
xnor

โอ้แน่นอน! ฉันถูกหลอกโดยชุดทดสอบ :)
ลินน์

12

GNU Sed, 32

คะแนนรวม +1 สำหรับ-Eตัวเลือกในการระงับ

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

ลองออนไลน์

  • ลบกลุ่มของตัวเลข 3 ตัวจากท้ายแต่ละหมายเลขจนกว่าจะเหลือเพียง 1 ถึง 3 หลัก
  • จับคู่หมายเลขใด ๆ ที่ขึ้นต้นด้วย 8 หรือ 11 หรือ 18 ทั้งหมดและเปลี่ยนเป็น an
  • เปลี่ยนหมายเลขอื่นทั้งหมดเป็น a

ขอบคุณ @ MartinBüttnerสำหรับวิธีเรตินาของเขาที่บันทึกไว้ 10 ไบต์


11

Shell + bsd-games อายุ 30 ปี

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

อินพุตอ่านจาก STDIN

numberแปลงสตริงทศนิยมให้เป็นคำ eแล้วมันเป็นเรื่องง่ายที่จะตัดสินใจหรือไม่ว่าผลที่ได้เริ่มต้นด้วยการ


2
+1 สำหรับการใช้ bsd-game ฉันไม่คิดว่าพวกเขาจะมีประโยชน์ :)
ASCIIThenANSI

@ ASCIIThenANSI อืม, bsd-game จะมีประโยชน์ที่นี่และที่นั่น :)
Digital Trauma

9

เรติน่า 27 ไบต์

นี่ไม่ได้แตกต่างจากคำตอบ Retina ของ DigitalTrauma มากนัก แต่พวกเขายืนยันว่าฉันโพสต์สิ่งนี้ด้วยตัวเอง

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

ลองออนไลน์

regex แรกแทนที่ตัวเลขที่เกี่ยวข้องทั้งหมดที่มีและที่สองแทนที่ตัวเลขที่เหลืออยู่ทั้งหมดด้วยan aสิ่งนี้ใช้ได้กับไบต์เดียวกัน:

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

1
+1 นี่เกือบจะเป็นระดับเดียวกับการใช้ regex ในทางที่ผิดเช่นเดียวกับการทดสอบในขั้นต้น :)
cat

1
และสิ่งที่ดีคือ Duolingo ถูกเขียนขึ้นใน Retina จริง ๆ ดังนั้นมันจึงเป็นเรื่องง่ายที่จะรวมมันเข้าด้วยกัน หรือรอเป็นภาษาอะไร
หยุดที่จะหมุนกลับใน

1
@ceasedtoturncounterclock ซึ่งฉันถูกบอกว่ามันเขียนใน Hexagony จริง ๆ แต่พวกเขาเขียน transpiler Retina-to-Hexagony ดังนั้นนี่ไม่ควรเป็นปัญหา
Martin Ender

6

C ++, 101

นี่คือความท้าทายของฉันดังนั้นนี่ไม่ได้หมายความว่าจะเป็นคำตอบที่แข่งขันได้ แค่อยากรู้ว่าฉันจะได้มันสั้นแค่ไหนใน C ++ การดำเนินการกับสตริงนั้นละเอียดเกินไปดังนั้นนี่จึงเป็นการคำนวณทางคณิตศาสตร์ ฉันรู้สึกว่าต้องมีวิธีที่จะทำให้อาการเล็กลง แต่ฉันก็ไม่สามารถเข้าใจได้

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

Mathematica, 53 ไบต์

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

วิธีการแก้ปัญหาที่ใช้การประมวลผลสตริงจะสิ้นสุดลงอีกต่อไป


3

PostScript, 119 113 ตัวอักษร

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

ด้วยรหัสทดสอบ:

/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 ไบต์

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

วิกิชุมชนเพราะโซลูชันปัจจุบันแตกต่างจากของเดิมมาก ขอบคุณทุกคน!

การสาธิต: http://www.es6fiddle.net/iio40yep/


1
ที่เหมาะสม ขอบคุณที่อธิบาย
Daniel F

1
@Pavlo ดีมากฉันลืมเกี่ยวกับการแสดงออกเดียวหลังจากค้นพบevalเคล็ดลับ! ฉันรู้ว่าต้องมีการแสดงออกปกติที่ดีขึ้นเช่นกัน แต่ฉันไม่สามารถคิดออกว่าอะไรที่สั้นกว่านี้ ขอขอบคุณ!
Scott

1
@Pavlo Sweet อัปเดตอีกครั้ง! เรียนรู้มากมายขอบคุณมาก :)
สกอตต์

2
Urgh! ลืมโกน 2 ไบต์! นี่คือขั้นตอนสุดท้าย: n=>/^8|^(?=1[18])..(\d{3})*$/.test(n)?'an':'a'( es6fiddle.net/iiehl1ex ) มีความยาว 46 ไบต์
Ismael Miguel

2
@ScottKaye รหัสที่ง่ายมาก: มันจะตรวจสอบถ้ามันเริ่มต้นด้วย8ถ้ามันเริ่มต้นด้วยและถ้าความยาวของตัวเลขที่เป็น1[18] 2 * (3n)โดยทั่วไปมันเป็นรหัสทั้งหมดของคุณ แต่ภายในนิพจน์ปกติ
Ismael Miguel

2

อย่างจริงจัง43 40 ไบต์

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

กลยุทธ์ที่นี่คือดูเฉพาะตัวเลขที่สำคัญที่สุด 1, 2 หรือ 3 หลักโดยการหารจำนวนเต็มด้วยค่าที่มากที่สุด10^(3n)ซึ่งน้อยกว่าอินพุต

ลองออนไลน์

คำอธิบาย:

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 ไบต์

{'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 ใช้[ ]ใน regexes สำหรับการไม่จับภาพ( )และใช้<[ ]>สำหรับชุดอักขระ)

การใช้งาน:

# 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 ไบต์

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

รหัสตรวจสอบว่าหมายเลขเริ่มต้นด้วยคำนำหน้าบางอย่าง คำนำหน้า8จะถูกตรวจสอบเสมอ ( แปด , แปดสิบแปด , แปด - ร้อย - และ ), 11และและ18( สิบเอ็ดและสิบแปด ) จะถูกตรวจสอบเฉพาะเมื่อจำนวนหลักเป็นจำนวนหลาย 3 บวก 2

เราเริ่มต้นด้วยผลเบื้องต้นของและเมื่อคำนำหน้าพบว่าผลที่ได้รับการแทนที่ด้วยa จะใช้เพื่อหลีกเลี่ยงการแยกคำนำหน้าจากสตริง แม้ว่าจะพบการแข่งขันเรายังตรวจสอบส่วนที่เหลือของคำนำหน้าต่อไป - ทำไมต้องเสีย 5 ไบต์สำหรับ? - แต่เนื่องจากสตริงต้นฉบับถูกแทนที่ด้วยเรามั่นใจว่าจะไม่ได้รับผลบวกปลอมใด ๆananchorsearch exita

ในการส่งคืนผลลัพธ์aหรือanบนตัวถูกดำเนินการแทนการพิมพ์ให้ลบส่วนท้าย =(ความยาวที่เกิด: 107 ไบต์)

รหัสทดสอบ:

/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 (พร้อมโทเค็นไบนารี), 63 ไบต์

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

เป็นไบต์มีค่า 146 (ทศนิยม) ¥เป็น 165 และ$เป็น 3. อื่น ๆ ทั้งหมดอยู่ที่พิมพ์อักขระ ASCII 7 บิต

นี่เป็นสิ่งเดียวกันกับเวอร์ชัน PostScript [pure ASCII] ของฉัน แต่ใช้โทเค็นไบนารีซึ่งช่วยลดความยาวทั้งหมด ฉันโพสต์แยกต่างหากด้วยเหตุผล 3 ประการ:

  • ในกรณีทั่วไปการใช้งานที่ย่อเล็กสุดรหัส ASCII ไม่จำเป็นต้องเหมือนกับการย่อขนาดไบนารีรุ่น รหัส ASCII PostScript ที่ยาวกว่าบางส่วนสามารถบีบอัดได้ดีกว่าอีกชิ้นหนึ่งและรุ่นไบนารีที่เกี่ยวข้องจะสั้นกว่า
  • รหัสไบนารีไม่เหมาะสมทุกที่ดังนั้นคำตอบ ASCII แท้อาจเป็นที่ต้องการแม้ว่าจะนานกว่า
  • มันไม่ยุติธรรมเลยที่จะเปรียบเทียบความยาวของคำตอบ ASCII PostScript แท้กับคำตอบเดียวโดยใช้การเข้ารหัสไบนารี่

1

Python 3, 110 93 91 76 74 70 65 64 64 ไบต์

ที่นี่มีความยาว แต่ที่เรียบง่าย

แก้ไข:แก้ไขด้วยความขอบคุณไปisaacg บันทึกช่องว่างหลังจากการเปรียบเทียบ จำนวนไบต์ที่บันทึกไว้ขอบคุณที่Timwi , ชำเลือง , benpopและAlissa

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

หรือสำหรับจำนวนไบต์เดียวกัน

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

นี้ไม่ถูกต้องในการป้อนข้อมูล843"แปดร้อยสี่สิบสาม" anซึ่งควรจะเป็น
isaacg

@isaacg ไม่เพียง แต่คุณจะถูกต้อง แต่สิ่งนี้ทำให้รหัสของฉันง่ายขึ้นอย่างมาก ขอบคุณ! ปรากฎว่าฉันดูเฉพาะแปด, แปดพันแปดล้านในขณะที่ไม่สนใจกรณีเช่นแปดสิบแปดร้อย
Sherlock9

ทำไม(-~len(n)%3)<1แทนlen(n)%3==2?
Timwi

อาจ(n[:2]=="11"or n[:2]=="18")ย่อให้สั้นลงไป"118".contains(n[:2])?
Timwi

หรือแม้กระทั่งn[:2]in"118"?
Timwi

1

Java 10, 102 ไบต์

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

ลองออนไลน์

คำอธิบาย:

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 ไบต์

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

ลองออนไลน์!

เอาออกแล้วมันทำงานอย่างไร

'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

คุณสามารถแทนที่1e3ด้วย
Oliver

1

GNU sed -r+ BSD number, 34 ไบต์

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

ก่อนอื่นเราแปลงเป็นเลขภาษาอังกฤษ แล้วลบทุกอย่างยกเว้นเริ่มต้นที่เป็นไปได้และคำนำหน้าด้วยe aจากนั้นแปลงe(ถ้ามี) nเพื่อ เคล็ดลับการเล่นกอล์ฟเพียงอย่างเดียวคือการจับคู่ทางเลือกeในการเปลี่ยนตัวครั้งแรกดังนั้นเราจึงสามารถนำรูปแบบดังกล่าวมาใช้ใหม่ในบรรทัดต่อไปนี้

การสาธิต

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 ไบต์

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

ลองที่นี่

การอธิบาย

               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

Python 2.7, 66

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

เห็นได้ชัดว่าไม่สั้นเท่ากับlambdaหนึ่ง


0

05AB1E , 26 ไบต์

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

อาจจะเป็นสนามกอล์ฟอีกเล็กน้อย แต่มันก็ใช้งานได้

ลองมันออนไลน์หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย:

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 ไบต์

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

เรียกใช้และแก้ไขข้อบกพร่อง

คลายกล่อง ungolfed และแสดงความคิดเห็นมันมีลักษณะเช่นนี้

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"

เรียกใช้อันนี้


0

ช่องว่าง 243 ไบต์

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

เพิ่มตัวอักษรS(ช่องว่าง), T(แท็บ) และN(บรรทัดใหม่) เป็นการเน้นเท่านั้น
[..._some_action]เพิ่มเป็นคำอธิบายเท่านั้น

ลองใช้ออนไลน์ (ด้วยพื้นที่ว่างเปล่าแท็บและบรรทัดใหม่เท่านั้น)
โปรแกรมหยุดทำงานโดยมีข้อผิดพลาด: ไม่พบทางออก

คำอธิบายในรหัสเทียม:

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 ไบต์

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

มันกลับกลายเป็น 4 ไบต์ที่สั้นกว่าเพื่อทดสอบกับ 8xx และ 8x อย่างชัดเจนมากกว่าการ/=10วนซ้ำอื่นเช่นนี้:

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

การสาธิต

#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

ฉันไม่รู้จัก C ++ ดีเกินไป แต่i/=1000เป็นได้i/=1e3และทุกคนสามารถ&&กลายเป็นได้&หรือไม่
Kevin Cruijssen

ดูเหมือนว่าใช้งานได้จริง: ลองออนไลน์
Kevin Cruijssen

1
@ เควิน - ฉันถึงจุดหนึ่งมี 1e3 ที่นั่น; ฉันเปลี่ยนมันในระหว่างการดีบักและลืมเปลี่ยนกลับไป &&ไม่ได้ทุกคนสามารถเป็น&เพราะอัตราผลตอบแทนการลบจำนวนเต็มและไม่ booleans - เช่น19-11คือ 8 และ19-18เป็น 1; เห็นว่า8 && 1เป็นเรื่องจริง แต่8 & 1เป็นเท็จ เราสามารถใช้&แต่เราจะต้องเปลี่ยน-ไป!=และยังเพิ่มวงเล็บ
Toby Speight

แน่นอน .. &แน่นอนว่าใช้งานไม่ได้ที่นี่ แต่ทำไมคุณไม่เพิ่ม TIO-link เข้าไปในคำตอบของคุณด้วยล่ะ?
Kevin Cruijssen


-1

Perl, 71 55 49 ไบต์

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

ฉันรู้ว่าผู้ประกอบการที่สามจะช่วยหนึ่งวัน ...

ขอผมทำลายมันลง

  • $_=<> ยอมรับตัวเลขเป็นอินพุต
  • $_=...บล็อกใหญ่จะกำหนดค่า$_หลังจากใช้งานแล้ว
    • ...?...:...เป็นผู้ประกอบการที่สาม หากเงื่อนไข (อาร์กิวเมนต์แรก) เป็นจริงมันจะส่งกลับอาร์กิวเมนต์ที่สอง มิฉะนั้นจะส่งคืนค่าที่สาม
    • /^8/||(/^1[18]/&&length%3==2)ตรวจสอบเพื่อดูว่าจำนวนเริ่มต้นด้วย 8 หรือเริ่มต้นด้วย 11 หรือ 18 ( 1[18]ยอมรับอย่างใดอย่างหนึ่ง) และมีความยาว mod 3 ของ 2
    • หากเป็นจริงมีการตั้งค่า$_ มิฉะนั้นจะตั้งค่าให้ana
  • จากนั้นก็พิมพ์ออกเนื้อหาของ$_(อย่างใดอย่างหนึ่งaหรือan) sayด้วย

การเปลี่ยนแปลง

  • บันทึก 16 ไบต์ขอบคุณ msh210
  • บันทึก 6 ไบต์โดยลบ parens และใช้ค่าเริ่มต้น

$_=<>;$_=(/^8/)||/^1[18]/&&length($_)%3==1?'an':'a';sayบันทึกไม่กี่ไบต์ (แม้ว่าจำนวนที่จะเปรียบเทียบกับมันขึ้นอยู่กับว่าอักขระบรรทัดใหม่ของคุณคืออะไร แต่นั่นไม่ได้เปลี่ยนจำนวนไบต์)
msh210

@ msh210 ดูเหมือนว่าจะมีเพียง 55 ไบต์ซึ่งจะช่วยให้ประหยัดได้ 16 ไบต์ ฉันจะเพิ่มนั้นขอบคุณ!
ASCIIThenANSI

ไม่เป็นไร โอ้และคุณสามารถดร็อป parens แรก (ฉันถือว่าฉันยังไม่ได้ทดสอบ) ฉันคิดว่าคุณสามารถเปลี่ยนlength($_)เป็นlength(หรืออย่างน้อยวาง parens) แต่นั่นไม่ทำงานสำหรับฉันด้วยเหตุผลบางอย่าง
msh210

@ msh210 ใช่คุณสามารถวาง parens และ($_)รับ$_=<>;$_=/^8/||/^1[18]/&&length%3==1?'an':'a';sayซึ่งเป็นเพียง 49 ไบต์
ASCIIThenANSI

คุณสามารถบันทึกไบต์บางอย่างโดยใช้-pแทน$_=<>และsay, y///cแทนlength, และวางคำพูดที่อยู่รอบ ๆaและan: perl -pe'$_=/^8/||/^1[18]/&&y///c%3==2?an:a'(34 ไบต์ + 1 -p) echo -n 11 | perl -pe'...'หมายเหตุการป้อนข้อมูลที่ไม่สามารถจบลงด้วยการขึ้นบรรทัดใหม่: สิ่งนี้จะแก้ไขข้อผิดพลาด: length%3==2ถูกแยกวิเคราะห์เป็นlength(%3)==2ไม่เหมือนlength($_)%3==2ดังนั้นจะส่งคืนค่าเท็จเสมอ
ThisSuitIsBlackNot

-1

Pyth, 29 31

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

ย้อนกลับสตริงแยกออกเป็นส่วนของสามย้อนกลับอีกครั้งจากนั้นเลือกตอนจบที่เหมาะสม


5
นี่เป็นความผิดพลาดในข้อมูลที่ป้อน111- จะให้an
isaacg

คุณถูก. แก้ไขแล้ว.
Moose
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.