Знайдіть найменше число, яке не ділить N


50

Це завдання досить проста , що це в основному все в назві: ви дали позитивне ціле число N і ви повинні повернути найменше позитивне ціле число , яке не є дільником N .

Приклад: дільники N = 24 є 1, 2, 3, 4, 6, 8, 12, 24. Найменше додатне ціле число, якого немає в цьому списку, становить 5 , тому саме такий результат має знайти ваше рішення.

Це послідовність OEIS A007978 .

Правила

Ви можете написати програму чи функцію та скористатися будь-яким із наших стандартних методів отримання вводу та надання виводу.

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

Це , тому найкоротший вірний відповідь - вимірюється в байтах - виграє.

Випробування

Першими 100 термінами є:

2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 
3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 
2, 3, 2, 4, 2, 3, 2, 3, 2, 7, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 
3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3

Зокрема, переконайтеся, що ваша відповідь працює для входів 1 і 2, і в цьому випадку результат більший, ніж вхідний.

І для деяких великих тестових випадків:

N          f(N)
1234567    2
12252240   19
232792560  23

Я перетворив зразок вихідного рядка у вектор чисел і зрозумів, що якщо відформатувати його 24 колонки впоперек, це буде надзвичайно повторюваним, за винятком непарного відхилення.
Carcigenicate

Це має сенс, 24 - 0 мод 2, 3 і 4, тому єдині відмінності полягатимуть у стовпцях, де числа> 4. Це ще більше повторюється на ширині 120.
КалькуляторFeline

Відповіді:


18

Mathematica, 19 байт (кодування UTF-8)

1//.x_/;x∣#:>x+1&

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

1                   Starting with 1,
 //.                apply the following rule until it stops mattering:
    x_                if you see a number x
      /;x∣#           such that x divides the function argument,
           :>x+1      replace it with x+1.
                &   Cool, that's a function.

Відредаговано, щоб додати: ngenisis вказує, що //.за замовчуванням буде повторюватися максимум 65536 разів. Таким чином, ця реалізація працює для всіх вхідних чисел, менших за найменше загальне кратне число цілих чисел від 1 до 65538 (зокрема, для всіх чисел, що мають щонайбільше 28436 цифр), але технічно не для всіх чисел. Можна замінити x//.yз , ReplaceRepeated[x,y,MaxIterations->∞]щоб виправити цей недолік, але , очевидно , за рахунок 34 додаткових байтів.


Дуже цікавий спосіб петлі без використання For, Whileі т.д.
ngenisis

5
Я дізнався це з цього сайту! Мені, безумовно, подобається дізнатися більше про Mathematica, будучи тут (чи можу я виправдати це на моєму розкладі ...?).
Грег Мартін

3
Це не схоже на математику O_o
Mama Fun Roll

2
не дозволяйте нестачу великих літер і дужок дурити вас;)
Грег Мартін


14

Pyth, 3 байти

f%Q

В основному, fциклічний код до тих пір, поки %QT( Q % Tде Tітераційна змінна) є істинним.

Спробуйте його онлайн тут.


2
Побачив проблему, зробив цю відповідь, прийшов сюди, щоб опублікувати її, знайшов свою. Молодці!
isaacg

Я написав це і відчув себе приголомшливо: .V1In%Qb0bBпобачив свою відповідь, і вже не відчуваю себе такою приголомшливою.
Джон Червоний

@JohnRed Lol, я думаю, що вам просто потрібно ознайомитись із вбудованими в Pyth.
busukxuan

14

JavaScript (ES6), 25 23 байт

f=(n,k)=>n%k?k:f(n,-~k)

Примітка. Тут є одне цікаве, що kпараметр ініціалізується ex nihilo на першій ітерації. Це працює тому, що n % undefinedє NaN(хибним, як очікувалося) і -~undefinedдорівнює 1. На наступних ітераціях, -~kпо суті, еквівалентний k+1.

Тест


Саме те, що я отримав. Я був би здивований, якщо можливо щось коротше
ETHproductions

@ETHproductions По-друге, існує коротша. :-)
Арнальд

5
Гм. Це ... е-е ... ух.
ETHproductions



11

R, 28 байт

Досить прямо, нічого фантазійного. Здійснює введення з stdin, з кроком значення, Tдоки iмодуль не Tбуде нульовим.

i=scan()
while(!i%%T)T=T+1
T

Якщо ви хочете чогось більш фантазійного, є 29 байтів :

i=scan()
match(0,!i%%1:(i+1))

