Wyprowadzanie liczb porządkowych (1., 2., 3.)

43

Chciałbym wygenerować (jako wynik funkcji lub po prostu wynik programu) porządkowy sufiks dodatniej liczby całkowitej połączonej z liczbą.

Próbki:

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

I tak dalej, z sufiksem powtarzającym początkowy wzór 1-10 co 10 aż do 100, gdzie wzór ostatecznie zaczyna się od nowa.

Dane wejściowe to liczba, a dane wyjściowe ciąg porządkowy, jak pokazano powyżej.

Jaki jest najmniejszy algorytm do tego?

Nicole
źródło
Cześć, NickC i witaj w codegolf.SE! Wyjaśniając, czy masz na myśli, że powinniśmy czytać liczby takie 11jak dane wejściowe i wyjściowe np. 11th? Czy każda liczba na wejściu znajduje się w osobnym wierszu i czy numery wyjściowe powinny być również w osobnych wierszach? I czy musimy obsłużyć więcej niż jeden wiersz danych wejściowych?
Ilmari Karonen,
1
Szukasz najmniejszego algorytmu lub najmniejszego kodu?
Toto
@Ilmari Szukam 11jako danych wejściowych i 11thwyjściowych. Nie mam nic przeciwko, jeśli przetwarza wiele linii, ale miałem na myśli przetworzenie tylko jednej liczby.
Nicole,
@ M42 Wiesz, nie jestem do końca pewien. Nie mam ścisłych wymagań - ale prawdopodobnie myślałem o najmniejszym algorytmie.
Nicole,

Odpowiedzi:

30

Perl, 37 + 1 znaków

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

Jest to podstawienie wyrażenia regularnego, które dołącza odpowiedni sufiks porządkowy do dowolnej liczby, po $_której nie występuje już litera. Aby zastosować go do danych wejściowych pliku, użyj pprzełącznika wiersza polecenia:

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

Jest to kompletny program Perla, który odczytuje dane wejściowe ze standardowego wejścia i zapisuje przetworzone dane wyjściowe na standardowe wyjście. Rzeczywisty kod ma 37 znaków, ale pprzełącznik liczy się jako jeden dodatkowy znak .

Przykładowe dane wejściowe:

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

Wynik:

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

Liczby, po których następują litery, zostaną zignorowane, więc ponowne podanie wyników przez filtr nie zmieni tego. Spacje, przecinki i kropki między liczbami nie są traktowane specjalnie, więc zakłada się, że oddzielają liczby jak każdą inną interpunkcję. Tak np . 3.14159Staje się 3rd.14159th.

