Виведення порядкових чисел (1-й, 2-й, 3-й)


43

Я хотів би генерувати (як результат повернення функції, або просто як вихід програми) порядковий суфікс додатного цілого числа, з’єднаного з числом.

Зразки:

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

І так далі, із суфіксом, що повторює початкові 1–10 субпредмет кожні 10 до 100, де в кінцевому рахунку шаблон починається заново.

Введенням буде число, а вихід - порядковий рядок, як показано вище.

Який найменший алгоритм для цього?


Привіт, NickC, і ласкаво просимо до codegolf.SE! Просто для уточнення, ви маєте на увазі, що ми повинні читати таке число, як 11вхід і вихід, наприклад 11th? Чи кожне число на вході в окремому рядку, і чи повинні виводити числа також на окремих рядках? І чи потрібно нам обробляти більше, ніж один рядок введення?
Ільмарі Каронен

1
Шукаєте найменший алгоритм чи найменший код?
Toto

@Ilmari Я шукаю 11як вхід, так і 11thяк вихід. Я не проти, якщо він обробляє кілька рядків, але те, що я мав на увазі, обробляв лише одне число.
Ніколь

@ M42 Ви знаєте, я не дуже впевнений. У мене немає жорсткої вимоги - але я, мабуть, думав про найменший алгоритм.
Ніколь

Відповіді:


30

Perl, 37 + 1 символів

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

Це заміна regexp, яка додає відповідний порядковий суфікс до будь-яких цифр, за $_якими вже не йде буква. Щоб застосувати його до введення файлів, використовуйте pперемикач командного рядка, як це:

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

Це повна програма Perl, яка зчитує вхід зі stdin та записує оброблений вихід у stdout. Дійсний код становить 37 знаків, але pперемикач вважається одним додатковим символом .

Зразок введення:

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

Вихід:

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

Числа, за якими вже слідують літери, будуть ігноровані, тому подача результату знову через фільтр не змінить його. Пробіли, коми і періоди між числами не трактуються спеціально, тому їх передбачається розділяти числами, як і будь-які інші розділові знаки. Таким чином, наприклад , 3.14159стає 3rd.14159th.

Як це працює?

  • По-перше, це глобальна заміна regexp ( s///g). Згенерований регулярний параметр є 1?\d\b, де \dвідповідає будь-якій цифрі і \bє твердженням нульової ширини, що відповідає межі між буквено-цифровим та не алфавітно-цифровим символом. Таким чином, 1?\d\bвідповідає остання цифра будь-якого числа, плюс попередня цифра, якщо вона трапиться 1.

  • У підстановці, яка оцінюється як код Perl завдяки /eкомутатору, ми беремо відповідний рядковий сегмент ( $&) і додаємо .до нього суфікс, отриманий, використовуючи $&себе як цілий індекс до списку (0,st,nd,rd); якщо цей суфікс дорівнює нулю або не визначено (тобто коли $&дорівнює нулю або перевищує три), ||оператор замінює його на th.


Редагувати: Якщо введення обмежено одним цілим числом, цього 35 символьного рішення буде достатньо:

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

1
Потрібно мати можливість відмовитися gвід підстановки, якщо ви вкажете, що кожне число повинно бути у власному рядку. Крім того, це дозволить вам змінити межу слова $. Але в цілому +1, чортово розумне рішення.
Містер Лама

@GigaWatt: Дійсно, я написав код до того, як NickC відповів на моє запитання щодо формату введення, тому я зробив це максимально загальним.
Ільмарі Каронен

38

Python 2, 49 байт

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

Анонімна функція. Повна програма буде враховуватися в 55 байт.

'tsnrhtdd'[i::4]кодує суфікси th st nd rdдля значень iвід 0 до 3. Виходячи з цього, всі , що нам потрібно , це спосіб відображення значень nіндексу відповідного суфікса i. Прямий вираз, який працює (n%10)*(n%10<4 and 10<n%100<14). Ми можемо легко скоротити це, скинувши перший набір дужок і спостерігаючи, що n%5дає ті самі результати, що і n%10для значень nспеціальних суфіксів. Маючи трохи проб і помилок, ви можете також скоротити 10<n%100<14їх n%100^15>4, що може бути пов'язане з іншими умовними, щоб зберегти ще більше байтів.


3
ось якась чорна магія тут c:
кіт


Я не розумію. Хтось може пояснити, що тут відбувається?
Павло

@Pavel Я оновив свою відповідь поясненням.
xsot

Дивовижно! Блискучий спосіб думати ...
Бенісон Сем

10

Пітон, 68 символів

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

4
Це дійсно пізно, але ви можете зняти 7 байтів, виконавши `i`+"tsnrhtdd". Інакше це саме точне рішення, яке я щойно отримав.
DLosc

10

Mathematica 39 45 байт

Примітка. В останніх версіях Mathematica запит на nthчастину p, де pне визначено, генерує повідомлення про помилку, але все одно повертає правильну відповідь. Я додав, Quietщоб запобігти друку повідомлення про помилку.

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

Використання

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-е "}


Як це працює

SpokenStringвиписує будь-який дійсний вираз Mathematica, як це може бути сказано. Нижче наведено два приклади з документації для SpokenString ,

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

"квадратний корінь величини х над кількістю y плюс z" *)

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

