Числа на ланцюжку


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 ніколи не буде дорівнює чи більшої кількості цифр у введеному повідомленні. Це завжди буде менше. Я редагую, щоб це відобразити.
абсент

Нам потрібно написати повну програму, чи функцій вистачає?
Джон Дворак

@Martin Так. Обмеження обмежень символів.
абсент

@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} .
  • Отриманий рядок є eval редагується, щоб розширити всі ці вирази дужок.
  • The 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. Перегляньте історію редагування оригінальної версії.

Редагувати: виправлені основні випадки підкреслення.


Чи не слід використовувати перестановки замість Tuples (з видом на кількість символів)?
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.