Jak to działa?

  • Po pierwsze, jest to globalna zamiana wyrażeń regularnych ( s///g). Dopasowywanym wyrażeniem regularnym jest 1?\d\b, gdzie \dpasuje do dowolnej cyfry i \bjest twierdzeniem o zerowej szerokości pasującym do granicy między znakiem alfanumerycznym i niealfanumerycznym. W ten sposób 1?\d\bdopasowuje ostatnią cyfrę dowolnej liczby plus poprzednią cyfrę, jeśli tak się dzieje 1.

  • W podstawieniu, które z powodu /eprzełączenia jest oceniane jako kod Perla , bierzemy dopasowany segment łańcucha ( $&) i dołączamy .do niego sufiks uzyskany przez użycie go $&jako indeksu liczb całkowitych na liście (0,st,nd,rd); jeśli ten sufiks jest zerowy lub nieokreślony (tj. gdy $&wynosi zero lub więcej niż trzy), ||operator zastępuje go th.


Edycja: Jeśli dane wejściowe są ograniczone do jednej liczby całkowitej, wystarczy 35-znakowe rozwiązanie:

s/1?\d$/$&.((0,st,nd,rd)[$&]||th)/e
Ilmari Karonen
źródło
1
Powinien być w stanie porzucić gpodstawienie, jeśli podasz, że każda liczba musi znajdować się w osobnej linii. Pozwoli to również zmienić granicę słowa na $. Ale ogólnie +1, cholernie sprytne rozwiązanie.
Pan Llama,
@GigaWatt: Rzeczywiście, napisałem kod zanim NickC odpowiedział na moje pytanie dotyczące formatu wejściowego, więc uczyniłem go tak ogólnym, jak to możliwe.
Ilmari Karonen,
38

Python 2, 49 bajtów

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

Anonimowa funkcja. Pełny program będzie liczona na 55 bajtów.

'tsnrhtdd'[i::4]koduje przyrostków th st nd rddla wartości iod 0 do 3. Biorąc pod uwagę to wszystko, czego potrzebujemy jest sposobem odwzorowywania wartości ndo indeksu odpowiedniego przyrostka i. Proste wyrażenie, które działa (n%10)*(n%10<4 and 10<n%100<14). Możemy to łatwo skrócić, upuszczając pierwszy zestaw nawiasów i obserwując, że n%5daje to takie same wyniki, jak n%10w przypadku wartości nze specjalnymi sufiksami. Przy odrobinie prób i błędów można również skrócić 10<n%100<14do n%100^15>4, który można połączyć z drugim, aby zaoszczędzić jeszcze więcej bajtów.

xsot
źródło
3
to jest jakaś czarna magia tutaj c:
kot
Nie rozumiem Czy ktoś może wyjaśnić, co się tutaj dzieje?
Pavel
@Pavel Zaktualizowałem swoją odpowiedź z wyjaśnieniem.
xsot
Niesamowite! Świetny sposób na myślenie ...
Benison Sam
10

Python, 68 znaków

i=input()
k=i%10
print"%d%s"%(i,"tsnrhtdd"[(i/10%10!=1)*(k<4)*k::4])
Gareth
źródło
4
Jest naprawdę późno, ale możesz zrobić 7 bajtów `i`+"tsnrhtdd". W przeciwnym razie właśnie to właśnie otrzymałem.
DLosc
10

Mathematica 39 45 bajtów

Uwaga: W najnowszych wersjach Mathematica pytanie o nthczęść p, gdzie pjest niezdefiniowana, generuje komunikat o błędzie, ale mimo to zwraca poprawną odpowiedź. Dodałem, Quietaby zapobiec drukowaniu komunikatu o błędzie.

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

Stosowanie

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”}


Jak to działa

SpokenStringwypisze dowolne poprawne wyrażenie Mathematica, które może być wypowiedziane. Poniżej znajdują się dwa przykłady z dokumentacji SpokenString ,

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

„pierwiastek kwadratowy z ilości x ponad ilość y plus z” *)

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

„trójwymiarowa grafika składająca się z kulek jednostkowych wyśrodkowanych na 0, 0, 0 i 1, 1, 1”


Teraz, na przykład, pod ręką

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

„31. element p”

Przedstawmy powyższy ciąg jako listę słów:

StringSplit[%]

{„the”, „31st”, „element”, „of”, „p”}

i weź drugi element ...

%[[2]]

31

DavidC
źródło
Jestem zmieszany; gdzie jest pzdefiniowane? EDYCJA: nieważne, widzę, jak tego używasz; niestety to nie działa w moim systemie. : - /
Mr.Wizard
Działa na wersji 9.0.1. (Wydaje mi się, że pamiętam, że używasz wersji 7.0). Tak, p nie musi być zdefiniowane.
DavidC,
Teraz to rozumiem. Jednak w wersji 7 otrzymuję SpokenString @ p[[117]]dane wyjściowe " part 117 of p".
Mr.Wizard
Więc SpokenStringzostaje zmieniony od czasu do czasu. Nie zdziwiłbym się, że ten kod ( codegolf.stackexchange.com/questions/8859/... ) również nie działa w wersji 7. BTW, to nie miało być trwałe rozwiązanie.
DavidC,
Hah, nie widziałem wcześniej tej odpowiedzi.
Mr.Wizard
7

Ruby, 60 lat

Nie jest tak dobry, jak wpis Perla, ale pomyślałem, że będę pracować nad umiejętnościami Ruby.

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

Funkcja przyjmuje jeden argument liczby całkowitej ni zwraca ciąg znaków w postaci liczby porządkowej.

Działa zgodnie z następującą logiką:
Jeśli cyfra dziesiątek jest 1 lub cyfra jedności jest większa niż 3, użyj przyrostka „th”; w przeciwnym razie znajdź przyrostek z tablicy ['th', 'st', 'nd', 'rd'], używając ostatniej cyfry jako indeksu.

