Xuất số thứ tự (thứ 1, thứ 2, thứ 3)


43

Tôi muốn tạo (như là kết quả trả về của hàm, hoặc đơn giản là đầu ra của chương trình) hậu tố thứ tự của một số nguyên dương được nối với số.

Mẫu:

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

Và như vậy, với hậu tố lặp lại mẫu con 1-10 ban đầu cứ sau 10 đến 100, trong đó mẫu cuối cùng bắt đầu lại.

Đầu vào sẽ là số và đầu ra chuỗi thứ tự như hình trên.

Thuật toán nhỏ nhất cho việc này là gì?


Xin chào, NickC và chào mừng bạn đến với codegolf.SE! Chỉ cần làm rõ, bạn có nghĩa là chúng ta nên đọc một số như 11đầu vào và đầu ra, ví dụ 11th? Có phải mỗi số trong đầu vào trên một dòng riêng biệt và các số đầu ra cũng nằm trên các dòng riêng biệt? Và chúng ta có cần xử lý nhiều hơn một dòng đầu vào không?
Ilmari Karonen

1
Bạn đang tìm kiếm thuật toán nhỏ nhất hoặc mã nhỏ nhất?
Toto

@Ilmari Tôi đang tìm kiếm 11như đầu vào và 11thđầu ra. Tôi không phiền nếu nó xử lý nhiều dòng nhưng những gì tôi có trong đầu chỉ là xử lý một số duy nhất.
Nicole

@ M42 Bạn biết đấy, tôi không chắc lắm. Tôi không có một yêu cầu nghiêm ngặt - nhưng có lẽ tôi đã nghĩ đến thuật toán nhỏ nhất.
Nicole

Câu trả lời:


30

Perl, 37 + 1 ký tự

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

Đây là một sự thay thế regrec gắn thêm hậu tố thứ tự thích hợp cho bất kỳ số nào trong $_đó chưa được theo sau bởi một chữ cái. Để áp dụng nó cho đầu vào tập tin, sử dụng pchuyển đổi dòng lệnh, như thế này:

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

Đây là một chương trình Perl hoàn chỉnh, đọc đầu vào từ stdin và ghi đầu ra được xử lý vào thiết bị xuất chuẩn. Mã thực tế dài 37 ký tự, nhưng công ptắc được tính là một ký tự phụ .

Đầu vào mẫu:

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

Đầu ra:

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

Các số đã được theo sau bởi các chữ cái sẽ bị bỏ qua, do đó, việc cung cấp lại đầu ra thông qua bộ lọc sẽ không thay đổi nó. Dấu cách, dấu phẩy và dấu chấm giữa các số không được xử lý đặc biệt, vì vậy chúng được giả định là tách các số như bất kỳ dấu câu nào khác. Vì vậy, ví dụ 3.14159trở thành 3rd.14159th.

