Menghasilkan angka urut (1, 2, 3)

43

Saya ingin menghasilkan (sebagai hasil kembali dari suatu fungsi, atau hanya sebagai output dari suatu program) akhiran ordinal dari bilangan bulat positif digabungkan ke nomor tersebut.

Sampel:

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

Dan seterusnya, dengan sufiks yang mengulangi sub-pola awal 1-10 setiap 10 hingga 100, di mana polanya dimulai dari awal.

Input akan menjadi nomor dan output string ordinal seperti yang ditunjukkan di atas.

Apa algoritma terkecil untuk ini?

Nicole
sumber
Hai, NickC, dan selamat datang di codegolf.SE! Hanya untuk memperjelas, apakah maksud Anda bahwa kita harus membaca angka seperti 11sebagai input, dan output misalnya 11th? Apakah setiap angka dalam input pada baris yang terpisah, dan haruskah nomor output juga pada baris yang terpisah? Dan apakah kita perlu menangani lebih dari satu jalur input?
Ilmari Karonen
1
Apakah Anda mencari algoritma terkecil atau kode terkecil?
Toto
@Ilmari Saya mencari 11sebagai input dan 11thoutput. Saya tidak keberatan jika memproses beberapa baris tetapi yang ada dalam pikiran saya hanya memproses satu nomor.
Nicole
@ M42 Anda tahu, saya tidak begitu yakin. Saya tidak memiliki persyaratan yang ketat - tetapi saya mungkin berpikir algoritma terkecil.
Nicole

Jawaban:

30

Perl, 37 + 1 karakter

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

Ini adalah substitusi regexp yang menambahkan akhiran ordinal yang sesuai untuk nomor $_yang belum diikuti oleh surat. Untuk menerapkannya pada input file, gunakan psaklar baris perintah, seperti ini:

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

Ini adalah program Perl lengkap yang membaca input dari stdin dan menulis output yang diproses ke stdout. Kode aktual adalah 37 karakter, tetapi psakelar dianggap sebagai satu karakter tambahan .

Input sampel:

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

Keluaran:

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

Angka yang sudah diikuti oleh huruf akan diabaikan, jadi mengumpankan output lagi melalui filter tidak akan mengubahnya. Spasi, koma, dan periode di antara angka tidak diperlakukan secara khusus, sehingga dianggap memiliki angka yang terpisah seperti tanda baca lainnya. Jadi, misalnya 3.14159menjadi 3rd.14159th.