Pan Llama
źródło
o(113)jest "113rd", powinno być "113th". Kontrola dziesiątek cyfr nie uwzględnia liczb zawierających więcej niż dwie cyfry.
hammar
Ok, wrzuciłem inną, %10żeby to zrekompensować. Dodano 3 postacie. ( %10Wydaje mi się, że wydaje się, że wystarczy go skrócić, ale nie mogę znaleźć rozwiązania)
Pan Llama,
Nigdy nie
pokonasz
Ustaw zmienną na 10?
wizzwizz4
Myślę, że ustawienie zmiennej na n%10jest lepsze.
CalculatorFeline
6

JavaScript (ES6) 50 44 bajtów (nie konkuruje)

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

Notatki

  • przyjmuje imput jako ciąg
  • Usunięto 6 bajtów, dzięki @ user81655
Shaun H.
źródło
1
a+-> a+=, usuń nawiasy, \d-> ., usuń [0], a jeśli weźmiesz numer jako ciąg: a.match`1?.$`zamiast /1?.$/.exec(a).
user81655
Prawdopodobnie powinieneś dodać powiadomienie, że ta odpowiedź nie jest konkurencyjna, ponieważ ES6 nie istniał w momencie opublikowania wyzwania.
user2428118,
5

JavaScript, 68 71

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

Wspólny wysiłek z ItsCosmo.

EDYCJA: Nie działał poprawnie z liczbami> 100

aebabis
źródło
Możesz obniżyć go do 62 za pomocą: function o(n)n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')i możesz obniżyć go do 54, jeśli z przyjemnością używasz grubej notacji:o=n=>n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')
WallyWest
@WallyWest Z jakiegoś powodu bardzo podoba mi się to, że moje rozwiązanie działa w nowoczesnych przeglądarkach. Możesz opublikować własną odpowiedź; Myślę, że jest wystarczająco inny.
aebabis
Nie, jest w porządku! Tylko kilka alternatyw!
WallyWest,
3

Golfscript, 34 znaki

~.10/10%1=!1$10%*.4<*'thstndrd'2/=
hammar
źródło
3

Haskell, 95 znaków

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

Testowanie:

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

Musi być załadowany z -XNoMonomorphismRestriction.

Will Ness
źródło
3

JavaScript, 64 znaki (ES3) lub 47 znaków (ES6)

ES3 (64 znaki):

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

ES6 (47 znaków):

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

Wyjaśnienie

Wyrażenie n % 100 >> 3 ^ 1przyjmuje wartość 0 dla każdego pozytywnego nzakończenia z cyframi 08- 15. Tak więc na każdy n mod 100kończy się 11, 12lub 13powraca odnośników arrayundefined , co prowadzi do przyrostek th.

Dla każdej dodatniej nkońcówki w innych znaków niż 08- 15, ekspresja n % 100 >> 3 ^ 1ma wartość dodatnią liczbę całkowitą, opierając się na ekspresji n % 10dla odnośnika tablicy, powrót st, ndlub rdna nktórym kończy się 1, 2albo 3. W przeciwnym razie th.

Tomas Langkaas
źródło
Zapisz bajty za pomocą n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'.
Kudłaty
@Shaggy, dzięki, zaktualizowano zgodnie z sugestią.
Tomas Langkaas
@ guest271314, fajnie jest zobaczyć ten kod. Zauważ, że działa tylko dla liczb dodatnich, inną alternatywą jest n+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th", zaadaptowana z tego postu .
Tomas Langkaas,
3

APL (Dyalog Unicode) , 38 36 bajtów

Dzięki ngn za naprawienie błędu przy zachowaniu liczby bajtów.

Anonimowa ukryta funkcja prefiksu. Wymaga ⎕IO( I ndex O rigin) ustawionej na 0, co jest domyślne w wielu systemach. Działa nawet dla 0!

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

Wypróbuj online!

{} Anonimowa lambda; jest argumentem:

⍳4 Pierwsze cztery ɩ ndices;[0,1,2,3]

10↑ weź dziesięć pierwszych elementów, wypełniając je zerami: [0,1,2,3,0,0,0,0,0,0]

 dołącz, aby traktować jako pojedynczy element; [[0,1,2,3,0,0,0,0,0,0]]