Làm thế nào nó hoạt động?

  • Đầu tiên, đây là một sự thay thế regrec toàn cầu ( s///g). Biểu thức chính quy được khớp là 1?\d\b, trong đó \dkhớp với bất kỳ chữ số nào và \blà xác nhận có độ rộng bằng 0 khớp với ranh giới giữa chữ và số và ký tự không chữ và số. Do đó, 1?\d\bkhớp với chữ số cuối của bất kỳ số nào, cộng với chữ số trước nếu nó xảy ra 1.

  • Trong phần thay thế, được đánh giá là mã Perl do /echuyển đổi, chúng tôi lấy đoạn chuỗi khớp ( $&) và nối ( .) với hậu tố có được bằng cách sử dụng $&chính nó làm chỉ số nguyên cho danh sách (0,st,nd,rd); nếu hậu tố này bằng 0 hoặc không xác định (nghĩa là khi $&bằng 0 hoặc lớn hơn ba), ||toán tử thay thế nó bằng th.


Chỉnh sửa: Nếu đầu vào bị giới hạn ở một số nguyên, thì giải pháp 35 ký tự này sẽ đủ:

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

1
Sẽ có thể loại gbỏ sự thay thế nếu bạn chỉ định rằng mỗi số phải nằm trên dòng riêng của nó. Ngoài ra, điều đó sẽ cho phép bạn thay đổi ranh giới từ thành $. Nhưng nhìn chung, +1, giải pháp thông minh chết tiệt.
Ông Llama

@GigaWatt: Thật vậy, tôi đã viết mã trước khi NickC trả lời câu hỏi của tôi về định dạng đầu vào, vì vậy tôi đã làm cho nó chung chung nhất có thể.
Ilmari Karonen

38

Python 2, 49 byte

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

Một chức năng ẩn danh. Một chương trình đầy đủ sẽ được tính ở 55 byte.

'tsnrhtdd'[i::4]mã hóa các hậu tố th st nd rdcho các giá trị itừ 0 đến 3. Với điều này, tất cả những gì chúng ta cần là một cách để ánh xạ các giá trị của nchỉ mục của hậu tố tương ứng , i. Một biểu hiện đơn giản mà làm việc là (n%10)*(n%10<4 and 10<n%100<14). Chúng ta có thể dễ dàng rút ngắn điều này bằng cách bỏ tập ngoặc đơn đầu tiên và quan sát n%5cho kết quả tương tự như n%10đối với các giá trị nvới các hậu tố đặc biệt. Với một chút thử nghiệm và lỗi, người ta cũng có thể rút ngắn 10<n%100<14lại n%100^15>4, có thể được kết nối với điều kiện khác để lưu nhiều byte hơn.


3
đây là một số ma thuật đen ngay tại đây c:
con mèo


Tôi không hiểu Bất cứ ai có thể giải thích những gì đang xảy ra ở đây?
Pavel

@Pavel Tôi đã cập nhật câu trả lời của tôi với một lời giải thích.
xsot

Tuyệt vời! Cách suy nghĩ tuyệt vời ...
Benison Sam

10

Con trăn, 68 ký tự

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

4
Điều này thực sự muộn, nhưng bạn có thể lấy ra 7 byte bằng cách thực hiện `i`+"tsnrhtdd". Nếu không, đây là giải pháp chính xác tôi vừa có.
DLosc

10

Toán học 39 45 byte

Lưu ý: Trong các phiên bản gần đây của Mathicala, yêu cầu nthmột phần của p, nơi pkhông xác định, sẽ tạo ra một thông báo lỗi, nhưng dù sao cũng trả lời đúng. Tôi đã thêm Quietđể ngăn thông báo lỗi in.

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

Sử dụng

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

Ngày 31

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

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


Làm thế nào nó hoạt động

SpokenStringviết ra một biểu thức Mathicala hợp lệ vì nó có thể được nói. Dưới đây là hai ví dụ từ tài liệu cho SpokenString ,

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

"Căn bậc hai của số lượng x so với số lượng y cộng với z" *)

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

"một đồ họa ba chiều bao gồm các quả cầu đơn vị tập trung tại 0, 0, 0 và 1, 1, 1"


Bây giờ, ví dụ trong tầm tay,

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

"yếu tố thứ 31 của p"

Hãy biểu diễn chuỗi trên dưới dạng danh sách các từ:

StringSplit[%]

{"the", "31", "phần tử", "của", "p"}

và lấy yếu tố thứ hai ...

%[[2]]

Ngày 31


Tôi bối rối; được pđịnh nghĩa ở đâu? EDIT: đừng bận tâm, tôi thấy bạn đang sử dụng cái này như thế nào; Thật không may, nó không hoạt động trên hệ thống của tôi. : - /
Mr.Wizard

Nó hoạt động trên v.9.0.1. (Tôi dường như nhớ lại rằng bạn đang sử dụng 7.0.) Có, p không cần xác định.
DavidC

Tôi hiểu điều đó bây giờ. Tuy nhiên, trong v7 tôi nhận được từ SpokenString @ p[[117]]đầu ra " part 117 of p".
Mr.Wizard

Vì vậy, SpokenStringđược sửa đổi theo thời gian. Tôi sẽ không ngạc nhiên khi mã này ( codegolf.stackexchange.com/questions/8859/ mẹo ) cũng không hoạt động trên câu 7. BTW, nó không có nghĩa là một giải pháp lâu dài.
DavidC

Hah, tôi đã không thấy câu trả lời trước đó.
Mr.Wizard

7

Hồng ngọc, 60

Nó không tốt như mục Perl, nhưng tôi nghĩ rằng tôi sẽ làm việc với các kỹ năng Ruby của mình.

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

Hàm lấy một đối số nguyên nvà trả về một chuỗi dưới dạng thứ tự.

Hoạt động theo logic sau:
Nếu chữ số hàng chục là 1 hoặc chữ số lớn hơn 3, hãy sử dụng hậu tố 'th'; mặt khác, tìm hậu tố từ mảng ['th', 'st', 'nd', 'rd'] bằng cách sử dụng chữ số cuối cùng làm chỉ mục.


