Automatize seu exercício de contagem da primeira série

36

CodeGolf Challenge

PWSSHHHH! Você acorda em um laboratório de criogenia no ano 3000. Ao ser escoltado para o escritório de designação para receber seu chip de carreira, presumivelmente o de um entregador, uma sonda detecta que você é do ano 2000. Por causa disso, e alguns estereótipos, você é considerado estúpido em comparação com o ser humano moderno de hoje e é forçado a repetir a escola.

Você entra na sala de aula da primeira série e o professor está dando uma tarefa. Ela dirá ou escreverá um número até 50. Se ela escrever o número no quadro (por exemplo: 25), será necessário dizer os números até esse número "um, dois, três, ..., vinte e cinco " Se ela disser o número em voz alta (por exemplo: "seis"), em seu tablet, você deverá escrever os números até esse número "1, 2, 3, 4, 5, 6"

Isso se torna muito entediante e você decide que automatizará o processo com seu conhecimento de programação ainda em funcionamento, ainda que arcaico, do século XXI.


Objetivo:

Seu programa deve receber uma entrada. Essa entrada será um número decimal ( 1 thru 50) ou um número gravado ( one thru fifty).

• Se a entrada for um número decimal, sua saída deverá contar de um a esse número, usando o estilo gravado. (por exemplo, trinta e dois )

• Se a entrada for um número gravado, sua saída deverá contar de 1 a esse número, usando o estilo decimal. (por exemplo, 32 )


Regras:

A entrada e a saída podem ser escolhidas em qualquer caso (para que você possa criar um programa que aceite apenas maiúsculas, se desejar).

Os números decimais de entrada não precisam ser do tipo de número (por exemplo, int), podem ser uma sequência de entrada contendo números (25 vs "25"). Ou estão bem e você pode escolher qual deles deseja que seu programa aceite. (Seu programa não precisa aceitar os dois)

O estilo gravado NÃO requer um hífen entre as palavras compostas, mas você pode, se desejar.

Os valores de saída precisam ser separados de alguma forma, qualquer separador é bom 1,2,3 1 2 3 etc

Você não pode adicionar bibliotecas extras, como num2words (python) etc. (no entanto, as bibliotecas do sistema estão boas)

Embora a história anterior diga que você é do ano 2000, você pode usar os idiomas criados após essa data (risos)


Isso é , então o programa com o menor número de bytes vence!

Albert Renshaw
fonte
1
Estamos autorizados a usar bibliotecas como num2words no caso de python.
Gurupad Mamadapur
1
@AlbertRenshaw, mas e as construções que fazem isso? (Mathematica)
Pavel
1
@coredump Significa que você pode escolher um ou outro ou ambos. Ele não tem que ser capaz de lidar com ambos os tipos de entradas
Albert Renshaw
2
"Morda minha bunda de metal brilhante!" Eu não vou me contar #
RaisingAgent #
1
Eu fico pensando o título é "o primeiro (contagem grau)" e não "o seu (primeiro grau) de contagem"
CAD97

Respostas:

32

Perl 6 , 119 113 bytes

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

Banco de dados Unicode FTW!

Usa números gravados em letras maiúsculas sem hífen, por exemplo TWENTYTWO.
Retorna uma lista de seqüências de caracteres ou um intervalo de números. (Ambos usam espaço como separador quando impresso com put.)

smls
fonte
3
Muito esperto, ahahaha! Love it
Albert Renshaw
13

Python3, 276 271 269 243 237 235 232 217 bytes

Tomando uma sugestão do envio @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])

Eu suspeito que possa ser jogado um pouco mais longe.

Utiliza a biblioteca do sistema unicodedatapara procurar nomes por números. Requer nomes de números em maiúsculas (separados por espaço FORTY TWO:) ou números inteiros decimais como entrada.

(Este é o meu primeiro envio de código de golfe.)

(Eu também acabei de notar que estava calculando mal o comprimento (codificação), portanto, são alguns bytes menos do que se pensava anteriormente. No entanto, só atualizei a contagem de bytes mais recente. Ops.)

