Tulis program untuk menemukan sebuah nomor yang terdiri dari 9 digit di mana masing-masing angka dari 1 sampai 9 muncul hanya sekali. Nomor ini juga harus memenuhi persyaratan dapat dibagi ini:
- Jumlahnya harus habis dibagi 9.
- Jika digit paling kanan dihapus, angka yang tersisa harus dapat dibagi 8.
- Jika digit paling kanan dari nomor baru dihilangkan, angka yang tersisa harus dibagi dengan 7.
- Dan seterusnya, sampai hanya ada satu digit (yang harus dibagi dengan 1).
Kredit Dávid Németh
Jawaban:
CJam - 26
Ini acak tetapi bekerja cukup cepat dengan penerjemah java . Diperlukan beberapa menit dengan juru bahasa online .
Penjelasan:
1
push 1 (akan dijelaskan nanti){…}g
adalah loop do-while;
menghapus nilai dari stack (awalnya 1 yang kita mulai dengan)9,
membuat array [0 ... 8]:)
menambah elemen array, menghasilkan [1 ... 9]_
menggandakan arraymr
mengocok array yangs
dikonversi ke string0@
push 0 kemudian membawa salinan array lainnya di atas{…}/
adalah untuk-setiap loop (lebih dari angka 1 ... 9)_
menduplikasi angka saat ini (sebut saja "k" )3$
menyalin string numerik dari stack<i
mendapat substring dengan karakter k pertama kemudian mengkonversi ke integer\%
swaps dengan salinan k lainnya lalu mendapat sisanya (% k)+
menambahkan sisanya ke nilai sebelumnya pada stack (awalnya 0 dari atas )Pada titik ini, kita memiliki string numerik pada stack, diikuti oleh 0 jika nomor cocok dengan semua persyaratan (yaitu semua sisa adalah 0) atau nilai bukan-0 sebaliknya.
Bagian atas tumpukan menjadi kondisi loop do-while. Itu muncul dan loop berlanjut jika kondisinya benar.
Jika kami menemukan solusinya, kondisinya adalah 0 (false), loop berakhir dan sisa tumpukan (string numerik) dicetak.
Jika bukan solusinya, kondisinya adalah nilai non-0 (true) dan loop berlanjut dengan string pada stack. String akan muncul pada awal iterasi berikutnya (sehingga loop mengharapkan nilai pada stack, dan itulah alasan untuk awal 1).
Terima kasih Dennis untuk membuat kode lebih pendek dan lebih berbelit-belit: p
sumber
0{;9,:)_mrsT@{_3$<i\%+}/}g
Javascript (E6) 105
125 134Bangunan rekursif nomor, setiap langkah memeriksa pembagian.
Runtime mendekati 0 dtk
Tidak I / O saat ini, ketika OP meminta program untuk menemukan nomornya, dan nomor tersebut ditemukan dan secara otomatis masuk ke konsol
Bermain Golf lainnya, courtesy of MT0
Golf
Jelek
Bonus
Dengan 3 perubahan kecil, Anda dapat menggunakan fungsi yang sama untuk menemukan nomor yang lebih panjang menggunakan basis> 10. Misalnya di ...
Tidak disatukan
sumber
(Q=(n,d,b)=>([(m=n+(s=[...b]).splice(i,1))%d||Q(m,d+1,s)for(i in b)],d>9&&(Q.z=n),Q.z))('',1,'123456789')
(Q=(n,d,b)=>Math.max(...[(m=n+(s=[...b]).splice(i,1))%d||Q(m,d+1,s)for(i in b)],n))('',1,'123456789')
Perl, 56
Pemakaian:
perl -E '...'
Keluaran:
381654729
Program ini sangat lambat . Seperti dalam lebih dari 3,5 jam.
Sebagai latihan yang lebih menyenangkan, saya memutuskan untuk mengembangkan algoritma yang sangat cepat:
Di atas berjalan dalam .00095 detik, dan mengonfirmasi bahwa hanya ada satu solusi untuk masalah ini.
sumber
Python3,
214,199,184,176,174,171,165,150, 146keluaran:
Ini skrip golf pertamaku. Harap Anda menyukainya :)
sumber
Pyth , 33 karakter
Untuk mengujinya, masukkan kode di atas sebagai input standar di tautan dalam judul.
Setelah dikompilasi ke dalam Python 3.4:
Penjelasan:
=Y]k
:Y=['']
FkY
: untuk k di F:~Y
: Tambahkan ke Yf
: Saring berdasarkan>ql{TlT
: Semua elemen unik dan%vTlT
: eval (elemen)% len (elemen) = 0m+k
`d
Pada daftar k + repr (d)r1T
: untuk d dari 1 hingga 9.)
: End for looppk
: cetak ksumber
Ruby, 66
78karakterRuntime adalah ~ 8 detik (output dicetak setelah 3 detik).
Ini tidak berhenti setelah menemukan angka pertama, jadi secara teknis ia mencetak semua angka yang memenuhi kriteria - tetapi karena hanya ada satu angka seperti itu, itu tidak membuat perbedaan.
Ruby 1.8, 63
Pada dasarnya solusi yang sama seperti di atas. Di Ruby 1.8, array dikonversi menjadi string dengan secara implisit memanggilnya
Array#join
, sehingga kami dapat menyimpan panggilan itu. Menariknya, kode ini juga berjalan lebih cepat di Ruby 1.8 dari 2.0 (total runtime 4,5 detik, output dicetak setelah 1,6 s).sumber
GolfScript (35 karakter)
Demo online
Ini membangun awalan yang memenuhi kondisi.
sumber
Haskell
129121Ini adalah usaha Haskell saya yang amatir (saran / peningkatan akan sangat dihargai). Ini mungkin bukan yang terpendek, tetapi hanya mengeksekusi
.190,65 detik setelah perubahan Flonk pada sistem saya.sumber
<!-- language: lang-haskell -->
dua baris sebelum kode Anda untuk penyorotan sintaksis!foldl1
fungsi menjadi, Anda dapat menggunakannya sebagai gantisum
atauany
.import Data.List;f=foldl1$(+).(*10);main=print$[f x|x<-permutations[1..9],f[mod(read.take y.show$f x)y|y<-[9,8..1]]<1]!!0
f
fungsi padamod
predikat untuk menghindari penulisan foldl1, meskipun siklus ekstra memang menghambat kinerja.!!0
dengan panggilan kef
, yang berfungsi karena hanya ada satu item dalam daftar. Daftar[9,8..1]
juga dapat diganti olehx
, karena urutannya tidak masalah. Bicara tentang penggunaan kembali kode!Javascript 75 (mengakhiri)
Solusi bruteforce (super lambat)
Jika Anda ingin melihat hasilnya dalam kehidupan ini, perbarui nilai awal menjadi seperti ini
a=c=38e7
Javascript 70 (tidak berhenti)
Dan hanya untuk bersenang-senang, bruteforce acak yang berjalan lebih cepat: (hanya ES6)
sumber
Python,
142,139,125, 124Pada dasarnya sama dengan solusi @ Ventero jika saya mengerti kodenya dengan benar, tetapi dengan Python. (Sebagian besar kredit diberikan ke @Greg Hewgill.)
sumber
r(9,1,-1)
denganr(9)
, karena urutan iterasi tidak terlalu penting.r(1,9)
karena%0
ada kesalahan.r(1, 9)
Python.permutations("123456789")
dan''.join(s[:i])
mungkin lebih pendek dari apa yang Anda miliki (dan kemudian Anda dapat menghilangkannyar=range
)Scala (128 karakter)
Tikaman saya di ini ...
sumber
(2 to 8)
danforall
.Perl, 72
Pemakaian:
perl -M5.010 find-9-digits.pl
Keluaran:
381654729
Program ini lambat . Mungkin butuh lebih dari 10 detik, karena mengocok angka "123456789", tetapi shuffle tersebut memiliki cacat.
Tidak Disatukan:
Saya memasukkan kode yang mengocok array angka 1..9:
use List'Util shuffle;shuffle 1..9
(34 karakter)sort{(-1,1)[rand 2]}1..9
(24 karakter)sort{.5<=>rand}1..9
(19 karakter)sort(2-rand 4}1..9
(18 karakter)sort{4-rand 8}1..9
(18 karakter)Perl mengharapkan blok sortir untuk membandingkan $ a dan $ b secara konsisten. Blok sortir saya tidak pernah melihat $ a dan $ b . Mereka mengembalikan pemesanan acak sehingga pengurutan menjadi acak.
Jika saya akan menggunakan
sort{.5<=>rand}1..9
, program saya akan berjalan lebih cepat. Yang membandingkan 0,5 dengan float acak dari 0,0 ke 1,0, tidak termasuk 1,0, untuk peluang 1/2 yang $ a <$ b , dan peluang hampir 1/2 bahwa $ a> $ b . ( Hati-hati: Ini adalah "Microsoft shuffle" , yang bukan shuffle yang adil. Ini bias karena.5<=>rand
tidak memberikan pemesanan yang konsisten.)Misalkan saya bermain golf satu karakter dan menggunakan yang jauh lebih buruk
sort(2-rand 4}1..9
. Perl mengharapkan blok sortir untuk mengembalikan integer, tetapi2-rand 4
float. Ini adalah float acak dari -2.0 ke 2.0, tidak termasuk -2.0. Perl memotong float ini ke nol, dengan hasil ini:Ketika $ a == $ b , Perl tidak mengocok dengan baik. Jadi, program saya akan melakukan lebih banyak pengocokan, sampai cukup banyak pengocokan di mana
2-rand 4
tidak mengembalikan 0 terlalu sering. Program saya akan berjalan sangat lambat, mungkin butuh lebih dari satu menit.Saya menggunakan
sort{4-rand 8}1..9
, jadi hanya ada peluang 1/4 bahwa $ a == $ b , dan program saya menggunakan shuffles lebih sedikit.sumber
CJam, 35 byte
Setelah kira-kira 27 menit, ini menghasilkan output berikut:
Bagaimana itu bekerja
sumber
Python 2 (78)
Tidak perlu menghasilkan permutasi, coba saja setiap angka dan periksa apakah angka plus 0 nya berbeda. Butuh waktu beberapa saat untuk berlari.
sumber
SWI-Prolog 84
Agak curang, karena daftar angka harus diberikan dalam kueri:
Namun, inilah yang membuat kode ini menarik: Anda dapat memecahkan masalah untuk daftar angka apa pun. Sebagai contoh:
sumber
Python 2 - 114
Bahkan bukan solusi Python terpendek, tapi saya tetap membagikannya:
sumber
Bash + coreutils, 159 byte
Ini agak panjang, tapi saya pikir algoritma ini mungkin salah satu yang tercepat, mengingat ini adalah skrip shell (biasanya lambat) yang berjalan dalam waktu kurang dari 0,1 detik.
Algoritma berjalan seperti ini:
grep
)$d
(angka digit) menggunakanbc
, dengan ekspresi yang dihasilkan olehprintf
Perhatikan kami mengambil beberapa pintasan, tapi saya pikir ini secara matematis bagus:
sumber
C ++, 187
Saya hanya harus mencoba ini di C ++. Jelas, itu tidak akan menjadi solusi terpendek tetapi ini dia:
mengembalikan nomor alih-alih mencetaknya untuk menyimpan beberapa karakter (sialan termasuk). Di bawah sistem POSIX ini tentu saja akan dikonversi menjadi 8-bit yang tidak ditandatangani dan dengan demikian tidak benar - tetapi program akan menghitung angka yang benar.
Tidak dikumpulkan (membutuhkan C ++ 11):
sumber
T-SQL 2005+ - 203
T-sql bukan bahasa golf yang sangat kompetitif ...
Harus dijalankan di master database. Anda dapat mengganti CTE pertama dengan ini untuk menjadikannya agnostik basis data tetapi kemudian menggunakan beberapa karakter lagi (dan membutuhkan 2008)
Formasi yang mudah dibaca:
Pada dasarnya kami terus menambahkan angka di belakang
r
angka yang belum kami lihat di string, dan memastikan bahwa string baru masih modulo 0 dari level saat ini. Kami menginisialisasi R ke\
, Ini benar-benar satu-satunya trik dalam kode ini. Yang merupakan cara gila untuk mengaturnya ke 0 dalammoney
tipe data. Ini saya menduga cara untuk membiarkan Anda mengetik\
alih-alih mata uang.$
juga melakukan hal yang sama di T-SQL, tetapi$l
akan mencoba menafsirkan kolom pseudo yang tidak ada dan melempar kesalahan. Ini memungkinkan kita menghindari kekhawatiran tentang penggunaanint
yang akan menyebabkan overflow biasanya pada rangkaian ke-10, memaksa kita untuk benar-benar memeriksa level. Sunting: Fakta menyenangkan T-sql bahkan pada tahun 2014 tidak memiliki cara untuk mengubah string menjadi tabel nilai (misalnya, tidak ada fungsi split), jadi kami juga dapat menggunakan kembaliA
tabel kami dua kali untuk mengulangi karakter dalam stringified R.Aturan diutamakan T-Sql mengganggu sehingga kita harus menggunakan concatenation numerik (* 10 + n), daripada string string.
sumber
with A as(select 1n union all select n+1 from A where n<9),
PHP, 89 byte
versi acak, 89 byte:
mengocok string yang berisi angka, lalu menguji keterpisahan dalam satu lingkaran.
Jalankan dengan
-nr
.loop brute force, 90 byte, sangat lambat:
loop dari 100000001, menguji dapat dibagi dalam loop batin, dan keluar ketika menemukan solusi.
fungsi rekursif, 94 byte, sangat cepat:
menambahkan satu digit yang belum dalam angka, jika dapat dibagi menurut panjangnya, berulang (atau cetak).
Ini mengeksploitasi bahwa hanya ada satu solusi. tanpa itu,
print$e>8?$x:f($x,$e+1)
harusprint$e>8?"$x\n":f($x,$e+1)
(+3 byte, cetak semua solusi) atau($e>8?die("$x"):f($x,$e+1))
(+4 byte, keluar pada solusi pertama) atau solusi akan dicetak tanpa pembatas.Telepon dengan
f();
-
TiO
Versi brute force tidak memiliki TiO untuk alasan yang jelas, tetapi Anda dapat mencoba dua lainnya .
Fungsi runtime panggilan diukur inline (di suatu tempat antara 2 dan 4 milidetik);
total runtime diukur oleh situs web (biasanya antara 50 dan 500 ms).
sumber