"тривимірна графіка, що складається з одиничних сфер, орієнтованих на 0, 0, 0 і 1, 1, 1"


Тепер, для прикладу,

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

"31-й елемент p"

Представимо вищезазначений рядок у вигляді списку слів:

StringSplit[%]

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

і візьміть другий елемент ...

%[[2]]

31-а


Я збентежений; де pвизначено? EDIT: неважливо, я бачу, як ви це використовуєте; на жаль, це не працює в моїй системі. : - /
Mr.Wizard

Він працює на v.9.0.1. (Здається, я пам'ятаю, що ви використовуєте 7.0.) Так, p не потрібно визначати.
DavidC

Я зараз це розумію. Однак у v7 я отримую з SpokenString @ p[[117]]висновку " part 117 of p".
Mr.Wizard

Тож SpokenStringчас від часу переглядається. Мене не здивувало б, що цей код ( codegolf.stackexchange.com/questions/8859/… ) також не працює на v. 7. BTW, це не повинно було бути міцним рішенням.
DavidC

Так, я не бачив такої відповіді раніше.
Mr.Wizard

7

Рубі, 60

Це не так добре, як запис Perl, але я зрозумів, що буду працювати над своїми навичками Ruby.

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

Функція бере один цілий аргумент, nі повертає рядок як порядкову форму.

Працює за такою логікою:
Якщо десятковий розряд дорівнює 1 або цифри більше 3, використовуйте суфікс 'th'; в іншому випадку знайдіть суфікс з масиву ['th', 'st', 'nd', 'rd'], використовуючи кінцеву цифру як індекс.


o(113)є "113rd", має бути "113th". Десятицифровий чек не враховує числа з більш ніж двома цифрами.
хаммар

Гаразд, розмістився в іншому %10для компенсації. Додано 3 символи. (Я відчуваю, що %10виявляється достатньо там, де його слід якось скоротити, але я не можу придумати рішення)
Містер Лама

Ви ніколи не можете перемогти Perl у написанні жахливого незрозумілого коду, який є максимально коротким :)
jamylak

Встановити змінну до 10?
wizzwizz4

Я думаю, що n%10краще встановити змінну .
CalculatorFeline

6

Javascript (ES6) 50 44 байт (неконкурентоспроможний)

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

Примітки

  • приймає імпульс як рядок
  • Видалено 6 байт, дякую @ user81655

1
a+-> a+=, видаліть дужки, \d-> ., видаліть [0], і якщо ви приймаєте число як рядок: a.match`1?.$`замість /1?.$/.exec(a).
користувач81655

Вам, ймовірно, слід додати повідомлення, що ця відповідь є неконкурентною, оскільки ES6 не існував під час опублікування виклику.
user2428118

5

Javascript, 68 71

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

Спільні зусилля з ItsCosmo.

EDIT: Не працює належним чином з цифрами> 100