unayok
fonte
Bem-vindo ao PPCG!
AdmBorkBork 31/01
Em advocacy: unicodedataé uma biblioteca de sistema que vem com a instalação padrão, não uma biblioteca "extra" que precisa ser instalada separadamente.
unayok
Bem vindo ao site! Você pode remover muitos espaços do seu código .
xnor 31/01
1
Bem-vindo ao PPCG. Você pode perder 3 bytes colocando a impressão dentro de um forloop e tendo novas linhas entre cada saída. print()não se importa se é um número inteiro ou uma string então. Experimente online!
precisa saber é o seguinte
1
Eu acho que você pode, em import*vez de import namesalvar um par de bytes
Assistente de trigo 02/02
10

Lisp comum, 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))))

Detalhes

(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 ~]é uma opção, com base no próximo valor do argumento disponível, que salta para o formato de subcontrole apropriado. Aqui, eu só tenho um caso de "0" e para "else". Isto é usado para inserir um separador antes de cada número, exceto o primeiro, graças a U começando do zero.

  • ~:[ FALSE ~; TRUE ~]é um formato condicional; aqui mostramos as coisas de maneira diferente, independentemente de a entrada s ser uma string ou não.

  • ~Rescreva um número como um número cardinal em inglês, enquanto ~Dsimplesmente imprime o número.

Exemplos

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
fonte
Pelo que entendi da pergunta, você deve poder analisar os dois estilos, não apenas um, para que sua solução de 55 bytes não seja válida. "Seu programa não precisa aceitar os dois" refere-se a 25 vs "25", o decimal como um número ou como uma string.
Tom
@TomDevs Thanks. Isso é definitivamente confuso. Certamente, se eu definir fpara que "(f 2)" imprima "um, dois" e (f "two")imprima "1, 2", isso lhe parece bom?
Coredump
Sim, acho que está certo.
Tom
@TomDevs Obrigado, eu corrigi
coredump
1
@AlbertRenshaw Não, apenas inglês; esse recurso já pode ser considerado inchado, mas como já foi implementado em alguns Lisps, foi padronizado.
Coredump
8

JavaScript ES6, 559 526 381 368 364 358 332 327 315 bytes

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

Agradecemos a Kritixi Lithos pela idéia de dividir o array e a Arnauld pelo truque 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));

Tom
fonte
1
Você pode remover vare alterar a matriz ['one,'two',..]para"one0two0three0...".split(0)
Kritixi Lithos
Espaço em branco redundante em null, Array(n).
Yytsi 31/01
2
Você pode substituir !isNaN(n)por 1/n. Isso fornece NaNuma cadeia de caracteres (falsy), uma flutuação diferente de zero para um número inteiro diferente de zero (truthy) ou Infinitypara 0 (também truthy).
Arnauld
Adicione 4 espaços na frente de cada linha de código
sagiksp
@sagiksp Sim, deve ter sujado alguma coisa ao editar o post, deve ser corrigido agora :)
Tom
6

Python 2 , 503 499 494 490 479 bytes

-5 com graças a @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)

Experimente online!

Digite um número ou a ortografia separada por espaço de um número.

Versão menos golfe e mais legível:

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
fonte
1
Economize 6 bytes coml="one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nin#".replace("#","teen ").split()
Jonathan Allan
... opa 5, perdeu o ede nineteen.
Jonathan Allan
Existe um motivo para você usar o Python 2, sem ele a impressão seria mais longa, mas o raw_input poderia ser apenas inserido? (Mesma pergunta para sua outra resposta)
nedla2004
@ nedla2004 - Nenhuma razão diferente da que eu não tenho rodada para instalar o Python 3 no meu laptop mais recente ainda :-)
ElPedro
6

Esquema, 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)))))))

Descomprimido:

(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)))))))
Michael Vehrs
fonte
Como você converte, por exemplo, "quatro" para 4? Não tenho certeza string->number, verifiquei rapidamente e parece ser usado para converter, por exemplo, de string "4"para número 4.
Coredump
@coredump Isso está correto. (string->number "four")retorna #f.
Michael Vehrs
Qual esquema você está executando?
Coredump
1
@coredump guile 2.0.9
Michael Vehrs
6

PHP - 397 372 349 344 329 bytes

Inspirado na solução JS de TomDevs

Economizou 25 bytes substituindo $a=[...]por$a=explode(...)

Salvou outros 23 bytes retornando a uma matriz sem delimitadores de string e armazenando teenem uma variável, graças a @ user59178

Salvou outros 5 bytes removendo a (int)conversão de letra

Salvou outros 15 bytes ao largar $b, $inas fordeclarações e entre chaves, graças a @ user59178 novamente

