Birinci sınıf sayma egzersizinizi otomatikleştirin


36

CodeGolf Mücadelesi

PWSSHHHH! 3000 yılında bir kriyojenik laboratuvarında uyanırsınız. Muhtemelen bir teslimat çocuğununki olan kariyer çipinizi almak için görevlendirme ofisine kadar eşlik ettiğinizde, bir sonda 2000 yılından geldiğinizi tespit eder. Bu nedenle ve birkaçı basmakalıp, bugünün modern insanına kıyasla aptal kabul edilir ve ilköğretim okulu tekrarlamak zorunda.

Birinci sınıfa giriyorsunuz ve öğretmen bir ödev veriyor. 50'ye kadar bir sayı söyleyecek veya yazacak. Numarayı tahtaya yazarsa (örneğin: 25) o zamana kadar olan sayıları söylemek zorundasınız "bir, iki, üç, ..., yirmi beş ". Numarayı yüksek sesle söylerse (örneğin: "altı") o zaman, tabletinizde, "1, 2, 3, 4, 5, 6" rakamlarına kadar yazmanız gerekir.

Bu çok sıkıcı hale geliyor ve hala işlevsel, ancak arkaik, 21. yüzyıl programlama bilginizle süreci otomatikleştireceğinize karar veriyorsunuz.


Amaç:

Programınız bir giriş yapmalıdır. Bu giriş ya ondalık sayı ( 1 thru 50) ya da yazılı sayı ( one thru fifty) olacaktır.

• Giriş bir ondalık sayı ise, çıktınız yazma stilini kullanarak bir ile belirtilen sayı arasında sayılmalıdır. (örneğin otuz iki )

• Giriş yazılı bir sayıysa, çıktınız ondalık stilini kullanarak 1'den söz konusu sayıya kadar sayılmalıdır. (örn. 32 )


Kurallar:

Giriş ve Çıkış, seçtiğiniz herhangi bir durumda olabilir (böylece, yalnızca isterseniz büyük harf kabul eden bir program yapabilirsiniz).