Ви можете звести його до 62 за допомогою: function o(n)n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')а ви можете знизити його до 54, якщо ви раді використовувати позначення жирної стрілки:o=n=>n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')
WallyWest

@WallyWest Чомусь мені дуже подобається, що моє рішення працює в сучасних браузерах. Не соромтеся розміщувати власну відповідь; Я думаю, що це досить різне.
аебабіс

Ні, це добре! Просто пропонуючи кілька альтернатив!
WallyWest


3

Хаскелл, 95 годин

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

Тестування:

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

Потрібно завантажувати -XNoMnomorphismRestriction.


3

JavaScript, 64 символи (ES3) або 47 символів (ES6)

ES3 (64 символи):

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

ES6 (47 символів):

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

Пояснення

Вираз n % 100 >> 3 ^ 1оцінюється до 0 для будь-якого позитивного nзакінчення з цифрами 08- 15. Таким чином, для будь-якого n mod 100закінчення в 11, 12або 13, пошук масиву повертається undefined, ведучи до суфіксу th.

Для будь-якого позитивного nзакінчення в інших цифрах , ніж 08- 15, то вираз n % 100 >> 3 ^ 1приймає значення позитивного цілого числа, посилаючись на вислів n % 10для пошуку масиву, повертаючи st, ndабо rdдля nякого закінчується 1, 2або 3. В іншому випадку th.


Збережіть байти за допомогою n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'.
Кудлатий

@Shaggy, спасибі, оновлено, як було запропоновано.
Томаш Лангкаас


@ guest271314, приємно бачити цей код, який використовується. Зауважте, що він працює лише для позитивних цифр, інша альтернатива - n+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th"адаптована з цього посту .
Томаш Лангкаас

3

APL (Dyalog Unicode) , 38 36 байт

Завдяки ngn за виправлення помилки, зберігаючи кількість байтів.

Функція анонімного негласного префікса. Потрібен ⎕IO( I ndex O rigin), встановлений у 0, що є типовим для багатьох систем. Навіть працює за 0!

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

Спробуйте в Інтернеті!

{} Анонімна лямбда; є аргументом:

⍳4 Перші чотири ɩ ndices;[0,1,2,3]

10↑ візьміть перші десять елементів з цього, оббиваючи нулями: [0,1,2,3,0,0,0,0,0,0]

 додавати до трактування як до одного елемента; [[0,1,2,3,0,0,0,0,0,0]]

1 0 8\ розгорнути до однієї копії, прототипної копії (все-нуль), восьми примірників;
  [[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)
   [0,1,2,3,0,0,0,0,0,0]]

ϵ nlist (сплющувати);
  [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)
   0,1,2,3,0,0,0,0,0,0]