Пояснили:

i=scan(): Читати iзі стдин.

1:(i+1): Створити всі цілі числа від 1до i+1( +1облік випадків 1і 2).

i%%1:(i+1) : Модулює введення кожного номера у нашому списку.

!i%%1:(i+1): Негатуйте отриманий список; це неявно перетворює його в логічний тип, такий, який 0є, FALSEі є ненульовим TRUE. Після заперечення TRUEзначення стають FALSEі навпаки. Тепер усі спочатку ненульові значення кодуються як FALSE.

match(0,!i%%1:(i+1)): Повертає індекс першої інстанції 0у нашому списку. 0є FALSE, тому це повертає індекс першого FALSEв списку, який є першим ненульовим значенням від операції модуля. Оскільки наш початковий список починався з 1, індекс дорівнює значенню найменшого не дільника.


Приємно, просто хотів запропонувати використовувати which.min, але потім я побачив редагування і, здається, matchробить подібну роботу.
JAD

2
Також приємний трюк із використанням T, врятуючи необхідність визначити його перед whileциклом.
JAD

@JarkoDubbeldam Дякую! Я не можу знайти спосіб, щоб векторизований підхід був коротшим, ніж whileпідхід, що чудово, оскільки це дуже інтенсивно пам’яті для великих Н. TТрюк - одна з тих частувань, яка чудово підходить для гольфу, але абсолютно жахлива для фактичного програмування. (І звичайно, ви можете також використовувати, Fколи вам потрібно 0.)
rturnbull

Ви можете зберегти два байти, використовуючи 0: i + 1 замість 1: (i + 1), хоча я не впевнений, як це грає з оператором %%.
antoine-sac

@ antoine-sac На жаль, %%має перевагу над тим +, тому паролі все ще потрібні: (0:i+1)з такою ж кількістю байтів, що і 1:(i+1). У мене фактично був перший, але змінив його на другий, оскільки його легше читати.
rturnbull

10

Haskell, 26 байт

f n=until((>0).mod n)(+1)1

Усі забувають until!


9

Брахілог , 10 байт

