9 Digit Masalah

8

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:

  1. Jumlahnya harus habis dibagi 9.
  2. Jika digit paling kanan dihapus, angka yang tersisa harus dapat dibagi 8.
  3. Jika digit paling kanan dari nomor baru dihilangkan, angka yang tersisa harus dibagi dengan 7.
  4. Dan seterusnya, sampai hanya ada satu digit (yang harus dibagi dengan 1).

Kredit Dávid Németh

Noelkd
sumber
28
Aturan pertama tampaknya tidak perlu. Setiap angka yang terdiri dari angka 1-9 setiap kali akan selalu habis dibagi 9.
Geobits
6
Apa aspek kode di sini? Ini kedengarannya seperti itu dapat diposting di Puzzling
Simon Forsberg
11
Bahkan jika kita akan menyebutnya "celah standar", tantangan golf kode yang menghasilkan output tetap umumnya lebih pendek daripada kode apa pun yang bisa membangunnya biasanya tidak terlalu menarik.
Ry-
9
Masalah yang saya miliki dengan tantangan seperti ini adalah bahwa perbatasan antara hardcoding dan penerapan properti matematika tidak jelas. Misalnya, aturan pembagian untuk 5 adalah bahwa angka harus diakhiri dengan 0 atau 5. Apakah membatasi pilihan untuk digit tersebut menjadi 0 dan 5 bagian hardcoding dari output? Akan lebih buruk jika kita berhadapan dengan angka 10 digit.
user2357112 mendukung Monica
4
@Sylwester Apa yang Anda lakukan adalah berasumsi hanya ada 1 cara untuk menyelesaikan masalah, karena Anda takut melanggar celah. + Msgstr "Periksalah persyaratan pengecekan angka". Ini sepenuhnya mengecualikan contoh menarik. Dan pertanyaannya adalah: "Bahasa mana yang dapat memeriksa hal-hal ini dan mengulang dalam karakter paling sedikit".
Cruncher

Jawaban:

9

CJam - 26

1{;9,:)_mrs0@{_3$<i\%+}/}g

Ini acak tetapi bekerja cukup cepat dengan penerjemah java . Diperlukan beberapa menit dengan juru bahasa online .

Penjelasan:

1push 1 (akan dijelaskan nanti)
{…}gadalah 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 array
mrmengocok array yang
sdikonversi ke string
0@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
<imendapat 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

aditsu berhenti karena SE adalah JAHAT
sumber
Bagus! Anda dapat menyimpan satu byte lagi dengan menggunakan nilai dummy:0{;9,:)_mrsT@{_3$<i\%+}/}g
Dennis
7

Javascript (E6) 105 125 134

Bangunan 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

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

Golf

(Q=(n='',d=1,b=[...'123456789'],i)=>{
for(i=0;s=[...b],m=n+s.splice(i,1),b[i];i++)m%d||Q(m,d+1,s);d>9&&(Q.z=n);return Q.z;
})()

Jelek

(Q=(n='', d=1, b=[...'123456789'], i) => {
   for(i=0; s=[...b], m=n+s.splice(i,1), b[i]; i++)
     m % d || Q(m,d+1,s);
   d > 9 && (Q.z=n);
   return Q.z;
})()

Bonus

Dengan 3 perubahan kecil, Anda dapat menggunakan fungsi yang sama untuk menemukan nomor yang lebih panjang menggunakan basis> 10. Misalnya di ...

(Q=(n='',d=1,b=[...'123456789ABCD'],i)=>{
  for(i=0; s=[...b], m = n+s.splice(i,1), b[i]; i++)
    parseInt(m,14)%d || Q(m,d+1,s);
  d>13 && (Q.z=n);
  return Q.z;
})()

9C3A5476B812D

Tidak disatukan

