Dörde uzaklık


13

Bu zorluk bu videoyu temel alıyor . Bu meydan okumayı denemeden önce izlemenizi tavsiye ederim.

İlk önce bir fonksiyon tanımlarız. Bu işlev ( OEIS ) n olarak bir tamsayı alır ve n'nin İngilizce temsilindeki (boşluk veya kısa çizgi olmadan) harf sayısını çıkarır. Örneğin "üç" ün 5 harfi vardır, bu nedenle 3 harf 5 ile eşleşir.

Videoda gösterildiği gibi, bu işlemi tekrarlayan herhangi bir sayı ile başlayarak, sonunda dörtle sonuçlanacak ve bu da sonsuza kadar kendi kendine eşleşecektir.

16'dan küçük sayıların yörüngelerini gösteren kaba bir grafik:

  12 11
    \|      
15 2 6 1 10 14 13
  \ \|/ /  /  /
   7 3-/  8--/
    \|   /
 9 0 5--/
  \ \|
   \-4

Buradaki zorluk, dördüncüye ulaşmadan önce bir sayının alacağı adım sayısını (veya bu fonksiyonun bir sayıya kaç kez uygulanması gerektiğini) belirlemektir (örn. Resimde gösterilen grafikteki seviye).

İngilizce numaralar oluşturma

İşte bu meydan okuma için İngilizce kelimeleri nasıl oluşturacağınıza dair kısa bir açıklama:

Bir ile on dokuz arasındaki sayılar:

bir, iki, üç, dört, beş, altı, yedi, sekiz, dokuz, on, onbir, on iki, on üç, on dört, on beş, on altı, on yedi, on sekiz, on dokuz

On dokuzdan büyük sayılar için işlem aşağıdaki gibidir:

Sayı yüzlerce yer varsa, yüzlerce yerde basamak adı ve "yüz" ile başlayın.

Örneğin

100 -> "onehundred"

Kalan yirmiden azsa kalanın İngilizce temsilini ekleyin.

Örneğin

714 -> "sevenhundredfourteen"

Aksi takdirde, onlar basamağı sıfır değilse uygun temsili ekleyin:

2-> twenty
3-> thirty
4-> forty
5-> fifty
6-> sixty
7-> seventy
8-> eighty
9-> ninety

Örneğin

470 -> "fourhundredseventy"

Sonunda bir rakam varsa temsilini ekleyin

Örneğin

681 -> "sixhundredeightyone"

Diğer Koşullar

  • Yüzden büyük sayılar için, harf sayısını sayarken "ve" işaretini dışarıda bırakmalısınız. Örneğin 577, 23 harften oluşan "beşyüzyüzyıl".

  • Programınız standart yöntemlerle 0'dan büyük ve 1.000'den küçük tamsayıları girdi olarak kabul etmelidir.

  • Programınızın standart çıktı yöntemleri için gereken adım sayısını vermesi gerekir.

  • Bu kodgolf bu yüzden en az bayt ile çözüm kazanır.

Test senaryoları

1 -> 3
4 -> 0
7 -> 2
23 -> 5
577 -> 6
600 -> 4 

1
İlgili Bunun bir dupe olduğunu düşündüm, ama bulamıyorum.
James

"Ve" ne oldu? Ya da daha doğrusu, neden dışarıda kalıyorsun?
Jonathan Allan

@JonathanAllan cuz 'Murica
LegionMammal978

Yanıtlar:


5

JavaScript (ES6), 106 bayt

f=(n,a="03354435543668877998")=>n-4&&1+f(7*(n>99)-(-a[n/100|0]-(a[n%=100]||a[n%10])-"0066555766"[n/10|0]))

Dizeler, sayısal dönüşüm yüküne rağmen uzunluğu kodlamanın en iyi yolu gibi görünüyor.


Tanrım, neredeyse tam olarak cevapladığım cevap neredeyse aynıydı, sadece 11 byte daha kısa.
ETHproductions

@ETHproductions İyi bir şey ben göndermeden önce 16 bayt off golfed!
Neil

2

Python, num2words ile 97111151159 93 92 bayt

