通过重复减去最大的质数,可以使数字达到1吗?


27

挑战:

给定一个数字,取严格小于该数字的最大质数,从该数字中减去它,再对该最大质数小于该数的新数字进行此操作,然后继续执行直到小于3。如果达到1,则表示程序应输出真实值,否则,程序应输出错误值。

例子:

所有这些都应该提供真实的价值:

3
4
6
8
10
11
12
14
16
17
18
20
22
23
24
26
27
29
30
32
34
35
37
38
40
41
42
44
46
47
48
50

所有这些都应提供假值:

5
7
9
13
15
19
21
25
28
31
33
36
39
43
45
49

规则:



1
5-3 = 2,2-(-2)= 4,4-3 = 1。(/ wiseguy)

@Hurkyl -2 = -1×2,所以不是素数;-)
ETHproductions 2016年

1
@ETHProductions:啊,但是-1是一个单位;该因式分解与2的素数并不矛盾,只要2 =(-1)×(-2)等于2。(甚至2 = 1×2)

3
@ETHproductions:有理数很有趣,因为有两种非常不同的方法在实践中很有用!有理数没有质数(甚至没有2!),因为一切都是单位。但是,您也可以将有理数视为由整数组成的构造,并使用整数的质数来研究它们。(例如,有人要求9/102^(-1) 3^2 5^(-1)思维方式对as 进行素数分解)

Answers:


8

果冻9 8 字节

’ÆRṪạµ¡Ḃ

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

怎么运行的

’ÆRṪạµ¡Ḃ  Main link. Argument: n

     µ    Combine all atoms to the left into a chain.
’           Decrement; yield n - 1.
 ÆR         Prime range; yield all primes in [2, ..., n -1].
   Ṫ        Tail; yield p, the last prime in the range.
            If the range is empty, this yields p = 0.
    ạ       Compute the absolute difference of p and n.
      ¡   Call the chain to the left n times.
          This suffices since each iteration decreases n, until one of the fixed
          points (1 or 2) is reached.
       Ḃ  Bit; return the parity of the fixed point.

11

视网膜,31字节

.+
$*
+`1(?!(11+)\1+$)11+
1
^1$

打印0(虚假)或1(真实)。

在线尝试!(第一行启用换行分隔的测试套件。)

说明

.+
$*

通过将输入N转换为的N副本,将输入转换为一元1

+`1(?!(11+)\1+$)11+
1

重复删除小于输入的最大质数。这基于regex的标准素数测试

^1$

检查结果是否为单个1


不用一元钱就可以使用Retina的感觉如何?Oo
Addison Crump

@Syxer的前两行将输入转换为一元。
马丁·恩德

这是否意味着您可以删除它们并请求一元输入?
Addison Crump

2
@Syxer我可以,但是我有点停止这样做了。看起来好像是一个晦涩的I / O格式,现在转换是6个字节(而不是以前的200个字节),我认为Retina算不上“不能合理地接受十进制输入”。
马丁·恩德

知道了 我只在Retina中看到一元输入,因此感到困惑。
Addison Crump

8

Pyth,18 15 14字节

感谢@Maltysen -1个字节

#=-QefP_TUQ)q1

在STDIN上接受输入并打印TrueFalse适当打印的程序。

在线尝试

怎么运行的

#=-QefP_TUQ)q1  Program. Input: Q
#          )    Loop until error statement (which occurs when Q<3):
         UQ      Yield [0, 1, 2, 3, ..., Q-1]
     fP_T        Filter that by primality
    e            Yield the last element of that
 =-Q             Q = Q - that
            q1  Q is 1 (implicit variable fill)
                Implicitly print

带reduce的旧版本,18字节

qu-G*<HGH_fP_TSQQ1

在线尝试

怎么运行的

qu-G*<HGH_fP_TSQQ1  Program. Input: Q
              SQ    Yield [1, 2, 3, ..., Q]
          fP_T      Filter that by primality
         _          Reverse it
 u                  Reduce it:
                Q    with base case Q and
                     function G, H -> 
     <HG              H<G
    *   H             *H (yields H if H<G, else 0)
  -G                  Subtract that from G
q                1  The result of that is 1
                    Implicitly print

StU15个字符
Maltysen 2016年

7

JavaScript(ES6),64 63字节

@Neil节省了1个字节

g=(x,n=x-1)=>n<2?x:x%n?g(x,n-1):g(x-1)
f=x=>x<3?x%2:f(x-g(x-1))

我在2分钟内写完了这篇文章…… 并且第一次成功。第一个发现不可避免的错误的用户。

试试看

怎么运行的