$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++ . ' ';

Experimente para uma sequência de entrada ou para um número de entrada

roberto06
fonte
1
Ao jogar golfe, você pode usar muitas cordas diretamente, sem aspas, incluindo todo o número usado. Isso causa um aviso, mas pode ser ignorado. Além disso, é mais curto (por 2 bytes inteiros) armazenar teenem uma variável em vez de repeti-la a cada vez. Como tal, ele se tornaria:$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 31/01
Não tinha pensado que, graças;)
Roberto06
Você pode salvar mais 7 bytes soltando $be colocando a segunda matriz diretamente no foreach, mais 6 bytes soltando todos os chavetas (embora seja necessário colocar $a=$cna configuração do loop for) e mais 6 bytes pós-incrementando $iquando você o usa, e não no bit 'after' dos loops for.
user59178
Salve seis bytes (dois por loop) movendo o pós-incremento de para para a seguinte linha:for ($i=0;$i<9;)$a[]=$c.'-'.$a[$i++];
Alex Howansky
Opa, desculpe, só notei que @ user59178 sugeriu a mesma coisa ...
Alex Howansky
6

Python 2, 262 bytes

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

As seqüências de entrada e saída são minúsculas e concatenadas *; portanto, para testar uma entrada de sequência, digite, por exemplo, "thirtyfive"no prompt.

Constrói a lista de todas as palavras (mais "fiftyone"para "fiftynine") e x, em seguida, testa se inputé uma palavra com o proxy v>50(as strings são maiores que os números no Python 2 e todos os números no intervalo de entrada válido da especificação são <=50) printes são os adequados valores dividindo a lista x[:v]ou criando um intervalo de números inteiros range(1,x.index(v)+2),.

* A adição de hifenização em ambos custa 11 bytes, substituindo a+"ty"bpor a+"ty"+'-'*(b>'')+b.

Jonathan Allan
fonte
5

Wolfram Language, 92 bytes

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

(Eu sou novo nisso, deixe-me saber se fiz algo errado)

user6014
fonte
2
-10 bytes:Do[Print@If[#>0,i,,IntegerName@i],{i,If[#>0,#,,Interpreter["SemanticNumber"]@#]}]&
JungHwan Min
5

JavaScript (ES6), 261 bytes

Nota: a sequência atribuída a z é codificada com atob. Na string codificada, existem 11 bytes que não posso postar neste site, mesmo que sejam caracteres válidos em uma string javascript. Então, eu usei um escape hexadecimal no formato \ xHH. Cada uma dessas escapes é contada como 1 byte.
A sequência original não compactada é a versão menos golfe .

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

Menos golfe

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

Teste

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
fonte
ö\x89ÞöÜ(öØ...essas coisas são ótimas hahaa
Albert Renshaw
Relevante para a sua nota principal: meta.stackoverflow.com/questions/342546/…
Albert Renshaw
5

Python 3 , 305 303 bytes

Convertido para Python 3 após o conselho de @ nedla2004. Agora também não há espaço entre os números escritos na entrada ou na saída, por exemplo, digite vinte e dois

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)

Experimente online 3!

Python 2 , 327 320 313 308 bytes

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

Experimente online 2!

163 170 177 bytes mais curtos que a minha resposta original, por isso estou postando-a como uma alternativa. Isso é usado fornas duas listas para criar uma lista completa de todas as representações de seqüência de caracteres dos números, em seguida, identifica a correta na lista e imprime tudo nela, por valor ou por índice. Gera uma nova linha para cada valor.

ElPedro
fonte
5

Python 2, 432 422 416 403 bytes

Tenho certeza de que isso pode ser melhorado. No mínimo, se eu conseguir codificar o valor a ser trabalhado e não precisar de uma função, posso salvar 20. Ele precisa de um espaço para separar as palavras na entrada de texto. Economizou 6 bytes graças ao comentário de JonathanAllan na resposta do ElPedro, 4 por reorganizar a matemática.

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: A versão atual disso usa guias para recuar em vez de espaços. QPaysTaxes adicionou um espaço único porque não estava sendo renderizado corretamente, para garantir que o código fornecido seja compilado. Não deve alterar a contagem de bytes.)

Chris H
fonte
O comentário de @ JonathanAllan na resposta de ElPedro também funciona aqui para -6 #
Chris H
1
len(`f`)>2pode ser ...`f`[2:]por mais 3 eu acredito. (ignore o ...não consigo obter os acentos graves funcionando corretamente)
Jonathan Allan
De fato, em python 2 você poderia ir para f>50para 6. (e outra por não usar d)
Jonathan Allan
@JonathanAllan isso não funcionar para passar números como inteiros, que atualmente eu fazer: TypeError: 'int' object has no attribute '__getitem__'. Se eu passar entrada numérica como uma string, f[2:]se aproxima, mas ainda falha quando trado como um boolean ( print f[2:] and Trueimprime uma linha em branco se len (f) <2, não Trueou False)
Chris H
@ JonathanAllan f>50funciona, obrigado. Soltar dnão é tão simples, como eu sempre coloco o valor final do loop para fque a linha 8 não possa ser alterada para if f>50, pois nunca será verdade.
Chris H
4

C ++ 11, 484 480 477 bytes

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

Entrada de texto em letras minúsculas sem hífens.

Steadybox
fonte
3

PowerShell , 362 bytes

$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])}