+16 bayt (num2words'un uyguladığı tireyi unutun, bu da test durumlarının hiçbirinin sonucunu gerçekten değiştirmez 23ve 577her birinin tiresi olmasına rağmen )
+2 bayt ( f=özyinelemeli de dahil etmeyi unuttum )
-20 bayt (kullanım re)
-8 bayt @Wheat Sihirbazı sayesinde (kullanım ~yerini n!=4ile n-4ve ... tek satır ithalat> _ <)
-1 bayt sayesinde @Cyoce için (uzay 4 and)

import re,num2words as w
f=lambda n:n-4and-~f(len(re.sub('\W|and','',w.num2words(n))))

Sadece adım sayısını sayar; çok büyük ve negatif tamsayılar için de çalışır ( \Wnum2words sonucundaki boşlukları, virgülleri ve kısa çizgileri bulur):

>>> for test in (1,4,7,23,577,600,-1*2**96,3**96):
...     print('test: {0}  ->  {1}'.format(test, f(test)))
...
test: 1  ->  3
test: 4  ->  0
test: 7  ->  2
test: 23  ->  5
test: 577  ->  6
test: 600  ->  4
test: -79228162514264337593543950336  ->  4
test: 6362685441135942358474828762538534230890216321  ->  5

İşte bu son durum, adım adım:

sixquattuordecillionthreehundredsixtytwotredecillionsixhundredeightyfiveduodecillionfourhundredfortyoneundecilliononehundredthirtyfivedecillionninehundredfortytwononillionthreehundredfiftyeightoctillionfourhundredseventyfourseptillioneighthundredtwentyeightsextillionsevenhundredsixtytwoquintillionfivehundredthirtyeightquadrillionfivehundredthirtyfourtrilliontwohundredthirtybillioneighthundredninetymilliontwohundredsixteenthousthreehundredtwentyone
fourhundredfiftyone
nineteen
eight
five

1
f=Lambda fonksiyonunuzdan önce ihtiyacınız yok
Ad Hoc Garf Hunter

1
import re,num2words as rİki farklı ifade yerine deneyin .
Ad Hoc Garf Hunter

1
n-4ile aynı şeyn!=4
Ad Hoc Garf Hunter

1
@WheatWizard num2wordsise w, rehala renot modülü ve fonksiyon hem dendiğini -num2words
Jonathan Allan

1
Tamam sonuncusu, bir bayt kaydetmek and 1+için ile değiştirilebilirand-~
Ad Hoc Garf Hunter


1

Mathematica, 89 bayt

Length@FixedPointList[StringLength@StringReplace[IntegerName@#,{" "->"","-"->""}]&,#]-2&

Tipik Mathematica: yerleşik işlevler iyi, uzun işlev adları kötü. FixedPointListilk değişkeni (işlev), yanıt değişmeyene kadar ikinci bağımsız değişkene sürekli olarak uygular ve tüm sonuçları listeler; sonuçlar orijinal girdiyi ve tekrarlanan çıktının iki kopyasını içerir, dolayısıyla -2sonunda. Mathematica'nın yerleşik IntegerNamealanı boşluklar ve kısa çizgiler içerir, bu yüzden bunlardan elle kurtulmamız gerekir.

Can sıkıcı bir şekilde, IntegerNameçıktısı normal tireler yerine "-" (Unicode # 8208) karakterini içeriyor; Bu gönderim 89 bayt yerine 88. olmasının nedeni en (Ve ben dört boşluklu kod yukarıda önüne olamayacağını ve yukarıdaki kod tam olarak doğru olmadığını çalışmaz-yani o? Unicode karakter-herhangi bir yardım kabul sahip kesim ve yapıştırılan .)


1

Python 2.7, 344 216 208 bayt:

x=`input()`;c=0;y=lambda v:dict(zip(range(0,10),[0]+v));l=[3,3,5,4,4,3,5,5,4];d=y(l);e=y([3,6,6,6,5,5,7,7,6]);f=y([i+7for i in l])
while x!='4':x=`sum([q[int(r)]for q,r in zip([d,e,f],x[::-1])])`;c+=1
print c

Diğer Python cevabından farklı olarak harici kütüphaneler kullanmaz. Girdiyi alır stdinve çıktısını alır stdout.

Tüm Test Durumlarıyla Repl.it!

açıklama

İlk olarak her biri, her bir sayının İngilizce sözcük temsillerinin uzunluğunu [1,9]sırasıyla on, on ve yüzlerce yerde kapalı aralıkta temsil ettiği sayı ile eşleştiren 3 sözlük oluşturur . Örneğin, sözlükte ilk giriş dedilir 1:3olarak 1yazıldığından oneİngilizce ve vardır 3harfleri.

Daha sonra, bazı dize girişlerindeki her basamak yeri xkarşılık gelen sözlüğüne atanır, daha sonra her bir yerdeki her sayı karşılık gelen sözlükteki değeri ile eşleştirilir. Örneğin, giriş numarasının olduğunu varsayalım 23. 20Onlarca yerinde sözlüğe ile eşleştirilmiş olacağını ehangi onunla eşleştirilir, 6ve 3olanları yerinde Sözlük ile eşleştirilmiş olacağını do ile eşleşti edildiği, 5. Bu eşleşen rakamlar daha sonra x, bir dize olarak atanan x!='4've while döngüsü devam ettiği sürece , sayının İngilizce temsilinin uzunluğunu temsil etmek için birlikte eklenir c.1her seferinde şimdiye kadar atılan adım sayısını temsil eder. Bu nedenle, 23buna karşılık 11gelecek ve sonuçta 6hangi aşamaya dönecek 3ve daha sonra 5ve sonuçta toplam adımlara 4yol açacaktır 5.

Son olarak, döngü bittikten sonra, bu durumda, "Dörde Uzaklık" ı temsil edecek şekilde cçıktılanır .stdout5


1

Java, 556 295 bayt

261 bayt kazandığı için @KevinCruijssen'e teşekkürler

  void int(n) {int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,9,8,6,9,9,11,10,6,6,5,5,7,7,6};int c=0,t=(int)Math.pow(10,(int)Math.log10(n)),v=1;while(n>0){if(n/100>0)c+=(s[n/100]+7);else {if(n>0&n<25){c+=s[n];break;}else{c+=s[(n/10)+22];}}n=n%t;t=t/10;}while(c!=4){v++;c=s[c];}System.out.print(v);}


Ungolfed:

  void int(n) {

    int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,9,8,6,9,9,11,10,6,6,5,5,7,7,6};
     int c=0,t=(int)Math.pow(10,(int)Math.log10(n)),v=1;
         while(n>0){
            if(n/100>0)
                c+=(s[n/100]+7);
            else {if(n>0&n<25){
                c+=s[n];
            break;
            }
            else{
                c+=s[(n/10)+22];

            }
            }
            n=n%t;
            t=t/10;
        }

        while(c!=4)
        {
            v++;
        c=s[c];
        }
System.out.print(v);
}

Kodunuzda bir hata olduğunu düşünüyorum, çünkü s++bir String-dizide mümkün değil ..: S
Kevin Cruijssen

@KevinCruijssen S'yi (sayaç) INT ve STRING olarak da beyan ederim .... java otomatik olarak bir INT olduğuna karar verir.
Numberknot

Eğer, ideone veya Eclipse IDE kodumu çalıştırırsanız Eğer iki var çünkü başarısız s.. Btw, sen kodu gibi oldukça büyük bir miktarda golf:int c(int n){int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8,6,9,9,11,10,6,5,5,5,7,6,6},c=0,t=(int)Math.pow(10,(int)Math.log10(n)),x=1;while(n>0)if(n/100>0)c+=s[n/100]+7;else{if(n>0&n<25){c+=s[n];break;}else c+=s[(n/10)+22];}n%=t;t/=10;}for(;c!=4;x++,c=s[c]);return x;}
Kevin Cruijssen

Ben şok oldum ...... benim kod ne olur ve @ KevinCruijssen teşekkürler .. ve ben düzeltiyorum ... Tekrar teşekkürler.
Numberknot

Np :) Ben if-else kullanmadan ve bir şekilde orada kullanmadan bir şekilde daha golf olabilir düşünüyorum (ama bunu başka birine bırakacağım), ama ilk kod meydan okuma ile mücadele için büyük bir üs oldu, bu yüzden +1 benden.
Kevin Cruijssen
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.