o(113)"113rd", nên được "113th". Kiểm tra hàng chục chữ số không chiếm các số có nhiều hơn hai chữ số.
hammar

Ok, ném vào một cái khác %10để bù đắp. Đã thêm 3 ký tự. (Tôi cảm thấy như %10xuất hiện đủ ở nơi cần rút ngắn bằng cách nào đó, nhưng tôi không thể nghĩ ra giải pháp)
Ông Llama

Bạn không bao giờ có thể đánh bại Perl bằng cách viết mã khó hiểu khủng khiếp đó càng ngắn càng tốt :)
jamylak

Đặt một biến thành 10?
wizzwizz4

Tôi nghĩ rằng thiết lập một biến n%10là tốt hơn.
Máy

6

Javascript (ES6) 50 44 Byte (không cạnh tranh)

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

Ghi chú

  • lấy imput như một chuỗi
  • Đã xóa 6 byte, cảm ơn @ user81655

1
a+-> a+=, xóa dấu ngoặc đơn, \d-> ., xóa [0]và nếu bạn lấy số dưới dạng chuỗi: a.match`1?.$`thay vì /1?.$/.exec(a).
dùng81655

Bạn có lẽ nên thêm một thông báo câu trả lời này là không cạnh tranh, vì ES6 không tồn tại khi thử thách được đăng.
dùng2428118

5

Javascript, 68 71

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

Nỗ lực chung với ItsCosmo.

EDIT: Không hoạt động đúng với số> 100


Bạn có thể hạ nó xuống còn 62 với: function o(n)n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')và bạn có thể hạ nó xuống còn 54 nếu bạn vui lòng sử dụng ký hiệu mũi tên béo:o=n=>n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')
WallyWest

@WallyWest Vì một số lý do, tôi thực sự thích rằng giải pháp của tôi hoạt động trong các trình duyệt hiện đại. Hãy đăng câu trả lời của riêng bạn; Tôi nghĩ rằng nó đủ khác nhau.
aebabis

Không, việc ấy chẳng có chi! Chỉ cần cung cấp một vài lựa chọn thay thế!
WallyWest

3

Golf, 34 ký tự

~.10/10%1=!1$10%*.4<*'thstndrd'2/=

3

Haskell, 95 ký tự

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

Kiểm tra:

*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"]

Phải được tải với -XNoMonomorphismRestriction.


3

JavaScript, 64 ký tự (ES3) hoặc 47 ký tự (ES6)

ES3 (64 ký tự):

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

ES6 (47 ký tự):

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

Giải trình

Biểu thức ước tính n % 100 >> 3 ^ 1thành 0 cho bất kỳ nkết thúc tích cực nào với các chữ số 08- 15. Như vậy, đối với bất kỳ n mod 100kết thúc bằng 11, 12hay 13, lợi nhuận mảng tra cứu undefined, dẫn đến một hậu tố của th.

Đối với bất kỳ dương nkết thúc ở con số khác hơn 08- 15, khái niệm n % 100 >> 3 ^ 1để đánh giá một số nguyên dương, gọi sự biểu hiện n % 10cho tra cứu mảng, trở về st, ndhoặc rdcho nđó kết thúc với 1, 2hoặc 3. Nếu không , th.


Lưu một byte với n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'.
Xù xì

@Shaggy, cảm ơn, cập nhật theo đề xuất.
Tomas Langkaas


@ guest271314, rất vui khi thấy mã này được sử dụng. Lưu ý rằng nó chỉ hoạt động cho các số dương, một cách khác là n+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th", được điều chỉnh từ bài đăng này .
Tomas Langkaas

3

APL (Dyalog Unicode) , 38 36 byte

Cảm ơn ngn đã sửa lỗi trong khi duy trì số byte.

Chức năng tiền tố ẩn danh. Yêu cầu ⎕IO( I ndex O rigin) được đặt thành 0mặc định trên nhiều hệ thống. Thậm chí hoạt động cho 0!

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

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

{... } lambda vô danh; là đối số:

⍳4 bốn đầu tiên ɩ ndices;[0,1,2,3]

10↑ lấy mười yếu tố đầu tiên từ đó, đệm bằng số không: [0,1,2,3,0,0,0,0,0,0]

 kèm theo để coi như là một yếu tố duy nhất; [[0,1,2,3,0,0,0,0,0,0]]