Q=(n,d,b,i,c,z)=>{ // i,c,z fake parameters instead of vars.
  for (i=0; b[i]; i++)
  {
    s=[...b];
    m = n + s.splice(i,1);
    if (m % d == 0)
      if (z = d<9 ? Q(m, d+1, s) : m) return z;
  }
}
Q('',1,[...'123456789'])
edc65
sumber
1
105 Karakter:(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')
MT0
101 Karakter:(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')
MT0
@ MT0 wow! Pemahaman array menyerang kembali. Saya akan mengambil yang pertama, karena yang lain dapat menemukan nomor yang salah jika tidak ada yang benar (IE menghitung hingga 7 bukannya 9).
edc65
5

Perl, 56

Pemakaian: perl -E '...'

{$s++;redo if grep{$s!~$_||substr($s,0,$_)%$_}1..9}say$s

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:

my $set = [1..9];
for my $divisor (2..9) {
    my $newset = [];
    for my $element (@$set) {
        my $num = $element * 10;
        for (my $digit = $divisor - ($num % $divisor); $digit < 10; $digit += $divisor) {
            if (index($element, $digit) == -1) {
                push @$newset, $num + $digit;
            }
        }
    }
    $set = $newset;
}

print "@$set\n";

Di atas berjalan dalam .00095 detik, dan mengonfirmasi bahwa hanya ada satu solusi untuk masalah ini.

Tukang giling
sumber
5

Python3, 214, 199, 184, 176, 174, 171, 165, 150, 146

from itertools import*
g=lambda i,d:d==1!=print(i)or int(i[9:])%d==0!=g(i[:-1],d-1)
for x in permutations("123456789"):g("".join(map(str,x))*2,9)

keluaran:

381654729

Ini skrip golf pertamaku. Harap Anda menyukainya :)

Anjing makan dunia kucing
sumber
4

Pyth , 33 karakter

=Y]kFkY~Yf>ql{TlT%vTlTm+k`dr1T)pk

Untuk mengujinya, masukkan kode di atas sebagai input standar di tautan dalam judul.

Setelah dikompilasi ke dalam Python 3.4:

k=''
T=10
Y=[k]
for k in Y:
 Y+=list(filter(lambda T:(len(set(T))==len(T))>(eval(T)%len(T)),
                map(lambda d:k+repr(d),range(1,T))))
print(k)

Penjelasan:

=Y]k:Y=['']

FkY: untuk k di F:

~Y: Tambahkan ke Y

f: Saring berdasarkan

>ql{TlT: Semua elemen unik dan

%vTlT: eval (elemen)% len (elemen) = 0

m+k` d Pada daftar k + repr (d)

r1T: untuk d dari 1 hingga 9.

): End for loop

pk: cetak k

isaacg
sumber
4

Ruby, 66 78 karakter

[*r=1..9].permutation{|i|r.all?{|x|eval(i[0,x]*"")%x<1}&&$><<i*""}

Runtime 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

[*r=1..9].permutation{|i|r.all?{|x|eval(i[0,x]*"")%x<1}&&$><<i}

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

Ventero
sumber
3

GolfScript (35 karakter)

1,{{10*){.)}8*}%{`..&=},{.`,%!},}9*

Demo online

Ini membangun awalan yang memenuhi kondisi.

# Initial prefixes: [0]
1,
# Loop 9 times
{
    # Extend each prefix by digits 1 to 9
    {10*){.)}8*}%
    # Filter out ones which repeat a digit
    {`..&=},
    # Filter down to ones which are divisible by their length
    {.`,%!},
}9*
Peter Taylor
sumber
3

Haskell 129 121

Ini adalah usaha Haskell saya yang amatir (saran / peningkatan akan sangat dihargai). Ini mungkin bukan yang terpendek, tetapi hanya mengeksekusi.19 0,65 detik setelah perubahan Flonk pada sistem saya.

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
DrJPepper
sumber
Selamat datang di PPCG.SE! Coba tambahkan <!-- language: lang-haskell -->dua baris sebelum kode Anda untuk penyorotan sintaksis!
Flonk
Dan saya memang menemukan cara untuk menyimpan 8 karakter lagi! Alih-alih memeriksa apakah setiap sisa == 0, Anda bisa menjumlahkan semuanya dan memeriksa apakah itu == 0, yang sama panjangnya. Dengan memisahkan foldl1fungsi menjadi, Anda dapat menggunakannya sebagai ganti sumatau any. 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
Flonk
Tampaknya Anda menghitung karakter Anda termasuk baris tambahan: hanya ada 128 karakter dalam kode Anda.
Peter Taylor
@Flonk Saya benar-benar menyukai penggunaan ffungsi pada modpredikat untuk menghindari penulisan foldl1, meskipun siklus ekstra memang menghambat kinerja.
DrJPepper
@DrJPepper 0,65 detik? Ah. Mari kita buat lebih buruk! Anda juga dapat mengganti !!0dengan panggilan ke f, yang berfungsi karena hanya ada satu item dalam daftar. Daftar [9,8..1]juga dapat diganti oleh x, karena urutannya tidak masalah. Bicara tentang penggunaan kembali kode!
Flonk
2

