找出不除N的最小数


50

这个挑战很简单,基本上就是标题中的所有内容:给您一个正整数N,并且应该返回最小的正整数,该整数不是N的因数。

一个例子:的约数N = 241, 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

特别是,请确保您的答案适用于输入12,在这种情况下,结果将大于输入。

对于一些较大的测试用例:

N          f(N)
1234567    2
12252240   19
232792560  23

我将示例输出字符串转换为数字向量,并意识到,如果将其格式化为24列,则除了奇数偏差之外,它都是非常重复的。
Carcigenicate's

这是有道理的,24是0 mod 2、3和4,所以唯一的区别是数字> 4的列。在宽度120处甚至更重复
CalculatorFeline

Answers:


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//.yReplaceRepeated[x,y,MaxIterations->∞]在另外的34个字节的成本来修复这个缺陷,但很明显。


非常有趣的方式来循环不使用ForWhile等等
ngenisis

5
我是从这个网站学到的!到这里来,我绝对很乐意学习更多有关Mathematica的信息(我可以在我的时间表中证明这一点吗??)。
格雷格·马丁

3
看起来不像mathematica O_o
Mama Fun Roll

2
不要让大写字母和方括号的缺乏变得愚蠢;)
Greg Martin


14

Pyth,3个字节

f%Q

基本上,f循环执行代码,直到%QTQ % Twhere T迭代变量)为true 为止。

在这里在线尝试。


2
看到了问题,做出了答案,来到这里发布,找到了你的问题。做得好!
isaacg

我写了这篇文章,对自己感到很敬畏:.V1In%Qb0bB看到您的回答,再也感觉不到如此出色。
约翰·雷德

@JohnRed Lol,我想您只需要熟悉Pyth的内置功能。
busukxuan

14

JavaScript(ES6),25 23字节

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

注意:这里有趣的是,k参数是在第一次迭代时从nihilo初始化的。这是有效的,因为n % undefinedis NaN(按预期是虚假的)和-~undefinedequals 1。在下一次迭代中,-~k基本上等于k+1

测试


正是我所得到的。如果更短的话,我会感到惊讶
ETHproductions'Jan

@ETHproductions第二个想法是一个简短的想法。:-)
Arnauld

5
嗯 那是...呃...哇
ETHproductions

13

Python,43 36 35字节

f=lambda n,d=2:d*(n%d>0)or f(n,d+1)


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从stdin中读取。

1:(i+1):从生成的所有整数1i+1(该+1占的案件12)。

i%%1:(i+1) :根据列表中的每个数字对输入进行模数化。

!i%%1:(i+1):否定结果列表;这会将其隐式转换为逻辑类型,例如0is FALSE和nonzero is TRUE。取反后,TRUE值变成FALSE,反之亦然。现在,所有原始非零值都编码为FALSE

match(0,!i%%1:(i+1)):返回0列表中第一个实例的索引。0FALSE,因此它返回FALSE列表中第一个的索引,它是取模操作的第一个非零值。由于我们的原始列表开始于1,因此索引等于最小非除数的值。


很好,只是想建议使用which.min,但是随后我看到了编辑,并且似乎match做了类似的工作。
JAD

2
另外,使用技巧很不错T,无需在while循环之前定义它。
JAD

@JarkoDubbeldam谢谢!我找不到矢量化方法比矢量化方法更短的while方法,这很好,因为它对于大型N来说占用大量内存。T技巧是其中一种,对高尔夫球运动非常有用,但对于实际编程而言绝对是可怕的。(当然,您也可以F在需要时使用0。)
rturnbull

您可以使用0:i + 1而不是1:(i + 1)来保存两个字节,尽管我不确定它如何与%%运算符一起播放。
antoine-ac

@ antoine-sac不幸的是,%%它优先于+,因此仍然需要parens:,其(0:i+1)字节数与相同1:(i+1)。我实际上原本是前者,但由于它更易于阅读而将其更改为后者。
rturnbull

10

Haskell,26个字节

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

大家都忘了until


9

Brachylog,10个字节

~{=#>:A'*}

在线尝试!

这个结果与Fatalize的原始解决方案非常相似(但比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是一个疯子派生类,它的功能与疯子的操作相对类似-无限条带,您可以向左或向右移动,增大或减小以及“循环”,而当前磁带值为非零。除了动脑筋,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行上的寄存器粘贴覆盖,并且当[0]被[1]整除时,[5]为零,因此我们不必清除它。如果[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

很好,我想知道您将如何在05AB1E中迭代执行此操作。
Magic Octopus Urn'1

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
John Red

仅限ASCII:2%@1#
Erik the Outgolfer

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

Perl,19个字节

18个字节的代码+ -p标志。

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

要运行它:

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

不是很详细的解释:
- $.是一个特殊的变量,其默认值为访问(标准输入这里),所以读取输入的第一行后,它被设置为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

@Emigna我也不知道Jelly;)我也不知道如何:提前增加它也会对N + 1进行模测试,或者增加余数[1, 1, 1, 1, 5, ...]
steenbergh

知道了 我以为可以做N%range(1,N + 1),但是如果在两种情况下都增加N,那是不好的。
Emigna

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¬

在线尝试!

而且,它的拼写是“ LINK!”。

Ì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

5

果冻,5个字节

‘ḍ€i0

在线尝试!

这个怎么运作

‘ḍ€i0  Main link. Argument: n

‘      Increment; yield n+1.
 ḍ€    Divisible each; test 1, ..., n+1 for divisibility by n.
   i0  Find the first index of 0.

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用于允许allow 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

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仅返回该列表的第一个条目(index处的条目0)。

在线尝试!


3

Dyalog APL,8 字节

1⍳⍨0≠⍳|⊢

1⍳⍨ 第一个True在的位置

0≠ 的非零值

⍳|除以1 ... 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
manatwork

ang 我到达了for(;!($argv[1]%$i);$i++);echo$i;。您的是我的自然进化。这是我的投票!
Ismael Miguel

3

Cubix14 12字节

I2/L/);?%<@O

多亏了MickyT,节省了2个字节。

试试吧

说明

在多维数据集形式中,代码为:

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

基本上,这只是输入并启动一个计数器。然后,它检查计数器的每个连续值,直到找到不是输入因素的一个。


I2/L/);?%<@O少几个字节。相同的一般过程,只是路径不同
MickyT

2

> <>,15 +3 = 18字节

1\n;
?\1+:{:}$%

预计输入将在程序启动时进入堆栈,因此该-v标志的+3字节。在线尝试!


2

水母12 10字节

p\~~|1
 >i

从STDIN接收输入,然后输出到STDOUT。 在线尝试!

Martin Ender保存了2个字节,谢谢!

说明

 \~~|
 >i

这部分是在其定义中使用输入值的函数。

   ~|

这个~-cell有一个函数,因此它翻转其自变量:它产生二进制函数“ left parameter modulo(|)right arguments”。水母中的内置模函数以相反的顺序接受其参数。

  ~~|
  i

这个~-cell有一个值和一个函数,因此它可以部分应用:它产生二进制函数“ input(i)模右参数”。我们将该函数称为f

 \~~|
 >i

\β细胞被给予两种功能,所以它的迭代:它产生的一元函数“增量(>),直到函数˚F施加到先前值和当前值给出了一个truthy(非零)的结果,则返回电流值”。这意味着该参数将递增,直到不对输入进行除法。

p\~~|1
 >i

最后,我们将此功能应用于初始值,1然后使用打印结果p

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.