1 0 8\ mở rộng thành một bản sao, một bản sao nguyên mẫu (tất cả bằng không), tám bản sao;
  [[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 thêm)
   [0,1,2,3,0,0,0,0,0,0]]

ε nlist (flatten);
  [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 nữa)
   0,1,2,3,0,0,0,0,0,0]

⍵⌽ xoay vòng theo chu kỳ trái nhiều bước như được chỉ ra bởi đối số

 chọn số đầu tiên (tức là số đối số-mod-100'th)

 nhân hai bằng cách đó (cho 0, 2, 4, hay 6)

'thstndrd'↓⍨bỏ nhiều ký tự từ chuỗi này

2↑ lấy hai ký tự đầu tiên

⍕, nối các đối số được sắp xếp theo đó


"thứ 31"?
ngn

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

xin lỗi, tôi quên đề cập đến ⎕io←0. Tôi có thể thấy bạn đoán điều đó, nhưng có một vài 1,2,3,4,0,0 ... sẽ là 0,1,2,3,0,0 ...
ngn

@ngn Đã sửa. Và xảy ra để làm việc cho 0 quá!
Adám

2

PowerShell, 92

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

Hoạt động với một số trên mỗi dòng đầu vào. Đầu vào được đưa ra thông qua các đường ống. Làm cho nó hoạt động chỉ với một số duy nhất không làm giảm kích thước.


2

J - 44 char

Không có gì trong J? Đó là một sự xúc phạm!

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

Giải thích (lưu ý rằng 1boolean đúng trong J và 0là sai):

  • 10 10(...)/@#:]- Đầu tiên chúng ta lấy đối số ( ]) và tìm chữ số hàng chục và một ( 10 10 #:). Sau đó, chúng tôi sẽ chèn (...)giữa hai.
  • (]*[(~:*])4>])- Trong phần phụ này, nhưng không phải là phần trong cùng, ]sẽ trỏ đến chữ số một và [chữ số hàng chục.
  • [(~:*])4>]- ~:là J cho "không bằng", do đó, kết quả này có 4>]nghĩa là (có hay không một chữ số nhỏ hơn 4) và nhân nó với kết quả của tens ~: (4>]). Tại sao mọi người sẽ làm điều này? Hãy xem xét những điều sau đây:
    • Nếu chúng ta đang kiểm tra 10, 11, 12, 13, sau đó tens1(chúng ta đang ở tuổi thiếu niên) và onesnhỏ hơn 4, vì vậy tens ~: (4>])là sai và kết quả là 0*1= 0.
    • Nếu chúng ta là bất kỳ ai khác trong {X0, X1, X2, X3}, thì rõ ràng tens ~: (4>])là đúng và chúng ta thoát ra 1*1= 1.
    • Nếu oneslớn hơn bốn, sau đó 4>]đã 0và nó không có vấn đề gì xảy ra với thử nghiệm nữa, chúng ta sẽ nhận 0ra không phân biệt.
    • Vì vậy, để tóm tắt, [(~:*])4>]1nếu chúng ta ở {X0, X1, X2, X3} nhưng không phải ở thanh thiếu niên, và 0nếu không.
  • ]*- Cuối cùng, chúng tôi nhân kết quả đó với các chữ số. Vì vậy, sản phẩm này sẽ là 0nếu số xứng đáng với một 'th'hậu tố, khác với giá trị của nó.
  • th`st`nd`rd{::~- Chúng tôi sử dụng các chữ số đã được sửa đổi từ phía trên để lập chỉ mục danh sách các hậu tố. 0được 'th', 1được 'st', và như vậy.
  • ":,- Cuối cùng, lấy số gốc, chuyển đổi nó thành một chuỗi ( ":) và sau đó thêm nó vào hậu tố.

Cách sử dụng là hiển nhiên, mặc dù động từ chỉ có thể lấy một thứ tự, không phải là một danh sách.

   (":,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 byte

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

Chương trình đầy đủ và xác minh:

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

Bạn có thể đánh gôn bằng hai byte bằng cách thay đổi ||thành |.
Kevin Cruijssen

2

Toán học 29 + 5 = 34 byte

SpokenStringDump`SpeakOrdinal

+5 byte vì Speakhàm phải được gọi trước khi sử dụng tích hợp này.

Sử dụng