1 0 8\ rozwiń do jednej kopii, kopii prototypowej (zero), osiem kopii;
  [[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 więcej)
   [0,1,2,3,0,0,0,0,0,0]]

ε nlist (spłaszczyć);
  [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 więcej)
   0,1,2,3,0,0,0,0,0,0]

⍵⌽ cyklicznie obracaj w lewo o tyle kroków, ile wskazuje argument

 wybierz pierwszą liczbę (tj. argument-mod-100-ta liczba)

 pomnożyć przez dwa, że (daje 0, 2, 4, a 6)

'thstndrd'↓⍨upuść tyle znaków z tego ciągu

2↑ weź dwie pierwsze pozostałe postacie

⍕, połącz z tym argument strunowy

Adám
źródło
„31”?
ngn
⍕,{2↑'thstndrd'↓⍨2×⊃⍵⌽∊1 0 8\⊂10↑⍳4}
ngn
przepraszam, zapomniałem wspomnieć ⎕io←0. Widzę, że się zgadłeś, ale jest kilka 1,2,3,4,0,0 ... to powinno być 0,1,2,3,0,0 ...
ngn
@ngn Naprawiono. I zdarza się, że działa również na 0!
Adám
2

PowerShell, 92

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

Działa z jedną liczbą na wiersz danych wejściowych. Dane wejściowe są przekazywane przez rurociąg. Sprawienie, by działało tylko dla jednej liczby, nie zmniejsza rozmiaru.

Joey
źródło
2

J - 44 char

Nic w J? To skandal!

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

Wyjaśnione (zwróć uwagę, że 1w J ma wartość logiczną true, a 0jest false):

  • 10 10(...)/@#:]- Najpierw bierzemy argument ( ]) i znajdujemy cyfrę dziesiątek i jedynek ( 10 10 #:). Następnie wstawimy (...)między nimi.
  • (]*[(~:*])4>])- W tym podwyrażeniu, ale nie w najgłębszym, ]wskaże cyfrę jedynek i [cyfrę dziesiątek.
  • [(~:*])4>]- ~:oznacza J dla „nie-równy”, więc bierze to wynik 4>](tj. czy jedna cyfra jest mniejsza niż 4) i mnoży ją przez wynik tens ~: (4>]). Dlaczego ktoś miałby to robić? Rozważ następujące:
    • Jeśli sprawdzamy 10, 11, 12, 13, to tensjest 1(jesteśmy nastolatkami) i oneswynosi mniej niż 4, więc tens ~: (4>])jest fałszywe, a wynikiem jest 0*1= 0.
    • Jeśli jesteśmy kimś innym z {X0, X1, X2, X3}, to oczywiście tens ~: (4>])jest to prawda i wychodzimy 1*1= 1.
    • Jeśli onesjest większa niż cztery, to 4>]była 0i nie ma już znaczenia, co stanie się z testem, wyjdziemy 0niezależnie od tego.
    • Podsumowując, [(~:*])4>]jest tak, 1jeśli jesteśmy w {X0, X1, X2, X3}, ale nie w wieku nastolatków, i 0inaczej.
  • ]*- Na koniec mnożymy ten wynik przez cyfrę jedynek. Tak więc ten produkt będzie, 0jeśli liczba zasługuje na 'th'przyrostek, w przeciwnym razie jego wartość.
  • th`st`nd`rd{::~- Używamy zmodyfikowanych jednocyfrowych od góry do indeksowania listy sufiksów. 0dostaje 'th', 1dostaje 'st'i tak dalej.
  • ":,- Na koniec weź oryginalny numer, przekonwertuj go na string ( ":), a następnie dodaj do sufiksu.

Użycie jest oczywiste, chociaż czasownik „tak jak jest” może przyjąć tylko jeden porządek, a nie listę.

   (":,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|
+----+----+----+----+----+----+----+----+----+----+
algorytmshark
źródło
2

C #, 62 bajty

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

Pełny program i weryfikacja:

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
źródło
Można golf go przez dwa bajty, zmieniając ||się |.
Kevin Cruijssen
2

Mathematica 29 + 5 = 34 bajty

SpokenStringDump`SpeakOrdinal

+5 bajtów, ponieważ Speakfunkcja musi zostać wywołana przed użyciem tego wbudowanego.

Stosowanie

