Angka pada Rantai

15

Beberapa bilangan bulat positif dapat ditunjukkan memiliki sifat yang disebut keterbagian rantai. Untuk angka yang dapat dibagi rantai oleh  n , itu harus memenuhi tiga persyaratan:

  1. Setiap digit membagi angka yang dibentuk oleh n  digit yang mengikutinya.

    Misalnya, angka 7143 adalah rantai-terbagi oleh 2 karena 7 membagi 14 dan 1 membagi 43. Yaitu tidak dapat dibagi rantai oleh 3 karena 7 tidak membagi 143.

  2. Setiap urutan diperhitungkan untuk dapat dibagi tidak harus memiliki nol di depan.

    Misalnya, angka 14208 tidak dapat dibagi rantai oleh 2 karena 08 memiliki nol di depan. Namun, rantai-dibagi oleh 3, karena 208 tidak memiliki nol di depan.

  3. Semua digit dalam angka harus unik.

Sebagai contoh, nomor 14280 adalah rantai-dibagi oleh 2, 3 dan 4. Jika penjelasan saya tentang pembagian rantai tidak jelas, silakan ajukan pertanyaan di komentar.

Memasukkan

Input ke program terdiri dari bilangan bulat tunggal n, diikuti oleh spasi, kemudian angka yang memiliki digit tertentu diganti dengan garis bawah. Misalnya, berikut ini adalah input yang mungkin:

3 6__2__4508

n akan lebih besar dari 1. Jumlahnya tidak akan sepenuhnya menjadi garis bawah. Anda tidak dijamin bahwa digit pertama bukan garis bawah. Digit pertama tidak akan pernah menjadi 0. n tidak akan pernah lebih besar atau sama dengan jumlah digit dalam angka.

Keluaran

Keluarkan angka tersebut, dengan digit yang digantikan oleh bilangan bulat sedemikian rupa sehingga angka yang dihasilkan dapat dibagi rantai oleh n . Jika ada lebih dari satu cara melengkapi nomor yang dapat dibagi-rantai, ada yang dapat digunakan sebagai output. Jika tidak ada angka yang bisa menyelesaikannya, output no answer. Sebagai contoh, output dari contoh input dapat berupa:

6132794508

Ini kode golf, jadi kode terpendek menang.

Absinth
sumber
Saya berasumsi bahwa jika nlebih besar dari atau sama dengan jumlah digit dalam angka itu, jumlahnya adalah rantai yang dapat dibagi?
John Dvorak
@ Jan Dvorak n tidak akan pernah sama atau lebih besar dari jumlah digit pada input. Itu akan selalu lebih kecil. Saya akan mengedit untuk mencerminkan itu.
absinthe
Apakah kita diharuskan untuk menulis program lengkap, atau apakah suatu fungsi mencukupi?
John Dvorak
@ Martin Ya. Padding batas karakter.
absinthe
@ Jan Dvorak Program lengkap.
absinthe

Jawaban:

5

Bash + coreutils, 197 byte