Bagaimana cara kerjanya?

  • Pertama, ini adalah penggantian regexp global ( s///g). Regexp yang dicocokkan adalah 1?\d\b, di mana \dcocok dengan digit mana pun dan \bpernyataan lebar nol yang cocok dengan batas antara karakter alfanumerik dan non-alfanumerik. Dengan demikian, 1?\d\bcocok dengan digit terakhir dari nomor apa pun, ditambah digit sebelumnya jika itu terjadi 1.

  • Dalam substitusi, yang dievaluasi sebagai kode Perl karena /esaklar, kami mengambil segmen string yang cocok ( $&) dan menambahkan ( .) kepadanya sufiks yang diperoleh dengan menggunakan $&dirinya sebagai indeks integer ke daftar (0,st,nd,rd); jika sufiks ini nol atau tidak terdefinisi (yaitu ketika $&nol atau lebih besar dari tiga), ||operator menggantinya dengan th.


Sunting: Jika input dibatasi untuk satu integer, maka solusi 35 karakter ini sudah cukup:

s/1?\d$/$&.((0,st,nd,rd)[$&]||th)/e
Ilmari Karonen
sumber
1
Seharusnya bisa gmelepaskan substitusi jika Anda menentukan bahwa setiap nomor harus berada di jalurnya sendiri. Juga, itu akan membiarkan Anda mengubah batas kata menjadi $. Tapi secara keseluruhan, +1, solusi pintar.
Tn. Llama
@ GigaWatt: Memang, saya menulis kode sebelum NickC menjawab pertanyaan saya tentang format input, jadi saya membuatnya menjadi generik mungkin.
Ilmari Karonen
38

Python 2, 49 byte

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

Fungsi anonim. Sebuah program penuh akan dihitung pada 55 byte.

'tsnrhtdd'[i::4]mengkodekan sufiks th st nd rduntuk nilai idari 0 hingga 3. Dengan ini, yang kita butuhkan hanyalah cara untuk memetakan nilai nke indeks sufiks yang sesuai i,. Ekspresi langsung yang berfungsi adalah (n%10)*(n%10<4 and 10<n%100<14). Kita dapat dengan mudah mempersingkat ini dengan menjatuhkan set kurung pertama dan mengamati yang n%5memberikan hasil yang sama seperti n%10untuk nilai-nilai ndengan sufiks khusus. Dengan sedikit trial and error, yang satu juga bisa disingkat 10<n%100<14menjadi n%100^15>4, yang bisa dirantai dengan syarat lain untuk menyimpan lebih banyak byte.

xsot
sumber
3
ini adalah beberapa ilmu hitam di sini c:
cat
Saya tidak mengerti. Adakah yang bisa menjelaskan apa yang terjadi di sini?
Pavel
@Pavel Saya telah memperbarui jawaban saya dengan penjelasan.
xsot
Luar biasa! Cara yang brilian untuk berpikir ...
Benison Sam
10

Python, 68 karakter

i=input()
k=i%10
print"%d%s"%(i,"tsnrhtdd"[(i/10%10!=1)*(k<4)*k::4])
Gareth
sumber
4
Ini benar-benar terlambat, tetapi Anda dapat melepas 7 byte dengan melakukan `i`+"tsnrhtdd". Kalau tidak, ini adalah solusi tepat yang baru saja saya dapatkan.
DLosc
10

Mathematica 39 45 byte

Catatan: Dalam versi terbaru dari Mathematica, meminta nthbagian p, di mana ptidak terdefinisi, menghasilkan pesan kesalahan, tetapi tetap mengembalikan jawaban yang benar. Saya telah menambahkan Quietuntuk mencegah pesan kesalahan dari pencetakan.

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

Pemakaian

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

Tanggal 31

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

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


Bagaimana itu bekerja

SpokenStringmenulis ekspresi Mathematica yang valid karena mungkin diucapkan. Di bawah ini adalah dua contoh dari dokumentasi untuk SpokenString ,

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

"akar kuadrat dari jumlah x lebih dari jumlah y ditambah z" *)

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

"grafik tiga dimensi yang terdiri dari satuan bola yang berpusat pada 0, 0, 0 dan 1, 1, 1"


Sekarang, untuk contoh yang ada,

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

"elemen 31 dari p"

Mari kita mewakili string di atas sebagai daftar kata-kata:

StringSplit[%]

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

dan ambil elemen kedua ...

%[[2]]

Tanggal 31

DavidC
sumber
Saya bingung; dimana pdidefinisikan? EDIT: sudahlah, saya melihat bagaimana Anda menggunakan ini; sayangnya tidak berfungsi di sistem saya. : - /
Mr.Wizard
Ini bekerja pada v.9.0.1. (Sepertinya saya ingat Anda menggunakan 7.0.) Ya, p tidak perlu didefinisikan.
DavidC
Saya mengerti itu sekarang. Namun, dalam v7 saya dapatkan dari SpokenString @ p[[117]]output " part 117 of p".
Mr.Wizard
Jadi SpokenStringdirevisi dari waktu ke waktu. Saya tidak akan terkejut kalau kode ini ( codegolf.stackexchange.com/questions/8859/... ) juga tidak berfungsi pada v. 7. BTW, itu tidak dimaksudkan sebagai solusi yang bertahan lama.
DavidC
Hah, saya belum pernah melihat jawaban itu sebelumnya.
Mr.Wizard
7

Ruby, 60

Ini tidak sebagus entri Perl, tapi saya pikir saya akan bekerja pada keterampilan Ruby saya.

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

Function mengambil satu argumen integer n,, dan mengembalikan sebuah string sebagai bentuk ordinal.

Bekerja sesuai dengan logika berikut:
Jika puluhan digit adalah 1 atau digit yang lebih besar dari 3 gunakan akhiran 'th'; jika tidak, temukan akhiran dari array ['th', 'st', 'nd', 'rd'] menggunakan digit terakhir sebagai indeks.