SpokenStringDump`SpeakOrdinal[1]

"1st "

SpokenStringDump`SpeakOrdinal[4707]

"4,707th "

JungHwan Min
źródło
1

PHP, 151

Wiem, że ten program nie jest porównywalny z innymi. Po prostu miałem ochotę dać rozwiązanie.

<?$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
źródło
możesz uratować kilka postaci, używającforeach($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 również:

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"

bez golfa:

def x (n: Int) =
  n + { if (((n % 100) / 10) == 1) "th" 
        else (("thstndrd"  + ("th"  * 6)).sliding (2, 2).toSeq (n % 10))
      }
nieznany użytkownik
źródło
1

OCaml

Jestem całkiem nowy w OCaml, ale to jest najkrótszy możliwy.

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

Utworzyłem funkcję n, która przyjmuje liczbę jako parametr i wykonuje pracę. Jest długi, ale pomyślał, że dobrze byłoby mieć funkcjonalny przykład.

Joseph Elcid
źródło
input: 11 dałoby wynik: 11
tak, masz rację .. Dokonałem korekty. Dzięki
Joseph Elcid,
Właśnie uporządkowałem formatowanie twojego kodu. Każda linia musi być poprzedzona czterema spacjami, aby mogła zostać rozpoznana jako blok kodu.
Gareth,
Czy pierwszy nie byłby, jeśli czek byłby krótszy if v>10 && v<14? Nie znam się na ocaml, ale czy konieczne jest, aby string_vzmienna była tak długa?
Gaffi
Nie, to nie jest konieczne, mogłem wybrać w lub x. Chciałem tylko czegoś znaczącego. Ale masz rację, kod byłby nieco krótszy.
Joseph Elcid
1

K - 44 znak

Zdarza się, że jest to dokładnie tak długo, jak J i działa prawie w ten sam sposób.

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

Wyjaśniono:

  • x$:- Najpierw konwertujemy operand xna ciąg, a następnie przypisujemy go z powrotem do x. Będziemy potrzebować jego powtórzenia ciągu później, więc robienie tego teraz zapisuje znaki.
  • .:'- Konwertuj ( .:) każdą ( ') cyfrę z powrotem na liczbę.
  • -2#0, - Dodaj 0 na początku listy cyfr (w przypadku liczb jednocyfrowych), a następnie weź dwie ostatnie.
  • {y*(y<4)*~1=x}.- Użyj dwóch cyfr jako argumentów xi ydo tej funkcji wewnętrznej, która zwraca, yjeśli yjest mniejsza niż 4 i xnie jest równa 1, w przeciwnym razie 0.
  • `th`st`nd`rd@ - Indeksuj listę przyrostków według tego wyniku.
  • x,$ - Konwertuj sufiks z symbolu na ciąg i dołącz go do pierwotnego numeru.

