Автоматизируйте упражнение по подсчету в первом классе

36

CodeGolf Challenge

PWSSHHHH! Вы просыпаетесь в криогенной лаборатории в 3000 году. После того, как вас сопровождают в офис назначения, чтобы получить ваш карьерный чип, предположительно таковой у курьера, зонд обнаруживает, что вы из 2000 года. Из-за этого и нескольких стереотипы, вы, как предполагается, глупы по сравнению с сегодняшним современным человеком и вынуждены повторить начальную школу.

Вы входите в класс в первом классе, и учитель дает задание. Она скажет или напишет число до 50. Если она напишет число на доске (например, 25), то вы должны сказать числа до этого числа «один, два, три, ..., двадцать пять ». Если она произносит число вслух (например, «шесть»), то на планшете вы должны написать числа до этого числа «1, 2, 3, 4, 5, 6».

Это становится очень утомительным, и вы решаете, что автоматизируете этот процесс с помощью своих все еще действующих, но архаичных знаний по программированию 21-го века.


Задача:

Ваша программа должна принять участие. Этим вводом будет либо десятичное число ( 1 thru 50), либо записанное число ( one thru fifty).

• Если ввод является десятичным числом, ваш вывод должен считаться от одного до указанного числа, используя выписанный стиль. (например, тридцать два )

• Если ввод является записанным числом, ваш вывод должен считаться от 1 до указанного числа, используя десятичный стиль. (например, 32 )


Правила:

Ввод и вывод могут быть в любом случае по вашему выбору (так что вы можете создать программу, которая принимает заглавные буквы только при желании).

Входные десятичные числа не обязательно должны быть числового типа (например, int), они могут быть входной строкой, содержащей числа (25 против «25»). Либо в порядке, и вы можете выбрать тот, который вы хотите, чтобы ваша программа приняла. (Ваша программа не должна принимать оба)

Записанный стиль НЕ требует дефиса между составными словами, но вы можете при желании.

Выходные значения должны быть разделены в какой-либо форме, любой разделитель в порядке 1,2,3 1 2 3 etc

Вы не можете добавлять дополнительные библиотеки, такие как num2words (python) и т. Д. (Однако системные библиотеки в порядке)

Хотя в предыстории говорится, что вы из 2000 года, вы можете использовать языки, созданные после этой даты (смеется)


Это , поэтому выигрывает программа с самым коротким байтом!

Альберт Реншоу
источник
1
Разрешено ли использовать библиотеки, такие как num2words, в случае с python.
Гурупад Мамадапур
1
@AlbertRenshaw, а как насчет встроенных, которые делают это? (Mathematica)
Павел
1
@coredump Либо означает, что вы можете выбрать один или другой, или оба. Это не должно быть в состоянии обрабатывать оба вида входных данных
Альберт Реншоу
2
"Укуси мою блестящую металлическую задницу!" Я не буду считать себя
RaisingAgent
1
Я продолжаю думать, что название «Ваш первый (подсчет оценок)», а не «Ваш подсчет (первого класса)»
CAD97

Ответы:

32

Perl 6 , 119 113 байтов

{my \n=<①     ㊿>.map:{|map *.uniname.words[2..*].join,$^a..$^b}
/\d/??n[^$_]!!1..1+first $_,n,:k}

База данных Unicode FTW!

Использует прописные числа в верхнем регистре без переноса, например TWENTYTWO.
Возвращает список строк или диапазон чисел. (Оба используют пробел в качестве разделителя при печати с помощью put.)

SMLS
источник
3
Очень умная ахахаха! Люблю это
Альберт Реншоу
13

Python3, 276 271 269 243 237 235 232 217 байт

Принимая реплику из представления @smls perl ...

from unicodedata import*
o=[name(chr(k)).split(' ',2)[-1]for j in['①⑴','㉑㉠','㊱㋀']for k in range(ord(j[0]),ord(j[1]))]
i=input()
w=i in o
for i in range(w and o.index(i)+1or int(i)):print(w and i+1or o[i])

Я подозреваю, что это может быть игра в гольф немного дальше.