Tuan Llama
sumber
o(113)adalah "113rd", seharusnya "113th". Cek puluhan digit tidak memperhitungkan angka dengan lebih dari dua digit.
hammar
Oke, pilih yang lain %10untuk mengganti rugi. Menambahkan 3 karakter. (Saya merasa %10cukup muncul di tempat yang seharusnya diperpendek, tetapi saya tidak bisa menemukan solusinya)
Tn. Llama
Anda tidak pernah bisa mengalahkan Perl dalam menulis kode mengerikan yang tidak bisa dimengerti itu sesingkat mungkin :)
jamylak
Tetapkan variabel ke 10?
wizzwizz4
Saya pikir pengaturan variabel menjadi n%10lebih baik.
CalculatorFeline
6

Javascript (ES6) 50 44 Bytes (tidak bersaing)

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

Catatan

  • mengambil imput sebagai string
  • Dihapus 6 byte, terima kasih @ user81655
Shaun H
sumber
1
a+-> a+=, hapus tanda kurung, \d-> ., hapus [0], dan jika Anda mengambil nomor sebagai string: a.match`1?.$`alih-alih /1?.$/.exec(a).
user81655
Anda mungkin harus menambahkan pemberitahuan bahwa jawaban ini tidak bersaing, karena ES6 tidak ada saat tantangan dipasang.
user2428118
5

Javascript, 68 71

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

Upaya bersama dengan ItsCosmo.

EDIT: Tidak berfungsi dengan benar dengan angka> 100

aebabis
sumber
Anda bisa membawanya ke 62 dengan: function o(n)n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')dan Anda bisa membawanya lebih jauh ke 54 jika Anda senang menggunakan notasi panah gemuk:o=n=>n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')
WallyWest
@WallyWest Untuk beberapa alasan, saya sangat suka bahwa solusi saya berfungsi di browser modern. Jangan ragu untuk mengirim jawaban Anda sendiri; Saya pikir ini cukup berbeda.
aebabis
Tidak, tidak apa-apa! Hanya memberikan beberapa alternatif!
WallyWest
3

Golfscript, 34 karakter

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

Haskell, 95 karakter

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

Pengujian:

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

Harus dimuat dengan -XNoMonomorphismRestriction.

Will Ness
sumber
3

JavaScript, 64 karakter (ES3) atau 47 karakter (ES6)

ES3 (64 karakter):

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

ES6 (47 karakter):

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

Penjelasan

Ekspresi n % 100 >> 3 ^ 1bernilai 0 untuk setiap nakhiran positif dengan digit 08- 15. Dengan demikian, untuk setiap n mod 100berakhir di 11, 12, atau 13, kembali array lookup undefined, yang mengarah ke akhiran th.

Untuk setiap positif nberakhir di angka selain 08- 15, ekspresi n % 100 >> 3 ^ 1mengevaluasi ke bilangan bulat positif, menyerukan ekspresi n % 10untuk array lookup, kembali st, ndatau rduntuk nyang berakhir dengan 1, 2atau 3. Jika tidak th,.

Tomas Langkaas
sumber
Simpan byte dengan n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'.
Shaggy
@ Shaggy, terima kasih, diperbarui seperti yang disarankan.
Tomas Langkaas
@ guest271314, asyik melihat kode ini digunakan. Perhatikan bahwa ini hanya berfungsi untuk angka positif, alternatif lain adalah n+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th", diadaptasi dari pos ini .
Tomas Langkaas
3

APL (Dyalog Unicode) , 38 36 byte

Terima kasih kepada ngn untuk memperbaiki bug sambil mempertahankan jumlah byte.

Fungsi awalan diam-diam anonim. Membutuhkan ⎕IO( I ndex O rigin) diatur ke 0, yang merupakan default pada banyak sistem. Bahkan bekerja untuk 0!

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

Cobalah online!

{... } lambda anonim; adalah argumen:

⍳4 empat penemuan pertama;[0,1,2,3]

10↑ ambil sepuluh elemen pertama dari itu, padding dengan nol: [0,1,2,3,0,0,0,0,0,0]

 melampirkan untuk memperlakukan sebagai elemen tunggal; [[0,1,2,3,0,0,0,0,0,0]]