Experimente online! entrada de palavras ou entrada de números

Esta é uma bagunça certa, e não estou muito feliz com isso, mas aqui está. Sugestões de golfe são bem-vindas.

A primeira linha define $zcomo uma matriz de todas as palavras em inglês. Você pode ver a -split0para números 1para 12, eo loop para construir todas as teens, e então há um monte de lógica para juntar tudo certo.Experimente online!

A segunda linha começa com alguma lógica. Pegamos a entrada $args(como uma string), -splitem espaço em branco, a armazenamos $npara uso posterior, pegamos a primeira [0]palavra e o primeiro [0]caractere e verificamos se é -inum intervalo 48..57(por exemplo, ASCII 0para 9). Então, estamos verificando se temos entrada decimal ou entrada em inglês.Experimente online!

No primeiro caso, criamos um intervalo com base nas entradas decimais $n[0]..$n[2]e o usamos para indexar $z[...]. No outro caso, encontramos a .indexOf()primeira e a última palavra e construímos apenas um intervalo numérico a partir disso. Em qualquer uma das situações, agora temos uma matriz de objetos no pipeline (cadeias ou números inteiros), e um implícito Write-Outputna conclusão do programa nos fornece uma nova linha entre os elementos.

AdmBorkBork
fonte
3

Swift3, 402 bytes

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

Nada de especial aqui, basta usar uma matriz para fazer backup dos números gravados.

Eu originalmente pensei que esta solução usando esta outra maneira de calcular a valuesmatriz:

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

Que poderia ser jogado para:

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

substituindo a terceira linha no código do golfe

Eu poderia ter marcado 381 bytes, mas há um erro do compilador que diz: "a expressão era muito complexa para ser resolvida em tempo razoável", mais informações sobre o erro podem ser encontradas aqui

Rodrigo Ruiz Murguía
fonte
AMO ver rápido aqui, vou ter que verificar isso mais quando voltar
Albert Renshaw
3

R, 452 430 424 bytes

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

Coloca os números em um data.frame com números gravados como nomes de colunas, facilitando bastante a tradução entre os dois (e a impressão subsequente).

A principal tentativa de jogar golfe foi criar os números gravados para 20-49, provavelmente muito mais para jogar aqui.

Fiz uma tentativa as.matrixde imprimir o data.frame apenas com os números, mas ainda estou com um cabeçalho de matriz. Espero que esteja tudo bem.

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
fonte
Pequena melhoria para 359 bytes: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)]
contagem
@count parece uma grande melhoria! Parece que não consigo descobrir onde está a função ou onde você levaria uma discussão.
BLT
2

C, 342 331 bytes

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

Experimente online!

Ahemone
fonte
A minha linguagem favorita :)
Albert Renshaw
1
Na verdade, você não precisa de 1 a 1; tudo o que esse codegolf exige é seu terceiro argumento. Os dois primeiros sempre serão "1 e thru" (ou "um e thru")
Albert Renshaw
@AlbertRenshaw Good call! Obrigado :)
Ahemone
1

SAS, 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;

A saída é gravada no log separado por novas linhas. O SAS possui um formato interno para converter dígitos em palavras, o que é uma grande vantagem para esse desafio, mas irritantemente não possui informações para fazer o inverso.

user3490
fonte