Numéros sur une chaîne

15

Certains entiers positifs peuvent avoir une propriété appelée divisibilité en chaîne. Pour qu'un nombre soit divisible par une chaîne par  n , il doit remplir trois conditions:

  1. Chaque chiffre divise le nombre formé par les n  chiffres qui le suivent.

    Par exemple, le nombre 7143 est divisible en chaîne par 2 car 7 divise 14 et 1 divise 43. Il n'est pas divisible en chaîne par 3 car 7 ne divise pas 143.

  2. Chaque sous-séquence prise en compte pour la divisibilité ne doit pas avoir de zéros de tête.

    Par exemple, le nombre 14208 n'est pas divisible en chaîne par 2 car 08 a un zéro non significatif. Il est cependant divisible en chaîne par 3, car 208 n'a pas de zéro de tête.

  3. Tous les chiffres du numéro doivent être uniques.

Par exemple, le nombre 14280 est divisible en chaîne par 2, 3 et 4. Si mon explication de la divisibilité de la chaîne n'est pas claire, veuillez poser des questions dans les commentaires.

Contribution

L'entrée du programme se compose d'un seul entier n, suivi d'un espace, puis d'un nombre dont certains chiffres ont été remplacés par des traits de soulignement. Par exemple, ce qui suit est une entrée possible:

3 6__2__4508

n sera supérieur à 1. Le nombre ne sera jamais entièrement souligné. Vous n'êtes pas assuré que le premier chiffre n'est pas un trait de soulignement. Le premier chiffre ne sera jamais 0. n ne sera jamais supérieur ou égal au nombre de chiffres du nombre.

Production

Sortez le nombre, avec les chiffres remplacés par des entiers tels que le nombre résultant est divisible en chaîne par n . S'il existe plusieurs manières de compléter le nombre divisible par chaîne, n'importe laquelle peut être utilisée comme sortie. S'il n'y a pas de chiffres qui peuvent le compléter, sortez no answer. Par exemple, la sortie de l'exemple d'entrée pourrait être:

6132794508

C'est le golf de code, donc le code le plus court gagne.

Absinthe
la source
Je suppose que si nest supérieur ou égal au nombre de chiffres de ce nombre, le nombre est divisible en chaîne?
John Dvorak
@Jan Dvorak n ne sera jamais égal ou supérieur au nombre de chiffres dans l'entrée. Il sera toujours plus petit. Je vais modifier pour refléter cela.
absinthe
Sommes-nous tenus d'écrire un programme complet ou une fonction suffit-elle?
John Dvorak
@Martin Oui. Remplissage de limite de caractères.
absinthe
@Jan Dvorak Un programme complet.
absinthe

Réponses:

5

Bash + coreutils, 197 octets

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

Production:

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

Explication

  • L'extension des paramètres ${2//_/{0..9\}}remplace tous les traits de soulignement par {0..9}.
  • La chaîne résultante est evaléditée pour développer toutes ces expressions d'accolade.
  • Il grepélimine toutes les possibilités là où il y a des chiffres répétés.
  • Ensuite, chaque numéro restant est vérifié, chiffre par chiffre pour les conditions 1 et 2.
Traumatisme numérique
la source
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'

Lent, mais court. Comparez simplement toutes les permutations possibles à N chiffres avec le modèle donné et vérifiez toutes les exigences. Je ne l'ai testé qu'avec 7 ou 8 chiffres. Devrait également fonctionner pendant 9 ou 10, mais cela prendra un certain temps.

Edit: j'ai ajouté la sortie par défaut manquante "pas de réponse".

Falko
la source
2

Mathematica Ruby, 349 224 229 octets

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

Il s'agit d'une implémentation très naïve. Je compte le nombre de soulignements, puis je crée simplement une liste de toutes les permutations de chiffres de cette longueur, pour forcer brutalement toutes les combinaisons possibles. Cela fonctionnera horriblement pour un plus grand nombre de traits de soulignement, mais il s'agit du code golf et non du code le plus rapide. :)

Edit: Porté ceci depuis Mathematica. Voir l'historique des modifications pour la version originale.

Edit: Correction des principaux cas de soulignement.

Martin Ender
la source
Les permutations ne devraient-elles pas être utilisées à la place des tuples (sans tenir compte du nombre de caractères)?
DavidC
@DavidCarraher Pourquoi? Il me manquerait beaucoup de combinaisons, non?
Martin Ender
Chaque chiffre du numéro doit être unique. Tuplesn'impose pas cette contrainte. Permutations, à condition qu'il n'y ait pas de chiffres répétés dans l'ensemble d'entrée. Et vous ne pouvez permuter que les chiffres qui n'ont pas encore été utilisés. (Bien que, encore une fois, cela puisse allonger votre code.)
DavidC
@DavidCarraher Ohhh, j'ai ignoré l'exigence d'unicité. Je dois ensuite ajouter cela à la boucle intérieure, auquel cas je ferais aussi bien de rester Tuplescar il est plus court.
Martin Ender
@DavidCarraher corrigé.
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);}}}

Moins golfé, avec explication:

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
la source