1 0 8\ perluas satu salinan, salinan prototipikal (semuanya nol), delapan salinan;
  [[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 lebih banyak)
   [0,1,2,3,0,0,0,0,0,0]]

ϵ daftar (ratakan);
  [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 lebih banyak)
   0,1,2,3,0,0,0,0,0,0]

⍵⌽ putar secara siklik ke kiri sebanyak langkah yang ditunjukkan oleh argumen

 pilih angka pertama (yaitu argumen-mod-100'th number)

 kalikan dua dengan itu (memberikan 0, 2, 4, atau 6)

'thstndrd'↓⍨jatuhkan banyak karakter dari string ini

2↑ ambil dua karakter pertama yang tersisa

⍕, menggabungkan argumen yang dirumuskan untuk itu

Adm
sumber
"31"?
ngn
⍕,{2↑'thstndrd'↓⍨2×⊃⍵⌽∊1 0 8\⊂10↑⍳4}
ngn
maaf, saya lupa menyebutkan ⎕io←0. Saya dapat melihat Anda menebaknya, tetapi ada beberapa 1,2,3,4,0,0 ... yang seharusnya 0,1,2,3,0,0 ...
ngn
@ ngn Diperbaiki. Dan kebetulan bekerja untuk 0 juga!
Adám
2

PowerShell, 92

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

Bekerja dengan satu angka per baris input. Masukan diberikan melalui pipa. Membuatnya hanya berfungsi untuk satu nomor tidak mengurangi ukuran.

Joey
sumber
2

J - 44 char

Tidak ada dalam J? Ini adalah kemarahan!

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

Dijelaskan (perhatikan bahwa 1boolean benar dalam J dan 0salah):

  • 10 10(...)/@#:]- Pertama kita ambil argumen ( ]) dan menemukan puluhan dan digit satu ( 10 10 #:). Lalu, kita akan menyisipkan di (...)antara keduanya.
  • (]*[(~:*])4>])- Dalam sub-ekspresi ini, tetapi bukan yang paling dalam, ]akan menunjuk ke digit yang dan [digit puluhan.
  • [(~:*])4>]- ~:adalah J untuk "tidak sama dengan", jadi ini mengambil hasil 4>](yaitu apakah satu digit kurang dari 4) dan mengalikannya dengan hasil tens ~: (4>]). Mengapa ada orang yang melakukan hal ini? Pertimbangkan yang berikut ini:
    • Jika kita memeriksa 10, 11, 12, 13, maka tensadalah 1(kita berada di remaja) dan oneskurang dari 4, jadi tens ~: (4>])itu salah dan hasilnya adalah 0*1= 0.
    • Jika kita salah satu dari {X0, X1, X2, X3}, maka jelas tens ~: (4>])benar dan kita keluar 1*1= 1.
    • Jika oneslebih besar dari empat, maka 4>]sudah 0dan tidak masalah apa yang terjadi pada tes lagi, kita akan 0keluar terlepas.
    • Jadi untuk meringkas, [(~:*])4>]adalah 1jika kita berada di {X0, X1, X2, X3} tetapi tidak di remaja, dan 0sebaliknya.
  • ]*- Akhirnya kita mengalikan hasil itu dengan angka satu. Jadi produk ini akan menjadi 0jika nomor tersebut layak 'th'akhiran, kalau tidak nilainya.
  • th`st`nd`rd{::~- Kami menggunakan digit satu yang dimodifikasi dari atas untuk mengindeks daftar sufiks. 0mendapat 'th', 1mendapat 'st', dan sebagainya.
  • ":,- Akhirnya, ambil nomor aslinya, konversikan ke string ( ":), dan kemudian tambahkan ke akhiran.

Penggunaannya jelas, meskipun kata kerja apa adanya hanya bisa mengambil satu urutan, bukan daftar.

   (":,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|
+----+----+----+----+----+----+----+----+----+----+
algoritme hiu
sumber
2

C #, 62 byte

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

Program dan verifikasi lengkap:

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));
        }
    }
}
adrianmp
sumber
Anda dapat golf dengan dua byte dengan mengubah ||to |.
Kevin Cruijssen
2

Mathematica 29 + 5 = 34 byte

SpokenStringDump`SpeakOrdinal

+5 byte karena Speakfungsi harus dipanggil sebelum menggunakan built-in ini.