Javascript 75 (mengakhiri)

Solusi bruteforce (super lambat)

for(a=c=1;b=c&&++a;)for(c=9;~(a+'').search(c)&&b%c<1;)--c?b=b/10|0:alert(a)

Jika Anda ingin melihat hasilnya dalam kehidupan ini, perbarui nilai awal menjadi seperti ini a=c=38e7

Javascript 70 (tidak berhenti)

for(a=1;b=++a;)for(c=9;~(a+'').search(c)&&b%c<1;)--c?b=b/10|0:alert(a)

Dan hanya untuk bersenang-senang, bruteforce acak yang berjalan lebih cepat: (hanya ES6)

for(a=i=[..."123456789"];b=c=i&&a.sort(x=>Math.random()*9-5|0).join('');)for(i=9;c%i<1;)--i?c=c/10|0:alert(b)
nderscore
sumber
2

Python, 142, 139, 125, 124

Pada dasarnya sama dengan solusi @ Ventero jika saya mengerti kodenya dengan benar, tetapi dengan Python. (Sebagian besar kredit diberikan ke @Greg Hewgill.)

from itertools import*;print[s for s in map(''.join,permutations('123456789'))if all(t(s[:i])%i==0 for i in range(1,9))][0]
Ashwini Chaudhary
sumber
Anda harus dapat menggantinya r(9,1,-1)dengan r(9), karena urutan iterasi tidak terlalu penting.
Ventero
Anda harus menggunakan r(1,9)karena %0ada kesalahan.
Greg Hewgill
@GregHewgill Ah, tentu saja Anda benar, tidak menyadarinya dimulai dengan 0. Sepertinya sudah jelas saya bukan ahli Python. :)
Ventero
@Ventero Terima kasih atas tipnya, Greg benar saya harus menggunakan r(1, 9)Python.
Ashwini Chaudhary
1
Menggunakan permutations("123456789")dan ''.join(s[:i])mungkin lebih pendek dari apa yang Anda miliki (dan kemudian Anda dapat menghilangkannya r=range)
Greg Hewgill
2

Scala (128 karakter)

Tikaman saya di ini ...

Seq(1,2,3,4,5,6,7,8,9).permutations.filter(p=>(2 to 8)forall{n=>(p.take(n).mkString.toLong%n==0)}).map(_.mkString.toLong).toList
Keith Pinson
sumber
Anda dapat menyimpan karakter dengan menghapus spasi di antara (2 to 8)dan forall.
ProgramFOX
@ProgramFOX Saya tidak tahu. Saya selalu berpikir titik atau ruang diperlukan di sana. Terima kasih, saya telah mengedit hingga 128 karakter.
Keith Pinson
2

Perl, 72

Pemakaian: perl -M5.010 find-9-digits.pl

{$s=join'',sort{4-rand 8}1..9;redo if grep{substr($s,0,$_)%$_}2..9}say$s

Keluaran: 381654729

Program ini lambat . Mungkin butuh lebih dari 10 detik, karena mengocok angka "123456789", tetapi shuffle tersebut memiliki cacat.

Tidak Disatukan:

# Enter a block.
{
     # Shuffle the characters "123456789".
     $s = join('', sort({2 - rand(4)} 1..9));

     # Redo block if any divisiblity test fails; grep returns the
     # number of failing tests.
     redo if grep({
        # For each divisor $_ in 2..9, test if the first $_ digits of
        # of $s are divisible by $_.  The test fails if the remainder
        # is a true value (not zero).
        substr($s, 0, $_) % $_
     } 2..9);
}
say $s;

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<=>randtidak 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, tetapi 2-rand 4float. Ini adalah float acak dari -2.0 ke 2.0, tidak termasuk -2.0. Perl memotong float ini ke nol, dengan hasil ini:

  • 1/4 peluang $ a <$ b , bilangan bulat -1 dari -2.0 <float <= -1.0
  • hampir 1/2 peluang $ a == $ b , bilangan bulat 0 dari -1.0 <float <1.0
  • mendekati 1/4 peluang $ a> $ b , bilangan bulat 1 atau 2 dari 1.0 <= float <= 2.0

