Найдите наименьшее число, которое не делит 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 mod 2, 3 и 4, поэтому единственные различия будут в столбцах, где числа> 4. Это еще более повторяющийся на ширине 120.
CalculatorFeline

Ответы:

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
Это не похоже на mathematica O_o
Mama Fun Roll
2
не позволяйте отсутствию заглавных букв и скобок обмануть вас;)
Грег Мартин
14

Pyth, 3 байта

f%Q

По сути, fциклы кода до %QT( Q % Tгде Tпеременная итерации) истина.

Попробуйте это онлайн здесь.

busukxuan
источник
2
Увидел проблему, сделал этот ответ, пришел сюда, чтобы опубликовать его, нашел ваш. Отлично сработано!
Исаак
Я написал это и почувствовал себя потрясающе: .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.

Контрольная работа

Arnauld
источник
Именно то, что я получил. Я был бы удивлен, если что-нибудь более короткое возможно
ETHproductions
@ETHproductions Если подумать, есть более короткая. :-)
Arnauld
5
Um. Это ... э-э ... вау.
ETHproductions
13

Python, 43 36 35 байт

f=lambda n,d=2:d*(n%d>0)or f(n,d+1)
orlp
источник
11

R, 28 байт

Довольно просто, ничего особенного. Принимает ввод из стандартного ввода, увеличивает значение 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в нашем списке. 0is FALSE, так что это возвращает индекс первого FALSEв списке, который является первым ненулевым значением из операции по модулю. Поскольку наш первоначальный список начинался с 1, индекс равен значению наименьшего неделителя.

rturnbull
источник
Хорошо, просто хотел предложить использовать which.min, но потом я увидел редактирование, и, похоже, matchвыполняет аналогичную работу.
JAD
2
Также неплохо использовать трюк T, избавляя от необходимости определять его перед whileциклом.
JAD
@JarkoDubbeldam Спасибо! Я не могу найти способ, чтобы векторизованный подход был короче, чем whileподход, и это хорошо, так как он требует большого объема памяти для больших N. TУловка - это одно из тех удовольствий, которое отлично подходит для игры в гольф, но абсолютно ужасно для реального программирования. (И, конечно, вы можете использовать его, Fкогда вам нужно 0.)
rturnbull
Вы можете сохранить два байта, используя 0: i + 1 вместо 1: (i + 1), хотя я не уверен, как он работает с оператором %%.
asac - Восстановить Монику
@ antoine-sac К сожалению, %%приоритет имеет приоритет +, поэтому по-прежнему необходимы символы Paren : (0:i+1)с тем же числом байтов, что и 1:(i+1). Первоначально у меня был первый, но я сменил его на второй, так как его легче читать.
rturnbull
10

Haskell, 26 байтов

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

Все забывают о until!

XNOR
источник
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 вверх), пока не найдете тот, который не может быть умножен на что-либо, чтобы произвести ввод ". Brachylog не выполняет вычисления с плавающей точкой, если не известны все входные данные, поэтому он будет учитывать только целое число A.


источник
1
Никогда не думал об этом, это здорово!
фатализировать
8

COW, 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

05AB1E , 7 байтов

Xµ¹NÖ_½

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

объяснение

Xµ       # run until counter is 1
  ¹      # push input
   N     # push iteration counter
    Ö_   # push input % iteration counter != 0
      ½  # if true, increase counter
         # output last iteration
Emigna
источник
Хорошо, мне было интересно, как вы будете делать это итеративно в 05AB1E.
Волшебная Осьминог Урна
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;}

Сохранено два байта благодаря Мартину!

Альфи Гудэйкр
источник
Мне нравится while (! (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 байта.

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

flawr
источник
@(n)find(mod(n,1:n+1),1)короче, не так ли?
Джузеппе
это действительно, спасибо!
flawr
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
steenbergh
источник
Я не знаю Jelly, но не могли бы вы сохранить байт, увеличив N до того, как сгенерировать диапазон?
Emigna
@Emigna Я тоже не знаю Jelly;) Я не вижу, как: увеличение его ранее также делает тест по модулю для N + 1 или увеличивает остатки [1, 1, 1, 1, 5, ...].
Стинберг
Ах я вижу. Я думал, что возможно сделать диапазон N% (1, N + 1), но если он увеличивает N в обоих случаях, это не хорошо.
Emigna
5

Perl 6 , 17 байт

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

Попробуй

Expanded:

{  # 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 .. *
}
Брэд Гилберт b2gills
источник
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)

Тест на идеоне

Рекурсивно подсчитывает потенциальные неделители d. Короче рекурсивно увеличивать результат, чем выводить d. Смещение от 1достигается булевым значением True, равным 1, но, поскольку d==1оно всегда является делителем, выходные данные всегда преобразуются в число.

Python 2.7.9 используется, чтобы разрешить 0or. Версии, начинающиеся с 2.7.10, будут пытаться проанализировать 0orкак начало восьмеричного числа и получить синтаксическую ошибку. Смотрите это на Ideone .

XNOR
источник
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

Haskell , 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) из этого списка.

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

flawr
источник
3

Dyalog APL , 8 байт

1⍳⍨0≠⍳|⊢

1⍳⍨ Положение первого Правда в

0≠ ненулевые значения

⍳|остатки деления 1 ... N при делении на

N

Попробуй APL онлайн!

Примечание: это работает для 1 и 2, потому что 1⍳⍨возвращает 1 + длину его аргумента, если ничего не найдено.

Адам
источник
3

джулия, 28 байт

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

Примечание: так 1:N+2как не выделяет память, проблем Nс памятью для большого s
- @flawr нет, N+2за исключением нескольких байтов
- предложение @Martin сохранило 1 байт

rahnema1
источник
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]
steenbergh
источник
3

PHP, 30 байт

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

если запустить из консоли с -rопцией (thx to @ 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.
manatwork
Dang. Я достиг к 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

Эта часть является одной функцией, которая использует входное значение в своем определении.

   ~|

Эта ~-клетка получает функцию, поэтому она переворачивает свои аргументы: она создает двоичную функцию «левый аргумент, modulo ( |) правый аргумент». Встроенная функция по модулю в Jellyfish принимает аргументы в обратном порядке.

  ~~|
  i

Эта ~-клетка получает значение и функцию, поэтому она выполняет частичное применение: она создает двоичную функцию "input ( i) по модулю правого аргумента". Давайте назовем эту функцию f .

 \~~|
 >i

Для \-cell даны две функции, поэтому она выполняет итерацию: она генерирует унарную функцию «increment ( >) до тех пор, пока функция f, примененная к предыдущим и текущим значениям, не даст верный (ненулевой) результат, а затем вернет текущее значение». Это означает, что аргумент увеличивается до тех пор, пока он не разделит входные данные.

p\~~|1
 >i

Наконец, мы применяем эту функцию к начальному значению 1и выводим результат с помощью p.

Zgarb
источник