Он использует системную библиотеку unicodedataдля поиска имен для чисел. В FORTY TWOкачестве входных данных требуются имена в верхнем регистре (разделенные пробелом ) или десятичные целые числа.

(Это моя первая подача кода в гольф.)

(Я также только что заметил, что неправильно подсчитал длину (кодировку), поэтому она на несколько байтов меньше, чем предполагалось ранее. Однако я обновил только самый последний счетчик байтов. Упс.)

unayok
источник
Добро пожаловать в PPCG!
AdmBorkBork
В защиту: unicodedataэто системная библиотека, которая поставляется с установкой по умолчанию, а не «дополнительная» библиотека, которая должна быть установлена ​​отдельно.
Унайок
Добро пожаловать на сайт! Вы можете удалить много пробелов из вашего кода .
xnor
1
Добро пожаловать в PPCG. Вы можете потерять 3 байта, поместив печать в forцикл и имея новые строки между каждым выводом. print()не волнует, если это целое число или строка тогда. Попробуйте онлайн!
ElPedro
1
Я думаю, что вы можете import*вместо того, import nameчтобы сохранить пару байтов
Wheat Wizard
10

Обыкновенный Лисп, 297 253 243 242 144 128

(lambda(s)(#1=dotimes(u(or(#1#(i 51)(if(equal(#2=format()"~R"i)s)(return i)))s))(#2#t"~[~:;, ~]~:[~R~;~D~]"u(stringp s)(1+ u))))

Детали

(lambda (s) 
  (dotimes                         ; iterate...                                                                          
      (u                           ; for u from zero below ...                
       (or                         ; if s is a string, then                   
        (dotimes (i 51)            ;   parse s by iterating from 0 to 50      
          (if (equal               ;   until we find a match between          
               (format nil "~R" i) ;   the English word(s) for i              
               s)                  ;   and the given s                        
              (return i)))         ;   (exit loop)                            
        s))                        ; otherwise, use s, which is a number      
    (format t                      ; for each U, print to standard output     
            "~[~:;, ~]~:[~R~;~D~]" ; (see below for details)                  
            u                      ; ...                                      
            (stringp s)            ; ... arguments to format                  
            (1+ u))))              ; ...                                      
  • ~[ 0 ~; 1 ~; ... ~:; else ~]это переключатель, основанный на значении следующего доступного аргумента, который переходит к соответствующему формату подчиненного элемента управления. Здесь у меня есть только случай «0» и для «еще». Это используется для вставки разделителя перед каждым числом, кроме первого, благодаря U, начинающемуся с нуля.

  • ~:[ FALSE ~; TRUE ~]это условный формат; здесь мы выводим вещи по-разному, независимо от того, является ли ввод s строкой или нет.

  • ~Rнапишите число в виде кардинального английского числа, а ~Dпросто напечатайте число.

Примеры

CL-USER> (test "five")
1, 2, 3, 4, 5

CL-USER> (test 32)
one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty, twenty-one, twenty-two, twenty-three, twenty-four, twenty-five, twenty-six, twenty-seven, twenty-eight, twenty-nine, thirty, thirty-one, thirty-two
CoreDump
источник
Исходя из того, что я понимаю в вопросе, вы должны иметь возможность анализировать оба стиля, а не только один, поэтому ваше 55-байтовое решение может оказаться недействительным. «Ваша программа не должна принимать оба» означает 25 против «25», десятичное число или число.
Том
@ TomDevs Спасибо. Это определенно сбивает с толку. Чтобы быть уверенным, если я определю fтак, чтобы "(f 2)" печатал "один, два" и (f "two")печатал "1, 2", это выглядит хорошо для вас?
coredump
Да, я думаю, что это правильно.
Том
@TomDevs Спасибо, я исправил это
coredump
1
@AlbertRenshaw Нет, только английский; эта функция может уже считаться раздутой, но, поскольку она уже была реализована в некоторых Лиспах, она была стандартизирована.
coredump
8

JavaScript ES6, 559 526 381 368 364 358 332 327 315 байт

a="one0two0three0four0five0six0seven0eight0nine0ten0eleven0twelve0thir10four10fif10six10seven10eigh10nine1".replace(/1/g,'teen').split(0),b="twenty0thirty0forty0fifty".split(0),c=(n,d=Array,e=b.forEach(i=>a=a.concat(i,a.slice(0,9).map(x=>i+x))))=>1/n?a.slice(0,n).join():d.from(d(a.indexOf(n)+1),(x,i)=>i+1).join();

Спасибо Kritixi Lithos за идею расщепления массива и Arnauld за трюк 1 / n.

a="one0two0three0four0five0six0seven0eight0nine0ten0eleven0twelve0thir10four10fif10six10seven10eigh10nine1".replace(/1/g,'teen').split(0),b="twenty0thirty0forty0fifty".split(0),c=(n,d=Array,e=b.forEach(i=>a=a.concat(i,a.slice(0,9).map(x=>i+x))))=>1/n?a.slice(0,n).join():d.from(d(a.indexOf(n)+1),(x,i)=>i+1).join();

console.log(c("twentyfive"));
console.log(c("fifty"));
console.log(c(50));

Том
источник
1
Вы можете удалить varи вы можете изменить массив ['one,'two',..]на"one0two0three0...".split(0)
Kritixi Lithos
Избыточный пробел в null, Array(n).
Yytsi
2
Вы можете заменить !isNaN(n)на 1/n. Это дает вам NaNстроку (ложь), ненулевое число с плавающей точкой для ненулевого целого числа (правда) или Infinity0 (также верно).
Arnauld
Добавьте 4 пробела перед каждой строкой кода
sagiksp
@sagiksp Да, должно быть что-то напутало при редактировании поста, должно быть исправлено сейчас :)
Том
6

Python 2 , 503 499 494 490 479 байт

-5 с благодарностью @JonathanAllan

l='one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nine#'.replace('#','teen ').split()
m='twenty','thirty','forty','fifty'
i,z,R=raw_input(),' ',range
try:n=int(i);p=(n/10)-2;o=(l+sum([[m[x]]+[m[x]+z+l[y]for y in R(9)]for x in R(p)],[])+[m[p]]+[m[p]+z+l[y]for y in R(n%10)],l[:n])[n<20]
except:j=i.split();o=map(str,R(1,(m.index(j[0])+2)*10+l.index(j[1])+2if z in i else l.index(i)+2if i in l else(m.index(i)+2)*10+1))
print','.join(o)

Попробуйте онлайн!

Введите число или разделенное пробелами написание числа.

Чуть менее гольф и более читаемая версия:

l='one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen'.split()
m='twenty','thirty','forty','fifty'
i=raw_input()
try:
 n=int(i)
 if n<20:
  o=l[0:n]
 else:
  o=l
  for x in range((n/10)-2):
   o+=[m[x]]+[m[x]+' '+l[y]for y in' '*9]
  p=m[(n/10)-2]
  o+=[p]+[p+' '+l[y]for y in' '*n%10]
except:
 if' 'in i:
  t=i.split()
  s=((m.index(t[0])+2)*10)+l.index(t[1])+2
 else:
  s=l.index(i)+2 if i in l else((m.index(i)+2)*10)+1
 r=range(1,s)
 o=map(str,r)
print','.join(o)
ElPedro
источник
1
6-байтовое сохранениеl="one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nin#".replace("#","teen ").split()
Джонатан Аллан
... ой 5, пропустил eиз nineteen.
Джонатан Аллан
Есть ли причина, по которой вам нужно использовать Python 2, без него печать была бы более длинной, но raw_input мог бы просто быть введен? (Тот же вопрос для вашего другого ответа)
nedla2004
@ nedla2004 - Нет другой причины, кроме того, что я еще не успел установить Python 3 на свой последний ноутбук :-)
ElPedro
6

Схема, 161 , 152 , 149

(define (c x)(let((r(string->number x)))(let l((i 1))(let((n (format #f "~r" i)))(display(if r n i))(newline)(or(eq? r i)(equal? x n)(l (+ i 1)))))))

несжатый:

(define (count limit)
  (let ((numerical-limit (string->number limit)))
    (let l ((i 1))
      (let ((current-number (format #f "~r" i)))
        (display (if numerical-limit current-number i))
        (newline)
        (or (eq? numerical-limit i)
            (equal? limit current-number)
            (l (+ i 1)))))))
Майкл Верс
источник
Как вы конвертируете, например, из "четырех" в 4? Я не уверен, что string->numberделает это, я проверил быстро, и, кажется, используется для преобразования, например, из строки "4"в число 4.
coredump
@coredump Это правильно. (string->number "four")возвращается #f.
Майкл Vehrs
По какой схеме вы работаете?
coredump
1
@coredump guile 2.0.9
Майкл Вёрс,
6

PHP - 397 372 349 344 329 байт

Вдохновленный JS-решением TomDevs

Сохранено 25 байт путем замены $a=[...]на$a=explode(...)

Сохранение еще 23 байтов путем переключения обратно в массив без разделителей строк и сохранения teenв переменной благодаря @ user59178

Сохранены еще 5 байтов, удалив (int)приведение типов

Добавлено еще 15 байт путем сбрасывания $b, в $iв forдекларации, и фигурные скобки, благодаря @ user59178 снова

$a=[one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir.$t=teen,four.$t,fif.$t,six.$t,seven.$t,eigh.$t,nine.$t];foreach([twenty,thirty,forty,fifty] as$c){$a[]=$c;for($i=0;$i<9;)$a[]=$c.'-'.$a[$i++];}if($argv[1]!=0)for($i=0;$i<$argv[1];)echo$a[$i++].' ';else for($i=1;$i<=array_search($argv[1],$a)+1;)echo$i++.' ';

Ungolfed:

$a =[one,two,three,four,five,six,seven,eight,nine,ten,eleven,‌​twelve,thir.$t=teen,‌​four.$t,fif.$t,six.$‌​t,seven.$t,eigh.$t,n‌​ine.$t];
foreach ([twenty,thirty,forty,fifty] as $c){
    $a[] = $c;
    for ($i=0;$i<9;)
        $a[] = $c . '-' . $a[$i++];
}
if( $argv[1] !=0 )
    for ($i=0;$i<$argv[1];)
        echo $a[$i++] . ' ';
else
    for ($i=1;$i<=array_search($argv[1], $a)+1;)
        echo $i++ . ' ';

Попробуйте это для входной строки или для входного числа

roberto06
источник
1
При игре в гольф вы можете использовать множество струн напрямую, без кавычек, включая все количество, которое вы используете. Это вызывает уведомление, но это может быть проигнорировано. Кроме того, она короче (на 2 целых байта), чтобы хранить ее teenв переменной, а не повторять ее каждый раз. Как таковой он станет:$a=[one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir.$t=teen,four.$t,fif.$t,six.$t,seven.$t,eigh.$t,nine.$t];
user59178
Не думал об этом, спасибо;)
roberto06
Вы можете сэкономить еще 7 байтов, удалив $bи поместив второй массив непосредственно в foreach, еще 6 байтов, опустив все фигурные скобки (хотя вам нужно поместить $a=$cв настройку цикл for), и еще 6 байтов, увеличивая их после приращения. $iкогда вы используете его, а не в бите «после» цикла for.
user59178
Сохраните шесть байтов (по два на цикл), переместив for ($i=0;$i<9;)$a[]=$c.'-'.$a[$i++];
постинкремент
Упс, извините, только что заметил, что @ user59178 предложил то же самое ...
Алекс Ховански
6

Python 2, 262 байта

x="one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nine#".replace("#","teen ").split()
x+=[a+"ty"+b for a in"twen","thir","for","fif"for b in['']+x[:9]]
v=input()
for s in range(1,x.index(v)+2)if v>50else x[:v]:print s

repl.it

Строки ввода и вывода строчные и сцепленные *, поэтому для проверки ввода строки введите, например, "thirtyfive"приглашение.

Формирует список всех слов (от плюс "fiftyone"до "fiftynine"), xзатем проверяет, inputявляется ли слово прокси v>50(строки больше, чем числа в Python 2, и все числа в допустимом диапазоне ввода из спецификации <=50), и printсоответствует значения путем нарезки списка, x[:v]или построения диапазона целых чисел range(1,x.index(v)+2).

* Добавление переносов для обоих стоит 11 байт, заменив a+"ty"bна a+"ty"+'-'*(b>'')+b.

Джонатан Аллан
источник
5

Wolfram Language, 92 байта

If[NumberQ@#, Do[Print@IntegerName@i, {i, #}], 
  Do[Print@i, {i, Interpreter["SemanticNumber"]@#}]] &

(Я новичок в этом, дайте мне знать, если я сделал что-то не так)

user6014
источник
2
-10 байт:Do[Print@If[#>0,i,,IntegerName@i],{i,If[#>0,#,,Interpreter["SemanticNumber"]@#]}]&
JungHwan Мин
5

JavaScript (ES6), 261 байт

Примечание: строка, назначенная z, закодирована с atob. В закодированной строке есть 11 байтов, которые я не могу опубликовать на этом сайте, даже если они являются допустимыми символами в строке javascript. Поэтому я использовал шестнадцатеричный код в виде \ xHH. Каждое из этих побегов считается за 1 байт.
Оригинальная несжатая струна является менее гольфовой версией.

x=>(z=btoa('ö\x89ÞöÜ(öØkyï_¢êý~+Þöȱöǯz\x7f^\x8a\x08möx§{Û^\x9f×¥z÷§öÜ\x1e\x96÷½¶\x18«÷×â\x7fß}z(!÷Ûpz\x7f}~\x8aý').split(9),o=(0+z.map((v,i)=>i<20?i<13?v:(v||z[i-10])+'teen':z.slice(0,10).map(d=>(z[i]||z[i-8]||z[i-18])+'ty'+d))).split`,`,p=o.indexOf(x),o.slice(1,-~x+p+!~p).map((x,i)=>~p?i+1:x))

Меньше гольфа

x => (
  z = '9one9two9three9four9five9six9seven9eight9nine9ten9eleven9twelve9thir99fif999eigh99twen99for9'
      .split(9),
  o = (0 + // 0 + array to build a comma separated string
       z.map( (v, i) => 
         i < 20 
         ? i < 13 
           ? v // 1 to 13 are 'as is'
           : (v||z[i-10])+'teen' // compose for 14 to 19
         : z.slice(0,10).map(d=>(v||z[i-8]||z[i-18])+'ty'+d)) // 20s, 30s, 40s, 50s
      ).split`,`, // from comma separated to array again
  // o contains strings from one to fiftynine
  p = o.indexOf(x), // look for input
  o.slice(1, -~x+p+!~p).map((x,i) => ~p?i+1:x)
)

Тест

F=
x=>(z=btoa('ö\x89ÞöÜ(öØkyï_¢êý~+Þöȱöǯz\x7f^\x8a\x08möx§{Û^\x9f×¥z÷§öÜ\x1e\x96÷½¶\x18«÷×â\x7fß}z(!÷Ûpz\x7f}~\x8aý').split(9),o=(0+z.map((v,i)=>i<20?i<13?v:(v||z[i-10])+'teen':z.slice(0,10).map(d=>(v||z[i-8]||z[i-18])+'ty'+d))).split`,`,p=o.indexOf(x),o.slice(1,-~x+p+!~p).map((x,i)=>~p?i+1:x))

function update() {
  var i=I.value
  O.textContent = F(i)
}  

update()
<input id=I value=25 oninput='update()'><pre id=O></pre>

edc65
источник
ö\x89ÞöÜ(öØ...этот материал отличный хахаа
Альберт Реншоу
Относится к вашей главной заметке: meta.stackoverflow.com/questions/342546/…
Альберт Реншоу
5

Python 3 , 305 303 байта

Преобразован в Python 3 по совету от @ nedla2004. Теперь также нет пробела между записанными числами на входе или выходе, например, введите Twenty

l='one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nine#'.replace('#','teen ').split()
m='twenty','thirty','forty','fifty'
i,R=input(),range
l+=sum([[m[x]]+[m[x]+l[y]for y in R(9)]for x in R(3)],[])
for x in R(1,l.index(i)+2)if i in l else l[:int(i)]:print(x)

Попробуйте онлайн 3!

Python 2 , 327 320 313 308 байт

l='one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nine#'.replace('#','teen ').split()
m='twenty','thirty','forty'
i,R=raw_input(),range
l+=sum([[m[x]]+[m[x]+l[y]for y in R(9)]for x in R(3)],[])+['fifty']
for x in R(1,l.index(i)+2)if i in l else l[:int(i)]:print x

Попробуйте онлайн 2!

163 170 177 байт короче, чем мой первоначальный ответ, поэтому я публикую его в качестве альтернативы. Это использует forдва списка для создания полного списка всех строковых представлений чисел, затем идентифицирует правильное в списке и печатает все до него либо по значению, либо по индексу. Выводит новую строку для каждого значения.

ElPedro
источник
5

Python 2, 432 422 416 403 байта

Я уверен, что это можно улучшить. По крайней мере, если мне удастся избежать жесткого кодирования значения, над которым нужно работать, и при этом мне не понадобится функция, которую я могу сохранить 20. Для ввода текста требуется пространство для разделения слов. Сохранено 6 байтов благодаря комментарию Джонатана Аллана к ответу ElPedro, 4 для перестановки математики.

def z(f):
 a,b,i,d="one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nine#".replace("#","teen ").split()+[""],"twenty thirty forty fifty".split(),1,f>50
 if d:f=f.split();f=a.index(f[-1])+21+b.index(f[-2])*10 if len(f)>1 else b.index(f[-1])*10+20 if f[-1]in b else a.index(f[-1])+1
 while i<=f:s=i if d else a[i-1]if i<20 else b[i//10-2]+a[i%10-1];print s;i+=1

(NB: Фактическая версия этого использует вкладки для отступа вместо пробелов. QPaysTaxes добавил один пробел, потому что он не рендерился должным образом, чтобы гарантировать, что данный код компилируется. Он не должен изменять количество байтов.)

Крис Н
источник
@ JonathanAllan - комментарий к ответу ElPedro - здесь тоже работает для -6
Крис Х
1
len(`f`)>2может быть ...`f`[2:]еще на 3 я верю. (не ...
Джонатан Аллан
На самом деле в Python 2 вы могли бы пойти на f>506. (и еще один, не используя d)
Джонатан Аллан
@JonathanAllan , что не работает для передачи чисел в виде целых чисел, которые я в настоящее время сделать: TypeError: 'int' object has no attribute '__getitem__'. Если я передаю числовой ввод в виде строки, он f[2:]становится ближе, но все равно терпит неудачу, когда трактуется как логическое значение ( print f[2:] and Trueпечатает пустую строку, если len (f) <2, нет Trueили False)
Крис Х
@JonathanAllan f>50работает, спасибо. Отбрасывание dне так просто, так как я всегда помещаю конечное значение цикла в fстроку 8, чтобы ее нельзя было изменить, if f>50поскольку она никогда не будет истинной.
Крис Х
4

C ++ 11, 484 480 477 байт

#import<iostream>
#import<cstdlib>
#import<vector>
using namespace std;f(){int j,i=2;string s="teen";vector<string>v={"","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve"};for(;i++<9;)v.push_back(v[i]+s);v[13]="thir"+s;v[15]="fif"+s;v[18]="eigh"+s;for(i=19;i++<50;){string n[4]={"twenty","thirty","forty","fifty"};v.push_back(n[i/10-2]+v[i%10]);}cin>>s;if(i=atoi(s.c_str()))for(j=0;j++<i;)cout<<v[j]<<" ";else while(v[i++]!=s)cout<<i<<" ";}

Ввод текста в нижнем регистре без дефисов.

Steadybox
источник
3

PowerShell , 362 байта

$z=0..50|%{("0twenty0thirty0forty0fifty"-split0)[+(($b="$_"[0])-gt49)*($_-gt19)*(+"$b"-1)]+($x=(("0one0two0three0four0five0six0seven0eight0nine0ten0eleven0twelve"-split0)+(-split'thir four fif six seven eigh nine'|%{$_+'teen'})))[($_%10)*($_-gt19)]+$x[$_*($_-le19)]}
if(($n=-split$args)[0][0]-in48..57){$z[$n[0]..$n[2]]}else{$z.IndexOf($n[0])..$z.IndexOf($n[2])}

Попробуйте онлайн! ввод слов или ввод цифр

Это правильный беспорядок, и я не очень доволен этим, но вот он. Предложения по игре в гольф приветствуются.

Первая строка $zпредставляет собой массив полных английских слов. Вы можете увидеть -split0числа 1для 12и цикл для построения всех teens, а затем есть куча логики, чтобы все сложить правильно. Попробуйте онлайн!

Вторая строка начинается с некоторой логики. Мы берем входные данные $args(в виде строки), -splitпомещаем их в пробел, сохраняем их $nдля последующего использования, берем первое [0]слово и первый [0]символ этого и проверяем, является ли он -inдиапазоном 48..57(т. Е. ASCII 0to 9). Итак, мы проверяем, есть ли у нас десятичный или английский ввод. Попробуйте онлайн!

В первом случае мы строим диапазон на основе десятичных входных данных $n[0]..$n[2]и используем его для индексации $z[...]. В другом случае мы находим .indexOf()первое слово и последнее слово и строим из этого только числовой диапазон. В любой ситуации у нас теперь есть массив объектов в конвейере (либо строки, либо целые числа), и неявное Write-Outputзавершение программы дает нам новую строку между элементами.

AdmBorkBork
источник
3

Swift3, 402 байта

let f=["one","two","three","four","five","six","seven","eight","nine"]
let g=["twenty","thirty","forty","fifty"]
let v=[f,["ten","eleven","twelve"],["thir","four","fif","six","seven","eigh","nine"].map{$0+"teen"},[g[0]],f.map{g[0]+$0},[g[1]],f.map{g[1]+$0},[g[2]],f.map{g[2]+$0},[g[3]]].flatMap{$0}
func c(s:String){if let i=Int(s){print(v.prefix(upTo:i))}else{for j in 1...v.index(of:s)!+1{print(j)}}}

Ungolfed:

let f = ["one","two","three","four","five","six","seven","eight","nine"]
let g = ["twenty","thirty","forty","fifty"]

let values = [f,["ten","eleven","twelve"],["thir","four","fif","six","seven","eigh","nine"].map{$0+"teen"},
              [g[0]], f.map{g[0]+$0},
              [g[1]], f.map{g[1]+$0},
              [g[2]], f.map{g[2]+$0},
              [g[3]]].flatMap{$0}

func count(s:String){
    if let i = Int(s) {
        print(values.prefix(upTo: i))
    } else {
        for j in 1...values.index(of: s)!+1{
            print(j)
        }
    }
}

count(s:"29")
count(s:"twentyeight")

Ничего особенного, просто использование массива для резервного копирования записанных чисел.

Я изначально думал, что это решение, используя этот другой способ для расчета valuesмассива:

let values = f + ["eleven","twelve"]
    + ["thir","four","fif","six","seven","eigh","nine"].map{$0+"teen"}
    + [g[0]] + f.map{g[0]+$0}
    + [g[1]] + f.map{g[1]+$0}
    + [g[2]] + f.map{g[2]+$0}
    + [g[3]]

Который может быть в гольф, чтобы:

let v=f+["eleven","twelve"]+["thir","four","fif","six","seven","eigh","nine"].map{$0+"teen"}+[g[0]]+f.map{g[0]+$0}+[g[1]]+f.map{g[1]+$0}+[g[2]]+.map{g[2]+$0}+[g[3]]

замена 3-й строки в коде гольфа

Я мог бы набрать 381 байт, но есть ошибка компилятора, которая говорит: «выражение было слишком сложным, чтобы его можно было решить за разумное время», более подробную информацию об ошибке можно найти здесь

Родриго Руис Мургия
источник
ЛЮБОВЬ, видя, как быстро здесь, я должен будет проверить это больше, когда я вернусь
Альберт Реншоу
3

R 452 430 424 байта

o=c("","one","two","three","four","five","six","seven","eight","nine") 
t=gsub(0,"teen",c("ten","eleven","twelve","thir0","four0","fif0","six0","seven0","eigh0","nine0"))
s=c("twenty","thirty","forty") 
p=""
for(i in s){for(j in o){p=paste0(p,i,j," ")}}
as.data.frame(t(d<-1:50))
names(d)=c(o[-1],t,as.vector(strsplit(p," ")[[1]]),"fifty")
f=function(x){if(is.numeric(x)){names(d)[1:x]}else{matrix(d[1:d[x]],dimnames=NULL)}}

#> f(5)
#[1] "one"   "two"   "three" "four"  "five" 

#> f('five')
#     [,1]
#[1,]    1
#[2,]    2
#[3,]    3
#[4,]    4
#[5,]    5

Помещает числа в data.frame с записанными числами в качестве имен столбцов, что делает перевод между ними (и последующую печать) довольно простым.

Основная попытка игры в гольф заключалась в создании выписанных номеров для 20-49, вероятно, гораздо больше, чтобы играть в гольф здесь.

Я сделал попытку с as.matrix напечатать data.frame только с числами, но все еще остался с заголовком матрицы. Надеюсь, это нормально.

Ungolfed:

ones <- c("","one","two","three","four","five","six","seven","eight","nine") 
teens <- c("ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen")
tens <- c("twenty","thirty","forty") 

p=""
for(i in tens){
  for(j in ones){
    p=paste0(p, i, j," ")
  }
}

nums <- 1:50
as.data.frame(t(nums))
names(nums) <- c(ones[-1], teens, as.vector(strsplit(p, " ")[[1]]), "fifty")
f <- function(x){
  if(is.numeric(x)){
    names(nums)[1:x]
  } else {
    matrix(nums[1:nums[x]], dimnames = NULL)
  }
}
BLT
источник
Небольшое улучшение до 359 байт:o=c("","one","two","three","four","five","six","seven","eight","nine") ; v=c("ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"); w=c("twenty","thirty","forty"); a=data.frame(0:50, c(o,v, sapply(w[1:3],function(y) sapply(o,function(x) paste0(y,x))),"fifty")); b=which(a==i); a[if(b<52) 2:b else 2:(b-51),ifelse(b<52,2,1)]
считать
@count выглядит как большое улучшение! Похоже, я не могу понять, где находится функция или где вы берете аргумент.
BLT
2

C 342 331 байт

char*x[]={"teen","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thir","four","fif","twenty","thirty","fourty","fifty"};void main(int z,char**i){for(z=1;z<=atoi(i[3]);z++)printf("%s%s%s\n",z<16?x[z]:z<20?z^18?x[z-10]:"eigh":x[z/10+14],z>20&&z%10?"-":z>12&&z<20?*x:"",z>20&&z%10?x[z%10]:"");}

Попробуйте онлайн!

Ahemone
источник
Мой любимый язык :)
Альберт Реншоу
1
Вы на самом деле не нуждаетесь в 1 или 1; все, что требует этот Codegolf, это ваш третий аргумент. Первые два всегда будут "1 и через" (или "один и через")
Альберт Реншоу
@AlbertRenshaw Хороший звонок! Спасибо :)
Ahemone
1

САС, 179

%macro c(n);%let f=words.;%if%length(&n)>2%then%do;%do c=1%to 50;%if%qsysfunc(putn(&c,&f))=&n%then%let n=&c;%end;%let f=2.;%end;%do i=1%to &n;%put%sysfunc(putn(&i,&f));%end;%mend;

Вывод записывается в журнал, разделенный новыми строками. SAS имеет встроенный формат для преобразования цифр в слова, что является основным преимуществом для этой задачи, но, к сожалению, ему не хватает информации для выполнения обратного.

user3490
источник