それよりも小さい最大の素数を繰り返し減算することにより、数は1に達することができますか?


27

チャレンジ:

数を指定して、それより厳密に小さい最大の素数を取り、この数からそれを減算し、それよりも小さい最大の素数でこの新しい数に再度これを行い、3未満になるまでこれを続けます。プログラムは真偽値を出力する必要があります。そうでない場合、プログラムは偽値を出力する必要があります。

例:

これらはすべて、真の価値をもたらすはずです。

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

1
@ETHProductions:ああ、しかし-1は単位です。その因数分解は、-2の素数と2 =(-1)×(-2)の2を超えないことを矛盾しません(または2 = 1×2でさえ)

3
@ETHproductions:実際に役立つ2つの非常に異なるアプローチがあるため、有理数は興味深いです!すべてが単位であるため、有理数には素数がありません(2でもありません!)。ただし、整数から作られた構造として有理数を表示し、整数の素数を使用してそれらを調べることもできます。(例えばの素因数分解を求めて誰9/10としては2^(-1) 3^2 5^(-1)、後者の観点で考えている)

回答:


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(falsy)または1(truthy)。

オンラインでお試しください!(最初の行は、改行で区切られたテストスイートを有効にします。)

説明

.+
$*

入力NをのNコピーに変換して、入力を単項に変換します1

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

入力よりも小さい最大の素数を繰り返し削除します。これは、regexを使用した標準の素数性テストに基づいてます。

^1$

結果が単一かどうかを確認し1ます。


単項式なしでRetinaを使用できるのはどうですか?Oo
アディソンクランプ

@Syxer最初の2行は、入力を単項に変換します。
マーティンエンダー

それは、それらを削除して単項入力を要求できるという意味ではありませんか?
アディソンクランプ

2
@Syxerできましたが、それをやめました。危険なI / O形式のようで、変換が6バイト(以前の200バイトではなく)になったため、Retinaは「10進数で入力を合理的に取得できない」とは見なされません。
マーティンエンダー

ああ、なるほど。私はRetinaで単項入力のみを見たことがあります。
アディソンクランプ

8

Pyth、18 15 14バイト

-1バイトの@Maltysenに感謝

#=-QefP_TUQ)q1

STDINおよび印刷物上に入力を受け取りプログラムTrueまたはFalse適宜。

オンラインで試す

使い方

#=-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

StであるU15の文字
Maltysen

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分で書きました... そしてそれは初めて完全に機能しました。避けられないバグを見つけた最初のユーザーが勝ちます...

やってみて

使い方

最初に、最初の素数p <= xを見つける関数としてg(x)を定義します。これは、次のプロセスを使用して行われます。

  1. n = x-1から始めます。
  2. n <2の場合、xは素数です。xを返します。
  3. 場合は、xがで割り切れるnは、デクリメントXとステップ1に進みます。
  4. それ以外の場合は、nをデクリメントして手順2に進みます。

この課題に対する解決策f(x)は、今やかなり簡単です:

  1. x <3の場合、x = 1を返します。
  2. それ以外の場合は、g(x-1)を減算して再試行してください。

4326はtrueを返すはずですが、4328(true)と4329(false)はそうではありませんが、これはJSの制限またはバグですか?
ジョナサンアラン

@JonathanAllan 4326 too much recursionはFirefox 48のブラウザーコンソールにスローされるため、再帰はFFの再帰制限を超えていると思います。
ETHproductions

うん、次のプライムダウンは4297(そして次のアップは4327)で、これが4328が機能する理由です。
ジョナサンアラン

4
x%2で1バイト節約できますx==1
ニール

@ニール私はそれを考えたことがなかっただろう:
ETHproductions

6

パイク、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

1trueの場合に戻り、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最後に使用すると。
マーティンエンダー

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私と同じ長さを得るために;)
アーロン

2

Python、sympy、60バイト

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

私の以前の方法は、再帰を使用したsympyなしの83バイトでしたが、識別可能かつ一貫性を意味するために真実/偽りを取りましたが、間違った解釈であると通知されました。私は尾のためにそれを救うようには見えませんが、誰かがそうする方法を知っている場合のためにここに残します:

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必要であれば仕様は「trueまたはfalse」であると考えましたが、「truthyまたはfalsey」は区別可能で一貫性があることを意味しますか?
ジョナサンアラン

1
いや。これらは、メタサイトで決定したとおりに定義されます。「識別可能で一貫性のある」出力を許可する質問は、真実/偽りではなく、それを指定する必要があります。
mbomb007

OK私が読んで、これをどこかの時点で更新されます...、
ジョナサン・アラン

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バイト

4バイトを節約してくれたDennisに感謝します。

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=-}*動作するはずです。
デニス

@Dennisありがとう、1|本当に賢い。:)(そして{...},、暗黙の範囲を行うことを常に忘れています...)
マーティンエンダー

1

Perl、42バイト

+1を含む -p

STDINで入力して実行する

reach1.pl

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

古典的な素数の正規表現を使用します


1

.NET正規表現、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

私はこの言語を2日前に作成しました。基本的な前提は、組み込みのループがなく、唯一の機能は基本的な算術演算と意思決定であり、プログラム評価は正規表現に基づいているということです。

説明

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

この部分は、入力を単項に変換します。0になるまで入力から1を繰り返し減算し、1_毎回先頭に追加します。次に、すべてのを削除します_break私のコードでを忘れていなければ、次のように書くことができます。

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

入力を受け取ります$n。まだまたはそれ以上であるwhile限り、ループに入ります。各反復で、から数値を引きます。数値は、()演算子を介して範囲に対して適用された正規表現の素数性テストの結果であり、最初の結果(範囲が減少しているため、最大のものが選択されます)。ループの終了後、定義により、またはのいずれかになるため、事前にデクリメント(またはのいずれかに変換)し、そのブール否定を取ります。それはパイプラインに残り、出力は暗黙的です。$n3$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

Matlab、51バイト

v=@(x)x-max(primes(x-1));while(x>=3)x=v(x);end;x==1

これはETHProductionsのJS6ソリューションに非常に似ていますが、変数がワークスペースにある必要があります。


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代わりに言うことで1バイト節約できます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)))

Yikes、それは1つの長いコードです。最も冗長な言語が再び登場!

ゴルフをしていない:

(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))))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.