Liczby na łańcuchu

15

Niektóre dodatnie liczby całkowite mogą wykazywać właściwość zwaną podzielnością łańcucha. Aby liczba mogła być podzielna przez  n , musi spełniać trzy wymagania:

  1. Każda cyfra dzieli liczbę utworzoną przez n  cyfr po niej.

    Na przykład, liczba 7143 jest podzielna przez łańcuch 2, ponieważ 7 dzieli 14 i 1 dzieli 43. Nie łańcucha podzielna przez 3 ponieważ 7 nie dzieli 143.

  2. Każda podsekwencja brana pod uwagę przy podzielności nie może mieć zer wiodących.

    Na przykład liczby 14208 nie można podzielić przez 2, ponieważ 08 ma wiodące zero. Można go jednak podzielić przez 3, ponieważ 208 nie ma wiodącego zera.

  3. Wszystkie cyfry w numerze muszą być unikalne.

Na przykład liczba 14280 jest podzielna przez 2, 3 i 4. Jeśli moje wyjaśnienie podzielności przez łańcuch jest niejasne, proszę zadawać pytania w komentarzach.

Wejście

Dane wejściowe do programu składają się z jednej liczby całkowitej n, po której następuje spacja, a następnie liczba, w której pewne cyfry zostały zastąpione znakami podkreślenia. Na przykład możliwe są dane wejściowe:

3 6__2__4508

n będzie większe niż 1. Liczba nigdy nie będzie całkowicie podkreślona. Nie ma gwarancji, że pierwsza cyfra nie jest znakiem podkreślenia. Pierwsza cyfra nigdy nie będzie wynosić 0. n nigdy nie będzie większa ani równa liczbie cyfr w liczbie.

Wynik

Wyprowadza liczbę z cyframi zastąpionymi liczbami całkowitymi, tak że wynikowa liczba jest podzielna przez n . Jeśli istnieje więcej niż jeden sposób uzupełnienia liczby podzielnej przez łańcuch, dowolny może być użyty jako wynik. Jeśli nie ma liczb, które mogłyby go uzupełnić, wyjdź no answer. Na przykład dane wyjściowe przykładowego wejścia mogą wyglądać następująco:

6132794508

To jest kod golfowy, więc wygrywa najkrótszy kod.

Absynt
źródło
Zakładam, że jeśli liczba njest większa lub równa liczbie cyfr w tej liczbie, liczba jest podzielna przez łańcuch?
John Dvorak
@Jan Dvorak n nigdy nie będzie równy ani większy niż liczba cyfr na wejściu. Zawsze będzie mniejszy. Będę edytować, aby to odzwierciedlić.
absynt
Czy musimy napisać pełny program, czy wystarcza funkcja?
John Dvorak
@ Martin Tak. Dopełnianie limitu znaków.
absynt
@Jan Dvorak Pełny program.
absynt

Odpowiedzi:

5

Bash + coreutils, 197 bajtów

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

Wynik:

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

Wyjaśnienie

  • Rozszerzenie parametru ${2//_/{0..9\}}zastępuje wszystkie podkreślenia znakiem{0..9} .
  • Wynikowy ciąg to eval edytowany, aby rozwinąć wszystkie te wyrażenia nawiasów.
  • The grepChwasty wszystkie możliwości, gdzie istnieją powtarzające się cyfry.
  • Następnie sprawdzany jest każdy pozostały numer, cyfra po cyfrze dla warunków 1 i 2.
Cyfrowa trauma
źródło
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'

Powoli, ale krótko. Wystarczy porównać każdą możliwą permutację N-cyfrową z danym wzorcem i sprawdzić wszystkie wymagania. Przetestowałem to tylko z 7 lub 8 cyframi. Powinien działać również na 9 lub 10, ale zajmie to sporo czasu.

Edycja: Dodałem brakujące wyjście „brak odpowiedzi”.

Falko
źródło
2

Mathematica Ruby, 349 224 229 bajtów

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

To bardzo naiwna implementacja. Liczę liczbę znaków podkreślenia, a następnie po prostu tworzę listę wszystkich kombinacji cyfr o tej długości, aby brutalnie wymusić każdą możliwą kombinację. Będzie to działało okropnie w przypadku większej liczby znaków podkreślenia, ale jest to kod golfowy, a nie najszybszy kod. :)

Edytować: Przeniesiono to z Mathematica. Zobacz historię edycji oryginalnej wersji.

Edycja: Naprawiono wiodące przypadki podkreślenia.

Martin Ender
źródło
Czy nie należy stosować permutacji zamiast krotek (pomijając liczbę znaków)?
DavidC
@DavidCarraher Dlaczego? Brakowałbym tam wielu kombinacji, prawda?
Martin Ender
Każda cyfra w numerze musi być unikalna. Tuplesnie nakłada tego ograniczenia. Permutationsbędzie, pod warunkiem, że w zestawie wejściowym nie ma powtarzających się cyfr. I możesz permutować tylko cyfry, które nie zostały jeszcze użyte. (Chociaż znowu może to wydłużyć twój kod.)
DavidC
@DavidCarraher Ohhh, przeoczyłem wymóg wyjątkowości. Muszę dodać to do wewnętrznej pętli, w którym to przypadku równie dobrze mogę się trzymać, Tuplesponieważ jest krótszy.
Martin Ender
Naprawiono @DavidCarraher.
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);}}}

Mniej golfa, z wyjaśnieniem:

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
źródło