Numeri su una catena


15

È possibile dimostrare che alcuni numeri interi positivi hanno una proprietà chiamata divisibilità a catena. Perché un numero sia divisibile per catena per  n , deve soddisfare tre requisiti:

  1. Ogni cifra divide il numero formato dalle n  cifre che lo seguono.

    Ad esempio, il numero 7143 è catena divisibile per 2 perchè 7 divide 14 e 1 divide 43. È non catena-divisibile per 3 perché 7 non divide 143.

  2. Ogni sottosequenza presa in considerazione per la divisibilità non deve avere zeri iniziali.

    Ad esempio, il numero 14208 non è divisibile per catena per 2 perché 08 ha uno zero iniziale. È, tuttavia, divisibile per catena per 3, perché 208 non ha uno zero iniziale.

  3. Tutte le cifre del numero devono essere univoche.

Ad esempio, il numero 14280 è divisibile per catena per 2, 3 e 4. Se la mia spiegazione della divisibilità della catena non è chiara, fare domande nei commenti.

Ingresso

L'input per il programma è costituito da un singolo numero intero n, seguito da uno spazio, quindi da un numero a cui sono state sostituite determinate cifre con caratteri di sottolineatura. Ad esempio, ciò che segue è un possibile input:

3 6__2__4508

n sarà maggiore di 1. Il numero non sarà mai interamente sottolineato. Non si garantisce che la prima cifra non sia un carattere di sottolineatura. La prima cifra non sarà mai 0. N non sarà mai maggiore o uguale al numero di cifre nel numero.

Produzione

Emette il numero, con le cifre sostituite da numeri interi in modo tale che il numero risultante sia divisibile per catena per n . Se esiste più di un modo per completare il numero divisibile a catena, è possibile utilizzarne uno qualsiasi come output. Se non ci sono numeri che possono completarlo, emettere no answer. Ad esempio, l'output dell'input di esempio potrebbe essere:

6132794508

Questo è il codice golf, quindi vince il codice più corto.


Presumo che se nè maggiore o uguale al numero di cifre in quel numero, il numero è divisibile a catena?
John Dvorak,

@Jan Dvorak n non sarà mai uguale o maggiore del numero di cifre nell'input. Sarà sempre più piccolo. Modificherò per riflettere questo.
assenzio

Ci viene richiesto di scrivere un programma completo o è sufficiente una funzione?
John Dvorak,

@Martin Sì. Riempimento limite caratteri.
assenzio

@Jan Dvorak Un programma completo.
assenzio

Risposte:


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

Produzione:

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

Spiegazione

  • L'espansione dei parametri ${2//_/{0..9\}}sostituisce tutti i trattini bassi con {0..9}.
  • La stringa risultante viene modificata evalper espandere tutte queste espressioni di parentesi graffe.
  • Il greperbacce tutte le possibilità in cui ci sono le cifre ripetute.
  • Quindi viene controllato ogni numero rimanente, cifra per cifra per le condizioni 1 e 2.

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'

Lento, ma corto. È sufficiente confrontare ogni possibile permutazione a N cifre con il modello dato e verificare tutti i requisiti. L'ho provato solo con 7 o 8 cifre. Dovrebbe funzionare anche per 9 o 10, ma richiederà un po 'di tempo.

Modifica: ho aggiunto l'output predefinito mancante "nessuna risposta".


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

Questa è un'implementazione molto ingenua. Conto il numero di caratteri di sottolineatura, quindi creo semplicemente un elenco di tutte le permutazioni delle cifre di quella lunghezza, per forzare ogni possibile combinazione. Questo funzionerà in modo orribile per un numero maggiore di caratteri di sottolineatura, ma questo è il golf del codice e non il codice più veloce. :)

Modifica: portato da Mathematica. Vedi la cronologia delle modifiche per la versione originale.

Modifica: risolti i casi di sottolineatura iniziali.


Permutations non dovrebbe essere usato al posto di Tuples (trascurando il conteggio dei personaggi)?
DavidC

@DavidCarraher Why? Mi mancheranno molte combinazioni lì, no?
Martin Ender,

Ogni cifra nel numero deve essere unica. Tuplesnon impone questo vincolo. Permutationssarà, a condizione che non vi siano cifre ripetute nel set di input. E puoi permutare solo le cifre che non sono ancora state usate. (Anche se, di nuovo, questo può allungare il tuo codice.)
DavidC

@DavidCarraher Ohhh, ho trascurato il requisito di unicità. Quindi devo aggiungerlo al ciclo interno, nel qual caso potrei anche attenermi Tuplesperché è più corto.
Martin Ender,

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

Meno golfato, con spiegazione:

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);
        }
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.