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?
11
sebagai input, dan output misalnya11th
? 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?11
sebagai input dan11th
output. Saya tidak keberatan jika memproses beberapa baris tetapi yang ada dalam pikiran saya hanya memproses satu nomor.Jawaban:
Perl, 37 + 1 karakter
Ini adalah substitusi regexp yang menambahkan akhiran ordinal yang sesuai untuk nomor
$_
yang belum diikuti oleh surat. Untuk menerapkannya pada input file, gunakanp
saklar baris perintah, seperti ini:Ini adalah program Perl lengkap yang membaca input dari stdin dan menulis output yang diproses ke stdout. Kode aktual adalah 37 karakter, tetapi
p
sakelar dianggap sebagai satu karakter tambahan .Input sampel:
Keluaran:
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.14159
menjadi3rd.14159th
.Bagaimana cara kerjanya?
Pertama, ini adalah penggantian regexp global (
s///g
). Regexp yang dicocokkan adalah1?\d\b
, di mana\d
cocok dengan digit mana pun dan\b
pernyataan lebar nol yang cocok dengan batas antara karakter alfanumerik dan non-alfanumerik. Dengan demikian,1?\d\b
cocok dengan digit terakhir dari nomor apa pun, ditambah digit sebelumnya jika itu terjadi1
.Dalam substitusi, yang dievaluasi sebagai kode Perl karena
/e
saklar, 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 denganth
.Sunting: Jika input dibatasi untuk satu integer, maka solusi 35 karakter ini sudah cukup:
sumber
g
melepaskan 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.Python 2, 49 byte
Fungsi anonim. Sebuah program penuh akan dihitung pada 55 byte.
'tsnrhtdd'[i::4]
mengkodekan sufiksth st nd rd
untuk nilaii
dari 0 hingga 3. Dengan ini, yang kita butuhkan hanyalah cara untuk memetakan nilain
ke indeks sufiks yang sesuaii
,. 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 yangn%5
memberikan hasil yang sama sepertin%10
untuk nilai-nilain
dengan sufiks khusus. Dengan sedikit trial and error, yang satu juga bisa disingkat10<n%100<14
menjadin%100^15>4
, yang bisa dirantai dengan syarat lain untuk menyimpan lebih banyak byte.sumber
Python, 68 karakter
sumber
`i`+"tsnrhtdd"
. Kalau tidak, ini adalah solusi tepat yang baru saja saya dapatkan.Mathematica
3945 byteCatatan: Dalam versi terbaru dari Mathematica, meminta
nth
bagianp
, di manap
tidak terdefinisi, menghasilkan pesan kesalahan, tetapi tetap mengembalikan jawaban yang benar. Saya telah menambahkanQuiet
untuk mencegah pesan kesalahan dari pencetakan.Pemakaian
Bagaimana itu bekerja
SpokenString
menulis ekspresi Mathematica yang valid karena mungkin diucapkan. Di bawah ini adalah dua contoh dari dokumentasi untuk SpokenString ,Sekarang, untuk contoh yang ada,
Mari kita mewakili string di atas sebagai daftar kata-kata:
dan ambil elemen kedua ...
sumber
p
didefinisikan? EDIT: sudahlah, saya melihat bagaimana Anda menggunakan ini; sayangnya tidak berfungsi di sistem saya. : - /SpokenString @ p[[117]]
output" part 117 of p"
.SpokenString
direvisi 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.Ruby, 60
Ini tidak sebagus entri Perl, tapi saya pikir saya akan bekerja pada keterampilan Ruby saya.
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.
sumber
o(113)
adalah"113rd"
, seharusnya"113th"
. Cek puluhan digit tidak memperhitungkan angka dengan lebih dari dua digit.%10
untuk mengganti rugi. Menambahkan 3 karakter. (Saya merasa%10
cukup muncul di tempat yang seharusnya diperpendek, tetapi saya tidak bisa menemukan solusinya)10
?n%10
lebih baik.Javascript (ES6)
5044 Bytes (tidak bersaing)Catatan
sumber
a+
->a+=
, hapus tanda kurung,\d
->.
, hapus[0]
, dan jika Anda mengambil nomor sebagai string:a.match`1?.$`
alih-alih/1?.$/.exec(a)
.Javascript,
6871Upaya bersama dengan ItsCosmo.
EDIT: Tidak berfungsi dengan benar dengan angka> 100
sumber
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')
Golfscript, 34 karakter
sumber
Haskell, 95 karakter
Pengujian:
Harus dimuat dengan -XNoMonomorphismRestriction.
sumber
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 ^ 1
bernilai 0 untuk setiapn
akhiran positif dengan digit08
-15
. Dengan demikian, untuk setiapn mod 100
berakhir di11
,12
, atau13
, kembali array lookupundefined
, yang mengarah ke akhiranth
.Untuk setiap positif
n
berakhir di angka selain08
-15
, ekspresin % 100 >> 3 ^ 1
mengevaluasi ke bilangan bulat positif, menyerukan ekspresin % 10
untuk array lookup, kembalist
,nd
ataurd
untukn
yang berakhir dengan1
,2
atau3
. Jika tidakth
,.sumber
n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'
.n+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th"
, diadaptasi dari pos ini .APL (Dyalog Unicode) ,
3836 byteTerima kasih kepada ngn untuk memperbaiki bug sambil mempertahankan jumlah byte.
Fungsi awalan diam-diam anonim. Membutuhkan
⎕IO
( I ndex O rigin) diatur ke0
, yang merupakan default pada banyak sistem. Bahkan bekerja untuk 0!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)2×
kalikan dua dengan itu (memberikan0
,2
,4
, atau6
)'thstndrd'↓⍨
jatuhkan banyak karakter dari string ini2↑
ambil dua karakter pertama yang tersisa⍕,
menggabungkan argumen yang dirumuskan untuk itusumber
⍕,{2↑'thstndrd'↓⍨2×⊃⍵⌽∊1 0 8\⊂10↑⍳4}
⎕io←0
. Saya dapat melihat Anda menebaknya, tetapi ada beberapa 1,2,3,4,0,0 ... yang seharusnya 0,1,2,3,0,0 ...PowerShell, 92
Bekerja dengan satu angka per baris input. Masukan diberikan melalui pipa. Membuatnya hanya berfungsi untuk satu nomor tidak mengurangi ukuran.
sumber
J - 44 char
Tidak ada dalam J? Ini adalah kemarahan!
Dijelaskan (perhatikan bahwa
1
boolean benar dalam J dan0
salah):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 hasil4>]
(yaitu apakah satu digit kurang dari 4) dan mengalikannya dengan hasiltens ~: (4>])
. Mengapa ada orang yang melakukan hal ini? Pertimbangkan yang berikut ini:tens
adalah1
(kita berada di remaja) danones
kurang dari 4, jaditens ~: (4>])
itu salah dan hasilnya adalah0*1
=0
.tens ~: (4>])
benar dan kita keluar1*1
=1
.ones
lebih besar dari empat, maka4>]
sudah0
dan tidak masalah apa yang terjadi pada tes lagi, kita akan0
keluar terlepas.[(~:*])4>]
adalah1
jika kita berada di {X0, X1, X2, X3} tetapi tidak di remaja, dan0
sebaliknya.]*
- Akhirnya kita mengalikan hasil itu dengan angka satu. Jadi produk ini akan menjadi0
jika nomor tersebut layak'th'
akhiran, kalau tidak nilainya.th`st`nd`rd{::~
- Kami menggunakan digit satu yang dimodifikasi dari atas untuk mengindeks daftar sufiks.0
mendapat'th'
,1
mendapat'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.
sumber
C #, 62 byte
Program dan verifikasi lengkap:
sumber
||
to|
.Mathematica 29 + 5 = 34 byte
+5 byte karena
Speak
fungsi harus dipanggil sebelum menggunakan built-in ini.Pemakaian
sumber
PHP, 151
Saya tahu bahwa program ini tidak sebanding dengan yang lain. Rasanya ingin memberikan solusi.
sumber
foreach($s as $n){echo$n;
Scala 86
Scala 102:
102 juga:
ungolfed:
sumber
OCaml
Saya cukup baru di OCaml, tetapi ini adalah yang terpendek yang bisa saya dapatkan.
Saya membuat fungsi n yang mengambil angka sebagai parameter dan melakukan pekerjaan. Itu panjang tetapi berpikir itu akan bagus untuk memiliki contoh fungsional.
sumber
if v>10 && v<14
? Saya tidak terbiasa dengan ocaml, tetapi apakah perlu memilikistring_v
variabel yang begitu lama?K - 44 char
Kebetulan bahwa ini persis sepanjang J, dan bekerja dengan cara yang hampir sama.
Dijelaskan:
x$:
- Pertama, kita mengubah operanx
menjadi sebuah string, dan kemudian menetapkan itu kembalix
. 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 argumenx
dany
fungsi dalam ini, yang mengembalikany
jikay
kurang dari 4 danx
tidak 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:
sumber
C -
9583 karakterDiturunkan:
Kita bisa melakukan
k=(n-1)%10
alih - alih menambahkan 9, tetapi untuk n = 0 kita akan mendapatkan perilaku yang salah, karena di C(-1)%10
mengevaluasi menjadi -1, bukan 9.sumber
Javascript, 75
sumber
PHP, 98 byte
Bit 11-13 membunuhku di sini. Bekerja untuk bilangan bulat apa pun
$n >= 0
.Untuk bilangan bulat apa pun
$n
:PHP, 103 byte
sumber
Python,
8884 byteTidak Disatukan:
lambda x
mendefinisikan fungsi anonim dengan parameterx
.((('th','st','nd','rd')+('th',)*6)[int(x[-1])]
mendefinisikan tuple dari ujung untuk angka kurang dari 10,0-th
elemen untuk0
, dan sebagainya. yangif ('0'+x)[-2] != '1'
cek jika ada11
,12
, atau13
untuk memperbaiki, dan menambahkan kemudianelse 'th'
menambahkanth
bukanst
,rd
ataund
.sumber
JavaScript (Node.js) , 51 byte
kredit ke @KevinCruijssen untuk meningkatkan jawabannya
Cobalah online!
Penjelasan:
sumber
R ,
7976 byteKarena 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)]
.Cobalah online!
Dengan
substr
, 79 byte:Cobalah online!
sumber
1+x%%10*!x%%100==11
untuk indeks?!
di depan ekspresi alih-alih!=
.^
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.Python 2.7, 137 karakter
n
harus berupa stringSaya 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
e
dan ordinalo
. 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 positifsumber
n[-1]==e
adalah 5 karakter lebih pendek darin.endswith(e)
C: 95 karakter
Solusi yang sangat panjang:
Itu perlu lebih hancur.
sumber
Javascript, 75
sumber
Oracle SQL 11.2, 101 byte
sumber
Javascript ES6, 52 karakter
sumber