Pemakaian

SpokenStringDump`SpeakOrdinal[1]

"1st "

SpokenStringDump`SpeakOrdinal[4707]

"4,707th "

JungHwan Min
sumber
1

PHP, 151

Saya tahu bahwa program ini tidak sebanding dengan yang lain. Rasanya ingin memberikan solusi.

<?$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";}
l0n3sh4rk
sumber
Anda dapat menyimpan beberapa karakter dengan menggunakanforeach($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 juga:

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))
      }
Pengguna tidak diketahui
sumber
1

OCaml

Saya cukup baru di OCaml, tetapi ini adalah yang terpendek yang bisa saya dapatkan.

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

Saya membuat fungsi n yang mengambil angka sebagai parameter dan melakukan pekerjaan. Itu panjang tetapi berpikir itu akan bagus untuk memiliki contoh fungsional.

Joseph Elcid
sumber
input: 11 akan menghasilkan output: 11
ya, kamu benar .. Saya sudah melakukan koreksi. Terima kasih
Joseph Elcid
Saya baru saja merapikan pemformatan pada kode Anda. Setiap baris harus didahului oleh empat spasi agar dapat dikenali sebagai blok kode.
Gareth
Bukankah pertama Anda jika cek lebih pendek if v>10 && v<14? Saya tidak terbiasa dengan ocaml, tetapi apakah perlu memiliki string_vvariabel yang begitu lama?
Gaffi
Tidak itu tidak perlu, saya bisa memilih w atau x. Hanya menginginkan sesuatu yang bermakna. Tapi Anda benar, itu akan membuat kode sedikit lebih pendek.
Joseph Elcid
1

K - 44 char

Kebetulan bahwa ini persis sepanjang J, dan bekerja dengan cara yang hampir sama.

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

Dijelaskan:

  • x$:- Pertama, kita mengubah operan xmenjadi sebuah string, dan kemudian menetapkan itu kembali x. Kita perlu rep stringnya lagi nanti, jadi melakukannya sekarang menyimpan karakter.
  • .:'- Konversi ( .:) setiap ( ') digit kembali menjadi angka.
  • -2#0, - Tambahkan 0 di bagian depan daftar digit (untuk nomor satu digit), lalu ambil dua terakhir.
  • {y*(y<4)*~1=x}.- Gunakan dua digit sebagai argumen xdan yfungsi dalam ini, yang mengembalikan yjika ykurang dari 4 dan xtidak sama dengan 1, jika tidak 0.
  • `th`st`nd`rd@ - Buat indeks daftar sufiks berdasarkan hasil ini.
  • x,$ - Konversi akhiran dari simbol ke string, dan menambahkannya ke nomor asli.

Pemakaian:

  {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")
algoritme hiu
sumber
1

C - 95 83 karakter

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

Diturunkan:

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

Kita bisa melakukan k=(n-1)%10alih - alih menambahkan 9, tetapi untuk n = 0 kita akan mendapatkan perilaku yang salah, karena di C (-1)%10mengevaluasi menjadi -1, bukan 9.

pawel.boczarski
sumber
1

Javascript, 75

function s(i){return i+'thstndrd'.substr(~~(i/10%10)-1&&i%10<4?i%10*2:0,2)}
wolfhammer
sumber
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];}

Bit 11-13 membunuhku di sini. Bekerja untuk bilangan bulat apa pun $n >= 0.

Untuk bilangan bulat apa pun $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];}
ricdesi
sumber
1

Python, 88 84 byte

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

Tidak Disatukan:

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