⍵⌽ циклічно обертати ліворуч стільки ж кроків, скільки вказано аргументом

 вибрати перше число (тобто аргумент-mod-100'-е число)

 помножити два на що (дає 0, 2, 4, або 6)

'thstndrd'↓⍨викиньте з цього рядка багато символів

2↑ візьміть перші два символи, що залишилися

⍕, приєднати до цього аргументований аргумент


"31-й"?
ngn

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

вибачте, забув згадати ⎕io←0. Я можу бачити, що ви здогадалися, але є кілька 1,2,3,4,0,0 ... що повинно бути 0,1,2,3,0,0 ...
п

@ngn Виправлено. І, здається, працює і для 0!
Адам

2

PowerShell, 92

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

Працює з одним числом на рядок введення. Вхід подається по трубопроводу. Робота лише для одного номера не зменшує розмір.


2

J - 44 char

Нічого в J? Це обурення!

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

Пояснено (зауважте, що 1булева істина в J та 0хибна):

  • 10 10(...)/@#:]- Спочатку беремо аргумент ( ]) і знаходимо десятки та одиниці цифр ( 10 10 #:). Потім ми вставимо (...)між ними.
  • (]*[(~:*])4>])- У цій піддепресії, але не найглибшій, ]буде вказуватися на цифру та [десятку.
  • [(~:*])4>]- ~:J для "не дорівнює", тому це приймає результат 4>](тобто, чи є одна цифра менше 4) і помножує її на результат tens ~: (4>]). Навіщо хтось це робити? Розглянемо наступне:
    • Якщо ми перевіряємо 10, 11, 12, 13, то tensє 1(ми в підлітковому віці) і onesменше 4, значить tens ~: (4>]), помилково і результат 0*1= 0.
    • Якщо ми будь-який інший із {X0, X1, X2, X3}, тоді явно tens ~: (4>])вірно і ми виходимо 1*1= 1.
    • Якщо onesбільше чотирьох, то 4>]було, 0і вже не має значення, що станеться з тестом, ми 0вийдемо незалежно.
    • Отже, підсумовуючи [(~:*])4>]це, 1якщо ми знаходимося в {X0, X1, X2, X3}, але не в підлітковому віці, 0інакше.
  • ]*- Нарешті множимо цей результат на цифру. Тож цей продукт буде, 0якщо число заслуговує 'th'суфікса, інакше його значення.
  • th`st`nd`rd{::~- Ми використовуємо модифіковані однозначні зверху для індексації списку суфіксів. 0отримує 'th', 1отримує 'st'тощо.
  • ":,- Нарешті, візьміть оригінальне число, перетворіть його у рядок ( ":), а потім додайте до суфіксу.

Використання очевидно, хоча як-є дієслово може приймати лише один порядковий, а не список.

   (":,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 байти

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

Повна програма та перевірка:

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

Ви можете пограти в гольф на два байти, змінивши ||на |.
Kevin Cruijssen

2

Mathematica 29 + 5 = 34 байти

SpokenStringDump`SpeakOrdinal

+5 байт, тому що Speakфункція повинна бути викликана перед використанням цієї вбудованої.

Використання

SpokenStringDump`SpeakOrdinal[1]

"1st "

SpokenStringDump`SpeakOrdinal[4707]

"4,707th "


1

PHP, 151

Я знаю, що ця програма не порівнянна з іншими. Просто відчував, як дати рішення.

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

ви можете зберегти кілька символів, скориставшисьforeach($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 також:

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"

неозорений:

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

1

OCaml

Я досить новачок у OCaml, але це найкоротший, який я міг отримати.

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

Я створив функцію n, яка приймає число як параметр і виконує роботу. Дуже довго, але думав, що було б чудово мати функціональний приклад.


вхід: 11 дасть вихід:

так, ти маєш рацію .. Я вніс виправлення. Спасибі
Джозеф Ельцид

Я щойно налагодив форматування вашого коду. Кожному рядку потрібно передувати чотири пробіли, щоб його можна було розпізнати як блок коду.
Гарет

Чи не буде ваш перший, якщо перевірка буде коротшою if v>10 && v<14? Я не знайомий з ocaml, але чи потрібно, щоб string_vзмінна була такою довгою?
Гаффі

Ні, це не потрібно, я міг обрати w або x. Просто хотілося чогось значущого. Але ви праві, це зробило б код трохи коротшим.
Джозеф Ельцид

1

K - 44 char

Так трапляється, що це точно так само, як і J, і працює майже так само.

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

Пояснили:

  • x$:- Спочатку ми перетворюємо операнда xв рядок, а потім присвоюємо це назад x. Пізніше нам знову знадобиться його рядкове повторення, тому тепер це зберігає символи.
  • .:'- Перетворити ( .:) кожну ( ') цифру назад у число.
  • -2#0, - Додайте 0 до передньої частини списку цифр (у разі одноцифрових чисел), а потім візьміть останні дві.
  • {y*(y<4)*~1=x}.- Використовуйте дві цифри як аргументи xта yдо цієї внутрішньої функції, яка повертається, yякщо yвона менша за 4 та xне дорівнює 1, інакше 0.
  • `th`st`nd`rd@ - Індексуйте список суфіксів за цим результатом.
  • x,$ - Перетворіть суфікс із символу в рядок та додайте його до початкового числа.

Використання:

  {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 символи

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

Дегольф:

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)%10замість того, щоб додати 9, але при n = 0 ми отримали б неправильну поведінку, оскільки в C (-1)%10оцінюється до -1, а не 9.



