Zincirdeki Sayılar


15

Bazı pozitif tamsayıların zincir bölünebilirliği adı verilen bir özelliğe sahip olduğu gösterilebilir . Bir sayının n'ye zincirle bölünebilmesi için  üç gereksinimi karşılaması gerekir:

  1. Her  basamak, onu takip eden n basamaktan oluşan sayıyı böler .

    Örneğin, sayı 7143 zincir bölünebilir 2 7 için böler 14 ve O 1 böler 43. tarafından değil zincir bölünebilir 143 bölünmemesi 3 ila 7, çünkü ile.

  2. Bölünebilirlik için dikkate alınan her alt dizinin başında sıfır olmamalıdır.

    Örneğin, 14208 sayısı 2'ye zincirle bölünemez, çünkü 08 önde gelen sıfıra sahiptir. Bununla birlikte, zincir 3'e bölünebilir, çünkü 208 önde gelen sıfıra sahip değildir.

  3. Sayıdaki tüm rakamlar benzersiz olmalıdır.

Örneğin, 14280 sayısı 2, 3 ve 4'e zincirle bölünebilir. Zincir bölünebilirliği açıklamam net değilse lütfen yorumlarda soru sorun.

Giriş

Programın girdisi tek bir tamsayı n, ardından bir boşluk, daha sonra belirli rakamların alt çizgi ile değiştirilmiş bir sayıdan oluşur. Örneğin, aşağıdakiler olası bir girdidir:

3 6__2__4508

n 1'den büyük olacaktır. Sayı hiçbir zaman tamamen alt çizgi olmayacaktır. İlk rakamın alt çizgi olmadığı garanti edilmez. İlk hane asla 0 olmaz. N , sayıdaki hane sayısından asla daha büyük veya eşit olmaz.

Çıktı

Sayıyı, elde edilen sayı n ile zincir bölünebilir olacak şekilde tamsayılarla değiştirerek sayıyı çıktılayın . Zincire bölünebilir sayıyı tamamlamanın birden fazla yolu varsa, çıktı olarak herhangi biri kullanılabilir. Tamamlayabilecek sayı yoksa çıktı alın no answer. Örneğin, örnek girişin çıktısı şöyle olabilir:

6132794508

Bu kod golf, bu yüzden en kısa kod kazanır.


Bu nsayıdaki basamak sayısından büyük veya ona eşitse, sayının zincir bölünebilir olduğunu varsayıyorum ?
John Dvorak

@Jan Dvorak n girişteki rakam sayısına asla eşit veya ondan daha büyük olmayacaktır. Her zaman daha küçük olacaktır. Bunu yansıtacak şekilde düzenleyeceğim.
Absinthe

Tam bir program yazmamız gerekiyor mu yoksa bir işlev yeterli mi?
John Dvorak

@Martin Evet. Karakter sınırı dolgusu.
Absinthe

@Jan Dvorak Tam bir program.
Absinthe

Yanıtlar:


5

Bash + coreutils, 197 bayt

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

Çıktı:

$ ./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
$

açıklama

  • Genişletme parametresi, ${2//_/{0..9\}}tüm alt çizgileri ile değiştirir {0..9}.
  • Ortaya çıkan dize, evaltüm bu ayraç ifadelerini genişletmek için düzenlenir.
  • grepHerhangi tekrarlanan rakam vardır tüm olanakları eler.
  • Daha sonra kalan her sayı kontrol edilir, koşullar 1 ve 2 için basamak basamak.

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'

Yavaş ama kısa. Mümkün olan her N haneli permütasyonu verilen modelle karşılaştırın ve tüm gereksinimleri kontrol edin. Sadece 7 veya 8 basamakla test ettim. 9 veya 10 için de çalışmalı, ancak biraz zaman alacaktır.

Düzenleme: Ben eksik varsayılan çıktı "cevap yok" ekledim.


2

Mathematica Yakut, 349 224 229 bayt

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

Bu çok naif bir uygulama. Alt çizgilerin sayısını sayıyorum ve sonra mümkün olan her kombinasyonu kaba kuvvetlendirmek için bu uzunluktaki tüm rakam permütasyonlarının bir listesini oluşturuyorum. Bu, daha fazla sayıda alt çizgi için korkunç bir performans gösterecektir, ancak bu kod golfü ve en hızlı kod değildir. :)

Düzenleme: Bunu Mathematica'dan taşıdık. Orijinal sürüm için düzenleme geçmişine bakın.

Düzenleme: Baştaki alt çizgi durumları düzeltildi.


Tuples (karakter sayısına bakan) yerine Permütasyon kullanılmamalı mı?
DavidC

@DavidCarraher Neden? Orada çok fazla kombinasyon eksik olurdu, değil mi?
Martin Ender

Sayıdaki her rakam benzersiz olmalıdır. Tuplesbu kısıtı dayatmaz. Permutationsgirilirse, giriş kümesinde tekrarlanan rakamlar olmazsa. Ve yalnızca henüz kullanılmamış rakamlara izin verebilirsiniz. (Yine de, bu kodunuzu uzatabilir.)
DavidC

@DavidCarraher Ohhh, benzersizlik gereksinimini göz ardı ettim. İç döngüye eklemeliyim, bu durumda Tuplesdaha kısa olduğu için de yapışabilirim .
Martin Ender

@DavidCarraher düzeltildi.
Martin Ender

1

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

Daha az golf, açıklama ile:

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