Sıra numaralarını çıkarma (1., 2., 3.)


43

(Bir fonksiyonun dönüş sonucu olarak veya sadece bir programın çıktısı olarak) sayıya birleştirilmiş pozitif bir tamsayı sıralı sonekini üretmek istiyorum .

Örnekler:

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

Ve böylece, son 1-10 alt şablonunun her 10 ile 100 arasında bir tekrarlanmasıyla, sonuçta modelin başlaması ile birlikte.

Giriş, yukarıda gösterildiği gibi sıra dizgisinin numarası ve çıktısı olacaktır.

Bunun için en küçük algoritma nedir?


Merhaba, NickC ve codegolf.SE'ye hoş geldiniz! Sadece netleştirmek için, 11örneğin giriş ve çıkış gibi bir sayı okumanız gerektiği anlamına mı geliyor 11th? Girişteki her sayı ayrı bir satırda mı ve çıktı numaraları da ayrı satırlarda mı olmalıdır? Ve birden fazla girdi satırını ele almamız gerekiyor mu?
Ilmari Karonen

1
En küçük algoritmayı mı yoksa en küçük kodu mu arıyorsunuz?
Toto,

@Ilmari 11Giriş ve 11thçıkış olarak arıyorum . Birden çok satırı işlerse aldırış etmem ama aklımdaki tek bir numarayı işlemekti.
Nicole

@ M42 Biliyor musun, gerçekten emin değilim. Kesin bir şartım yok - ama muhtemelen en küçük algoritmayı düşünüyordum.
Nicole

Yanıtlar:


30

Perl, 37 + 1 karakter

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

Bu, $_halihazırda bir harf tarafından takip edilmeyen rakamlara uygun sıra ekini ekleyen regexp ikamesidir . Dosya girişine uygulamak için p, aşağıdaki gibi komut satırı anahtarını kullanın :

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

Bu, stdin'den girdi okuyan ve işlenen çıktıyı stdout'a yazan eksiksiz bir Perl programıdır. Gerçek kod 37 karakter uzunluğunda olmasına rağmen, panahtar ekstra bir karakter olarak sayılıyor .

Örnek giriş:

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

Çıktı:

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

Harflerin takip ettiği sayılar dikkate alınmaz, bu nedenle çıktıyı süzgeçten beslemek değişmez. Sayılar arasındaki boşluklar, virgüller ve süreler özel olarak işlem görmez, bu nedenle sayıları diğer noktalama işaretleri gibi ayırdıkları varsayılır. Böylece, örneğin 3.14159olur 3rd.14159th.

O nasıl çalışır?

  • İlk olarak, bu global bir regexp değişimidir ( s///g). Eşleştirilen regexp 1?\d\b, \dherhangi bir rakamla \beşleşen ve bir alfanümerik ve alfanümerik olmayan bir karakter arasındaki sınırı eşleşen sıfır genişliğinde bir iddiadır. Böylece, 1?\d\bherhangi bir sayının son basamağı ile eşleşirse önceki rakamla eşleşir 1.

  • /eAnahtar nedeniyle Perl kodu olarak değerlendirilen sübstitüsyonda, eşleşen dize segmentini ( $&) alıp listeye bir tamsayı dizini olarak .kullanarak elde edilen son eki ekleriz ; eğer bu son ek sıfırsa veya tanımsızsa (yani sıfır veya üçten büyük olduğunda), operatör ile değiştirir .$&(0,st,nd,rd)$&||th


Düzenleme: Girdi, tek bir tamsayı ile sınırlıysa, bu 35 karakterlik çözüm yeterli olacaktır:

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

1
gHer numaranın kendi satırında olması gerektiğini belirtirseniz, oyuncu değişikliği iptal edebilmelidir . Ayrıca, sınır kelimesini değiştirmene izin verirdi $. Ama genel olarak, +1, akıllıca bir çözüm.
Bay Llama,

@GigaWatt: Aslında, NickC giriş formatı hakkındaki sorumu cevaplamadan önce kodu yazdım, bu yüzden mümkün olduğunca jenerik yaptım.
Ilmari Karonen,

38

Python 2,49 bayt

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

Anonim bir işlev. Bir tam bir program 55 bayt sayılabilecektir.

'tsnrhtdd'[i::4]0 ila 3 arasındaki th st nd rddeğerler için sonekleri kodlar. iBuna göre, tek ihtiyacımız, nkarşılık gelen sonekin indeksinin değerlerini haritalamanın bir yoludur i. Çalışan basit bir ifadedir (n%10)*(n%10<4 and 10<n%100<14). İlk parantez kümesini bırakarak ve özel eklerle n%5aynı n%10değerleri veren gözlemleyerek bunu kolayca kısaltabiliriz n. Deneme yanılma biraz ile, bir de kısaltabilir 10<n%100<14için n%100^15>4daha bayt kaydetmek için Diğer şartlı ile zincirleme edilebilir.


3
Bu tam burada bazı kara büyü olduğunu c:
kedi


Anlamadım. Burada neler olduğunu açıklayan var mı?
Pavel

@Pavel Cevabımı bir açıklama ile güncelledim.
xsot


10

Python, 68 karakter

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

4
Bu gerçekten geç, ancak yaparak 7 bayt çıkarabilirsiniz `i`+"tsnrhtdd". Aksi halde, bu yeni aldığım kesin çözümdür.
DLosc

10

Mathematica 39 45 bayt

Not: soran Mathematica'nın son sürümlerinde, nthbir parçası p, ptanımlanmamış bir hata iletisi oluşturur, ancak yine de doğru cevabı verir. QuietHata mesajının yazdırılmasını önlemek için ekledim .

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

kullanım

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

31

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

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


Nasıl çalışır

SpokenStringKonuşulan herhangi bir geçerli Mathematica ifadesini yazar. Aşağıda için belgelerinden iki örnektir SpokenString ,

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

"x miktarının karekökü y artı z miktarının üzerinde" *)

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