首先,我们将g(x)定义为找到第一个素数p <= x的函数。使用以下过程完成此操作:

  1. n = x-1开始
  2. 如果n <2,则x为质数; 返回x
  3. 如果x可被n整除,则将x1并转到步骤1。
  4. 否则,递减n并转到步骤2。

现在,解决这个挑战f(x)的方法非常简单:

  1. 如果x <3,则返回x = 1
  2. 否则,减去g(x-1),然后重试。

应该返回true的4326似乎没有返回,但是4328(true)和4329(false)会返回,这是JS限制还是错误?
乔纳森·艾伦

@JonathanAllan 4326抛出too much recursion了Firefox 48中的浏览器控制台,所以我猜想递归超过了FF的递归限制。
ETHproductions 2016年

是的,下一个主要下跌是4297(接下来是4327),这就是为什么4328有效的原因。
乔纳森·艾伦

4
x%2应该为您节省一个字节x==1
尼尔

@Neil我永远也不会想到:-)
ETHproductions 2016年

6

Pyke,15个 11字节

WDU#_P)e-Dt

在这里尝试!

            - stack = input
W           - while continue:
  U#_P)     -     filter(is_prime, range(stack))
       e    -    ^[-1]
 D      -   -   stack-^
         Dt -  continue = ^ != 1

1如果为true,则返回;如果为false,则引发异常


5

朱莉娅,32个字节

虽然这不是所有语言中最短的解决方案,但这可能是人类可读的最短的解决方案...

!n=n>2?!(n-primes(n-1)[end]):n<2

或者,说得更清楚一点

function !(n)
  if n>2
    m=primes(n-1)[end]   # Gets largest prime less than n
    return !(n-m)        # Recurses
  else
    return n<2           # Gives true if n is 1 and false if n is 2
  end
end

以调用,例如!37


3

Mathematica,32个字节

2>(#//.x_/;x>2:>x+NextPrime@-x)&

这是一个未命名的函数,它接受一个整数并返回一个布尔值。

说明

这里有很多语法和有趣的阅读顺序,所以...

   #                               This is simply the argument of the function.
    //.                            This is the 'ReplaceRepeated' operator, which applies
                                   a substitution until the its left-hand argument stops
                                   changing.
       x_/;x>2                     The substitution pattern. Matches any expression x as
                                   long as that expression is greater than 2.
              :>                   Replace that with...
                  NextPrime@-x     Mathematica has a NextPrime built-in but no
                                   PreviousPrime built-in. Conveniently, NextPrime
                                   works with negative inputs and then gives you the 
                                   next "negative prime" which is basically a
                                   PreviousPrime function (just with an added minus sign).
                x+                 This gets added to x, which subtracts the previous
                                   prime from it.
2>(                           )    Finally, we check whether the result is less than 2.

接近节拍#+0~Min~NextPrime@-#&~FixedPoint~#==1&(36个字节)。很好用//.
格雷格·马丁

1
@GregMartin 35 <2最后使用时。
Martin Ender's

3

Python3,102 92 90 89 88字节

f=lambda n:n<2if n<3else f(n-[x for x in range(2,n)if all(x%y for y in range(2,x))][-1])

欢迎打高尔夫球!我看到其中gmpy包含一个函数next_prime,但是我还不能对其进行测试:(

-2个字节,感谢@JonathanAllan

-1个字节,感谢@Aaron

测试用例

f=lambda n:n<2if n<3else f(n-[x for x in range(2,n)if all(x%y for y in range(2,x))][-1])

s="3 4 6 8 10 11 12 14 16 17 18 20 22"
h="5 7 9 13 15 19 21 25 28 31 33 36 39"

for j in s.split(" "):print(f(int(j)))
for j in h.split(" "):print(f(int(j)))

输出是13个真实值和13个虚假值。 s包含真实案例和虚假案例h


1
if all(x%y for...作品
乔纳森·艾伦

1
n<3 else-> n<3else与我的长度相同;)
Aaron

2

Python,带有sympy,60个字节

import sympy
f=lambda n:n>2and f(n-sympy.prevprime(n))or n<2

我以前的方法是83个字节,没有使用递归的sympy,但是我将true / falsey表示为可区分且一致的意思,但是我被告知这是一个错误的解释。由于尾巴,我似乎无法挽救它,但是如果有人知道该怎么做,我将其留在这里:

f=lambda n,p=0:n>2and(any(p%x==0for x in range(2,p))and f(n,p-1)or f(n-p,n+~p))or n


@ mbomb007我认为如果需要的话,规格是“真假”,而“真假”则是可区分且一致的?
乔纳森·艾伦

1
不。它们是根据我们在元站点上决定的定义的。任何允许“可区分且一致的”输出的问题都必须指定该值,而不是真/假。
mbomb007'9

好了,我读了这篇文章,将会在某个时候更新...
Jonathan Allan

1

Vitsy,28 26字节

这绝对可以缩短。

<]xN0)l1)-1[)/3D-];(pD-1[D

<                    Traverse the code in this direction, rotating on the line.
                     For the sake of reading the code easier, I'm reversing the
                     code on this line. This will be the order executed.

 D[1-Dp(;]-D3/)[1-)1l)0Nx]
 D                         Duplicate the top member of the stack.
  [      ]                 Do the stuff in brackets until break is called.
   1-                      Subtract 1 from the top item of the stack.
     D                     Duplicate the top member of the stack.
      p(                   If the top member is a prime...
        ;                  break;
          -                Pop a, b, push a - b.
           D3/)[         ] If this value is less than 3, do the bracketed code.
                1-         Subtract the top item of the stack by 1.
                  )        If the top item is zero...
                   1       Push 1.
                    l)     If the length of the stack is zero...
                      0    Push 0.
                       N   Output the top member of the stack.
                        x  System.exit(0);

