确定您的源代码中的数字是否为2017易写的无素数


41

在我一直挑战的所有年份中,2017年是第一年。因此,问题将是关于质数及其性质。

您的任务是生成一个将任意大的正整数作为输入的程序或函数,并输出或返回该数字是否为2017易碎的数字,即该数字中最大的质数是否为2017或更小。


一些示例输入及其输出:

1 (has no prime factors)
true

2 (= 2)
true

80 (= 2 x 2 x 2 x 2 x 5)
true

2017 (= 2017)
true

2019 (= 3 x 673)
true

2027 (= 2027)
false

11111 (= 41 x 271)
true

45183 (= 3 x 15061)
false

102349 (= 13 x 7873)
false

999999 (= 3 x 3 x 3 x 7 x 11 x 13 x 37)
true

1234567 (= 127 x 9721)
false

4068289 (= 2017 x 2017)
true

您的程序不必逐字输出,true并且false-任何真实值或虚假值,实际上在真假情况下一致的任何两个不同输出都可以。


但是,您不得在源代码中使用任何素数。素数有两种类型:

  • 表示素数文字的字符或字符序列。

    • 字符235,和7是在数字是有效的标记语言是非法的。

    • 该数字141是非法的,因为它包含41,即使14都是有效的。

    • 字符BD(或bd)在通常用作11和13的语言中是非法的,例如CJam或Befunge。

  • 具有素数值Unicode值或在其编码中包含素数值字节的字符。

    • 这些字符%)+/5;=CGIOSYaegkmq以及ASCII回车符都是非法的。

    • 该字符ó在UTF-8中是非法的,因为其中包含其编码0xb3。但是,在ISO-8859-1中,它的编码很简单0xf3,是复合的,因此可以。

以任何语言完成上述操作的最短代码均胜出。


旁注:在这种情况下,“易碎”是对旧的和未描述的“平滑”的一种改进。
格雷格·马丁

1
诚实和虚假的价值观需要保持一致吗?还是只要它们是真实的还是虚假的,它们就可以变化吗?
路易斯·门多

10
缺少=大多数标准语言的规则...
Neil

4
-1做X而不Y挑战。隐藏在一组不必要的字符限制后面确实非常琐碎
Downgoat

1
我不喜欢关于它们任意大的部分。如果它们上升到2 ^ 31-1会更好。
Bijan

Answers:


37

果冻,8字节

44‘²!*ḍ@

在线尝试!请注意,对于TIO ,测试用例11111及更高版本有点过多。

验证

$ source="34,34,fc,82,21,2a,d5,40"
$ xxd -ps -r > 2017.jelly <<< $source
$ xxd -g 1 2017.jelly
0000000: 34 34 fc 82 21 2a d5 40                          44..!*.@
$ eval printf '"%d "' 0x{$source}; echo # Code points in decimal
52 52 252 130 33 42 213 64
$ test_cases="1 2 80 2017 2019 2027 11111 45183 102349 999999 1234567 4068289"
$ for n in $test_cases; do printf "%11d: %d\n" $n $(jelly f 2017.jelly $n); done
      1: 1
      2: 1
     80: 1
   2017: 1
   2019: 1
   2027: 0
  11111: 1
  45183: 0
 102349: 0

测试案例999999已经运行了13个小时。我对2025年的计算感到悲观4068289 ...

这个怎么运作

44‘²!*ḍ@  Main link. Argument: n

44        Yield 44.
  ‘       Increment to yield 45.
   ²      Square to yield 2025.
          Note that no integers in [2018, ..., 2025] are prime numbers.
    !     Take the factorial of 2025.
     *    Raise it to the n-th power.
          This repeats all prime factors in 2025! at least n times, so the result
          will be divisible by n if (and only if) all of its prime factors fall
          in the range [1, ..., 2025].
      ḍ@  Test the result for divisibility by n.

22
你对数字很残酷。:)
格雷格·马丁

3
@GregMartin bah。我已经看到了一个答案(用另一种语言),其中大小为6的输入将占用内存几个小时,然后崩溃。我只会说:(2^n)!。这对于六位输入也有影响,但是至少输入使用十进制字母而不是二进制字母。
约翰·德沃夏克

这不是13个字节吗?丹尼斯,您享有很高的声誉,我敢肯定,我是在这里犯错的人哈哈
阿尔伯特·伦肖

7
@AlbertRenshaw在UTF-8中确实是13个字节,但是Jelly使用了一个自定义代码页该页将它理解的所有字符编码为一个字节。
丹尼斯,

3
@丹尼斯知道会有一个解释;非常酷的学习,谢谢!
艾伯特·伦肖

11

果冻,8个字符,14个字节的UTF-8

Æf½ṀḤ<90

在线尝试!

Jelly通常将自己的代码页用于程序。但是,它的大多数与素相关的内建Æ函数都以开头,即代码点13。不是很有帮助。幸运的是,解释器还支持UTF-8,该编码具有更友好的编码。

验证

此程序以UTF-8格式存储,如下所示:

00000000: c386 66c2 bde1 b980 e1b8 a43c 3930  ..f........<90