~{=#>:A'*}

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

Це вийшло дуже схожим на (але коротше, ніж) оригінальне рішення Fatalize. З тих пір Fatalize перейшов на інший алгоритм, який зв'язується з цим методом іншим методом, тому мені доведеться пояснювати це сам:

~{=#>:A'*}
~{       }    inverse of the following function:
  =           try possible values for the input, if it's unbound
   #>         the input is a positive integer
     :A'*     there is no A for which the input times A is the output

Коли ми інвертуємо функцію, замінюючи "введення" та "вихід", ми отримуємо досить розумний алгоритм (просто виражений незграбно): "спробуйте можливі додатні цілі числа в їх природному порядку (тобто 1 вгору), поки не знайдете той, який не може бути помножений ні на що для отримання вводу ". Брахілог не проводить обчислень з плаваючою комою, якщо всі входи не відомі, тому він буде враховувати лише ціле число А.


1
Ніколи не думав робити це, це акуратно!
Фаталізувати


8

КОРО, 174 байт

oomMOOMMMmoOmoOmoOMMMmOomOoMoOMMMmoOmoOmoOMMMmOoMOOmoO
MOomoOMoOmOoMOOmoOmoomoOMOOmOoMoOmoOMOomoomOomOoMOOmOo
moomoOMOomoomoOmoOMOOmOomOomOomOoOOMOOOMOomOOmoomOomOo
mOomOomOomoo

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

Цей код лише частково мій власний - він реалізує алгоритм модуля, який я переніс із brainfuck. Решта коду - моя власна. Однак, оскільки я не написав алгоритм модуля, я не по-справжньому дослідив, як він працює, і не можу документувати цю частину коду. Натомість я наведу свою звичайну розбивку з подальшим більш глибоким поясненням того, чому працює код.

Розбивка коду

oom                          ;Read input into [0].
MOO                          ;Loop while [0].  We never change [0], so the program only terminates forcibly after a print.
  MMMmoOmoOmoOMMMmOomOo      ; Copy [0] to [3] and navigate to [1].
  MoOMMMmoOmoOmoOMMM         ; Increment [1], and copy it to [4]
  mOo                        ; Navigate back to [3].
  MOO                        ; Modulus algorithm.  Direct port of brainfuck algorithm.
    moOMOomoOMoOmOo
    MOO
      moO
    moo
    moO
    MOO
      mOoMoOmoOMOo
    moo
    mOomOo
    MOO
      mOo
    moo
    moOMOo
  moo                        ; End modulus algorithm.
  moOmoO                     ; Navigate to [5].  This contains our modulus.
  MOO                        ; Only perform these operations if [5] is non-zero -- i.e. [0] % [1] != 0
    mOomOomOomOoOOMOOOMOomOO ;  Navigate to [1], print its contents, then error out.
  moo                        ; End condition
  mOomOomOomOomOo            ; Since we're still running, [0] % [1] == 0, so navigate back to [0] and try again.
moo                          ;End main loop.

Пояснення

Код спочатку зчитує ціле число в [0]. Кожна ітерація основного циклу (рядки 2 - 26) з кроком [1], потім копіює все необхідне в алгоритм модуля, який розбиває його результат на [5]. Якщо [5] містить якесь значення, то [1] - це число, яке нам потрібно надрукувати. Ми друкуємо його, а потім примусово закриваємо програму.

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

(0) moo -- Equivalent to ]
(1) mOo -- Equivalent to <
(2) moO -- Equivalent to >
(3) mOO -- No equivalent.  Evaluate current tape value as instruction from this list.
(4) Moo -- If tape is 0, equivalent to ,; if tape is non-zero, equivalent to .
(5) MOo -- Equivalent to -
(6) MoO -- Equivalent to +
(7) MOO -- Equivalent to [
(8) OOO -- No equivalent.  Set tape (positive or negative) to 0
(9) MMM -- No equivalent.  If register is empty, copy tape to register.  If register is non-empty, paste register to tape and clear register.
(10) OOM -- No equivalent.  Print an integer from tape to STDOUT
(11) oom -- No equivalent.  Read an integer from STDIN and store it on tape

Справжньою цікавою тут є інструкція 3 mOO,. Інтерпретатор зчитує поточне значення стрічки та виконує інструкцію на основі цього значення стрічки. Якщо значення менше 0, більше 11 або дорівнює 3, інтерпретатор припиняє програму. Ми можемо використовувати це як швидко-брудне вимушене завершення роботи основного циклу (і програми цілком), як тільки ми знайдемо нашого неділітеля. Все, що нам потрібно зробити, це надрукувати наш номер, очистити [1] (з OOO), зменшити його на -1 MOo, а потім виконати інструкцію -1, через mOOяку закінчується програма.

Сама стрічка для цієї програми функціонує так:

[0]  -- Read-in integer from STDIN.
[1]  -- Current divisor to test
[2]  -- Placeholder for modulus algorithm
[3]  -- Temporary copy of [0] for use for modulus algorithm
[4]  -- Temporary copy of [1] for use for modulus algorithm
[5]  -- Placeholder for modulus algorithm.  Location of remainder at end of loop.
[6]  -- Placeholder for modulus algorithm
[7]  -- Placeholder for modulus algorithm

Алгоритм модуля природно очищає [2], [3], [6] та [7] наприкінці операції. Вміст [4] перезаписується реєстровою пастою в рядку 4, а [5] дорівнює нулю, коли [0] ділиться на [1], тому нам не потрібно його очищати. Якщо [5] не дорівнює нулю, ми змушуємо вийти з лінії 23, тому нам не доведеться турбуватися про це.



7

Желе , 5 байт

1%@#Ḣ

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

Пояснення:

1%@#Ḣ
1  #      Find the first … numbers, counting up from 1, such that
 %@       dividing those numbers into … gives a truthy remainder
    Ḣ     then return the first

Це жахливе зловживання #; Операторів у цій програмі безліч, але тонна відсутніх операндів. #дійсно хоче, 1щоб це було явно надано з якихось причин (інакше він намагається за замовчуванням ввести); проте все інше, що не вказано в програмі, за замовчуванням вводить програму. (Так, наприклад, якщо ви вводите 24 як вхід, ця програма знаходить перші 24 числа, які не ділять 24, потім повертає перше; вид марнотратний, але він працює.)


Чорт ти, желе! Піт сьогодні б’є тебе! : D
Джон Ред

Тільки ASCII:2%@1#
Ерік Атголфер

7

C, 32 35 байт

i;f(x){for(i=1;x%++i<1;);return i;}

Редагувати: додано i=1в циклі

Використання

main(c,v)char**v;{printf("%d",f(atoi(*++v)));}

Повна версія програми, 64 байти:

main(c,v)char**v;{*++v;for(c=1;atoi(*v)%++c<1;);printf("%d",c);}

6

C #, 39 37 байт

n=>{int i=0;while(n%++i<1);return i;}

Збережено два байти завдяки Мартіну!


Мені подобається, поки (! (N% ++ i)); краще, але, звичайно, це код гольфу, а 1 байт - 1 байт.
Джон Гамільтон

Це працює? Я не знав, що 0 оцінюється як помилковий автоматично
Alfie Goodacre

Ах, я спробував це в C ++, так, це не працює з C #.
Джон Гамільтон

6

Perl, 19 байт

18 байт коду + -pпрапор.

$_=$_%++$.?$.:redo

Щоб запустити його:

perl -pE '$_=$_%++$.?$.:redo' <<< 12252240

Не дуже детальні пояснення:
- $.це спеціальна змінна, значенням якої за замовчуванням є поточний номер рядка останнього доступу до файлу (тут stdin), тому після прочитання першого рядка введення він встановлюється на 1.
- $_тримає введення та друкується неявно наприкінці (завдяки -pпрапору).
- redo(у цьому контексті) вважає, що програма перебуває в циклі і повторює поточну ітерацію (тільки $.буде іншою, оскільки вона зростала).
- Отже, якщо ми знайшли найменше число (збережене в $.), яке не ділиться $_, то встановимо $_його, інакше спробуємо наступне число (завдяки redo).


6

Октава / MATLAB, 26 24 байти

@(n)find(mod(n,1:n+1),1)

find(...,1)повертає індекс ( 1-оснований) першого ненульового елемента вектора в першому аргументі. Перший аргумент - [n mod 1, n mod 2, n mod 3, n mod 4,...,n mod (n+1)]це означає, що нам потрібно додати +1до індексу, оскільки ми починаємо тестувати в 1. Дякую @Giuseppe за -2 байти.

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


@(n)find(mod(n,1:n+1),1)коротше, чи не так?
Джузеппе

це справді, дякую!
недолік

5

Желе , 6 байт

%R;‘TḢ

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

Пояснення:

                                               Assume 24 is our N
 R      Generate all numbers from 1 to N         [1, 2, 3, 4 .., 24]
  ;‘    Attach N+1 to that list (for cases 1,2)  [1, 2, 3, 4 .., 25]
%       And modulo-divide our input by it
        Yields a list with the remainder         [0, 0, 0, 0, 4 ...]
    T   Return all thruthy indexes               [5, 7, ...]
     Ḣ  Takes the first element of that list -->  5

Я не знаю Jelly, але чи можете ви зберегти байт, збільшивши N, перш ніж генерувати діапазон?
Емінья

@Emigna Я не знаю також Jelly;) Я не розумію, як: збільшення його раніше також робить модульний тест на N + 1 або збільшує залишки [1, 1, 1, 1, 5, ...].
steenbergh

А, бачу. Я подумав, що можна зробити діапазон N% (1, N + 1), але якщо це збільшить N в обох випадках, це не добре.
Емінья

5

Perl 6 , 17 байт

{first $_%*,1..*}

Спробуй це

Розширено:

{  # bare block lambda with implicit parameter 「$_」

  # return the first value
  first

  # where the block's argument 「$_」 modulus the current value 「*」
  # doesn't return 0 ( WhateverCode lambda )
  $_ % *,
  # ( 「$_ !%% *」 would be the right way to write it )

  # from 1 to Whatever
  1 .. *
}

5

05AB1E , 6 байт

ÌL¹ÑK¬

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

Крім того, в ньому написано "СПІЛКУЙТЕ!" ... Щось ...

ÌL     # Push [1..n+2]
  ¹Ñ   # Push divisors of n.
    K¬ # Push a without characters of b, and take first item.

@Zgarb пропустив цю частину, початковий приріст на 2 виправляє проблему.
Чарівний восьминога Урна

1
Приємно! Я завжди забуваю, що 05ab1e має функцію дільника :)
Emigna