Giriş ondalık sayıları sayı türünde olmak zorunda değildir (örneğin int), sayı içeren bir giriş dizesi olabilir (25'e "25"). Her ikisi de iyidir ve programınızın hangisini kabul etmesini istediğinizi seçebilirsiniz. (Programınızın her ikisini de kabul etmesi gerekmez)

Yazılı stil, bileşik kelimeler arasında kısa çizgi gerektirmez, ancak isterseniz kullanabilirsiniz.

Çıktı değerleri bir biçimde ayrılmalıdır, herhangi bir ayırıcı iyidir 1,2,3 1 2 3 etc

Num2words (python) etc gibi ekstra kütüphaneler ekleyemezsiniz (Ancak sistem kütüphaneleri iyidir)

Hikayenin 2000 yılından beri olduğunu söylemesine rağmen, bu tarihten sonra oluşturulan dilleri kullanabilirsiniz (lol).


Bu , yani en kısa bayt sayısına sahip olan program kazanıyor!


1
Python durumunda num2words gibi kütüphaneler kullanmamıza izin verilir .
Gurupad Mamadapur

1
@AlbertRenshaw, peki ya bunu yapan yerleşikler? (Mathematica)
Pavel

1
@ coredump Her ikisi de birini veya diğerini seçebileceğiniz anlamına gelir. Her iki tür girdiyi de ele almak zorunda olmak zorunda değil
Albert Renshaw,

2
"Parlak metal kıçımı ısır!" Kendimi
saymayacağım

1
Sanırım unvanın "ilk (notu sayma)" olduğunu düşünüyorum "" (ilk notu sayma "değil)
CAD97 19

Yanıtlar:


32

Perl 6 , 119 113 bayt

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

Unicode veritabanı FTW!

Büyük harfli yazılan sayıları, hiçbir satır işareti olmadan kullanır, örn TWENTYTWO.
Dizelerin listesini veya sayı aralığını döndürür. (Her ikisi de ile basıldığında ayırıcı olarak boşluk kullanın put.)


3
Çok zekice ahahaha! Sevdim
Albert Renshaw

13

Python3, 276 271 269 243 237 235 232, 217 bayt

Smls perl teslimi bir ipucu alarak ...

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

Biraz daha golf oynayabileceğinden şüpheleniyorum.

Sayılara unicodedataisim aramak için sistem kütüphanesini kullanır. Büyük harfli sayı adları (boşlukla ayrılmış olarak FORTY TWO) veya giriş olarak ondalık sayılar gerektirir.

(Bu benim ilk kod golf gönderim.)

(Ayrıca, uzunluğu yanlış kodladığımı da fark ettim (kodlama), bu yüzden daha önce düşünülenden birkaç bayt daha az. Ancak en son bayt sayısını güncelledim.


PPCG'ye Hoşgeldiniz!
AdmBorkBork

Savunuculukta: unicodedataAyrı ayrı yüklenmesi gereken "ekstra" bir kütüphane değil, varsayılan kurulumla gelen bir sistem kütüphanesidir.
unayok

Siteye Hoşgeldiniz! Sen edebilirsiniz kodunuzdan çok sayıda aksesuar kaldırmak .
xnor

1
PPCG'ye Hoşgeldiniz. forBaskıyı bir döngünün içine koyarak ve her çıktı arasında yeni satırlar alarak 3 bayt kaybedebilirsiniz . print()o zaman bir tamsayı veya bir dize olup olmadığını umursamıyor. Çevrimiçi deneyin!
ElPedro

1
Bence yapabilirsin import*yerine import namebayt bir çift kaydetmek için
Buğday Sihirbazı

10

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

ayrıntılar

(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 ~]uygun alt kontrol formatına atlayan bir sonraki kullanılabilir argümanın değerini temel alan bir anahtardır. Burada sadece "0" ve "else" için bir durum var. Sıfırdan başlayan U sayesinde, birincisi hariç her sayıdan önce bir ayırıcı eklemek için kullanılır.

  • ~:[ FALSE ~; TRUE ~]şartlı bir formattır; burada s girişinin bir dize olup olmadığına göre farklı şeyler çıkarırız.

  • ~RKardinal İngilizce numarası olarak bir sayı yazın, ancak sayıyı ~Dbasitçe yazdırın.

Örnekler

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

Soruyu anladığım kadarıyla, sadece bir tane değil, her iki stili de ayrıştırabilmelisiniz, bu nedenle 55 baytlık çözümünüz geçerli olmayabilir. "Programınızın her ikisini de kabul etmesi gerekmez", 25 ile "25" arasında, bir sayı veya bir dize olarak
Tom,

@ TomDevs Teşekkürler. Bu kesinlikle kafa karıştırıcı. Emin olmak gerekirse f, "(f 2)" nin "bir, iki" (f "two")harfini ve "1, 2" harfini basacağını tanımlarsam , size iyi görünüyor mu?
Şubat'ta

Evet, bence doğru.
Tom,

@TomDevs Teşekkürler, ben düzelttim
coredump

1
@AlbertRenshaw Hayır, sadece İngilizce; Bu özellik zaten şişkinlik olarak kabul edilebilir, ancak bazı Lisps'ta zaten uygulandığı için standartlaştırılmıştır.
coredump

8

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

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

Diziyi bölme fikri için Kritixi Lithos'a ve 1 / n numara için Arnauld'a teşekkür ederiz.

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
Sen kaldırabilir varve dizi değiştirebilir ['one,'two',..]için"one0two0three0...".split(0)
Kritixi Lithos

Yedekli boşluk null, Array(n).
Yytsi,

2
Sen değiştirebilirsiniz !isNaN(n)tarafından 1/n. Bu size NaNbir dize (falsy), sıfır olmayan bir tamsayı (truthy) Infinityiçin sıfır olmayan bir float veya 0 (aynı zamanda truthy) için verir.
Arnauld

Her kod satırına infront 4 boşluk ekleyin
sagiksp

@sagiksp Evet, yazıyı düzenlerken bir şeyleri berbat etmiş olmalı, şimdi düzeltilmelidir :)
Tom

6

Python 2 , 503 499 494 490 479 bayt

-5 @JonathanAllan sayesinde

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)

Çevrimiçi deneyin!

Bir sayı veya boşlukla ayrılmış bir sayının yazılışını girin.

Biraz daha az golf oynadı ve okunabilir versiyon:

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)

1
6 byte tasarruf edinl="one two three four five six seven eight nine ten eleven twelve thir#four#fif#six#seven#eigh#nin#".replace("#","teen ").split()
Jonathan Allan

... 5 ayy, cevapsız egelen nineteen.
Jonathan Allan,

Python 2'yi kullanmanız için bir neden var mı, onsuz baskı daha uzun olurdu, ama raw_input sadece girdi olabilir mi? (Diğer cevabınız için de aynı soru)
nedla2004

@ nedla2004 - Python 3'ü henüz en son dizüstü bilgisayarıma
kurmayı başaramadığımdan başka sebep

6

Şema, 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)))))))