在线尝试!


1

MATL,13字节

`tqZq0)-t2>}o

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

说明

`        % Do...while
  t      %   Duplicate. Takes input implicitly in the first iteration
  qZq    %   All primes less than that
  0)     %   Get last one
  -      %   Subtract (this result will be used in the next iteration, if any)
  t      %   Duplicate
  2>     %   Does it exceed 2? If so: next iteration. Else: execute the "finally" 
         %   block and exit do...while loop
}        % Finally
  o      %   Parity. Transforms 2 into 0 and 1 into 1
         % End do...while implicitly
         % Display implicitly

1

CJam21 16字节

感谢Dennis节省了4个字节。

ri{_1|{mp},W=-}h

在线尝试!

说明

ri       e# Read input and convert to integer N.
{        e# Run this block as long as N is positive (or until the program aborts
         e# with an error)...
  _1|    e#   Duplicate and OR 1. This rounds up to an odd number. For N > 2, this
         e#   will never affect the greatest prime less than N.
  {mp},  e#   Get all primes from 0 to (N|1)-1.
         e#   For N > 2, this will contain all primes less than N.
         e#   For N = 2, this will contain only 2.
         e#   For N = 1, this will be empty.
  W=     e#   Select the last element (largest prime up to (N|1)-1).
         e#   For N = 1, this will result in an error and terminate the program, which
         e#   still prints the stack contents though (which are 1, the desired output).
  -      e#   Subtract from N. Note that this gives us 0 for N = 2, which terminates the 
         e#   loop.
}h

ri_{_1|{mp},W=-}*应该管用。
丹尼斯

@丹尼斯,谢谢,1|真的很聪明。:)(而且我总是忘记这样{...},做有隐式范围...)
Martin Ender

1

Perl,42个字节

包括+1的 -p

在STDIN上输入运行

reach1.pl

