Números em uma corrente


15

Alguns números inteiros positivos podem ter uma propriedade chamada Divisibilidade da cadeia. Para que um número seja divisível em cadeia por  n , ele deve atender a três requisitos:

  1. Cada dígito divide o número formado pelos n  dígitos seguintes.

    Por exemplo, o número 7143 está cadeia-divisível por 2, porque 7 divisões 14 e 1 43. É divide não cadeia-divisível por três 7 porque não se divide 143.

  2. Cada subsequência considerada para a divisibilidade não deve ter zeros à esquerda.

    Por exemplo, o número 14208 não é divisível em cadeia por 2 porque 08 tem um zero inicial. É, no entanto, divisível em cadeia por 3, porque 208 não tem um zero inicial.

  3. Todos os dígitos do número devem ser exclusivos.

Por exemplo, o número 14280 é divisível em cadeia por 2, 3 e 4. Se minha explicação sobre a divisibilidade em cadeia não for clara, faça perguntas nos comentários.

Entrada

A entrada para o programa consiste em um único número inteiro n, seguido por um espaço e, em seguida, um número que teve determinados dígitos substituídos por sublinhados. Por exemplo, a seguir é uma entrada possível:

3 6__2__4508

n será maior que 1. O número nunca será totalmente sublinhado. Você não tem garantia de que o primeiro dígito não seja um sublinhado. O primeiro dígito nunca será 0. n nunca será maior ou igual ao número de dígitos no número.

Resultado

Emita o número, com os dígitos substituídos por números inteiros, de modo que o número resultante seja divisível em cadeia por n . Se existir mais de uma maneira de completar o número divisível em cadeia, qualquer uma pode ser usada como saída. Se não houver números que possam concluí-lo, faça a saída no answer. Por exemplo, a saída da entrada de exemplo pode ser:

6132794508

Isso é código de golfe, então o código mais curto vence.


Presumo que, se nfor maior ou igual ao número de dígitos desse número, o número é divisível em cadeia?
John Dvorak

@Jan Dvorak n nunca será igual ou superior ao número de dígitos na entrada. Será sempre menor. Vou editar para refletir isso.
absinto

Somos obrigados a escrever um programa completo ou uma função é suficiente?
John Dvorak

@ Martin Sim. Preenchimento de limite de caracteres.
absinto

@ Jan Dvorak Um programa completo.
absinto

Respostas:


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

Resultado:

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

Explicação

  • A expansão do parâmetro ${2//_/{0..9\}}substitui todos os sublinhados por {0..9}.
  • A sequência resultante é evaled para expandir todas essas expressões de colchetes.
  • As grepervas daninhas eliminam todas as possibilidades onde há dígitos repetidos.
  • Em seguida, cada número restante é verificado, dígito por dígito, para as condições 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, mas curto. Basta comparar todas as permutações possíveis de dígitos N com o padrão fornecido e verificar todos os requisitos. Eu testei apenas com 7 ou 8 dígitos. Deve funcionar por 9 ou 10 também, mas levará um tempo.

Editar: eu adicionei a saída padrão ausente "sem resposta".


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

Esta é uma implementação muito ingênua. Conto o número de sublinhados e, em seguida, simplesmente crio uma lista de todas as permutações de dígitos desse comprimento, para força bruta em todas as combinações possíveis. Isso terá um desempenho horrível para um número maior de sublinhados, mas esse é o código golf e não o código mais rápido. :)

Edit: Portado isso do Mathematica. Veja o histórico de edições da versão original.

Editar: Corrigidos os principais casos de sublinhado.


Permutações não devem ser usadas em vez de Tuplas (com vista para a contagem de caracteres)?
21414

@DavidCarraher Why? Eu estaria perdendo muitas combinações por lá, não?
Martin Ender

Cada dígito no número deve ser exclusivo. Tuplesnão impõe essa restrição. Permutations, desde que não haja dígitos repetidos no conjunto de entrada. E você pode permutar apenas os dígitos que ainda não foram usados. (Embora, novamente, isso possa prolongar o seu código.) #
187

@DavidCarraher Ohhh, eu negligenciei o requisito de exclusividade. Preciso acrescentar isso ao loop interno, caso em que também devo ficar Tuplesporque é mais curto.
Martin Ender

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

Menos golfe, com explicações:

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);
        }
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.