แสดงผลหมายเลขลำดับที่ (1, 2, 3)


43

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

ตัวอย่าง:

1st  
2nd  
3rd  
4th  
...  
11th  
12th  
13th  
...  
20th  
21st
22nd
23rd
24th

และด้วยส่วนต่อท้ายที่ทำซ้ำ subpattern 1-10 เริ่มต้นทุก 10 จนถึง 100 ซึ่งรูปแบบเริ่มต้นในที่สุด

อินพุตจะเป็นตัวเลขและเอาต์พุตสตริงลำดับที่แสดงด้านบน

อัลกอริธึมที่เล็กที่สุดสำหรับสิ่งนี้คืออะไร?


สวัสดี NickC และยินดีต้อนรับสู่ codegolf.SE! เพื่อชี้แจงคุณหมายถึงว่าเราควรอ่านตัวเลขเช่น11อินพุทและเอาท์พุทเช่น11th? แต่ละหมายเลขในอินพุตบนบรรทัดแยกกันหรือไม่และหมายเลขเอาต์พุตควรเป็นบรรทัดแยกกันด้วยหรือไม่? และเราต้องจัดการอินพุตมากกว่าหนึ่งบรรทัดหรือไม่?
Ilmari Karonen

1
คุณกำลังมองหาอัลกอริทึมที่เล็กที่สุดหรือโค้ดที่เล็กที่สุดหรือไม่?
โตโต้

@Ilmari ฉันกำลังมองหา11อินพุตและ11thเอาต์พุต ฉันไม่คิดว่ามันจะประมวลผลหลายบรรทัด แต่สิ่งที่ฉันมีอยู่ในใจคือการประมวลผลเพียงจำนวนเดียว
Nicole

@ M42 คุณรู้ฉันไม่แน่ใจจริงๆ ฉันไม่มีข้อกำหนดที่เข้มงวด - แต่ฉันอาจคิดว่าอัลกอริทึมที่เล็กที่สุด
Nicole

คำตอบ:


30

Perl, 37 + 1 ตัวอักษร

s/1?\d\b/$&.((0,st,nd,rd)[$&]||th)/eg

นี่คือการทดแทน regexp ที่ผนวกส่วนต่อท้ายตามลำดับที่เหมาะสมกับตัวเลขใด ๆ ใน$_ที่ไม่ได้ตามด้วยตัวอักษร หากต้องการใช้กับอินพุตไฟล์ให้ใช้pสวิตช์บรรทัดคำสั่งดังนี้:

perl -pe 's/1?\d\b/$&.((0,st,nd,rd)[$&]||th)/eg'

นี่เป็นโปรแกรม Perl ที่สมบูรณ์ที่อ่านอินพุตจาก stdin และเขียนเอาต์พุตที่ประมวลผลไปยัง stdout รหัสจริงคือ 37 ตัวอักษรยาว แต่pสวิทช์นับเป็นตัวละครตัวหนึ่งเป็นพิเศษ

ตัวอย่างอินพุต:

This is the 1 line of the sample input...
...and this is the 2.
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
101 102 103 104 105 106 107 108 109 110

เอาท์พุท:

This is the 1st line of the sample input...
...and this is the 2nd.
1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
11th 12th 13th 14th 15th 16th 17th 18th 19th 20th
21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th
101st 102nd 103rd 104th 105th 106th 107th 108th 109th 110th

ตัวเลขที่ตามด้วยตัวอักษรจะถูกละเว้นดังนั้นการป้อนข้อมูลผลลัพธ์อีกครั้งผ่านตัวกรองจะไม่เปลี่ยนแปลง ช่องว่างเครื่องหมายจุลภาคและจุดระหว่างตัวเลขไม่ได้รับการปฏิบัติเป็นพิเศษดังนั้นพวกเขาจึงสันนิษฐานว่าจะแยกตัวเลขเช่นเครื่องหมายวรรคตอนอื่น ๆ ดังนั้นเช่นกลายเป็น3.141593rd.14159th