"0, 0, 0 ve 1, 1, 1'de ortalanmış birim alanlardan oluşan üç boyutlu bir grafik"


Şimdi, eldeki örnek için

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

"p'nin 31. elemanı"

Yukarıdaki dizgiyi bir sözcük listesi olarak temsil edelim:

StringSplit[%]

{"", "31", "öğe", ",", "p"}

ve ikinci elemanı al ...

%[[2]]

31


Kafam karıştı; nerede ptanımlanır EDIT: boşver, bunu nasıl kullandığını görüyorum; maalesef sistemimde çalışmıyor. : - /
Mr.Wizard

V.9.0.1'de çalışır. (7.0 kullandığınızı hatırlıyor gibiyim.) Evet, p tanımlanması gerekmez.
DavidC,

Bunu şimdi anlıyorum. Ancak, v7'de SpokenString @ p[[117]]çıktıdan alıyorum " part 117 of p".
Mr.Wizard

Böylece SpokenStringzaman zaman gözden geçirilir. Bu kodun ( codegolf.stackexchange.com/questions/8859/… ) de v. 7'de çalışmamasına şaşırmam . BTW, kalıcı bir çözüm olması gerekmedi.
DavidC,

Hah, bu cevabı daha önce görmemiştim.
Mr.Wizard

7

Ruby, 60

Perl girişi kadar iyi değil ama Ruby becerilerim üzerinde çalışacağımı düşündüm.

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

İşlev bir tamsayı argümanı alır nve sıralı biçim olarak bir dize döndürür.

Aşağıdaki mantığa göre çalışır:
Onlarca rakam 1 ise veya rakamlar 3'ten büyükse 'th' ekini kullanın; Aksi halde, endeksi son dizini kullanarak ['th', 'st', 'nd', 'rd'] dizisinden soneki bulun.


o(113)olduğu "113rd", olması gerektiği "113th". Onlarca rakam kontrolü ikiden fazla rakam olan sayıları hesaba katmaz.
Hammar

Tamam, %10telafi etmek için başka bir yere geçti. 3 karakter eklendi. (Bir %10şekilde kısaltılması gereken yerlerde yeterince göründüğünü hissediyorum , ancak bir çözüm düşünemiyorum)
Bay Llama


Değişken 10mi?
wizzwizz4

Bir değişkeni ayarlamak n%10daha iyi olduğunu düşünüyorum .
Hesap MakinesiFeline

6

Javascript (ES6) 50 44 Bayt (rekabet etmeyen)

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

notlar

  • dize olarak imput alır
  • 6 bayt kaldırıldı, teşekkürler @ user81655

1
a+-> a+=, parantezleri kaldırın, \d-> ., kaldırın [0]ve sayıyı bir dizge olarak alırsanız: a.match`1?.$`yerine /1?.$/.exec(a).
user81655

Muhtemelen, meydan okuma yayınlandığında ES6'nın mevcut olmadığı için bu cevabın rekabet dışı olduğuna dair bir not eklemelisiniz.
user2428118 28:16

5

JavaScript, 68 71

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

ItsCosmo ile ortak çaba.

EDIT:> 100 sayılarla düzgün çalışmıyor