sıkıştırılmamış:

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

Örneğin "dört" den 4 e nasıl dönüştürebilirsiniz? Bunu yaptığımdan emin değilim string->number, hızlıca kontrol ettim ve örneğin dizgiden "4"sayıya dönüştürmek için kullanılıyor gibi görünüyor 4.
coredump,

@ coredump Bu doğru. (string->number "four")döner #f.
Michael Vehrs,

Hangi şema çalışıyorsunuz?
coredump,

1
@coredump guile 2.0.9
Michael Vehrs

6

PHP - 397 372 349 344 329 bayt

TomDevs'in JS çözümünden ilham alındı

Değiştirerek 25 bayt Kaydedilen $a=[...]tarafından$a=explode(...)

teen@ User59178 sayesinde dize sınırlayıcıları olmayan bir diziye geri dönerek ve bir değişkeni saklayarak bir başka 23 byte kaydetti

(int)Yazı tipini kaldırarak 5 bayt daha kaydedildi

Bırakarak başka 15 bayt Kaydedilen $b, $iiçinde forhiç @ user59178 tekrar bildirimleri ve küme parantezleri sayesinde

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

Bir giriş dizesi için veya bir giriş numarası için deneyin


1
Golf oynarken, kullandığınız tüm numaralar da dahil olmak üzere herhangi bir alıntı olmadan doğrudan birçok ipucu kullanabilirsiniz. Bu bir bildirime neden olur, ancak bu göz ardı edilebilir. Ek olarak, teenher seferinde tekrarlamak yerine bir değişkende saklamak (2 tam bayt ile) daha kısadır . Gibi olacak:$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:17

Bunu hiç düşünmemiştim, teşekkürler;)
roberto06 15

$bİkinci diziyi doğrudan foreach'a bırakarak ve yerleştirerek 7 bayt , tüm kıvrık parantezleri ( $a=$cfor döngüsünün kurulumuna koymanız gerekse de) ve 6 bayttan sonra ekleyerek 6 bayt daha tasarruf edebilirsiniz . $ifor döngülerinin 'after' bitinden ziyade onu kullandığınızda.
kullanici59178

Artış sonrası için ile aşağıdaki çizgiyi hareket ettirerek altı bayttan for ($i=0;$i<9;)$a[]=$c.'-'.$a[$i++];
tasarruf edin

Üzgünüz, sadece şunu fark ettim, @ user59178 de aynı şeyi önerdi ...
Alex Howansky,

6

Python 2,262 bayt

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

Giriş ve çıkış dizeleri küçük harf ve birleştirilmiş * olur, bu nedenle bir dizge girişini test etmek için, örneğin "thirtyfive"komut istemine girin.