4

Python 2.7.9, 32 байти

f=lambda n,d=1:n%d>0or-~f(n,d+1)

Тест на Ideone

Рекурсивно підраховує потенційних недільників d. Рекурсивно збільшувати результат, ніж результат d. Зсув 1досягається булевим числом True, яке дорівнює 1, але оскільки d==1це завжди дільник, вихід завжди перетворюється на число.

Python 2.7.9 використовується для дозволу 0or. Версії, що починаються з 2.7.10, спробують проаналізувати 0orяк початок восьмеричного числа та подати синтаксичну помилку. Дивіться це на Ideone .


3

Власне , 7 байт

;÷@uR-m

Спробуйте в Інтернеті! (зверніть увагу: це дуже повільне рішення, і це займе багато часу для великих тестових випадків)

Пояснення:

;÷@uR-m
;÷       duplicate N, divisors
  @uR    range(1, N+2)
     -   set difference (values in [1, N+1] that are not divisors of N)
      m  minimum

3

Хаскелл , 29 байт

f n=[k|k<-[2..],mod n k>0]!!0

Вираз [k|k<-[2..]]просто створює нескінченний список [2,3,4,5,...]. З умовою mod n k>0ми допускаємо лише тих, хто kв списку, які не діляться n. Додавання !!0просто повертає перший запис (запис в індексі 0) форми цього списку.

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