function o(n)n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')Yağ ok gösterimini kullanmaktan mutluysanız, aşağıdakini 62'ye çıkarabilirsiniz : ve 54'e daha da aşağıya o=n=>n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')
çekebilirsiniz

@WallyWest Nedense, çözümümün modern tarayıcılarda çalışmasını seviyorum. Kendi cevabınızı göndermek için çekinmeyin; Bence yeterince farklı.
aebabis

Hayır bu iyi! Sadece birkaç alternatif sunmak!
WallyWest

3

Golf Betiği, 34 karakter

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

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

Test yapmak:

*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 ile yüklenmelidir.


3

JavaScript, 64 karakter (ES3) veya 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'

açıklama

İfade , basamak - ile biten n % 100 >> 3 ^ 1her pozitif sonuç için 0 olarak değerlendirilir . Bu durumda, herhangi biten , veya , dizi arama döner bir sonek yol açan .n0815n mod 100111213undefinedth

Herhangi bir pozitif için nbaşka haneli biten 08- 15, sentezleme n % 100 >> 3 ^ 1ifade yürütmesini pozitif tamsayıya değerlendirir, n % 10, dizi arama için dönen st, ndveya rdiçin nolan bu uçlar 1, 2ya da 3. Aksi takdirde th,.


İle bir bayt kaydedin n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'.
Shaggy,

@Shaggy, teşekkürler, önerildiği gibi güncellendi.
Tomas Langkaas


@ guest271314, kullanılmakta olan bu kodu görmek eğlenceli. Sadece pozitif sayılar için çalıştığını n+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th", bu yazıdan uyarlanan başka bir alternatif olduğunu unutmayın .
Tomas Langkaas

3

APL (Dyalog Unicode) , 38 36 bayt

Bayt sayısını korurken bir hatayı düzeltmek için ngn teşekkürler.

Anonim zımni önek işlevi. Gerektirir ⎕IO( I ndex O rigin) 0, birçok sistemde varsayılandır. Hatta 0 için çalışıyor!

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

Çevrimiçi deneyin!

{} Anonim lambda; bağımsız değişken:

⍳4 İlk dört ɩ ndices;[0,1,2,3]

10↑ ondan ilk 10 elemanı al, sıfırlarla doldur: [0,1,2,3,0,0,0,0,0,0]

 tek eleman olarak muamele etmek; [[0,1,2,3,0,0,0,0,0,0]]

1 0 8\ bir kopyaya, prototipik bir kopyaya (tümü sıfır), sekiz kopyaya genişlet;
  [[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 (5 kişi daha)
   [0,1,2,3,0,0,0,0,0,0]]

ε nlist (düzleştirmek);
  [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 daha fazla)
   0,1,2,3,0,0,0,0,0,0]

⍵⌽ döngüsel olarak sola döndürerek, argüman tarafından belirtilen sayıda adım atın

 ilk sayıyı seçin (örn. argüman-mod-100''ün sayısı)

 Bununla çarpın iki (verir 0, 2, 4, veya 6)

'thstndrd'↓⍨bu dizgiden o kadar çok karakter bırak

2↑ kalan karakterlerden ilk ikisini al

⍕, bunun argümanlı argümanını birleştirmek


"31."?
ngn

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

üzgünüm, söylemeyi unuttum ⎕io←0. Bunu tahmin bkz, ancak birkaç 1,2,3,4,0,0 vardır olabilir ... yani 0,1,2,3,0,0 olması ... gerektiğini
ngn

@ngn Sabit. Ve 0 için de işe yarar!
Adám

2

PowerShell, 92

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

Giriş satırı başına bir sayı ile çalışır. Giriş boru hattı aracılığıyla verilir. Yalnızca bir numara için çalışmasını sağlamak boyutu küçültmez.


2

J - 44 karakter

J'de bir şey yok mu? Bu bir rezalet!

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