验证所有字节都是复合字节:

$ for x in c3 86 66 c2 bd e1 b9 80 e1 b8 a4 3c 39 30; do factor $((0x$x)); done
195: 3 5 13
134: 2 67
102: 2 3 17
194: 2 97
189: 3 3 3 7
225: 3 3 5 5
185: 5 37
128: 2 2 2 2 2 2 2
225: 3 3 5 5
184: 2 2 2 23
164: 2 2 41
60: 2 2 3 5
57: 3 19
48: 2 2 2 2 3

验证所有Unicode代码点都是复合的:

$ perl -Mutf8 -E '$a = ord, print `factor $a` for split //, "Æf½ṀḤ<90"'
198: 2 3 3 11
102: 2 3 17
189: 3 3 3 7
7744: 2 2 2 2 2 2 11 11
7716: 2 2 3 643
60: 2 2 3 5
57: 3 19
48: 2 2 2 2 3

解析为数字的唯一令牌是90。没有的9090是素数。

说明

这里的主要数学见解是45²是2025,整整介于2017年(当年)和2027年(下一个素数)之间。因此,我们可以取数字的每个质数的平方根,看是否有超过45的数字。不幸的是,45由于字面量我们不能写5,因此我们必须将其加倍并与90进行比较。

Æf½ṀḤ<90
Æf        In the list of prime factors,
  ½       taking the square root of each element
   Ṁ      then taking the largest element
    Ḥ     and doubling it
     <90  produces a result less than 90.

2
Jelly是否不需要标志(1个字节)来使用UTF-8?
路易斯·门多

@LuisMendo:命令行解释器可以,但是在线试用的解释器!配置不同,不需要它。因此,这只是选择以所需方式解释程序的解释器的情况。(无论如何,有问题的标志u,是复合的,因此仅是更改得分而不是使得分无效的问题。)

10

Mathematica,62 58 55字节

保存的最后三个字节完全归功于Martin Ender!

#4<4||#<44*46&&#6[#^-1#4]&[Divisors[#][[6-4]],,,#,,#0]&

带有正整数参数并返回True或的未命名函数False

递归算法,#4<4它是真实的基本情况(我们只需要它在归因True1上返回,但是额外的基本情况就可以了)。否则,我们用来计算输入的第二小除数(必须是素数)Divisors[#][[6-4]]。如果大于2024(44*46),则以退出False,否则我们将输入除以这个小的质数因子(由于不允许,必须将其表示为input的次数)#6来递归调用函数(使用set )。#0##^-1#4/

在结构上,上半年#4<4||#<44*46&&#6[#^-1#4]&是六个参数匿名函数,调用带参数Divisors[#][[6-4]]NullNull#Null,和#0; 这是绕过禁令上的字符235

以前的版本通过替换8018-6000为节省了四个字节,这44*46ais523的果冻答案的启发(Martin Ender似乎也受ais523的评论启发):

#<4||Divisors[#][[6-4]]<44*46&&#0[Divisors[#][[6-4]]^-1#]&

这太讨厌了:在这些限制下,我仍然不知道在Mathematica中实际设置变量的方法!无论=eSet是不允许的。避免+)也是一个问题,但要解决更多字节并不太难。


您也许可以设置lambda参数而不是变量。(也就是说,#2这也是不允许的,因此您必须注意自己的lambda如何嵌套,并且缺少括号可能

实施@ ais523的建议可节省三个字节:#4<4||#<44*46&&#6[#^-1#4]&[Divisors[#][[6-4]],,,#,,#0]&抛出一堆警告,因为它现在Divisors[#][[2]]在确保输入大于1(或3)之前尝试,但结果仍然正确。
Martin Ender

哦,伙计,这真是狡猾。
格雷格·马丁

7

Haskell,48 47字节

\n->[snd$[product[1..44*46]^n]!!0`divMod`n]<[1]

基本上是丹尼斯·杰利答案的翻译。xnor保存了一个字节。

使用[…]!!0圆括号,因为)被禁止,snd+ divMod因为mmodrem被禁止。


divMod不错!我想你可以替换!!0<1使用<[1]。但是看起来它短div用作了[\p n->p^n`div`n*n>p^n-1]!!0$product[1..44*46]
xnor

还有\n->[0|p<-[product[1..44*46]^n],0<-[p,p-n..0]],它使用输出仅需保持一致。
xnor

@xnor可以随意将其作为单独的答案发布,我认为它们与我的答案有很大不同^^
Lynn

6

Pyke,10 8 7 9个字节

P_Z|hwMX<

在这里尝试!

使用Dennis的2025年生成方式节省了1个字节

P         -     factors(input)
 _        -    reversed(^)
  Z|      -   ^ or 0
    h     -  ^[0] or 1
        < - ^ < V
     wM   -  ⁴45 (ord("M")-32)
       X  -  ^**2

5

Brachylog9 10字节

*$ph$r*<90

在线尝试!

基本上使用与其他答案相同的算法。$ph找到第一个(h)素因数($p);这是最大的素数,因为Brachylog的素数列表从最大到最小。然后,我取平方根($r),双*精度(),并测试其是否小于90(<90)。