Ketika $ a == $ b , Perl tidak mengocok dengan baik. Jadi, program saya akan melakukan lebih banyak pengocokan, sampai cukup banyak pengocokan di mana 2-rand 4tidak 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.

kernigh
sumber
Acak linting tangan bagus
Miller
1

CJam, 35 byte

0{)_`$A,1>s=!1$9,{9\m1$\%@+\A/}/;}g

Setelah kira-kira 27 menit, ini menghasilkan output berikut:

381654729

Bagaimana itu bekerja

0         " Push 0 (“n”).                                                      ";
{         "                                                                    ";
  )_`$    " Increment “N”, duplicate, stringify and sort the resulting string. ";
  A,1>s   " Push '123456789'.                                                  ";
  =!      " Push 0 if the strings are equal and 1 otherwise (“a”).             ";
  1$      " Copy “n”.                                                          ";
  9,{     " For each i in [ 0 1 2 3 4 5 6 7 8 ].                               ";
    9\m   " Calculate “9 - i”.                                                 ";
    1$\%  " Calculate “n % (9 - i)”.                                           ";
    @+    " Add the result to “a”.                                             ";
    \A/   " Swap “a” with “n” and calculate “n / 10”.                          ";
  }/      "                                                                    ";
  ;       " Discard “n”.                                                       ";
}g        " If “a > 0”, repeat the loop.                                       ";
Dennis
sumber
Ukurannya mengesankan, tetapi tampaknya bahkan lebih lambat daripada milik saya, dan saya kira itu tidak benar
aditsu berhenti karena SE adalah JAHAT
Saya tidak sepenuhnya memahaminya, tetapi tampaknya menerima 0 sebagai angka? Juga, kapan itu berhenti?
Aditsu berhenti karena SE adalah JAHAT
1

Python 2 (78)

x=1
while len(set(`10*x`))<=9+sum(x/10**i%(9-i)for i in range(9)):x+=1
print x

Tidak perlu menghasilkan permutasi, coba saja setiap angka dan periksa apakah angka plus 0 nya berbeda. Butuh waktu beberapa saat untuk berlari.

Tidak
sumber
1

SWI-Prolog 84

g([],O,_,O).
g(L,N,I,O):-nth1(_,L,D,R),M is N*10+D,J is I+1,0 is M mod J,g(R,M,J,O).

Agak curang, karena daftar angka harus diberikan dalam kueri:

?- g([1,2,3,4,5,6,7,8,9],0,0,O).
O = 381654729 ;
false.

Namun, inilah yang membuat kode ini menarik: Anda dapat memecahkan masalah untuk daftar angka apa pun. Sebagai contoh:

?- g([1,2,3,4,5,6,7,8,9,0],0,0,O).
O = 3816547290 ;
false.

?- g([1,2,3,4,5,6,7,8],0,0,O).
O = 38165472 ;
false.

?- g([1,2,3,4,5,6,7],0,0,O).
false.

?- g([1,2,3,4,5,6],0,0,O).
O = 123654 ;
O = 321654 ;
false.

?- g([2,2,3,3,5,6,7,8,9],0,0,O).
O = 363258729 ;
O = 363258729 ;
O = 363258729 ;
O = 363258729 ;
O = 723258963 ;
O = 723258963 ;
O = 723258963 ;
O = 723258963 ;
false.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
sumber
1

Python 2 - 114

Bahkan bukan solusi Python terpendek, tapi saya tetap membagikannya:

e=""
f=lambda s,n:[[n,e.join(f(s.replace(j,e),n+j)for j in s)][s>e],e][n>e>0<int(n)%len(n)]
print f("123456789",e)
Wrzlprmft
sumber
1

Bash + coreutils, 159 byte

