Тест на нерозбірливість на подільність


14

Ваше завдання - написати програму або функцію, яка визначає, чи ділиться число на інше. Проблема полягає в тому, що вона повинна дати відповідь якнайшвидше , навіть якщо не всі цифри дано.

Ваша програма повинна взяти ціле число D ≥ 2, а потім ряд цифр як вхід. Вони представляють цифри іншого цілого числа N ≥ 1, починаючи з найменш значущої цифри. На першому етапі, що N або повинен, або не повинен бути розділеним на D , ваша програма повинна вивести відповідну відповідь і вийти. Якщо кінець введення буде досягнуто, то слід виводити повний N ділиться на D .

Ось перелік прийнятних вхідних форматів для N (залиште коментар, якщо ви вважаєте, що щось, що не включено, повинно бути дозволено):

  • Стандартне введення : цифри наводяться в окремих рядках; кінець введення - EOF або спеціальне значення; Вихід означає, що функція повертається або програма закінчується.

  • Аналоговий ввід : наприклад, натискання клавіш або десять кнопок, що представляють кожну цифру; кінець введення - це особливе значення; Вихід означає, що функція повертається або програма закінчується.

  • Функція з глобальним станом : викликається повторно з послідовними цифрами; кінець введення - це особливе значення; вихід означає, що функція повертає ненулеве значення. Зауважте, що якщо ви використовуєте глобальний стан, його потрібно очистити після повернення значення або скидання іншим способом , щоб функція працювала кілька разів .

  • Закрита функція : повертає або іншу функцію для виклику із наступною цифрою, або значенням; кінець введення - це спеціальне значення або виклик функції без аргументу; вихід означає, що функція повертає відповідь, а не іншу функцію.

  • Підказка GUI або подібне : відображається повторно; кінець введення - "скасувати" або еквівалент, або спеціальне значення; exit означає, що запити припиняють відображатися.

  • Функція ітератора : введення - це об'єктивний стан або функція, яка повертає наступну цифру при виклику, кінець введення - виняток або спеціальне значення; Вихід означає, що ітератор перестає викликатися.

Введення для D та вихід можна за допомогою будь-якого прийнятного стандартного методу .

Тестові приклади:

2;   6               => true
5;   6               => false
20;  0 3             => false
20;  0 4             => true
100; 1               => false
100; 0 0             => true
100; 0 2             => false
4;   2 4             => false
4;   2 5             => true
4;   2 [eof]         => false
4;   4 [eof]         => true
625; 5 5             => false
625; 5 7 2           => false
625; 5 7 3 6         => false
625; 5 7 3 4         => true
7;   9 3 4 [eof]     => false
7;   9 3 4 5 [eof]   => true
140; 0 3             => false
140; 0 4 5 [eof]     => false
140; 0 4 5 1 [eof]   => true
14;  4 5 1 4 [eof]   => false
14;  4 5 1 4 1 [eof] => true

Я думаю, ми повинні припустити, що одна цифра буде надаватися щоразу, коли наше рішення вимагає введення, правда? І це має бути повноцінна програма, оскільки це об'єктивний спосіб забезпечити, щоб введення було задано цифрою в цифрі, ні? (У виклику сказано: "програма чи функція", хм ...)
Ерік Вихідник

1
@EriktheOutgolfer Формат введення докладно пояснюється в маркованому списку питання.
Дверна ручка

1
Я просто думав про те, наскільки об'єктивними можуть бути ці формати ... Я думаю, що я просто кину з випивки і почну насправді вирішувати це . :-)
Ерік Аутгольфер

1
Щось поганого в тому, щоб просто взяти список як digitsвхід із спеціальним значенням для EOF?
Джонатан Аллан

1
@EriktheOutgolfer немає, якщо є значення EOF, якщо я щось неправильно зрозумів. Для прикладу припустимо, що вся цінність 132 і потенційний дільник 4 , то []і [2]повернення нічого, крім falseабо true( в тому числі і самої функції і т.д. ...) в той час як [2,3], [2,3,1]і [2,3,1,EOF]повернення true. Це вражає мене якнайбільш близьким до глобального державного варіанту.
Джонатан Аллан

Відповіді:


9

JavaScript (ES6), 70 байт

Формат введення: функція Curried

-101 (правда), або сама (без відповіді).

p=>(q='',g=(d,t=k=z=!~d||(q=d+q,p))=>k--?g(d,t-=(k+q)%p<1):t?t-z&&g:1)

Спробуйте в Інтернеті!

Як?

pqн0к<p

(1)к×10н+q(модp)

хpм10к<pх=мp+к , що призводить до:

х×10н+q(модp)=(мp+к)×10н+q(модp)=(мp×10н(модp))+(к×10н+q(модp))(модp)=0+(к×10н+q(модp))(модp)=к×10н+q(модp)

(1)00к<p0кp

(1)00к<p

(1)q

Прокоментував

p => (                       // p = divisor
  q = '',                    // q = dividend stored as a string, initially empty
  g = (                      // g() = curried function taking:
    d,                       //   d = next digit
    t =                      //   t = number of iterations yielding a non-zero value
    k =                      //   k = total number of iterations to process
    z =                      //   z = copy of k
      !~d ||                 //   if d == -1 (meaning EOF), use only 1 iteration
                             //   so that we simply test the current value of q
      (q = d + q, p)         //   otherwise, prepend d to q and use p iterations
  ) =>                       //
    k-- ?                    //   decrement k; if it was not equal to zero:
      g(                     //     do a recursive call to g():
        d,                   //       pass the current value of d (will be ignored anyway)
        t -= (k + q) % p < 1 //       test (k + q) % p and update t accordingly
      )                      //     end of recursive call
    :                        //   else:
      t ?                    //     if t is greater than 0:
        t - z && g           //       return 0 if t == z, or g otherwise
      :                      //     else:
        1                    //       return 1
)                            //

2

Пакет, 177 169 байт

@set n=
@set g=1
:l
@set/ps=
@if %s%==- goto g
@set n=%s%%n%
@set/ae=%1/g,g*=2-e%%2,g*=1+4*!(e%%5),r=n%%g
@if %g% neq %1 if %r%==0 goto l
:g
@cmd/cset/a!(n%%%1)

Приймає dяк параметр командного рядка і зчитує цифри nв окремих рядках -як маркер EOF. Виходи 1для ділених, 0якщо ні. Пояснення:

@set n=

Ініціалізація nдо порожнього рядка.

@set g=1

g є gcd(d, 10**len(n))

:l

Почніть цикл читання цифр.

@set/ps=

Прочитайте наступну цифру.

@if %s%==- goto g

Зупиніть обробку на EOF.

@set n=%s%%n%

Додайте наступну цифру до n.

@set/ae=%1/g,g*=2-e%%2,g*=1+4*!(e%%5),r=n%%g

Оновіть gтепер, що len(n)збільшилось, і обчисліть n%g.

@if %g% neq %1 if %r%==0 goto l

Якщо rне дорівнює нулю, то dнапевно не ділиться n, оскільки g, фактор d, не. Якщо rдорівнює нулю, то ми знаємо лише, чи dділиться, nякщо gдорівнює d, тож якщо це не так, продовжуйте цикл.

:g

Вирвіться з циклу читання цифр тут, на EOF.

@cmd/cset/a!(n%%%1)

Обчислити та неявно вивести результат.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.