มันทำงานยังไง?

  • อย่างแรกนี่คือการทดแทน regexp ทั่วโลก ( s///g) regexp ที่ถูกจับคู่เป็น1?\d\bที่\dตรงกับหลักใด ๆ และ\bเป็นศูนย์การยืนยันความกว้างตรงกับเขตแดนระหว่างตัวอักษรและตัวเลขและอักขระที่ไม่ใช่ตัวอักษรและตัวเลข ดังนั้น1?\d\bตรงกับหลักสุดท้ายของหมายเลขใด ๆ 1รวมทั้งหลักก่อนว่ามันจะเกิดขึ้น

  • แทนซึ่งได้รับการประเมินเป็นรหัส Perl เนื่องจากการ/eสวิทช์ที่เราใช้เวลาส่วนสตริงจับคู่ ( $&) และผนวก ( .) ไปต่อท้ายได้โดยใช้$&ตัวเองเป็นดัชนีจำนวนเต็มในรายการ(0,st,nd,rd); ถ้าต่อท้ายนี้เป็นศูนย์หรือไม่ได้กำหนด (เช่นเมื่อ$&เป็นศูนย์หรือมากกว่าสาม) ที่ผู้ประกอบการแทนที่มันด้วย||th


แก้ไข:หากอินพุตถูก จำกัด ให้เป็นจำนวนเต็มเดียวโซลูชัน 35 ตัวอักษรนี้จะพอเพียง:

s/1?\d$/$&.((0,st,nd,rd)[$&]||th)/e

1
ควรจะสามารถgปิดการแทนที่ถ้าคุณระบุว่าแต่ละหมายเลขจะต้องอยู่ในสายของตัวเอง $นอกจากนี้ที่ต้องการให้คุณเปลี่ยนขอบเขตของคำที่จะ แต่โดยรวมแล้ว +1 เป็นวิธีแก้ปัญหาที่ฉลาด
Mr. Llama

@GigaWatt: จริง ๆ แล้วฉันเขียนโค้ดก่อนที่ NickC จะตอบคำถามของฉันเกี่ยวกับรูปแบบการป้อนข้อมูลดังนั้นฉันจึงกำหนดให้เป็นแบบทั่วไปที่สุด
Ilmari Karonen

38

Python 2, 49 ไบต์

lambda n:`n`+'tsnrhtdd'[n%5*(n%100^15>4>n%10)::4]

ฟังก์ชั่นที่ไม่ระบุชื่อ โปรแกรมเต็มรูปแบบจะนับที่ 55 ไบต์

'tsnrhtdd'[i::4]ถอดรหัสคำต่อท้ายth st nd rdสำหรับค่าiตั้งแต่ 0 ถึง 3 ให้นี้ทั้งหมดที่เราต้องเป็นวิธีที่จะ map ค่าที่จะจัดทำดัชนีของคำต่อท้ายที่สอดคล้องกันn แสดงออกตรงไปตรงมาว่าการทำงานคือi (n%10)*(n%10<4 and 10<n%100<14)เราสามารถย่อให้สั้นลงได้โดยการวางวงเล็บชุดแรกและสังเกตว่าn%5ให้ผลลัพธ์เดียวกันกับn%10ค่าของnส่วนต่อท้ายพิเศษ กับบิตของการทดลองและข้อผิดพลาดหนึ่งยังอาจจะสั้นลง10<n%100<14ไปn%100^15>4ซึ่งจะถูกผูกมัดกับเงื่อนไขอื่น ๆ เพื่อประหยัดไบต์มากยิ่งขึ้น


3
นี่คือเวทย์มนตร์ดำที่นี่ c:
cat


ฉันไม่เข้าใจ ทุกคนสามารถอธิบายสิ่งที่เกิดขึ้นที่นี่ได้ไหม
Pavel

@Pavel ฉันได้อัปเดตคำตอบพร้อมคำอธิบายแล้ว
xsot

! น่ากลัว วิธีคิดที่ยอดเยี่ยม ...
สันแซม

10

Python 68 ตัวอักษร

i=input()
k=i%10
print"%d%s"%(i,"tsnrhtdd"[(i/10%10!=1)*(k<4)*k::4])

4
นี่คือจริงๆปลาย แต่คุณสามารถใช้เวลาปิด 7 `i`+"tsnrhtdd"ไบต์โดยการทำ มิฉะนั้นนี่เป็นคำตอบที่ฉันเพิ่งได้รับ
DLosc

10

Mathematica 39 45 ไบต์

หมายเหตุ: ใน Mathematica รุ่นล่าสุดการขอให้nthส่วนหนึ่งของpที่ไหนpไม่ได้กำหนดจะสร้างข้อความแสดงข้อผิดพลาด แต่กลับคำตอบที่ถูกต้องอยู่ดี ฉันได้เพิ่มQuietเพื่อป้องกันข้อผิดพลาดจากการพิมพ์

Quiet@StringSplit[SpokenString[p[[#]]]][[2]]&

การใช้

Quiet@StringSplit[SpokenString[p[[#]]]][[2]] &[31]

วันที่ 31

Quiet@StringSplit[SpokenString[p[[#]]]][[2]] &/@Range[21]

{"ที่ 1", "ที่ 2", "ที่ 3", "ที่ 4", "ที่ 5", "ที่ 6", "ที่ 7", "ที่ 8", "ที่ 9", "ที่ 10", "ที่ 10", "ที่ 11", "ที่ 12", " 13th "," 14 "," 15 "," 16 "," 17 "," 18 "," 19 "," 20 "," 21 "}


มันทำงานอย่างไร

SpokenStringเขียนนิพจน์ Mathematica ใด ๆ ที่ถูกต้องตามที่มันอาจจะพูด ด้านล่างนี้เป็นตัวอย่างที่สองจากเอกสารสำหรับSpokenString ,

SpokenString[Sqrt[x/(y + z)]]

"รากที่สองของปริมาณ x ในปริมาณ y บวก z" *)

SpokenString[Graphics3D[Sphere[{{0, 0, 0}, {1, 1, 1}}]], "DetailedGraphics" -> True]

"กราฟิกสามมิติประกอบด้วยหน่วยทรงกลมที่ศูนย์กลางที่ 0, 0, 0 และ 1, 1, 1"


ตอนนี้สำหรับตัวอย่างที่อยู่ในมือ

Quiet@SpokenString[p[[#]]] &[31]

"องค์ประกอบที่ 31 ของ p"

ลองแทนสตริงข้างต้นเป็นรายการของคำ:

StringSplit[%]

{"the", "31st", "element", "of", "p"}

และนำองค์ประกอบที่สอง ...

%[[2]]

วันที่ 31


ฉันสับสน ที่ถูกpกำหนดไว้? แก้ไข: ไม่เป็นไรฉันเห็นว่าคุณใช้สิ่งนี้อย่างไร น่าเสียดายที่มันใช้ไม่ได้กับระบบของฉัน : - /
Mr.Wizard

มันทำงานได้กับ v.9.0.1 (ฉันดูเหมือนจะจำได้ว่าคุณกำลังใช้ 7.0) ใช่ไม่จำเป็นต้องกำหนด p
DavidC

ตอนนี้ฉันเข้าใจแล้ว อย่างไรก็ตามใน v7 ฉันได้รับจากการส่งออกSpokenString @ p[[117]] " part 117 of p"
Mr.Wizard

ดังนั้นSpokenStringได้รับการแก้ไขเป็นครั้งคราว ฉันจะไม่แปลกใจเลยที่รหัสนี้ ( codegolf.stackexchange.com/questions/8859/ … ) ก็ใช้ไม่ได้กับข้อ 7 BTW มันไม่ได้หมายความว่าจะเป็นทางออกที่ยั่งยืน
DavidC

ฉันไม่เคยเห็นคำตอบนั้นมาก่อนเลย
Mr.Wizard

7

ทับทิม, 60

มันไม่ดีเท่ารายการ Perl แต่ฉันคิดว่าฉันจะใช้ทักษะทับทิมของฉัน

def o(n)n.to_s+%w{th st nd rd}[n/10%10==1||n%10>3?0:n%10]end

ฟังก์ชั่นรับอาร์กิวเมนต์จำนวนเต็มหนึ่งรายการnและส่งคืนสตริงเป็นรูปแบบปกติ

ทำงานตามตรรกะต่อไปนี้:
หากหลักสิบเป็น 1 หรือหลักที่มากกว่า 3 ใช้ส่วนต่อท้าย 'th'; มิฉะนั้นหาคำต่อท้ายจากอาร์เรย์ ['th', 'st', 'nd', 'rd'] โดยใช้ตัวเลขสุดท้ายเป็นดัชนี


o(113)เป็นที่ควรจะเป็น"113rd" "113th"การตรวจสอบหลักสิบไม่บัญชีสำหรับตัวเลขที่มีมากกว่าสองหลัก
hammar

ตกลงแหลมในที่อื่น%10เพื่อชดเชย เพิ่ม 3 ตัวอักษร (ฉันรู้สึกเหมือน%10ปรากฏพอที่จะสั้นลงอย่างใด แต่ฉันไม่สามารถคิดวิธีแก้ปัญหา)
Mr. Llama

คุณไม่สามารถเอาชนะ Perl ในการเขียนที่น่ากลัวรหัสไม่สามารถเข้าใจได้ว่าสั้นที่สุดเท่าที่เป็นไปได้ :)
jamylak

ตั้งค่าตัวแปรเป็น10?
wizzwizz4

ฉันคิดว่าการตั้งค่าตัวแปรn%10เป็นสิ่งที่ดีกว่า
CalculatorFeline

6

Javascript (ES6) 50 44 Bytes (ไม่แข่งขัน)

a=>a+=[,"st","nd","rd"][a.match`1?.$`]||"th"

หมายเหตุ

  • ใช้เวลา imput เป็นสตริง
  • นำออก 6 ไบต์ขอบคุณ @ user81655

1
a+-> a+=วงเล็บลบ, \d-> ., ลบ[0]และถ้าคุณใช้ตัวเลขเป็นสตริง: แทนa.match`1?.$` /1?.$/.exec(a)
user81655

คุณควรเพิ่มการแจ้งเตือนคำตอบนี้ไม่ได้แข่งขันกันเนื่องจาก ES6 ไม่มีอยู่เมื่อมีการโพสต์ความท้าทาย
user2428118

5

javascript, 68 71

function o(n){return n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')}

ร่วมความพยายามกับ ItsCosmo

แก้ไข: ทำงานไม่ถูกต้องกับตัวเลข> 100


คุณสามารถนำมันลงไปที่ 62 ด้วย: function o(n)n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')และคุณสามารถนำมันลงไปที่ 54 ถ้าคุณมีความสุขที่จะใช้สัญลักษณ์ลูกศรไขมัน:o=n=>n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')
WallyWest

@WallyWest ด้วยเหตุผลบางอย่างฉันชอบที่โซลูชันของฉันทำงานในเบราว์เซอร์ที่ทันสมัย โพสต์คำตอบของคุณเองฟรี ฉันคิดว่ามันแตกต่างกันพอสมควร
aebabis

ไม่เป็นไร! เพียงแค่ให้ทางเลือกน้อย!
WallyWest


3

Haskell, 95 ตัวอักษร

h=foldr g"th".show
g '1'"th"="1st"
g '2'"th"="2nd"
g '3'"th"="3rd"
g '1'[x,_,_]='1':x:"th"
g a s=a:s

การทดสอบ:

*Main> map h [1..40]
["1st","2nd","3rd","4th","5th","6th","7th","8th","9th","10th","11th","12th","13t
h","14th","15th","16th","17th","18th","19th","20th","21st","22nd","23rd","24th",
"25th","26th","27th","28th","29th","30th","31st","32nd","33rd","34th","35th","36
th","37th","38th","39th","40th"]

ต้องโหลดด้วย -XNoMonomorphismRestriction


3

JavaScript, 64 ตัวอักษร (ES3) หรือ 47 ตัวอักษร (ES6)

ES3 (64 ตัวอักษร):

function(n){return n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'}

ES6 (47 ตัวอักษร):

n=>n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'

คำอธิบาย

นิพจน์n % 100 >> 3 ^ 1ประเมินเป็น 0 สำหรับการnสิ้นสุดที่เป็นบวกด้วยดิจิต08- 15ดังนั้นสำหรับการn mod 100สิ้นสุดใน11, 12หรือ13, การค้นหาอาร์เรย์จะส่งกลับundefined, นำไปสู่คำต่อท้ายthนำไปต่อท้ายของ

สำหรับเชิงบวกใด ๆnที่ลงท้ายด้วยตัวเลขอื่นที่ไม่ใช่08- 15การแสดงออกn % 100 >> 3 ^ 1ประเมินจำนวนเต็มบวกเรียกการแสดงออกn % 10สำหรับการค้นหาอาร์เรย์กลับst, ndหรือrdสำหรับnที่ปลายด้วย1, หรือ2 3มิฉะนั้น, th.


n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'บันทึกไบต์ที่มี
Shaggy

@Shaggy ขอบคุณอัปเดตตามที่แนะนำ
Tomas Langkaas


@ guest271314 สนุกที่จะเห็นรหัสนี้ถูกใช้ โปรดทราบว่าจะใช้งานได้กับตัวเลขที่เป็นบวกเท่านั้นตัวเลือกอื่นถูกn+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th"ดัดแปลงจากโพสต์นี้
Tomas Langkaas

3

APL (Dyalog Unicode) , 38 36 ไบต์

ขอบคุณ ngn สำหรับการแก้ไขข้อบกพร่องในขณะที่ยังคงนับไบต์

ฟังก์ชันนำหน้าเงียบโดยไม่ระบุชื่อ ต้องการตั้งค่า⎕IO( I ndex O rigin) ให้0ซึ่งเป็นค่าเริ่มต้นในหลาย ๆ ระบบ ใช้งานได้สำหรับ 0!

⍕,{2'thstndrd'↓⍨2×⊃⍵⌽∊1 0 8\⊂10↑⍳4}

ลองออนไลน์!

{} แลมบ์ดานิรนาม คือการโต้แย้ง:

⍳4 สี่ครั้งแรกɩ ndices;[0,1,2,3]

10↑ รับสิบองค์ประกอบแรกจากนั้นเติมด้วยศูนย์: [0,1,2,3,0,0,0,0,0,0]

 ล้อมรอบเพื่อรักษาเป็นองค์ประกอบเดียว [[0,1,2,3,0,0,0,0,0,0]]

1 0 8\ ขยายไปยังหนึ่งสำเนาสำเนาต้นแบบ (ทั้งหมดเป็นศูนย์), แปดสำเนา;
  [[0,1,2,3,0,0,0,0,0,0],
   [0,0,0,0,0,0,0,0,0,0],
   [0,1,2,3,0,0,0,0,0,0],
   [0,1,2,3,0,0,0,0,0,0],
   ⋮ (อีก 5)
   [0,1,2,3,0,0,0,0,0,0]]

ε nlist (เรียบ);
  [0,1,2,3,0,0,0,0,0,0,
   0,0,0,0,0,0,0,0,0,0,
   0,1,2,3,0,0,0,0,0,0,
   0,1,2,3,0,0,0,0,0,0,
   ⋮ (อีก 50)
   0,1,2,3,0,0,0,0,0,0]

⍵⌽ หมุนวนไปทางซ้ายตามขั้นตอนหลายรอบตามที่ระบุโดยอาร์กิวเมนต์

 เลือกหมายเลขแรก (เช่นอาร์กิวเมนต์ -mod-100'th หมายเลข)

 คูณสองโดยที่ (ให้0, 2, 4หรือ6)

'thstndrd'↓⍨ปล่อยอักขระจำนวนมากจากสตริงนี้

2↑ ใช้อักขระสองตัวแรกที่เหลือ

⍕, เชื่อมอาร์กิวเมนต์ที่เป็นสตริงเข้าด้วยกัน


"31"?
ngn

⍕,{2↑'thstndrd'↓⍨2×⊃⍵⌽∊1 0 8\⊂10↑⍳4}
ngn

⎕io←0ขอโทษฉันลืมที่จะพูดถึง ฉันสามารถเห็นคุณเดาได้ว่า แต่มีไม่กี่ 1,2,3,4,0,0 ... ที่ควรจะเป็น 0,1,2,3,0,0 ...
ngn

@ngn คงที่ และเกิดขึ้นกับการทำงานสำหรับ 0 เกินไป!
อดัม

2

PowerShell, 92

process{"$_$(switch -r($_){"(?<!1)1$"{'st'}"(?<!1)2$"{'nd'}"(?<!1)3$"{'rd'}default{'th'}})"}

ทำงานร่วมกับหนึ่งหมายเลขต่อบรรทัดอินพุต อินพุตถูกส่งผ่านไปป์ไลน์ การทำให้มันใช้งานได้กับตัวเลขเพียงตัวเดียวจะไม่ลดขนาดลง


2

J - 44 ตัวอักษร

ไม่มีอะไรในเจ นี่คือความชั่วร้าย!

(":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])

อธิบาย (โปรดทราบว่า1บูลีนจริงใน J และ0เป็นเท็จ):

  • 10 10(...)/@#:]- ก่อนอื่นเราหาอาร์กิวเมนต์ ( ]) และหาหลักสิบและหลัก ( 10 10 #:) จากนั้นเราจะแทรก(...)ระหว่างสอง
  • (]*[(~:*])4>])- ใน subexpression นี้ แต่ไม่ใช่อันที่อยู่ด้านในสุด]จะชี้ไปที่ตัวเลขหลักและ[หลักสิบ
  • [(~:*])4>]- ~:คือ J สำหรับ "ไม่เท่ากับ" ดังนั้นสิ่งนี้จะใช้ผลลัพธ์ของ4>](คือตัวเลขหนึ่งหลักน้อยกว่า 4) หรือไม่และคูณด้วยผลลัพธ์ของtens ~: (4>])และคูณได้โดยผลจากการ ทำไมทุกคนจะทำเช่นนี้? พิจารณาสิ่งต่อไปนี้:
    • หากเรากำลังตรวจสอบ 10, 11, 12, 13 ก็tensคือ1(เราอยู่ในช่วงวัยรุ่น) และonesน้อยกว่า 4 ดังนั้นtens ~: (4>])เป็นเท็จและผลลัพธ์คือ0*1=0 =
    • หากเราเป็นอีกคนหนึ่งของ {X0, X1, X2, X3} แสดงว่าtens ~: (4>])เป็นเรื่องจริงและเราออกไปได้1*1=1 =
    • หากonesมีค่ามากกว่าสี่แล้ว4>]เป็น0และมันไม่สำคัญว่าสิ่งที่เกิดขึ้นในการทดสอบอีกต่อไปเราจะได้รับ0ออกมาโดยไม่คำนึงถึง
    • ดังนั้นเพื่อสรุป[(~:*])4>]คือ1ถ้าเราอยู่ใน {X0, X1, X2, X3} แต่ไม่ได้อยู่ในวัยรุ่นและ0เป็นอย่างอื่น
  • ]*- ในที่สุดเราก็คูณผลลัพธ์นั้นด้วยตัวเลขหลัก ดังนั้นผลิตภัณฑ์นี้จะเป็น0ถ้าจำนวนควรได้รับ'th'ส่วนต่อท้ายมิฉะนั้นค่าของมัน
  • th`st`nd`rd{::~- เราใช้เลขตัวที่ถูกแก้ไขจากด้านบนเพื่อจัดทำดัชนีรายการคำต่อท้าย 0ได้รับ'th', 1ได้รับ'st'และอื่น ๆ
  • ":,- ในที่สุดนำหมายเลขเดิมมาแปลงเป็นสตริง ( ":) จากนั้นเติมให้เป็นคำต่อท้าย

เห็นได้ชัดว่าการใช้แม้ว่าจะเป็นเพียงคำกริยาที่ใช้เป็นลำดับไม่ใช่รายการ

   (":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:]) 112         NB. single use
112th
   (":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:]) 1 2 3 4 5   NB. doing it wrong
|length error
|       (":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])1 2 3 4 5
   NB. i.5 10   makes a 5x10 grid of increasing integers
   NB. &.>      to operate on each integer separately, and box the result after
   (":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])&.> i.5 10   NB. all better
+----+----+----+----+----+----+----+----+----+----+
|0th |1st |2nd |3rd |4th |5th |6th |7th |8th |9th |
+----+----+----+----+----+----+----+----+----+----+
|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|
+----+----+----+----+----+----+----+----+----+----+
|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|
+----+----+----+----+----+----+----+----+----+----+
|30th|31st|32nd|33rd|34th|35th|36th|37th|38th|39th|
+----+----+----+----+----+----+----+----+----+----+
|40th|41st|42nd|43rd|44th|45th|46th|47th|48th|49th|
+----+----+----+----+----+----+----+----+----+----+

2

C #, 62 ไบต์

n=>n+(n/10%10==1||(n%=10)<1||n>3?"th":n<2?"st":n<3?"nd":"rd");

โปรแกรมเต็มรูปแบบและการตรวจสอบ:

using System;

namespace OutputOrdinalNumbers
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<int,string>f= n=>n+(n/10%10==1||(n%=10)<1||n>3?"th":n<2?"st":n<3?"nd":"rd");

            for (int i=1; i<=124; i++)
                Console.WriteLine(f(i));
        }
    }
}

คุณสามารถกอล์ฟได้โดยไบต์ที่สองโดยการเปลี่ยนไป|| |
Kevin Cruijssen

2

Mathematica 29 + 5 = 34 ไบต์

SpokenStringDump`SpeakOrdinal

+5 ไบต์เนื่องจากSpeakต้องเรียกใช้ฟังก์ชันก่อนใช้งานบิวด์อินนี้

การใช้

SpokenStringDump`SpeakOrdinal[1]

"1st "

SpokenStringDump`SpeakOrdinal[4707]

"4,707th "


1

PHP, 151

ฉันรู้ว่าโปรแกรมนี้ไม่สามารถเทียบได้กับโปรแกรมอื่น ๆ แค่รู้สึกเหมือนให้ทางออก

<?$s=explode(' ',trim(fgets(STDIN)));foreach($s as$n){echo$n;echo(int)(($n%100)/10)==1?'th':($n%10==1?'st':($n%10==2?'nd':($n%10==3?'rd':'th')))."\n";}

คุณสามารถบันทึกตัวละครไม่กี่ตัวโดยใช้foreach($s as $n){echo$n;
karthik

1

สกาล่า 86

def x(n:Int)=n+{if(n%100/10==1)"th"else(("thstndrd"+"th"*6).sliding(2,2).toSeq(n%10))}

สกาล่า 102:

def x(n:Int)=if((n%100)/10==1)n+"th"else if(n%10<4)n+("thstndrd".take(n+1)%5*2.drop(n%5*2))else n+"th"

102 เช่นกัน:

def x(n:Int)=if((n%100)/10==1)n+"th"else if(n%10<4)n+("thstndrd".sliding(2,2).toSeq(n%10))else n+"th"

ungolfed:

def x (n: Int) =
  n + { if (((n % 100) / 10) == 1) "th" 
        else (("thstndrd"  + ("th"  * 6)).sliding (2, 2).toSeq (n % 10))
      }

1

OCaml

ฉันค่อนข้างใหม่กับ OCaml แต่นี่เป็นระยะสั้นที่สุดที่ฉันจะได้รับ

let n x =
   let v = x mod 100 and string_v = string_of_int x in
   let z = v mod 10 in
   if v=11 || v=12 || v=13 then string_v^"th" 
   else if v = 1 || z = 1 then string_v^"st" else if v = 2 || z = 2 then string_v^"nd" else if v = 3 || z = 3 then string_v^"rd" else string_v^"th";;

ฉันสร้างฟังก์ชั่น n ซึ่งใช้ตัวเลขเป็นพารามิเตอร์และทำงานได้ มันยาว แต่คิดว่ามันคงจะดีถ้ามีตัวอย่างของหน้าที่


อินพุต: 11 จะให้เอาต์พุต: 11st

ใช่คุณพูดถูก .. ฉันแก้ไขแล้ว ขอบคุณ
Joseph Elcid

ฉันเพิ่งจัดรูปแบบในรหัสของคุณ แต่ละบรรทัดจะต้องมีช่องว่างสี่ช่องนำหน้าเพื่อให้สามารถจดจำได้ว่าเป็นบล็อกรหัส
Gareth

ไม่ใช่ครั้งแรกของคุณหากเช็คสั้นกว่าif v>10 && v<14หรือไม่ ฉันไม่คุ้นเคยกับ ocaml แต่จำเป็นต้องให้string_vตัวแปรมีความยาวหรือไม่
Gaffi

ไม่จำเป็นไม่ต้องเลือก w หรือ x แค่ต้องการสิ่งที่มีความหมาย แต่คุณพูดถูกมันจะทำให้รหัสสั้นลงเล็กน้อย
Joseph Elcid

1

K - 44 ตัวอักษร

มันเกิดขึ้นว่านี่จะเป็นเวลานานเท่าที่ J และทำงานในลักษณะเดียวกัน

{x,$`th`st`nd`rd@{y*(y<4)*~1=x}.-2#0,.:'x$:}

อธิบาย:

  • x$: - ก่อนอื่นเราแปลงตัวถูกดำเนินการ xxเป็นสตริงและจากนั้นกำหนดว่ากลับไป เราจะต้องใช้ตัวแทนสตริงอีกครั้งในภายหลังดังนั้นการทำเช่นนี้จึงเป็นการบันทึกอักขระ
  • .:' - แปลง (.: ) แต่ละ'หลัก( ) หลักกลับเป็นตัวเลข
  • -2#0, - ใส่ 0 ต่อท้ายรายการหลัก (ในกรณีที่เป็นตัวเลขหลักเดียว) จากนั้นใช้สองครั้งสุดท้าย
  • {y*(y<4)*~1=x}.- ใช้ตัวเลขสองหลักเป็นอาร์กิวเมนต์xและใช้yกับฟังก์ชันภายในนี้ซึ่งส่งคืนyถ้าyน้อยกว่า 4 และxไม่เท่ากับ 1 มิฉะนั้นเป็น 0
  • `th`st`nd`rd@ - จัดทำดัชนีรายการคำต่อท้ายด้วยผลลัพธ์นี้
  • x,$ - แปลงคำต่อท้ายจากสัญลักษณ์เป็นสตริงและผนวกเข้ากับหมายเลขเดิม

การใช้งาน:

  {x,$`th`st`nd`rd@{y*(y<4)*~1=x}.-2#0,.:'x$:} 3021
"3021st"
  {x,$`th`st`nd`rd@{y*(y<4)*~1=x}.-2#0,.:'x$:}' 1 2 3 4 11 12 13 14  /for each in list
("1st"
 "2nd"
 "3rd"
 "4th"
 "11th"
 "12th"
 "13th"
 "14th")

1

C - 95 83 ตัวอักษร

main(n,k){scanf("%d",&n);k=(n+9)%10;printf("%d%s\n",n,k<3?"st\0nd\0rd"+3*k:"th");}

Degolfed:

main(n,k)
{
    scanf("%d",&n);
    k=(n+9)%10; // xx1->0, xx2->1, xx3->2
    printf("%d%s\n",n,k<3?"st\0nd\0rd"+3*k:"th");
}

เราสามารถทำได้k=(n-1)%10แทนที่จะเพิ่ม 9 แต่สำหรับ n = 0 เราจะได้รับพฤติกรรมที่ไม่ถูกต้องเพราะใน C (-1)%10ประเมินถึง -1 ไม่ใช่ 9



1

PHP, 98 ไบต์

function c($n){$c=$n%100;$s=['','st','nd','rd'];echo$c>9&&$c<14||!$s[$c%10]?$n.'th':$n.$s[$c%10];}

บิตที่ 11-13 กำลังฆ่าฉันที่นี่ $n >= 0การทำงานสำหรับจำนวนเต็มใด ๆ

สำหรับจำนวนเต็มใด ๆ$n:

PHP, 103 ไบต์

function c($n){$c=abs($n%100);$s=['','st','nd','rd'];echo$c>9&&$c<14||!$s[$c%10]?$n.'th':$n.$s[$c%10];}

1

Python, 88 84 ไบต์

lambda x:x+((('th','st','nd','rd')+('th',)*6)[int(x[-1])]if('0'+x)[-2]!='1'else'th')

Ungolfed:

def y(x):
    return x + (('th', 'st', 'nd', 'rd') + ('th', ) * 6)[int(x[-1])] if ('0' + x)[-2] != '1' else 'th')

lambda xxกำหนดฟังก์ชั่นที่ไม่ระบุชื่อกับพารามิเตอร์ ((('th','st','nd','rd')+('th',)*6)[int(x[-1])]กำหนด tuple ของตอนจบสำหรับตัวเลขที่น้อยกว่า 10 0-thองค์ประกอบสำหรับ0และอื่น ๆ if ('0'+x)[-2] != '1'การตรวจสอบหากมี11, 12หรือ13ในการแก้ไขปัญหาและเพิ่มแล้วelse 'th'เพิ่มthแทนst, หรือrdnd


นี่เป็นคำตอบที่ดี แต่ฉันต้องใช้เวลาสักพักกว่าจะเข้าใจและเข้าใจ หากคุณสามารถเพิ่มคำอธิบายรหัสและรายละเอียดด้านล่างรหัสรุ่น golfed มันจะช่วยให้ผู้คนเรียนรู้จากรหัสของคุณและปรับปรุงคุณภาพของคำตอบของคุณ
wizzwizz4

ตกลงฉันจะ. ฉันควรเพิ่มคำตอบที่ยังไม่ตีกอล์ฟด้วยหรือไม่
NoOneIsHere ที่

มันไม่ควรจะเป็นคำตอบที่ต่างออกไป ... สิ่งที่คุณได้ทำไปแล้วนั้นทำได้ดีมาก หากคุณต้องการความท้าทายมากกว่านี้ฉันสามารถให้คำแนะนำได้
wizzwizz4

ตกลง. คุณสามารถลอง ... ปรับเก้าอี้ของคุณหรือเพื่อนของคุณจะนั่งที่ไหน หรือคุณอาจจะลองบางส่วนของความท้าทายของฉันเช่นอัศวินทัวร์ถัดไป หากสิ่งเหล่านี้ไม่ใช่ความท้าทายที่คุณชอบให้พูด
wizzwizz4

1

JavaScript (Node.js) , 51 ไบต์

ให้เครดิตกับ @KevinCruijssen เพื่อปรับปรุงคำตอบ

n=>n+=[,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th'

ลองออนไลน์!


คำอธิบาย:

n =>                      // input
    n+=[,'st','nd','rd']     // the array of suffices add everything to n
        [~~(n/10%10)-1?n%10:0] // the full magic 
    || 'th'               // works for everything except 1 , 2 , 3 just like what you want


1

R , 79 76 ไบต์

เนื่องจากยังไม่มีวิธีแก้ปัญหา R ... ไม่มีกลอุบายที่นี่การทำดัชนีเวกเตอร์ขั้นพื้นฐานลงไป 3 ตัวอักษรขอบคุณ Giuseppe พยายามก่อนหน้านี้ดัชนี: และ [1+(x%%10)-(x%%100==11)][1+(x%%10)*(x%%100!=11)]

function(x)paste0(x,c("th","st","nd","rd",rep("th",6))[1+x%%10*!x%%100==11])

ลองออนไลน์!

ด้วยsubstr79 ไบต์:

function(x,y=1+2*min(x%%10-(x%%100==11),4))paste0(x,substr("thstndrdth",y,y+1))

ลองออนไลน์!


1
1+x%%10*!x%%100==11สำหรับดัชนี?
Giuseppe

@Giuseppe ฉันต้องการที่จะสงบสติอารมณ์ในวงเล็บ :) เคลฟเวอร์ใช้ในหน้าของการแสดงออกแทน! !=
JayCe

1
ใช่ผู้ประกอบการมีความสำคัญแปลก ๆ ; ^สูงจริงๆแล้ว%%ผู้ประกอบการประเภทแล้ว*/และ+-และฉันคิดว่า==และ&|มาต่อไป !มีลำดับความสำคัญค่อนข้างต่ำเพื่อให้คุณสามารถใช้เป็นตัวคั่นระหว่างการดำเนินการ
Giuseppe

0

Python 2.7, 137 ตัวอักษร

def b(n):
 for e,o in[[i,'th']for i in['11','12','13']+list('4567890')]+[['2','nd'],['1','st'],['3','rd']]:
  if n.endswith(e):return n+o

n ควรเป็นสตริง

ฉันรู้ว่าฉันแพ้การแข่งขันที่นี่มาแล้ว แต่ฉันคิดว่าฉันจะให้ความคิดของฉันต่อไป

เพียงแค่นี้โดยทั่วไปจะสร้างรายการของคีย์คู่ค่าที่มีจำนวน (เป็นสตริง) สิ้นสุดและลำดับe oมันพยายามที่จะจับคู่ 'th' ก่อน (ดังนั้นทำไมฉันไม่ใช้พจนานุกรม) เพื่อที่มันจะไม่กลับมา 'st' โดยไม่ตั้งใจเช่นเมื่อมันควรจะเป็น 'th' สิ่งนี้จะใช้ได้กับจำนวนเต็มบวกใด ๆ


n[-1]==eน้อยกว่า 5 ตัวอักษรn.endswith(e)
hlt

0

C: 95 ตัวอักษร

ทางออกอันยาวนานที่น่าขัน:

n;main(){scanf("%d",&n);printf("%d%s",n,n/10%10-1&&(n=n%10)<4&&n?n>2?"rd":n<2?"st":"nd":"th");}

จะต้องมีการ mangled เพิ่มเติม


ผู้ใช้ตั้งค่าสถานะว่า"ไม่ถูกต้อง: ไม่วนซ้ำเลยนั่นคือใช้ได้เฉพาะกับตัวเลขที่กำหนดไม่ใช่ตัวเลขทั้งหมด _all_ ด้านล่างดู ideone.com/pO6UwV" นั่นไม่ใช่เหตุผลในการตั้งค่าสถานะเป็นผู้ดูแลไม่ตัดสินความถูกต้อง แต่อาจเป็นปัญหา
dmckee

ตามความคิดเห็นนี้จากผู้สร้างคำถาม: "@Ilmari ฉันกำลังมองหา 11 เป็นอินพุทและ 11 ในฐานะเอาท์พุทฉันไม่สนใจว่ามันจะประมวลผลหลายบรรทัด 20 '12 เวลา 21:00 น. "กำลังทำสิ่งที่ควรทำ คือควรประมวลผลหมายเลขเดียวเท่านั้น
Fors

ขอโทษสำหรับธงนั้น ฉันอ่านข้อกำหนดผิดและไม่มีตัวแทนเพียงพอในเวลาที่จะแสดงความคิดเห็นโดยตรง ขอโทษอีกครั้ง. :)
Will Ness



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