lambda xmendefinisikan fungsi anonim dengan parameter x. ((('th','st','nd','rd')+('th',)*6)[int(x[-1])]mendefinisikan tuple dari ujung untuk angka kurang dari 10, 0-thelemen untuk 0, dan sebagainya. yang if ('0'+x)[-2] != '1'cek jika ada 11, 12, atau 13untuk memperbaiki, dan menambahkan kemudian else 'th'menambahkan thbukan st, rdatau nd.

Tidak Ada Di Sini
sumber
Ini adalah jawaban yang bagus, tetapi butuh beberapa saat untuk saya lalui dan memahaminya. Jika Anda dapat menambahkan penjelasan kode dan uraian di bawah versi golf kode Anda, itu akan membantu orang belajar dari kode Anda dan meningkatkan kualitas jawaban Anda.
wizzwizz4
Ok saya akan. Haruskah saya juga menambahkan jawaban tidak golf?
NoOneIsHere
Itu seharusnya bukan jawaban yang berbeda ... Apa yang Anda lakukan baik-baik saja, dilakukan dengan baik. Jika Anda ingin tantangan lagi dilakukan, saya bisa memberikan beberapa rekomendasi.
wizzwizz4
Baik. Anda dapat mencoba ... Menyesuaikan kursi Anda , atau Di mana teman Anda akan duduk . Atau Anda bisa mencoba beberapa tantangan saya , seperti The Knight's Next Tour . Jika ini bukan jenis tantangan yang Anda sukai, katakan saja.
wizzwizz4
1

JavaScript (Node.js) , 51 byte

kredit ke @KevinCruijssen untuk meningkatkan jawabannya

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

Cobalah online!


Penjelasan:

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


sumber
1

R , 79 76 byte

Karena belum ada solusi R ... belum ada trik di sini, pengindeksan vektor dasar, diturunkan 3 karakter berkat Giuseppe. Indeks yang sebelumnya dicoba: [1+(x%%10)-(x%%100==11)]dan [1+(x%%10)*(x%%100!=11)].

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

Cobalah online!

Dengan substr, 79 byte:

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

Cobalah online!

JayCe
sumber
1
1+x%%10*!x%%100==11untuk indeks?
Giuseppe
@ Giuseppe Saya harus tenang dengan tanda kurung :). Penggunaan cerdas !di depan ekspresi alih-alih !=.
JayCe
1
Ya, operator memiliki prioritas yang aneh; ^benar-benar tinggi, kemudian %%operator tipe, lalu */dan +-dan saya pikir ==dan &|datang berikutnya. !memiliki prioritas lebih rendah sehingga Anda dapat menggunakannya sebagai pemisah antara operasi.
Giuseppe
0

Python 2.7, 137 karakter

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 harus berupa string

Saya tahu saya sudah dikalahkan oleh kompetisi di sini, tapi saya pikir saya akan memberikan ide saya

ini pada dasarnya hanya menghasilkan daftar pasangan kunci, nilai dengan angka (sebagai string) yang berakhir edan ordinal o. Ia mencoba untuk mencocokkan 'th' terlebih dahulu (maka dari itu mengapa saya tidak menggunakan kamus), sehingga tidak akan sengaja mengembalikan 'st', misalnya, ketika seharusnya 'th'. Ini akan berfungsi untuk bilangan bulat positif

Jaket
sumber
n[-1]==eadalah 5 karakter lebih pendek darin.endswith(e)
HLT
0

C: 95 karakter

Solusi yang sangat panjang:

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

Itu perlu lebih hancur.

Untuk S
sumber
Seorang pengguna menandai pepatah ini "tidak benar: tidak berulang sama sekali, yaitu hanya berfungsi untuk nomor yang diberikan, bukan angka _all_ di bawahnya. Lihat ideone.com/pO6UwV." Itu bukan alasan untuk menandai karena moderator tidak menilai kebenaran, tetapi itu mungkin masalah.
dmckee
Berdasarkan komentar dari pencipta pertanyaan ini: "@Ilmari Saya mencari 11 sebagai input dan 11 sebagai output. Saya tidak keberatan jika memproses beberapa baris tetapi yang ada dalam pikiran saya hanya memproses satu nomor. - NickC Jan 20 '12 pukul 21:00 "sedang melakukan apa yang seharusnya. Yaitu hanya harus memproses satu nomor.
Fors
maaf untuk bendera itu; Saya salah membaca persyaratan, dan tidak memiliki cukup perwakilan pada saat itu, untuk berkomentar secara langsung. Maaf lagi. :)
Will Ness
0

Javascript, 75

function o(s){return s+((0|s/10%10)==1?"th":[,"st","nd","rd"][s%10]||"th")}
Inkbug
sumber
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
Jeto
sumber
0

Javascript ES6, 52 karakter

n=>n+(!/1.$/.test(--n)&&'snr'[n%=10]+'tdd'[n]||'th')
Qwertiy
sumber