l=`echo {1..8}`
for d in {2..8};{
l=$(printf "a=%s;if(!a%%$d)a\n" $(eval echo {${l// /,}}{1..8}|tr \  '
'|grep -Pv '(\d).*\1')|bc|paste -d\  -s -)
}
echo ${l}9

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:

  • Mulai dengan angka paling kiri (1-8)
  • tambahkan digit berikutnya ke kanan (1-8)
  • hapus angka apa saja dengan angka berulang ( grep)
  • periksa pembagian dengan $d(angka digit) menggunakan bc, dengan ekspresi yang dihasilkan olehprintf
  • Ulangi langkah di atas hingga diperoleh angka 8 digit

Perhatikan kami mengambil beberapa pintasan, tapi saya pikir ini secara matematis bagus:

  • Digit paling kiri harus dapat dibagi dengan 1, yang semuanya digit, jadi kami tidak secara eksplisit memeriksa set pertama dari digit paling kiri
  • Digit paling kanan harus 9 (sebenarnya saya tidak yakin apakah ini asumsi yang valid - saya harus memikirkannya sedikit)
Trauma Digital
sumber
1

C ++, 187

Saya hanya harus mencoba ini di C ++. Jelas, itu tidak akan menjadi solusi terpendek tetapi ini dia:

#include <algorithm>
using namespace std;bool c(int n,int d=9){return d<2||n%d==0&c(n/10,d-1);}int main(){for(char n[]="123456789";next_permutation(n,n+9);)if(c(atoi(n)))return atoi(n);}

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

#include <iostream>
#include <algorithm>
using namespace std;

bool check(int n, int digit = 9)
{
  return (n % digit==0) && (digit == 1 || check(n/10,digit-1));
}

int main()
{
  string num {"123456789"};
  while (next_permutation(begin(num), end(num)))
    if (check(stoi(num))){
      cout << num << endl;
      break;
    }
}
erlc
sumber
1

T-SQL 2005+ - 203

T-sql bukan bahasa golf yang sangat kompetitif ...

with A(n)as(select top 10 number from spt_values where'p'=type),R as(select \r,1l union all select r*10+n,l+1from R,A where n not in(select substring(str(r),n,1)from A)and(r*10+n)%l=0)select max(r)FROM R

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)

with A as(select*from(VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9))f(n))

Formasi yang mudah dibaca:

 with A(n)as(select top 10 number from spt_values where'p'=type),
    R as(select \ r,1 l 
        union all 
        select r*10+n,l+1
        from R,A
        where n not in (
            select substring(str(r),n,1)
            from A
        )
        and(r*10+n)%l=0)
select max(r) FROM R

Pada dasarnya kami terus menambahkan angka di belakang rangka 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 dalam moneytipe data. Ini saya menduga cara untuk membiarkan Anda mengetik \alih-alih mata uang. $juga melakukan hal yang sama di T-SQL, tetapi $lakan mencoba menafsirkan kolom pseudo yang tidak ada dan melempar kesalahan. Ini memungkinkan kita menghindari kekhawatiran tentang penggunaanintyang 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 kembali Atabel 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.

Michael B
sumber
Anda dapat menyimpan 5 byte dan memungkinkannya berjalan di semua jenis database dengan mengganti baris pertama dengan:with A as(select 1n union all select n+1 from A where n<9),
comfortablydrei
Poin yang bagus. Dalam kode sebenarnya, saya tidak akan pernah menggunakan rCTE untuk menghitung sehingga bahkan tidak sadar saya untuk mencobanya!
Michael B
0

PHP, 89 byte

versi acak, 89 byte:

for($n=123456789;$n=str_shuffle($n);$d||die("$n"))for($d=10;--$d&&substr($n,0,$d)%$d<1;);

mengocok string yang berisi angka, lalu menguji keterpisahan dalam satu lingkaran.

Jalankan dengan -nr.


loop brute force, 90 byte, sangat lambat:

for(;++$i<1e9;$d||die("$i"))for($d=10;--$d&&max(count_chars($i))<2&substr($i,0,$d)%$d<1;);

loop dari 100000001, menguji dapat dibagi dalam loop batin, dan keluar ketika menemukan solusi.


fungsi rekursif, 94 byte, sangat cepat:

function f($n="",$e=1){while($d++<9)strpos(_.$n,"$d")|($x=$n.$d)%$e||print$e>8?$x:f($x,$e+1);}

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)harus print$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).

Titus
sumber