Stosowanie:

  {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")
algorytmshark
źródło
1

C - 95 83 znaków

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

Moglibyśmy to zrobić k=(n-1)%10zamiast dodawać 9, ale dla n = 0 otrzymalibyśmy nieprawidłowe zachowanie, ponieważ w C (-1)%10ocenia się na -1, a nie na 9.

pawel.boczarski
źródło
1

JavaScript, 75

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

PHP, 98 bajtów

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 mnie tutaj zabija. Działa dla dowolnej liczby całkowitej $n >= 0.

Dla dowolnej liczby całkowitej $n:

PHP, 103 bajty

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
źródło
1

Python, 88 84 bajtów

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

Nie golfowany:

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

lambda xdefiniuje anonimową funkcję z parametrem x. ((('th','st','nd','rd')+('th',)*6)[int(x[-1])]definiuje krotkę zakończeń dla liczb mniejszych niż 10, 0-thelement jest dla 0i tak dalej. to if ('0'+x)[-2] != '1'sprawdza czy istnieje 11, 12albo 13to naprawić, i dodaje następnie else 'th'dodaje thzamiast st, rdalbo nd.

Nikogo tu nie ma
źródło
To świetna odpowiedź, ale zajęło mi trochę czasu, aby ją zrozumieć i zrozumieć. Jeśli możesz dodać wyjaśnienie kodu i podział poniżej wersji kodu w golfa, pomogłoby to ludziom uczyć się na podstawie kodu i poprawić jakość twojej odpowiedzi.
wizzwizz4
Dobra zrobię to. Czy powinienem również dodać odpowiedź bez gry w golfa?
NoOneIsHere
To nie powinna być inna odpowiedź ... To, co zrobiłeś, jest w porządku, dobrze zrobione. Jeśli chcesz zrobić więcej wyzwań, mógłbym podać kilka zaleceń.
wizzwizz4
Dobrze. Możesz spróbować ... Wyreguluj krzesło lub Gdzie będą siedzieć twoi kumple . Lub możesz spróbować niektórych z moich wyzwań , takich jak The Knight's Next Tour . Jeśli nie są to wyzwania, które lubisz, po prostu powiedz.
wizzwizz4
1

JavaScript (Node.js) , 51 bajtów

Podziękowania dla @KevinCruijssen za poprawę odpowiedzi

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

Wypróbuj online!


Objaśnienie:

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


źródło
1

R , 79 76 bajtów

Ponieważ nie ma jeszcze rozwiązania R ... tutaj nie ma żadnych sztuczek, podstawowe indeksowanie wektorów, dzięki Giuseppe obniżył o 3 znaki. Poprzednio wypróbowany indeks: [1+(x%%10)-(x%%100==11)]i [1+(x%%10)*(x%%100!=11)].

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

Wypróbuj online!

Z substr, 79 bajtów:

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

Wypróbuj online!

JayCe
źródło
1
1+x%%10*!x%%100==11dla indeksu?
Giuseppe
@Giuseppe Muszę się uspokoić w nawiasie :). Sprytne użycie !przed wyrazem zamiast !=.
JayCe
1
Tak, operatorzy mają dziwne pierwszeństwo; ^jest więc naprawdę wysoka%% operatorzy Type, a następnie */i +-i myślę, ==i &|będzie dalej. !ma dość niski priorytet, więc możesz użyć go jako separatora między operacjami.
Giuseppe,
0

Python 2.7, 137 znaków

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 powinien być ciągiem

Wiem, że jestem już pokonany przez konkurencję tutaj, ale pomyślałem, że i tak przedstawię swój pomysł

generuje to po prostu listę par kluczy, wartości z zakończeniem liczby (jako łańcucha) ei porządkiem o. Najpierw próbuje dopasować „th” (dlatego dlaczego nie użyłem słownika), aby przypadkowo nie zwrócił „st”, na przykład, gdy powinien być „th”. Będzie to działać dla każdej dodatniej liczby całkowitej

Blezer
źródło
n[-1]==ejest o 5 znaków krótszy niżn.endswith(e)
hlt
0

C: 95 znaków

Śmiesznie długie rozwiązanie:

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

Musi być bardziej zniekształcony.

Fors
źródło
Użytkownik oznaczył to stwierdzeniem „jest niepoprawny: w ogóle nie zapętla się, tzn. Działa tylko dla określonej liczby, a nie _ wszystkie_ liczby poniżej. Patrz ideone.com/pO6UwV.” Nie jest to powód do oflagowania, ponieważ moderatorzy nie oceniają poprawności, ale może to być problem.
dmckee,
Na podstawie tego komentarza twórcy pytania: „@Ilmari Szukam 11 jako danych wejściowych i 11 jako danych wyjściowych. Nie mam nic przeciwko, jeśli przetwarza wiele wierszy, ale miałem na myśli przetwarzanie tylko jednej liczby. - NickC Jan 20 '12 o 21:00 ”robi to, co powinien. To znaczy, że powinien przetwarzać tylko jedną liczbę.
Fors
przepraszam za tę flagę; Źle odczytałem ten wymóg i nie miałem wtedy wystarczającej liczby przedstawicieli, aby móc bezpośrednio komentować. Jeszcze raz przepraszam. :)
Will Ness,
0

JavaScript, 75

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

Oracle SQL 11.2, 101 bajtów

SELECT:1||DECODE(ROUND(MOD(:1,100),-1),10,'th',DECODE(MOD(:1,10),1,'st',2,'nd',3,'rd','th'))FROM DUAL
Jeto
źródło
0

JavaScript ES6, 52 znaki

n=>n+(!/1.$/.test(--n)&&'snr'[n%=10]+'tdd'[n]||'th')
Qwertiy
źródło