Tüm kelimelerin listesini oluşturur (artı'ya "fiftyone"kadar "fiftynine"), xardından proxy'li inputbir kelime olup olmadığını test eder v>50(dizeler Python 2'deki sayılardan büyük, ve özellikteki geçerli giriş aralığındaki tüm sayılardır <=50) ve printuygun ya listeyi dilimleyerek ya x[:v]da bir tam sayı aralığı oluşturarak değerleri range(1,x.index(v)+2),.

* Değiştirerek, her iki maliyetlerinde 11 bayt tirelemeyi ekleme a+"ty"bile a+"ty"+'-'*(b>'')+b.


5

Wolfram Dili, 92 bayt

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

(Bu konuda yeniyim, yanlış bir şey yaparsam bana bildirin)


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

5

JavaScript (ES6), 261 bayt

Not: z'ye atanan dize ile kodlanır atob. Kodlanmış dizgede, bir javascript dizgisinde geçerli karakterler olsalar bile, bu siteye gönderemediğim 11 bayt var. Bu yüzden \ xHH biçiminde onaltılık bir kaçış kullandım. Bu kaçanların her biri 1 bayt olarak sayılır.
Orijinal sıkıştırılmamış dize daha az golf versiyonudur.

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

Daha az golf oynadı

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

Ölçek

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>


ö\x89ÞöÜ(öØ...Bu şeyler harika hahaa
Albert Renshaw


5

Python 3 , 305 303 bayt

@ Nedla2004 tavsiyesinden sonra Python 3'e dönüştürüldü. Ayrıca giriş veya çıkıştaki yazılı sayılar arasında boşluk kalmaz, örneğin yirmi iki

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)

Çevrimiçi deneyin 3!

Piton 2 , 327 320 313 308 bayt

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

Çevrimiçi deneyin 2!

163 170 177 bayt, orijinal cevabımdan daha kısa, bu yüzden alternatif olarak gönderiyorum. Bu for, iki listedeki, numaraların tüm dize temsillerinin tam bir listesini oluşturmak için kullanır , ardından listedeki doğru olanı tanımlar ve her şeyi değerine veya indeksine göre yazdırır. Her değer için yeni bir satır çıkarır.


5

Python 2,432 422 416 403 bayt

Bunun geliştirilebileceğinden eminim. En azından üzerinde çalışacak ve bir işleve gerek duymayan kodlamadan kurtulabiliyorsam, 20 tasarruf yapabilirim. JonathanAllan'ın ElPedro'nun cevabı hakkındaki yorumuna, 4'ünün matematiği yeniden düzenlemesiyle 6 bayta kurtarıldı.

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

(Not: Bunun asıl sürümü boşluklar yerine girintiler yapmak için sekmeler kullanır. QPaysTaxes, verilen kodun derlendiğinden emin olmak için düzgün bir şekilde oluşturulmadığından tek bir boşluk ekler.)


@ JonathanAllan'ın ElPedo'nun cevabı üzerine yaptığı yorum burada da -6 için çalışıyor
Chris H,

1
len(`f`)>2...`f`[2:]başka bir 3 için olabilir inanıyorum. ( ...geri tepmelerin düzgün çalışmasını sağlayamıyor gibi görünmüyor)
Jonathan Allan

Aslında python 2'de f>506'ya gidebilirsiniz (ve kullanmayacağınız bir tane daha d)
Jonathan Allan

Şu anda yaptığım tam sayılar olarak sayıları iletmek için çalışmayan @ Jonathanathan TypeError: 'int' object has no attribute '__getitem__'. Ben bir dize olarak sayısal giriş geçerseniz, f[2:]yaklaştıkça ama hala (boolean olarak trated zaman başarısız print f[2:] and True(f) <2, değil len eğer boş bir satır basılır Trueya False)
Chris H

@ JonathanAllan f>50çalışıyor, teşekkür ederim. Bırakma d, her zaman döngünün son değerini koyduğumdan, fsatır 8'in if f>50hiçbir zaman gerçek olamayacağı şekilde değiştirilemeyecek kadar basit değildir .
Chris H,

4

C ++ 11, 484 480 477 bayt

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

Küçük harflerle kısa çizgi olmadan metin girişi.


3

PowerShell , 362 bayt

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

Çevrimiçi deneyin! kelimeler girişi veya sayılar girişi

Bu doğru bir karmaşa ve onla çok mutlu değilim, ama işte burada. Golf önerileri kabul edilir.

İlk satır $ztam İngilizce kelimelerin bir dizi olarak ayarlar . Tüm -split0sayıları 1oluşturmak için for'ları 12ve döngüleri görebilirsin teen, ve sonra her şeyi bir araya getirmek için bir sürü mantık vardır. Çevrimiçi deneyin!

İkinci satır bazı mantıklarla başlar. Girdiyi $args(bir dize olarak) -splitboşlukta $nalıyoruz, daha sonra kullanmak üzere saklıyoruz, ilk [0]sözcüğü ve ilk [0]karakterini alıyoruz ve -inbir aralık olup olmadığını kontrol ediyoruz 48..57(yani, ASCII 0- 9). Bu nedenle, ondalık giriş veya İngilizce giriş olup olmadığını kontrol ediyoruz. Çevrimiçi deneyin!

İlk durumda, ondalık girişlere göre bir aralık oluşturur $n[0]..$n[2]ve bunu indekslemek için kullanırız $z[...]. Diğer durumda, .indexOf()ilk kelimeyi ve son kelimeyi buluruz ve bundan sadece sayısal bir aralık oluştururuz. Her iki durumda da, artık boru hattı üzerinde bir dizi nesneye sahibiz (dizgiler veya tamsayılar) ve Write-Outputprogram bitiminde örtük bir unsur bize öğeler arasında yeni bir satır verir.


3

Swift3, 402 bayt

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

Özel bir şey yok, sadece yazılı sayıları yedeklemek için bir dizi kullanıyoruz.

Aslında bu çözümü, valuesdiziyi hesaplamak için bu diğer yolu kullanarak düşündüm :

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

Hangi golf oynamak olabilir:

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

golfed kodunda 3. satırı değiştirmek

381 byte puan alabilirdim, ancak şunu söyleyen bir derleyici hatası var: "ifade makul bir zamanda çözülemeyecek kadar karmaşıktı", hata hakkında daha fazla bilgiyi burada bulabilirsiniz.


Burada hızlı bir şekilde görmeyi seviyorum, geri döndüğümde bunu daha kontrol edeceğim
Albert Renshaw

3

R, 452 430 424 bayt

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

İkili (ve ardından yazdırma) arasındaki çeviriyi oldukça kolaylaştıran, sayıları sütun adları olarak yazılan sayılarla bir data.frame içine yerleştirir.

Golf oynamadaki asıl girişim 20-49 için yazılan sayıları oluşturmaktı, muhtemelen golf oynamak için çok daha fazla.

as.matrixData.frame'i sadece sayılarla basmaya çalıştım , ama hala bir matris başlığına bıraktım. Umarım bu iyidir.

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

359 Byte'a hafif iyileştirme: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)]
say

@count, büyük bir gelişme gibi görünüyor! İşlevin nerede olduğunu, ama nerede tartışacağınızı çözemiyorum.
BLT

2

C, 342 331 bayt

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

Çevrimiçi deneyin!


En sevdiğim dil :)
Albert Renshaw

1
Aslında 1 veya 1'den birine ihtiyacınız yok; Bütün bu codegolf'un gerektirdiği üçüncü tartışman. İlk ikisi her zaman "1 ila thru" (veya "one and thru") olacaktır
Albert Renshaw

@AlbertRenshaw İyi arama! Thanks :)
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;

Çıktı, loglara yeni satırlarla ayrılmış olarak yazılır. SAS, basamakları kelimelere dönüştürmek için yerleşik bir formata sahiptir, bu zorluk için bu büyük bir avantajdır, ama can sıkıcı bir şekilde tersini yapmak için bir informattan yoksundur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.