Açıklanan ( 1J'de boolean'ın doğru olduğuna ve 0yanlış olduğuna dikkat edin ):

  • 10 10(...)/@#:]- Önce argümanı alırız ( ]) ve onlarcaları ve rakamları ( 10 10 #:) buluruz . Sonra (...)ikisinin arasına gireceğiz .
  • (]*[(~:*])4>])- Bu alt ifadenin, ancak içteki birinde, ]birler basamağının ve işaret eder [onlar basamağının.
  • [(~:*])4>]- ~:"eşittir olmayanlar" için J'dir, bu, bunun sonucunu alır 4>](yani bir rakamın 4'ten küçük olup olmaması) ve sonucu ile çarpar tens ~: (4>]). Birisi bunu neden yapar ki? Aşağıdakileri göz önünde bulundur:
    • 10, 11, 12, 13'ü kontrol ediyorsak, o tenszaman 1(biz gençleriz) ve ones4'ten azsa tens ~: (4>]), yanlış ve sonuç 0*1= olur 0.
    • Eğer {X0, X1, X2, X3} den herhangi bir başkasıysak, açıkça tens ~: (4>])doğrudur ve çıkarız 1*1= 1.
    • Dörtten onesbüyükse, 4>]öyleydi 0ve artık teste ne olduğu önemli değil, ne olursa olsun 0çıkacağız.
    • Yani özetlemek gerekirse, [(~:*])4>]bir 1biz {X0, X1, X2, X3} içinde değil gençler olduğunu ve eğer 0aksi.
  • ]*- Sonunda bu sonucu rakamlarla çarptık. Bu yüzden 0eğer bu sayı bir 'th'eki hak ediyorsa, değeri de o olacak
  • th`st`nd`rd{::~- Eklerin listesini indekslemek için yukarıdan değiştirilmiş olanları kullanın. 0alır 'th', 1alır 'st'vb.
  • ":,- Son olarak, orijinal numarayı alın, bir dizgeye ( ":) dönüştürün ve ardından son eke hazırlayın.

Kullanımı açıktır, ancak fiil bir sırayı alabilir, sadece bir sıra alabilir.

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

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

Tam program ve doğrulama:

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

Değiştirerek iki bit olarak yapabilirsiniz golf bunu ||için |.
Kevin Cruijssen

2

Mathematica 29 + 5 = 34 bayt

SpokenStringDump`SpeakOrdinal

+5 bayt çünkü Speakbu yerleşik işlevi kullanmadan önce işlev çağrılmalıdır.

kullanım

SpokenStringDump`SpeakOrdinal[1]

"1st "

SpokenStringDump`SpeakOrdinal[4707]

"4,707th "


1

PHP, 151

Bu programın diğerleriyle karşılaştırılabilir olmadığını biliyorum. Sadece bir çözüm vermek gibi hissettim.

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

kullanarak birkaç karakter kaydedebilirsinizforeach($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 de:

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 için oldukça yeniyim, ama bulabildiğim en kısa şey bu.

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

Parametre olarak bir sayı alan ve işi yapan bir n işlevi yarattım. Uzun, ama işlevsel bir örneğe sahip olmanın harika olacağını düşündüm.


giriş: 11 çıktısını verir: 11

evet, haklısın .. Düzeltme yaptım. Teşekkürler
Joseph Elcid

Kodunuzdaki biçimlendirmeyi daha yeni topladım. Bir kod bloğu olarak tanınması için her satırdan önce dört boşluk gelmesi gerekir.
Gareth,

İlk önce çekiniz daha kısa olsaydı, olmaz mıydı if v>10 && v<14? Ocaml ile aşina değilim, ancak string_vdeğişkenin bu kadar uzun olması gerekli mi?
Gaffi

Hayır, gerekli değil, w veya x seçebilirdim. Sadece anlamlı bir şey istedim. Ama haklısın, kodu biraz daha kısaltırdı.
Joseph Elcid

1

K - 44 karakter

Öyle olur ki, bu tam olarak J kadar uzun ve neredeyse aynı şekilde çalışıyor.

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

Açıklaması:

  • x$:- İlk önce operand'ı xbir dizgeye dönüştürdük ve sonra onu geri atayız x. Daha sonra tekrar string string'ine ihtiyacımız olacak, bu yüzden şimdi yapmak karakterleri kurtarıyor.
  • .:'- .:Her bir ( ') basamağı tekrar bir sayıya dönüştürün.
  • -2#0, - Rakamlar listesinin önüne 0 ekleyin (tek basamaklı sayılar olması durumunda) ve ardından son ikisini alın.
  • {y*(y<4)*~1=x}.- Kullanım bağımsız değişken olarak, iki basamak xve ydöner bu iç işlevine, yeğer yen az 4 ve xdeğildir, aksi halde 0, 1 'e eşit.
  • `th`st`nd`rd@ - Bu sonuca göre son eklerin listesini indeksleyin.
  • x,$ - Soneki sembolden dizeye dönüştürün ve orijinal sayıya ekleyin.

Kullanımı:

  {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 karakter

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)%109 eklemek yerine yapabiliriz , ancak n = 0 için hatalı bir davranış elde edeceğiz, çünkü C'de (-1)%109 değil -1 olarak değerlendiriliyor.


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 bayt

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 bit burada beni öldürüyor. Herhangi bir tamsayı için çalışıyor $n >= 0.

