Zahlen an einer Kette

15

Es kann gezeigt werden, dass einige positive Ganzzahlen eine Eigenschaft namens Chain divisibility haben. Damit eine Zahl durch n durch eine Kette teilbar ist  , muss sie drei Anforderungen erfüllen:

  1. Jede Ziffer teilt die Zahl durch die n darauf folgenden  Ziffern.

    Beispielsweise ist die Zahl 7143 durch 2 teilbar, weil 7 14 und 1 43 teilt. Sie ist nicht durch 3 teilbar, weil 7 143 nicht teilt.

  2. Jede für die Teilbarkeit berücksichtigte Teilfolge darf keine führenden Nullen haben.

    Beispielsweise ist die Zahl 14208 nicht durch 2 teilbar, da 08 eine führende Null hat. Es ist jedoch durch 3 teilbar, da 208 keine führende Null hat.

  3. Alle Ziffern in der Nummer müssen eindeutig sein.

Zum Beispiel ist die Zahl 14280 durch 2, 3 und 4 teilbar. Wenn meine Erklärung der Teilbarkeit der Kette unklar ist, stellen Sie bitte Fragen in den Kommentaren.

Eingang

Die Eingabe für das Programm besteht aus einer einzelnen Ganzzahl n, gefolgt von einem Leerzeichen und einer Zahl, bei der bestimmte Ziffern durch Unterstriche ersetzt wurden. Folgendes ist beispielsweise eine mögliche Eingabe:

3 6__2__4508

n ist größer als 1. Die Zahl wird niemals vollständig unterstrichen. Es kann nicht garantiert werden, dass die erste Ziffer kein Unterstrich ist. Die erste Ziffer wird niemals 0 sein. N wird niemals größer oder gleich der Anzahl der Ziffern in der Zahl sein.

Ausgabe

Geben Sie die Zahl aus, wobei die Ziffern durch Ganzzahlen ersetzt werden, sodass die resultierende Zahl durch n teilbar ist . Wenn mehr als eine Möglichkeit zur Vervollständigung der durch Ketten teilbaren Zahl vorhanden ist, kann jede als Ausgabe verwendet werden. Wenn es keine Zahlen gibt, die es vervollständigen können, wird ausgegeben no answer. Die Ausgabe der Beispieleingabe könnte beispielsweise sein:

6132794508

Das ist Codegolf, also gewinnt der kürzeste Code.

Absinth
quelle
Ich gehe davon aus, dass, wenn ngrößer oder gleich der Anzahl der Ziffern in dieser Nummer ist, die Anzahl der Ketten teilbar ist?
John Dvorak
@Jan Dvorak n ist niemals gleich oder größer als die Anzahl der Stellen in der Eingabe. Es wird immer kleiner sein. Ich bearbeite, um das zu reflektieren.
Absinth
Müssen wir ein vollständiges Programm schreiben, oder reicht eine Funktion aus?
John Dvorak
@ Martin Ja. Zeichenbegrenzung Auffüllen.
Absinth
@Jan Dvorak Ein volles Programm.
Absinth

Antworten:

5

Bash + Coreutils, 197 Bytes

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

Ausgabe:

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

Erläuterung

  • Die Parametererweiterung ${2//_/{0..9\}}ersetzt alle Unterstriche durch {0..9}.
  • Die resultierende Zeichenfolge wird evalbearbeitet, um alle diese Klammerausdrücke zu erweitern.
  • Das grepUnkraut beseitigt alle Möglichkeiten, bei denen sich Ziffern wiederholen.
  • Dann wird jede verbleibende Nummer ziffernweise auf die Bedingungen 1 und 2 überprüft.
Digitales Trauma
quelle
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'

Langsam, aber kurz. Vergleichen Sie einfach jede mögliche N-stellige Permutation mit dem angegebenen Muster und überprüfen Sie alle Anforderungen. Ich habe es nur mit 7 oder 8 Ziffern getestet. Sollte auch für 9 oder 10 funktionieren, wird aber eine Weile dauern.

Bearbeiten: Ich habe die fehlende Standardausgabe "keine Antwort" hinzugefügt.

Falko
quelle
2

Mathematica Ruby, 349 224 229 Bytes

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

Dies ist eine sehr naive Implementierung. Ich zähle die Anzahl der Unterstriche und erstelle dann einfach eine Liste aller Ziffernpermutationen dieser Länge, um jede mögliche Kombination zu erzwingen. Dies wird für eine größere Anzahl von Unterstrichen eine schreckliche Leistung erbringen, aber dies ist Codegolf und nicht der schnellste Code. :)

Edit: Portiert dies aus Mathematica. Die Originalversion finden Sie im Bearbeitungsverlauf.

Bearbeiten: Führende Unterstriche korrigiert.

Martin Ender
quelle
Sollten nicht Permutationen anstelle von Tupeln verwendet werden (mit Blick auf die Anzahl der Zeichen)?
DavidC
@ DavidCarraher Warum? Ich würde dort viele Kombinationen vermissen, nicht wahr?
Martin Ender
Jede Ziffer in der Nummer muss eindeutig sein. Tupleslegt diese Einschränkung nicht auf. Permutationswird, sofern der Eingabesatz keine wiederholten Ziffern enthält. Und Sie können nur die Ziffern permutieren, die noch nicht verwendet wurden. (Auch dies kann Ihren Code verlängern.)
DavidC
@ DavidCarraher Ohhh, ich habe das Erfordernis der Einzigartigkeit übersehen. Ich muss das dann zur inneren Schleife hinzufügen, in welchem ​​Fall ich mich genauso gut daran halten könnte, Tuplesweil es kürzer ist.
Martin Ender
@ DavidCarraher behoben.
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);}}}

Weniger Golf mit Erklärung:

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
quelle