Числа на цепочке


15

Можно показать, что некоторые положительные целые имеют свойство делимости Цепи. Чтобы число делилось на  n , оно должно удовлетворять трем требованиям:

  1. Каждая цифра делит число, образованное n  цифрами, которые следуют за ней.

    Например, число 7143 делится на 2 на цепочку, потому что 7 делит 14, а 1 делит на 43. Оно не делится на 3 на цепочку, потому что 7 не делит 143.

  2. Каждая подпоследовательность, принятая во внимание для делимости, не должна иметь ведущих нулей.

    Например, число 14208 не делится на 2, потому что 08 имеет начальный ноль. Однако он делится на цепочку на 3, потому что 208 не имеет ведущего нуля.

  3. Все цифры в номере должны быть уникальными.

Например, число 14280 делится на цепи на 2, 3 и 4. Если мое объяснение делимости цепи неясно, пожалуйста, задавайте вопросы в комментариях.

вход

Входные данные для программы состоят из единственного целого числа n, за которым следует пробел, а затем число, в котором определенные цифры заменены символами подчеркивания. Например, следующее является возможным вводом:

3 6__2__4508

n будет больше 1. Число никогда не будет полностью подчеркивать. Вам не гарантируется, что первая цифра не является подчеркиванием. Первая цифра никогда не будет 0. n никогда не будет больше или равна количеству цифр в числе.

Выход

Выведите число с заменой цифр на целые числа, чтобы полученное число делилось на цепочку на n . Если существует более одного способа завершения числа, кратного цепочке, любой из них может использоваться в качестве выходного. Если нет чисел, которые могут его завершить, выведите no answer. Например, выходные данные примера ввода могут быть:

6132794508

Это код гольф, поэтому выигрывает самый короткий код.


Я предполагаю, что если число nбольше или равно количеству цифр в этом числе, число делится на цепочку?
Джон Дворжак

@Jan Dvorak n никогда не будет больше или равно количеству цифр на входе. Это всегда будет меньше. Я отредактирую, чтобы отразить это.
Абсент

Нужно ли нам писать полную программу или функции достаточно?
Джон Дворжак

@ Мартин Да. Заполнение символов.
Абсент

@Jan Dvorak Полная программа.
Абсент

Ответы:


5

Bash + coreutils, 197 байт

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

Выход:

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

объяснение

  • Расширение параметра ${2//_/{0..9\}}заменяет все подчеркивания на {0..9}.
  • Результирующая строка evaled для расширения всех этих выражений в скобках.
  • grepОтсеивает все возможности там , где Есть любые повторяющиеся цифры.
  • Затем каждый оставшийся номер проверяется, цифра за цифрой для условий 1 и 2.

2

Питон - 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'

Медленно, но коротко. Просто сравните каждую возможную перестановку цифр N с данным шаблоном и проверьте все требования. Я проверял это только с 7 или 8 цифрами. Должен работать на 9 или 10, но займет довольно много времени.

Изменить: я добавил отсутствующий вывод по умолчанию "нет ответа".


2

Mathematica Ruby, 349 224 229 байт

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

Это очень наивная реализация. Я считаю количество подчеркиваний, а затем просто создаю список всех цифр-перестановок этой длины, чтобы перебрать все возможные комбинации. Это будет работать ужасно для большего количества подчеркиваний, но это код гольф, а не код самого быстрого кода. :)

Редактировать: перенес это из Mathematica. Смотрите историю изменений для оригинальной версии.

Редактировать: Исправлены ведущие подчеркивания.


Разве нельзя использовать перестановки вместо кортежей (с пропуском количества символов)?
DavidC

@DavidCarraher Почему? Я бы пропустил там много комбинаций, не так ли?
Мартин Эндер

Каждая цифра в номере должна быть уникальной. Tuplesне навязывает это ограничение. Permutationsбудет, при условии, что во входном наборе нет повторяющихся цифр. И вы можете переставлять только цифры, которые еще не были использованы. (Хотя, опять же, это может удлинить ваш код.)
DavidC

@DavidCarraher Оооо, я пропустил требование уникальности. Мне нужно добавить это во внутренний цикл, и в этом случае я мог бы также придерживаться, Tuplesпотому что он короче.
Мартин Эндер

@DavidCarraher исправлено.
Мартин Эндер

1

Ява, 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);}}}

Менее гольф, с объяснением:

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);
        }
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.