#!/usr/bin/perl -p
$_=1x$_;$_=$`while/\B(?!(11+)\1+$|$)|11$/

使用经典素数正则表达式


1

.NET Regex,38个字节

只是为了表明它可以在单个正则表达式中进行检查。

^(?>(?<=(.*))..+(?<!^\1\2+(.+.)|$))+.$

假定输入为一元。

说明

它只是简单地实现单词的要求,重复删除最大的质数,并检查剩余数是否为1。

  • (?>(?<=(.*))..+(?<!^\1\2+(.+.)|$))+:非回溯小组确保不会覆盖我们找到的最大素数,+只需重复匹配最大素数的过程即可。

    • (?<=(.*))..+(?<!^\1\2+(.+.)|$):匹配最大素数小于剩余数

      • (?<=(.*)):记录我们减去多少以建立断言的“锚点”。

      • ..+:寻找最大的数字...

      • (?<!^\1\2+(.+.)|$):...是素数,小于剩余数。
        • (?<!^\1\2+(.+.)):通常的主要测试程序,^\1前面加上了确保我们检查的匹配数量..+
        • (?!<$):断言少于剩余数量

(?<=(.*))部分相当笨拙。不知道是否有更好的方法。另外,我很好奇PCRE中是否有解决方案。
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

0

Perl 6的 54个53 52  51字节

{($_,{$_-($_-1...2).first: *.is-prime}...3>*)[*-1]==1}
{($_,{$_-($_-1...2).first: *.is-prime}...3>*).any==1}
{any($_,{$_-($_-1...2).first: *.is-prime}...3>*)==1}
{any($_,{$_-(^$_).grep(*.is-prime)[*-1]}...3>*)==1}

说明:

# bare block lambda with implicit parameter 「$_」
# used to generate all of the rest of the elements of the sequence
{
  # create an any Junction of the following list
  any(
    $_, # initialize sequence with the inner block's argument

    # bare block lambda with implicit parameter 「$_」
    {
      # take this inner block's argument and subtract
      $_ -

      ( ^$_ )            # Range up-to and excluding 「$_」
      .grep(*.is-prime)\ # find the primes
      [ * - 1 ]          # return the last value
    }

    ...   # keep doing that until

    3 > * # the result is less than 3

  # test that Junction against 「1」
  # ( returns an 「any」 Junction like 「any(False, False, True)」 )
  ) == 1
}

例:

# show what is returned and if it is truthy
sub show ($_) {
  # 「.&{…}」 uses the block as a method and implicitly against 「$_」
  my $value = .&{any($_,{$_-(^$_).grep(*.is-prime)[*-1]}...3>*)==1}
  say join "\t", $_, ?$value, $value.gist;
}

show 3;  # 3    True    any(False, True)
show 4;  # 4    True    any(False, True)
show 5;  # 5    False   any(False, False)
show 10; # 10   True    any(False, False, True)
show 28; # 28   False   any(False, False, False)
show 49; # 49   False   any(False, False)
show 50; # 50   True    any(False, False, True)

0

不规则的,63个字节

p~?1_$-1p:;
n=i(0)?1_$-1p:;
_~
N=n
1(?!(11+)\1+$)11+~1
^11$~0
N

我两天前创建了这种语言,其基本前提是没有内置循环,唯一的功能是基本的算术和决策制定,程序评估基于正则表达式。

说明

p~?1_$-1p:;
n=i(0)?1_$-1p:;
_~
N=n

这部分将输入转换为一元。它从输入中反复减去1,直到等于0,1_每次都在前面。然后删除所有_。如果我没有break在代码中忘记a ,可以这样写:

p~?1_$-1p:;
_~
n=i(0)?1_$-1p:;

下一部分重复从输入中除去最大的质数,直到等于1或为止11,并11替换为0

1(?!(11+)\1+$)11+~1
^11$~0
N

我使用了Martin Ender的答案中的正则表达式。


0

Haskell,79个字节

不是很短但是没有意义:)

(<2).until(<3)(until(flip(`until`(+1))2.(.)(<1).mod>>=(==))pred.pred>>=flip(-))

0

PowerShell v2 +,81字节

param($n)while($n-gt2){$n-=(($n-1)..2|?{'1'*$_-match'^(?!(..+)\1+$)..'})[0]}!--$n

接受输入$nwhile只要还是更大,$n就进入循环3。每次迭代都从中减去一个数字$n。数字是通过()运算符针对某个范围应用的正则表达式素数测试的结果,然后是结果的第一个(由于范围正在减小,因此将选择最大的结果)。结束循环之后,要么将是或,根据定义,所以我们预减量(将其变成任一或),并采取布尔不体。剩下的就在管道上,输出是隐式的。($n-1)..2Where-Object?[0]$n12$n01!

例子

PS C:\Tools\Scripts\golfing> 3..20|%{"$_ --> "+(.\can-the-number-reach-one.ps1 $_)}
3 --> True
4 --> True
5 --> False
6 --> True
7 --> False
8 --> True
9 --> False
10 --> True
11 --> True
12 --> True
13 --> False
14 --> True
15 --> False
16 --> True
17 --> True
18 --> True
19 --> False
20 --> True


0

Python 2.7: 88 87字节

r=lambda n:n>2and r(n-[a for a in range(2,n)if all(a%b for b in range(2,a))][-1])or n<2

Thx @TuukkaX还有-1个字节!


1
更新您的描述;)此外,您可以说n<2而不是来节省一个字节n==1
Yytsi


0

Clojure,125个字节

#(loop[x %](if(> x 2)(recur(- x(loop[y(dec x)](if(some zero?(vec(for[z(range 2 y)](mod y z))))(recur(dec y))y))))(quot 1 x)))

kes,那是一长段代码。最冗长的语言再次来袭!

取消高尔夫:

(defn subprime [n]
  (loop [x n]
    (if (> x 2)
      (recur
        (- x
          (loop [y (dec x)]
            (if (some zero? (vec (for [z (range 2 y)] (mod y z))))
              (recur (dec y)) y))))
      (quot 1 x))))
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.