我必须先将输入加倍,因为1没有素数(因此也没有第一个素数)。这会增加2的质数,它不会影响数字是否为2017易碎,但可以防止在处理1时失败。


5

实际上,9个字节

τyM:44u²≥

感谢Dennis提供了很多字节!

在线尝试!

说明:

τyM:44u²≥
τyM        largest prime factor of 2*input (doubled to deal with edge case of n = 1)
   :44u²   2025 (2027 is the next prime after 2017, so any number in [2017, 2026] can be used here - 2025 is very convenient)
        ≥  is 2025 greater than or equal to largest prime factor?

5

Mathematica,66 74字节

感谢Dennis指出这U+F4A1是禁止的。

Fold[Function[{x,d},And[x,Tr[Divisors@d^0]>6-4||d<44*46]],0<1,Divisors@#]&

说明:

Divisors@#:第一个参数的整数除数的列表#

0<1:高尔夫True(也避免使用字母e)。

Divisors@d^0{1, 1, ..., 1}长度为的除数的形式的列表d

Tr:对于平面列表,Tr返回该列表的总和。因此Tr[Divisors@d^0]返回的除数d

Function[{x,d},And[x,Tr[Divisors@d^0]>6-4||d<44*46]]:具有两个参数x和的匿名函数d。这个想法是d的除数,#我们测试一下它是否是合成的或小于或等于2017(包含)的。2017-易折性等于所有满足此条件的除数。正如ais523发现的,素数小于或等于等于2017素数小于2025。正如格雷格·马丁(Greg Martin)所指出的,足以测试它是否小于2024=44*46。该参数x充当到目前为止遇到的所有除数是否满足此属性的累加器。然后,我们Fold将该函数保留为所有#具有初始值的除数True,因为我们既得不到Map也没有/@


1
克服限制的方法!
格雷格·马丁

2

05AB1E,10个字节

fθ46n99-›È

如果为true,则返回1,否则返回0。

在线尝试!

说明

f          # Push the list of prime factors (ordered)
 θ         # Get the last element
  46n99-   # Push 2017 (46² - 99)
        >  # Push 1 if the last prime factor is greater than 2017, 0 otherwise
         È # Is the resulting number even ? Transforms 1 to 0 and 0 to 1.
           # Implicit display

欢迎来到PPCG!
马丁·恩德

1

MATL,15字节

t:\~ftZp*44QU<A

输出0非2017年易碎或12017年易碎。

在线尝试!验证所有测试用例

该程序检查所有字节是否都是复合字节。

说明

t       % Implicit input n. Duplicate
:       % Range [1 2 ... n]
\       % Modulo. Gives 0 for divisors of n
~f      % Indices of zero values
t       % Duplicate
Zp      % Is-prime. Gives 1 for primes, 0 for composites
*       % Multiply
44QU    % 44, add 1, square: 2025
<       % Less than, element-wise
A       % True (1) if all entries are nonzero

1

Bash,144个字节

ASCII编码:

{
printf '[ '
`tr D-Z _-z <<<KFH`tor $1|tr -d :|`tr B-Z _-z <<<JUH`p -o '[0-9]*$'
printf ' -lt $[24*86-46] ]'
}|tr \\n \ |`tr B-Z _-z <<<EDVK`

与shell一样,退出代码指示成功(0)或失败(非0)。

这实际上是的不同拼写

[ factor $1|tr -d :|grep -o '[0-9]*$' -lt 2018 ]

我们得到的最大因素factor $1|grep -o '[0-9]*$'; tr -d :对于输入= ,是特殊情况1

该表达式的$[6*6*69-466]计算结果为2018年。

使用tr命令名称并仍然使用命令替换非常棘手-我无法使用嵌套形式$( ),因此我最终将管道输送到另一个Bash中以评估结果。

检测结果:

$ for i in 1 2 80 2017 2019 2027 11111 45183 102349 999999 1234567 4068289; do printf '%d %s\n' $i `./105241.sh $i  && echo true || echo false`; done
1 true
2 true
80 true
2017 true
2019 true
2027 false
11111 true
45183 false
102349 false
999999 true
1234567 false
4068289 true

确认字符代码:

$ grep -v '^#' ./105241.sh | perl -n -Mutf8 -E '$a = ord, print `factor $a` for split //, $_' | grep -v ': .* ' | wc -l
0




0

Braingolf,11个字节[非常不竞争]

VRp#ߢ-?0:1

在线尝试!

由于ߢ带数字的螺钉不可读,但仍可在解释器中使用。

在撰写本文时,我什至没有注意到字符限制,但我要做的就是将2017年的奇怪unicode字符更改为2018年。

鉴于2018年不是素数,任何素数<= 2018也是<= 2017

说明

VRp#ߢ-?0:1  Implicit input from command-line args
VR            Create stack2, return to stack1
  p           Split last item into prime factors, push each one to stack in asc order
   #ߢ         Push 2018
     -      Subtract last 2 items (highest prime factor - 2017)
      ?     If last item > 0..
       0    ..push 1
        :   Else..
         1  ..Push 1
            Implicit output of last item on stack
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.