Jarak ke empat

13

Tantangan ini didasarkan pada video ini . Saya sarankan Anda menontonnya sebelum mencoba tantangan ini.

Pertama kita mendefinisikan suatu fungsi. Fungsi ini ( OEIS ) mengambil bilangan bulat n sebagai input dan menghasilkan jumlah huruf dalam representasi bahasa Inggris dari n (tanpa spasi atau tanda hubung). Misalnya "tiga" memiliki 5 huruf jadi 3 peta ke 5.

Seperti yang diperlihatkan dalam video dimulai dengan nomor yang berulang proses ini pada akhirnya akan menghasilkan empat, yang akan memetakan dirinya sendiri selamanya.

Berikut ini adalah grafik yang diarahkan langsung yang menunjukkan orbit angka kurang dari 16:

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

Tantangan Anda adalah menentukan jumlah langkah yang akan diambil suatu angka (atau berapa kali fungsi ini harus diterapkan pada angka) sebelum mencapai empat (yaitu level pada grafik yang diarahkan pada gambar).

Membentuk angka bahasa Inggris

Berikut adalah penjelasan singkat tentang bagaimana seseorang harus membentuk kata-kata bahasa Inggris untuk tantangan ini:

Angka satu hingga sembilan belas adalah:

satu, dua, tiga, empat, lima, enam, tujuh, delapan, sembilan, sepuluh, sebelas, dua belas, tiga belas, empat belas, lima belas, enam belas, tujuh belas, delapan belas, sembilan belas

Untuk angka yang lebih besar dari sembilan belas prosesnya adalah sebagai berikut:

Jika nomor tersebut memiliki ratusan tempat, mulailah dengan nama digit di ratusan tempat dan "ratus".

misalnya

100 -> "onehundred"

Jika sisanya kurang dari dua puluh tambahkan perwakilan bahasa Inggris sisanya.

misalnya

714 -> "sevenhundredfourteen"

Kalau tidak, jika puluhan digit bukan nol tambahkan representasi yang tepat:

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

misalnya

470 -> "fourhundredseventy"

Akhirnya jika ada satu digit menambahkan perwakilannya

misalnya

681 -> "sixhundredeightyone"

Ketentuan lebih lanjut

  • Untuk angka yang lebih besar dari seratus Anda harus meninggalkan "dan" saat menghitung jumlah huruf. Misalnya 577 adalah "fivehundredseventyseven" yang memiliki 23 huruf.

  • Program Anda harus menerima semua bilangan bulat yang lebih besar dari 0 dan kurang dari 1.000 sebagai input melalui metode standar.

  • Program Anda harus menampilkan jumlah langkah yang diperlukan untuk metode keluaran standar.

  • Ini codegolf sehingga solusi dengan byte paling sedikit menang.

Uji kasus

1 -> 3
4 -> 0
7 -> 2
23 -> 5
577 -> 6
600 -> 4 
Posting Rock Garf Hunter
sumber
1
Terkait saya pikir ini adalah penipuan, tetapi saya tidak dapat menemukannya.
James
Apa yang terjadi pada "dan"? Atau lebih tepatnya, mengapa keluar dan ?!
Jonathan Allan
@JonathanAllan cuz 'Murica
LegionMammal978

Jawaban:

5

JavaScript (ES6), 106 byte

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

String tampaknya menjadi cara terbaik untuk menyandikan panjang, meskipun overhead konversi numerik.

Neil
sumber
Astaga, hampir persis seperti apa jawaban saya (hampir diposting), hanya 11 byte lebih pendek.
ETHproduksi
@ EHProduk Untung saya bermain golf 16 byte sebelum mempostingnya!
Neil
2

Python, dengan num2words, 97 113 115 94 93 92 byte

+16 byte (lupa tanda hubung yang berlaku num2words yang tidak benar-benar mengubah hasil dari setiap kasus uji, meskipun 23dan 577masing-masing memiliki tanda hubung)
+2 byte (lupa untuk menyertakan f=meskipun rekursif)
-20 byte (gunakan re)
-8 byte berkat @Wheat Wizard (gunakan ~, ganti n!=4dengan n-4, dan ... satu impor baris> _ <)
-1 byte berkat @Cyoce (spasi dari 4 and)

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

Hitung saja jumlah langkah; berfungsi untuk bilangan bulat besar dan negatif juga ( \Wtemukan spasi, koma, dan tanda hubung dalam hasil num2words):

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

Inilah kasus terakhir, langkah demi langkah:

sixquattuordecillionthreehundredsixtytwotredecillionsixhundredeightyfiveduodecillionfourhundredfortyoneundecilliononehundredthirtyfivedecillionninehundredfortytwononillionthreehundredfiftyeightoctillionfourhundredseventyfourseptillioneighthundredtwentyeightsextillionsevenhundredsixtytwoquintillionfivehundredthirtyeightquadrillionfivehundredthirtyfourtrilliontwohundredthirtybillioneighthundredninetymilliontwohundredsixteenthousthreehundredtwentyone
fourhundredfiftyone
nineteen
eight
five
Jonathan Allan
sumber
1
Apakah Anda tidak memerlukan f=sebelum fungsi lambda Anda
Post Rock Garf Hunter
1
Coba import re,num2words as ralih-alih dari dua pernyataan yang berbeda.
Post Rock Garf Hunter
1
n-4adalah hal yang sama sepertin!=4
Post Rock Garf Hunter
1
@WheatWizard num2wordsadalah w, remasih re- perhatikan bahwa baik modul dan fungsinya disebutnum2words
Jonathan Allan
1
Ok yang terakhir, and 1+bisa diganti dengan and-~menyimpan satu byte
Post Rock Garf Hunter
1

Pyth - 54 byte

Akan mencoba untuk refactor.

KjC"Y©åláóê¤"Ttl.u?<NyT@KNs+V@LKJ_jNT[Z@jC"Ckg"ThtJ7

Test Suite .

Maltysen
sumber
1

Mathematica, 89 byte

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

Mathematica Khas: fungsi bawaan baik, nama fungsi panjang buruk. FixedPointListberlaku argumen pertamanya (fungsi) ke argumen kedua berulang kali sampai jawabannya tidak berubah, daftar semua hasil; hasilnya termasuk input asli dan dua salinan dari output berulang, karenanya-2 pada akhirnya. Built-in Mathematica IntegerNameberisi spasi dan tanda hubung, jadi kita harus menyingkirkannya dengan tangan.

Mengganggu, IntegerNameoutput berisi karakter "-" (Unicode # 8208) daripada tanda hubung normal; itu sebabnya kiriman ini adalah 89 byte daripada 88. (Dan saya tidak bisa mendahului kode di atas dengan empat spasi dan membuatnya menerima karakter Unicode — bantuan? —jadi kode di atas tidak akan berfungsi dengan tepat jika dipotong dan disisipkan .)

Greg Martin
sumber
1

Python 2.7, 344 216 208 byte:

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

Tidak menggunakan perpustakaan eksternal tidak seperti jawaban Python lainnya. Membawa input through stdindan output ke stdout.

Repl.it dengan Semua Kasing Uji!

Penjelasan

Pertama membuat 3 kamus dengan masing-masing memasangkan panjang representasi kata bahasa Inggris dari setiap angka ke angka yang diwakili dalam interval tertutup [1,9]di tempat, puluhan, dan ratusan masing-masing. Misalnya, entri pertama dalam kamus dadalah 1:3seperti 1yang diejaone dalam bahasa Inggris dan memiliki 3huruf.

Kemudian, setiap digit tempat di beberapa input string xditugaskan ke kamus yang sesuai, setelah itu setiap angka di setiap tempat dicocokkan dengan nilainya dalam kamus yang sesuai. Misalnya, misalkan nomor inputnya 23. Di 20tempat puluhan akan dipasangkan dengan kamus e, di mana ia dicocokkan dengan 6, dan 3di tempat yang akan dipasangkan dengan kamus d, di mana ia cocok dengan 5. Digit yang cocok ini kemudian ditambahkan bersama-sama untuk mewakili panjang representasi bahasa Inggris dari angka, yang ditugaskan xsebagai string dan, selama x!='4', loop sementara berjalan, bertambah cdengan1setiap kali mewakili jumlah langkah yang diambil sejauh ini. Oleh karena itu, 23akan sesuai dengan langkah-langkah total.11, yang pada gilirannya sesuai dengan 6yang akan beralih ke 3dan kemudian ke 5dan akhirnya ke 4, menghasilkan5

Akhirnya, setelah loop selesai, cadalah output stdoutuntuk mewakili "Distance to Four", yang dalam hal ini adalah 5.

R. Kap
sumber
1

Jawa, 556 295 byte

Terima kasih kepada @KevinCruijssen karena telah menghemat 261 byte

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


Tidak Disatukan:

  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);
}
Numberknot
sumber
Saya pikir Anda memiliki kesalahan dalam kode Anda, karena s++tidak mungkin pada sebuah String-array ..: S
Kevin Cruijssen
@KevinCruijssen Saya menyatakan S (penghitung) sebagai INT dan STRING juga .... java secara otomatis memutuskan itu adalah INT.
Numberknot
Nah, jika saya menjalankan kode Anda di ideone atau Eclipse IDE saya gagal karena Anda memiliki dua s.. Btw, Anda dapat golf kode Anda dengan jumlah yang cukup besar seperti ini: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
Saya terkejut ...... apa yang terjadi pada kode saya dan terima kasih @ KevinCruijssen..dan saya memperbaikinya ... Terima kasih lagi.
Numberknot
Np :) Saya pikir itu mungkin golf lagi entah bagaimana tanpa menggunakan if-else dan istirahat di sana (tapi saya akan menyerahkannya kepada orang lain), tetapi kode awal Anda adalah dasar yang bagus untuk menangani tantangan, jadi +1 dari saya.
Kevin Cruijssen