SpokenStringDump`SpeakOrdinal[1]

"1st "

SpokenStringDump`SpeakOrdinal[4707]

"4,707th "


1

PHP, 151

Tôi biết rằng chương trình này không thể so sánh với những người khác. Chỉ cảm thấy như đưa ra một giải pháp.

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

bạn có thể lưu một vài ký tự bằng cách sử dụngforeach($s as $n){echo$n;
karthik

1

Scala 86

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

Scala 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 cũng vậy:

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"

vô dụng:

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

1

Tháng 10

Tôi khá mới với OCaml, nhưng đây là lần ngắn nhất tôi có thể nhận được.

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

Tôi đã tạo một hàm n lấy một số làm tham số và thực hiện công việc. Nó dài nhưng nghĩ rằng thật tuyệt khi có một ví dụ chức năng.


đầu vào: 11 sẽ mang lại đầu ra: 11

Vâng, bạn đã đúng .. Tôi đã thực hiện chỉnh sửa. Cảm ơn
Joseph Elcid

Tôi vừa thu dọn định dạng trên mã của bạn. Mỗi dòng cần được đi trước bởi bốn khoảng trắng để được nhận dạng là một khối mã.
Gareth

Sẽ không phải là lần đầu tiên của bạn nếu kiểm tra được ngắn hơn if v>10 && v<14? Tôi không quen thuộc với ocaml, nhưng có cần thiết phải có string_vbiến quá dài không?
Gaffi

Không cần thiết, tôi có thể chọn w hoặc x. Chỉ muốn một cái gì đó có ý nghĩa. Nhưng bạn đã đúng, nó sẽ làm cho mã ngắn hơn một chút.
Joseph Elcid

1

K - 44 char

Nó thực sự xảy ra rằng điều này chính xác như J, và hoạt động theo cách tương tự.

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

Giải thích:

  • x$:- Đầu tiên, chúng tôi chuyển đổi toán hạng xthành một chuỗi, sau đó gán lại cho x. Chúng ta sẽ cần đại diện chuỗi của nó một lần nữa sau đó, vì vậy thực hiện nó bây giờ sẽ lưu các ký tự.
  • .:'- Chuyển đổi ( .:) mỗi 'chữ số ( ) trở lại thành một số.
  • -2#0, - Nối số 0 vào trước danh sách các chữ số (trong trường hợp số có một chữ số), sau đó lấy hai số cuối.
  • {y*(y<4)*~1=x}.- Sử dụng hai chữ số làm đối số xycho hàm bên trong này, trả về ynếu ynhỏ hơn 4 và xkhông bằng 1, nếu không thì 0.
  • `th`st`nd`rd@ - Lập chỉ mục danh sách các hậu tố theo kết quả này.
  • x,$ - Chuyển đổi hậu tố từ ký hiệu thành chuỗi và nối nó với số ban đầu.

Sử dụng:

  {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 ký tự

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

Bị thoái hóa:

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

Chúng ta có thể làm k=(n-1)%10thay vì thêm 9, nhưng với n = 0, chúng ta sẽ có một hành vi không chính xác, bởi vì trong C (-1)%10ước tính là -1 chứ không phải 9.


1

Javascript, 75

function s(i){return i+'thstndrd'.substr(~~(i/10%10)-1&&i%10<4?i%10*2:0,2)}

1

PHP, 98 byte

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

Các bit 11-13 đang giết tôi ở đây. Hoạt động cho bất kỳ số nguyên $n >= 0.

Đối với bất kỳ số nguyên nào $n:

PHP, 103 byte

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 byte

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

Ung dung:

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

lambda xđịnh nghĩa một hàm ẩn danh với tham số x. ((('th','st','nd','rd')+('th',)*6)[int(x[-1])]định nghĩa một bộ kết thúc cho các số nhỏ hơn 10, 0-thphần tử dành cho 0, v.v. các if ('0'+x)[-2] != '1'kiểm tra nếu có 11, 12hoặc 13để sửa chữa và bổ sung thêm sau đó else 'th'cho biết thêm ththay vì st, rdhoặc nd.


Đây là một câu trả lời tuyệt vời, nhưng tôi phải mất một thời gian để đi qua và hiểu nó. Nếu bạn có thể thêm phần giải thích mã và phân tích bên dưới phiên bản mã được đánh golf, nó sẽ giúp mọi người tìm hiểu từ mã của bạn và cải thiện chất lượng câu trả lời của bạn.
wizzwizz4

Ok, tôi sẽ làm. Tôi cũng nên thêm một câu trả lời không chơi gôn?
NoOneIsĐây là

Đó không phải là một câu trả lời khác nhau ... Những gì bạn đã làm là tốt, hoàn thành tốt. Nếu bạn muốn có thêm bất kỳ thử thách nào, tôi có thể đưa ra một số khuyến nghị.
wizzwizz4

Đồng ý. Bạn có thể thử ... Điều chỉnh ghế của bạn , hoặc bạn bè của bạn sẽ ngồi ở đâu . Hoặc bạn có thể thử một số thử thách của tôi , chẳng hạn như Chuyến tham quan tiếp theo của Hiệp sĩ . Nếu đây không phải là loại thử thách bạn thích, chỉ cần nói.
wizzwizz4

1

JavaScript (Node.js) , 51 byte

tín dụng cho @KevinCruijssen để cải thiện câu trả lời

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

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


Giải trình :

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 byte

Vì chưa có giải pháp R nào cả ... không có thủ thuật nào ở đây, lập chỉ mục vectơ cơ bản, đánh gôn xuống 3 ký tự nhờ Giuseppe. Chỉ số đã thử trước đây: [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])

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

Với substr, 79 byte:

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

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


1
1+x%%10*!x%%100==11cho chỉ số?
Giuseppe

@Giuseppe Tôi cần bình tĩnh về dấu ngoặc đơn :). Khéo léo sử dụng !trước biểu hiện thay vì !=.
JayCe

1
Vâng, các nhà khai thác có ưu tiên kỳ lạ; ^thực sự là cao, sau đó %%các nhà khai thác kiểu, sau đó */+-và tôi nghĩ ==&|ra tiếp theo. !có mức độ ưu tiên khá thấp nên bạn có thể sử dụng nó như một dấu phân cách giữa các hoạt động.
Giuseppe

0

Python 2.7, 137 ký tự

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 nên là một chuỗi

Tôi biết tôi đã bị đánh bại bởi cuộc thi ở đây, nhưng tôi nghĩ rằng dù sao tôi cũng cung cấp ý tưởng của mình

điều này về cơ bản chỉ tạo ra một danh sách các cặp khóa, giá trị với số (dưới dạng chuỗi) kết thúc evà thứ tự o. Nó cố gắng khớp với 'lần đầu tiên' (do đó tại sao tôi không sử dụng từ điển), do đó, nó sẽ không vô tình trả lại 'st', ví dụ, khi nó phải là 'th'. Điều này sẽ làm việc cho bất kỳ số nguyên dương


n[-1]==elà 5 ký tự ngắn hơnn.endswith(e)
hlt

0

C: 95 ký tự

Một giải pháp dài vô lý:

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

Nó cần phải được đọc nhiều hơn.


Một người dùng đã gắn cờ câu nói này "không chính xác: hoàn toàn không lặp, tức là nó chỉ hoạt động với một số đã cho, không phải là _all_ số bên dưới nó. Xem ideone.com/pO6UwV." Đó không phải là một lý do để gắn cờ vì người điều hành không đánh giá tính đúng đắn, nhưng nó có thể là một vấn đề.
dmckee

Dựa trên nhận xét này từ người tạo câu hỏi: "@Ilmari Tôi đang tìm kiếm 11 là đầu vào và thứ 11 là đầu ra. Tôi không phiền nếu nó xử lý nhiều dòng nhưng điều tôi nghĩ là chỉ xử lý một số duy nhất. - NickC Jan 20 '12 lúc 21:00 "nó đang làm những gì cần làm. Tức là nó chỉ nên xử lý một số duy nhất.
Dành cho

xin lỗi vì lá cờ đó; Tôi đã đọc sai yêu cầu và không có đủ đại diện tại thời điểm đó, để bình luận trực tiếp. Xin lỗi lần nữa. :)
Will Ness

0

Javascript, 75

function o(s){return s+((0|s/10%10)==1?"th":[,"st","nd","rd"][s%10]||"th")}

0

Oracle SQL 11.2, 101 byte

SELECT:1||DECODE(ROUND(MOD(:1,100),-1),10,'th',DECODE(MOD(:1,10),1,'st',2,'nd',3,'rd','th'))FROM DUAL

0

Javascript ES6, 52 ký tự

n=>n+(!/1.$/.test(--n)&&'snr'[n%=10]+'tdd'[n]||'th')
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.