3

Діалог APL , 8 байт

1⍳⍨0≠⍳|⊢

1⍳⍨ позиція першого True в

0≠ ненульові значення

⍳|поділ, що залишився 1 ... N при поділі на

N

СпробуйтеAPL онлайн!

Примітка: це працює для 1 і 2, оскільки 1⍳⍨повертає 1 + довжину його аргументу, якщо жоден не знайдений.


3

Джулія, 28 байт

N->findfirst(x->N%x>0,1:N+2)

Примітка: оскільки 1:N+2не виділяє пам'ять, немає проблем із пам'яттю для великих Ns
- @flawr, N+2збережіть для мене кілька байт
- пропозиція @Martin зберегла 1 байт


3

QBIC , 14 байт

:[a+1|~a%b|_Xb

Пояснення:

:      Read the first cmd line param as a number, called 'a'
[a+1|  FOR (b=1 ; b <= a+1; b++) <-- a+1 for cases a = 1 or 2
~a%b   IF A modulo B ( == 0, implicit)
|_Xb   THEN exit the program, printing b
       [IF and FOR implicitly closed by QBIC]

3

PHP, 30 байт

for(;$argv[1]%++$i<1;);echo$i;

якщо запустити з консолі з -rопцією (thx до @ ais523)

php -r 'for(;$argv[1]%++$i<1;);echo$i;' 232792560

32 байти

<?for(;$argv[1]%++$i<1;);echo$i;

завдяки @manatwork за видалення 1 байта

33 байти (оригінал)

<?for(;$argv[1]%++$i==0;);echo$i;

3
IIRC, <?це не повинно бути частиною вашого байта (тому що PHP має режим командного рядка, який цього не вимагає).

3
Стара хитрість: порівняйте проти <1замість ==0.
манантська робота

Данг. Я дістався до for(;!($argv[1]%$i);$i++);echo$i;. Ваше - це природна еволюція мого. Це моє підсумки!
Ісмаїл Мігель

3

Cubix , 14 12 байт

I2/L/);?%<@O

Збережено 2 байти завдяки MickyT.

Спробуй це

Пояснення

У формі куба код:

    I 2
    / L
/ ) ; ? % < @ O
. . . . . . . .
    . .
    . .

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


I2/L/);?%<@Oна пару байт менше. Той самий загальний процес, просто інший шлях
MickyT


2

Медузи , 12 10 байт

p\~~|1
 >i

Приймає вхід з STDIN і виводить на STDOUT. Спробуйте в Інтернеті!

Мартін Ендер врятував 2 байти, дякую!

Пояснення

 \~~|
 >i

Ця частина є однією з функцій, яка використовує вхідне значення у своєму визначенні.

   ~|

Цьому ~-cell надається функція, тому він перевертає свої аргументи: він виробляє двійкову функцію "лівий аргумент modulo ( |) правий аргумент". Вбудована функція модуля у медуз приймає свої аргументи у зворотному порядку.

  ~~|
  i

Цьому ~-елементу присвоюється значення та функція, тому він виконує часткове застосування: він виробляє двійкову функцію " iаргумент вводу ( ) модуля право". Назвемо цю функцію f .

 \~~|
 >i

\-Клітинами дається дві функції, так що це робить ітерацію: вона виробляє унарна функцію «прирощення ( >) до тих пір , функція F не застосовуються до попередніх і поточних значень дає результат truthy (нульове), а потім повертати поточне значення». Це означає, що аргумент збільшується, поки він не розділить вхідні дані.

p\~~|1
 >i

Нарешті, ми застосовуємо цю функцію до початкового значення 1та друкуємо результат за допомогою p.

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