Herhangi bir tamsayı için $n:

PHP, 103 bayt

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 bayt

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 xanonim bir işlevi parametre ile tanımlar x. ((('th','st','nd','rd')+('th',)*6)[int(x[-1])]10'dan daha küçük sayılar için sonların bir demetini tanımlar, 0-theleman bunun için 0vb. if ('0'+x)[-2] != '1'orada kontroller ise 11, 12ya da bir 13düzeltme ve sonra ekler else 'th'ekler thyerine st, rdya nd.


Bu harika bir cevap, ancak geçmesi ve anlaması biraz zaman aldı. Bir kod açıklaması ekleyebilir ve kodunuzun golf versiyonunun altına döküm ekleyebilirseniz, kişilerin kodunuzdan öğrenmelerine ve yanıtınızın kalitesini yükseltmelerine yardımcı olur.
wizzwizz4

Tamam yapacağım. Golfsüz bir cevap eklemeli miyim?
NoOneIsHere

Farklı bir cevap olmamalı ... Yaptıkların gayet iyi. Eğer daha fazla zorluk çekmek istiyorsanız, bazı önerilerde bulunabilirim.
wizzwizz4

Tamam. Deneyebilirsin ... Sandalyeni ayarla , veya arkadaşların nerede oturacak . Ya da The Knight's Next Tour gibi bazı zorluklarımı deneyebilirsin . Bunlar sevdiğiniz zorluklar değilse, sadece söyleyin.
wizzwizz4

1

JavaScript (Node.js) , 51 bayt

@KevinCruijssen 'e verilen cevabı geliştirmek için kredi

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

Çevrimiçi deneyin!


Açıklama:

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 bayt

Henüz R çözümü olmadığından ... hile yok, temel vektör indekslemesi, Giuseppe sayesinde 3 karakter attı. Daha önce denenmiş endeks: [1+(x%%10)-(x%%100==11)]ve [1+(x%%10)*(x%%100!=11)].

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

Çevrimiçi deneyin!

İle substr79 bayt:

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

Çevrimiçi deneyin!


1
1+x%%10*!x%%100==11endeks için mi?
Giuseppe,

@Giuseppe Parantezde sakinleşmem gerek :). !İfade önünde zekice kullanımı yerine !=.
JayCe

1
Evet, operatörlerin garip önceliği var; ^gerçekten yüksek, o zaman- %%tipi operatörler, o zaman */ve +-ve düşünüyorum ==ve sonra &|gelir. !oldukça düşük önceliğe sahip olduğundan, işlemler arasında bir ayırıcı olarak kullanabilirsiniz.
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 bir dize olmalı

Buradaki rekabet yüzünden çoktan dövüldüğümü biliyorum ama yine de fikrimi sağlayabileceğimi düşündüm.

Bu sadece temelde bir anahtar listesi, sayı (bir dize olarak) biten eve çift sıralı değer çiftleri oluşturur o. İlk önce 'th' ile eşleşmeye çalışır (bu nedenle neden bir sözlük kullanmadım), böylece yanlışlıkla 'st', örneğin 'th' olması gerektiğinde 'geri dönmeyecek'. Bu herhangi bir pozitif tamsayı için çalışacak


n[-1]==e5 karakterden kısan.endswith(e)
hlt

0

C: 95 karakter

Gülünç derecede uzun bir çözüm:

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

Daha fazla karışması gerekiyor.


Bir kullanıcı "yanlış: hiç döngü oluşturmuyor, yani sadece verilen bir numara için çalışıyor, altındaki _all_ sayıları için çalışmıyor" şeklinde işaretlenmiş bir kullanıcı olarak işaretlendi . İdeone.com/pO6UwV adresini ziyaret edin. Bu, moderatörlerin doğruluğunu yargılamadığı için işaretlemenin bir nedeni değil, ancak bir sorun olabilir.
dmckee

Soruyu oluşturandan bu yoruma dayanarak: "@Ilmari 11'i girdi, 11'i çıktı olarak arıyorum. Birden fazla satırı işleyip işlemediğini umursamıyorum ama aklımdaki tek bir sayıyı işlemekteydi. - NickC Jan 20 '12 21: 00'de "Yapması gerekeni yapıyor. Yani sadece bir numarayı işlemesi gerekir.
Fors

bu bayrak için üzgünüm; Gerekliliği yanlış anladım ve o sırada doğrudan yorum yapmak için yeterli zamanım olmadı. Tekrar özür dilerim. :)
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 bayt

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 karakter

n=>n+(!/1.$/.test(--n)&&'snr'[n%=10]+'tdd'[n]||'th')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.