1

PHP, 98 байт

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 мене тут вбиває. Працює для будь-якого цілого числа $n >= 0.

Для будь-якого цілого числа $n:

PHP, 103 байти

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

Пітон, 88 84 байт

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

Безголівки:

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

lambda xвизначає анонімну функцію з параметром x. ((('th','st','nd','rd')+('th',)*6)[int(x[-1])]визначає кортеж закінчень для чисел, менших від 10, 0-thелемент - для 0тощо. то if ('0'+x)[-2] != '1'перевіряє, чи є 11, 12чи 13для виправлення, і додає потім else 'th'додає thзамість st, rdабо nd.


Це чудова відповідь, але мені знадобився певний час, щоб зрозуміти це. Якщо ви можете додати пояснення коду та розбивки нижче гольф-версії свого коду, це допоможе людям дізнатися ваш код та покращити якість вашої відповіді.
wizzwizz4

Добре, я буду. Чи варто також додати відповідь, що не перебуває в гольфі?
NoOneIsHere

Це не повинна бути іншою відповіддю ... Те, що ви зробили, це добре, молодець. Якщо ви хочете зробити ще якісь завдання, я можу дати кілька рекомендацій.
wizzwizz4

Гаразд. Ви можете спробувати ... Налаштуйте своє крісло , або Де будуть сидіти ваші приятелі . Або ви можете спробувати деякі з моїх викликів , наприклад, The Knight's Next Tour . Якщо це не такі виклики, які вам подобаються, просто скажіть.
wizzwizz4

1

JavaScript (Node.js) , 51 байт

заслуга @KevinCruijssen за покращення відповіді

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

Спробуйте в Інтернеті!


Пояснення:

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 байт

Оскільки поки що немає рішення R ... тут немає жодних хитрощів, базове індексація вектора, завдяки Джузеппе знищило 3 знаки. Раніше випробуваний індекс: [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])

Спробуйте в Інтернеті!

З substr, 79 байт:

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

Спробуйте в Інтернеті!


1
1+x%%10*!x%%100==11для індексу?
Джузеппе

@Giuseppe Мені потрібно заспокоїтися в дужках :). Розумне використання !перед виразом замість !=.
JayCe

1
Так, оператори мають дивне перевагу; ^дуже висока, то %%-типу оператори, то */і +-я думаю , що ==і &|буде далі. !має досить низький пріоритет, тому ви можете використовувати його як роздільник між операціями.
Джузеппе

0

Python 2.7, 137 знаків

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 має бути рядок

Я знаю, що мене вже тут перемогла конкуренція, але я думав, що все-таки я дам свою ідею

це в основному генерує список ключів, пар значень з числом (у вигляді рядка), що закінчується, eі порядковим o. Він намагається спочатку співставити 'th' (отже, чому я не використовував словник), так що він випадково не поверне 'st', наприклад, коли він повинен бути 'th'. Це буде працювати для будь-якого додатного цілого числа


n[-1]==eна 5 n.endswith(e)
годин

0

C: 95 символів

Смішно довге рішення:

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

Це потрібно більше змушувати.


Користувач, позначений цим висловом, "невірно: взагалі не циклічний, тобто працює лише для заданого числа, а не для всіх номерів під ним. Див. Ideone.com/pO6UwV." Це не привід подавати прапор, оскільки модератори не судять про правильність, але це може бути проблемою.
dmckee

Виходячи з цього коментаря творця запитання: "@Ilmari Я шукаю 11 як вхідний і 11-й як вихідний. Я не заперечую, якщо він обробляє кілька рядків, але те, що я мав на увазі, обробляє лише одне число. - NickC Jan 20 '12 о 21:00 "він робить те, що повинен. Тобто він повинен обробляти лише одне число.
Форс

вибачте за цей прапор; Я неправильно прочитав вимогу, і мені не вистачало репрезентації на той час, щоб коментувати безпосередньо. Вибачте знову. :)
Буде Несс

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 байт

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 символи

n=>n+(!/1.$/.test(--n)&&'snr'[n%=10]+'tdd'[n]||'th')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.