for i in $(eval printf '%s\\n' ${2//_/{0..9\}}|grep -vP '(\d).*\1');{
for((f=d=0;d<${#i}-$1;d++));{
((${i:d+1:1}==0||10#${i:d+1:$1}%${i:d:1}))&&f=
}
[ $f ]&&echo $i&&((c++))
}
((c))||echo no answer

Keluaran:

$ ./chain.sh 3 714_
7140
$ ./chain.sh 2 7141
no answer
$ ./chain.sh 2 14208
no answer
$ ./chain.sh 3 14208
14208
$ ./chain.sh 2 1_208
no answer
$ ./chain.sh 3 1_208
14208
$ ./chain.sh 2 6__2__4508
no answer
$ ./chain.sh 3 6__2__4508
6132794508
$

Penjelasan

  • Ekspansi parameter ${2//_/{0..9\}}menggantikan semua garis bawah dengan{0..9} .
  • String yang dihasilkan adalah eval ed untuk memperluas semua ekspresi penjepit ini.
  • Itu grep gulma semua kemungkinan di mana ada diulang digit.
  • Kemudian setiap angka yang tersisa diperiksa, digit-demi-digit untuk kondisi 1 dan 2.
Trauma Digital
sumber
2

Python - 239 267

from itertools import*
T=raw_input()
n=int(T[0])
N=len(T)-2
J=''.join
for i in permutations('0123456789',N):
 if all([S in[I,'_']for S,I in zip(T[2:],i)])*all([i[j]>'0'<i[j+1]and int(J(i[j+1:j+n+1]))%int(i[j])<1for j in range(N-n)]):print J(i);exit()
print'no answer'

Lambat, tapi pendek. Cukup bandingkan setiap permutasi N-digit yang mungkin dengan pola yang diberikan dan periksa semua persyaratan. Saya sudah mengujinya hanya dengan 7 atau 8 digit. Harus bekerja untuk 9 atau 10 juga, tetapi akan memakan waktu cukup lama.

Sunting: Saya menambahkan output default yang hilang "tidak ada jawaban".

Falko
sumber
2

Mathematica Ruby, 349 224 229 byte

n=$*[0].to_i
r='no answer'
(?0..?9).to_a.permutation($*[1].count'_'){|q|s=$*[1]
q.map{|d|s=s.sub'_',d}
c=s.chars
(t=1
c.each_cons(n+1){|c|e=c.shift.to_i
(t=!t
break)if e<1||c[0]==?0||c.join.to_i%e>0}
(r=s)if t)if c==c.uniq}
$><<r

Ini adalah implementasi yang sangat naif. Saya menghitung jumlah garis bawah, dan kemudian cukup membuat daftar semua digit-permutasi panjang itu, untuk memaksa setiap kombinasi yang mungkin. Ini akan berkinerja buruk untuk jumlah garis bawah yang lebih besar, tetapi ini adalah kode golf dan bukan kode tercepat. :)

Sunting: Mengaitkan ini dari Mathematica. Lihat riwayat edit untuk versi aslinya.

Sunting: Memperbaiki kasus garis bawah terkemuka terkemuka.

Martin Ender
sumber
Bukankah seharusnya Permutasi digunakan alih-alih Tuples (menghadap jumlah karakter)?
DavidC
@DavidCarraher Mengapa? Saya akan kehilangan banyak kombinasi di sana, bukan?
Martin Ender
Setiap digit dalam angka harus unik. Tuplestidak memaksakan kendala itu. Permutationsakan, asalkan tidak ada digit berulang dalam set input. Dan Anda dapat mengubah hanya angka yang belum digunakan. (Meskipun, sekali lagi, ini dapat memperpanjang kode Anda.)
DavidC
@ DavidVarraher Ohhh, saya mengabaikan persyaratan keunikan. Saya perlu menambahkan itu ke loop batin kemudian, dalam hal ini saya mungkin juga tetap Tupleskarena itu lebih pendek.
Martin Ender
@DavidCarraher diperbaiki.
Martin Ender
1

Jawa, 421

class C{static int n;public static void main(String[]a){n=new Short(a[0]);f(a[1]);System.out.print("no answer");}static void f(String s){if(s.contains("_"))for(int i=0;i<=9;i++)f(s.replaceFirst("_",i+""));else{for(int i=1;i<s.length()-n+1;){String t=s.substring(i,i+n);if(t.charAt(0)<49||new Long(t)%new Long(s.substring(i-1,i++))>0||s.chars().distinct().count()<s.length())return;}System.out.print(s);System.exit(0);}}}

Kurang bermain golf, dengan penjelasan:

class C {

    static int n;

    public static void main(String[] a) {
        n = new Short(a[0]);
        f(a[1]);
        System.out.print("no answer");
    }

    /**
     * This method is called recursively, each time with
     * another underscore replaced by a digit, for all possible digits.
     * If there is a solution, the method prints it and exits the program.
     * Otherwise, it returns.
     */
    static void f(String s) {
        if (s.contains("_")) {
            for (int i = 0; i <= 9; i++) {
                f(s.replaceFirst("_", i + ""));
            }
        } else {
            for (int i = 1; i < s.length() - n + 1;) {
                String t = s.substring(i, i + n);       // on each substring...
                if (                                    // test for the three rules
                    t.charAt(0) < 49 ||
                    new Long(t) % new Long(s.substring(i - 1, i++)) > 0 ||
                    s.chars().distinct().count() < s.length()
                ) {
                    return;            // a rule was broken
                }
            }
            System.out.print(s);       // if we made it this far, it's a success!
            System.exit(0);
        }
    }
}
Ypnypn
sumber