ロッコ番号を見つける


12

インタビューでこの質問をされましたが、解決策を見つけることができませんでした。質問が正しかったかどうかはわかりません。私は多くのことを試みましたが、解決策に到達できませんでした。正直に言って、何も思い浮かばなかった。

ロッコ番号

正の整数nは、n=p(p+14)またはn=p(p14)いずれかで表現できる場合、ロッコ数です。ここで、pは素数です。

最初の10個のRocco番号は次のとおりです。

32,51,95,147,207,275,351,435,527,627

仕事

コードは入力として正の整数を受け入れ、それがRocco番号かどうかを判断する必要があります。

ブラウニーポイント

  • 100万以下のRocco数のカウントを計算して印刷する関数を作成します。
  • ボーナス質問(1つ以上)の素数であるRocco数のカウントを計算して出力する関数を作成します。

5
こんにちは、PPCGへようこそ。私たちは、客観的なスコアリングと勝利基準を備えた課題をホストします(あなたのものは本当に面白いようです)それを含めるように投稿を編集してみてください。正しい方法を見つけるのが最も簡単なので、目標としてコードゴルフをお勧めします。また、あなたはそれらのボーナスを避けたいです。1つの明確なタスクに集中するだけです。
アダム

3
出力は整数になります:入力がRocco数であるかどうかのブール値を意味しませんか?
アダム

5
ボーナス2: print 0。すべてのRocco数は合成な(n*..)ので、どの範囲にも素数はありません。
TFeld

4
「ボーナスポイント」は単純にハードコーディングされた値である可能性があり、チャレンジにとってまったく有益ではありません。それらを削除することをお勧めします。
エリックアウトゴルファー

5
質問とタグを編集しました。同意しない場合は、ロールバックするか、さらに編集してください。@EriktheOutgolferが言ったように、ボーナスは削除すべきだと思います。
アーナルド

回答:


10

05AB1E、8バイト

nがロッコ数の場合は1返し、そうでない場合は0を返します。n0

fDŠ/α14å

オンラインでお試しください!

どうやって?

正の整数を考えるとn素因数が存在するかどうか、我々のテストpn、このようなことを:

|pnp|=14

コメント済み

fDŠ/α14å  # expects a positive integer n as input       e.g. 2655
f         # push the list of unique prime factors of n  -->  2655, [ 3, 5, 59 ]
 D        # duplicate it                                -->  2655, [ 3, 5, 59 ], [ 3, 5, 59 ]
  Š       # moves the input n between the two lists     -->  [ 3, 5, 59 ], 2655, [ 3, 5, 59 ]
   /      # divide n by each prime factor               -->  [ 3, 5, 59 ], [ 885, 531, 45 ]
    α     # compute the absolute differences
          # between both remaining lists                -->  [ 882, 526, 14 ]
     14å  # does 14 appear in there?                    -->  1

11

JavaScript(ES7)、55バイト

n=>(g=k=>k>0&&n%--k?g(k):k==1)(n=(49+n)**.5-7)|g(n+=14)

オンラインでお試しください!

どうやって?

正の整数n与えられた場合x x + 14 = nまたはx x 14 = nとなるような素数x探します。x(x+14)=nx(x14)=n

したがって、次の二次方程式:

(1)x2+14xn=0
(2)x214xn=0

(1)正根は次のとおりです。

x0=49+n7

(2)

x1=49+n+7

x0x1

これを行うには、入力として無理数を与えられた場合に永久にループしないことを確認するための追加のテストとともに、古典的な再帰素数テスト関数を使用します。

g = k =>    // k = explicit input; this is the divisor
            // we assume that the implicit input n is equal to k on the initial call
  k > 0 &&  // abort if k is negative, which may happen if n is irrational
  n % --k ? // decrement k; if k is not a divisor of n:
    g(k)    //   do a recursive call
  :         // else:
    k == 1  //   returns true if k is equal to 1 (n is prime)
            //   or false otherwise (n is either irrational or a composite integer)

メインラッパー関数:

n => g(n = (49 + n) ** .5 - 7) | g(n += 14)


6

正規表現(ECMAScript)、64 62バイト

この正規表現は2つの数字を見つけます a そして a+14 そのような n=aa+14。それらが見つかった場合、次のいずれかをアサートしますa または a+14プライムです。それでおしまい!

これは、豊富な正規表現ポストの段落で簡単に説明されている乗算アルゴリズムの変形を使用しています。これはネタバレです。したがって、高度な単項正規表現の魔法を台無しにしたくない場合は、これ以上読み進めないでください。この魔法を自分で理解するためにショットを撮りたい場合は、この以前の投稿で連続してスポイラーでタグ付けされた推奨問題のリストのいくつかの問題を解決することから始めることを強くお勧めします、て、数学的な洞察を独自に考え出すことをします。

乗算アルゴリズムは、2つの既知の値が乗算されて別の既知の値に等しいことを主張しているため、ここで異なる方法で実装されます(数値が完全な正方形であるかどうかをテストするために、このポストの正規表現の代替バージョンでも同様です)。これまでに投稿された他のほとんどの正規表現の回答では、乗算は計算として実装され(概念的に言えばアサーションではなく)、目標は2つの既知の数値の積を見つけることです。どちらの方法も両方の状況で機能しますが、ゴルフに関しては、お互いの仕事をするのがより悪いです。

^(?=(x((x{14})(x+)))(?=(\1*)\4\2*$)(\1*$\5))\6\3?(?!(xx+)\7+$)

オンラインでお試しください!


 # For the purposes of these comments, the input number = N.
 ^
 # Find two numbers A and A+14 such that A*(A+14)==N.
 (?=
     (x((x{14})(x+)))   # \1 = A+14; \2 = \1-1; \3 = 14; \4 = A-1; tail -= \1
     (?=                # Assert that \1 * (\4+1) == N.
         (\1*)\4\2*$    # We are asserting that N is the smallest number satisfying
                        # two moduli, thus proving it is the product of A and A+14
                        # via the Chinese Remainder Theorem. The (\1*) has the effect
                        # of testing every value that satisfies the "≡0 mod \1"
                        # modulus, starting with the smallest (zero), against "\4\2*$",
                        # to see if it also satisfies the "≡\4 mod \2" modulus; if any
                        # smaller number satisfied both moduli, (\1*) would capture a
                        # nonzero value in \5. Note that this actually finds the
                        # product of \4*\1, not (\4+1)*\1 which what we actually want,
                        # but this is fine, because we already subtracted \1 and thus
                        # \4*\1 is the value of tail at the start of this lookahead.
                        # This implementation of multiplication is very efficient
                        # golf-wise, but slow, because if the number being tested is
                        # not even divisible by \1, the entire test done inside this
                        # lookahead is invalid, and the "\1*$" test below will only
                        # fail after this useless test has finished.
     )
     (\1*$\5)           # Assert that the above test proved \1*(\4+1)==N, by
                        # asserting that tail is divisible by \1 and that \5==0;
                        # \6 = tool to make tail = \1
 )
 # Assert that either A or A+14 is prime.
 \6                     # tail = \1 == A+14
 \3?                    # optionally make tail = A
 (?!(xx+)\7+$)          # Assert tail is prime. We don't need to exclude treating
                        # 1 as prime, because the potential false positive of N==15
                        # is already excluded by requiring \4 >= 1.
 


3

Brachylog13 12バイト

ṗ;14{+|-};?×

候補番号をコマンドライン引数として入力します。出力trueまたはfalseオンラインでお試しください!

説明

コードは、入力が制約されておらず、出力がテスト対象の数値である述語です。

ṗ             Let the input ? be a prime number
 ;14          Pair it with 14, yielding the list [?, 14]
    {+|-}     Either add or subtract, yielding ?+14 or ?-14
         ;?   Pair the result with the input, yielding [?+14, ?] or [?-14, ?]
           ×  Multiply; the result must match the candidate number

(ヒントは大歓迎です。{+|-}それでも不格好に感じます。)


3

Brachylog、9バイト

別のアプローチとDLosc答え

Ċ-14&∋ṗ&×

Nを出力として受け取り、[P、P-14]または[P + 14、P]を入力に戻します(最大数が最初)

説明

Ċ              # The 'input' is a pair of numbers
 -14           #   where the 2nd is 14 smaller then the first
    &∋ṗ        #   and the pair contains a prime
       &×      #   and the numbers multiplied give the output (N)

オンラインでお試しください!


2

Pyth、22 20バイト

}Qsm*Ld+Ld_B14fP_TSh

こちらからオンラインでお試しください。

}Qsm*Ld+Ld_B14fP_TShQ   Implicit: Q=eval(input())
                        Trailing Q inferred
                  ShQ   Range [1-(Q+1)]
              fP_T      Filter the above to keep primes
   m                    Map the elements of the above, as d, using:
          _B14            [14, -14]
       +Ld                Add d to each
    *Ld                   Multiply each by d
  s                     Flatten result of map
}Q                      Is Q in the above? Implicit print

編集:入力として3バイトを保存すると、常に正になるため、リストから負の値を除外する必要はありません。また、入力1およびのバグを修正しました2。コストは1バイトです。前のバージョン:}Qsm*Ld>#0+Ld_B14fP_TU


2

05AB1E16 15 14バイト

代わりに14を計算して1バイトを節約しましたžvÍ (cant believe I didnt think of this in the first place).

Emignaのおかげで1バイト節約

ÅPε7·D(‚+y*Q}Z

オンラインでお試しください!またはすべての入力をテストする

説明

                 # Implicit input n
ÅP               # Push a list of primes up to n
  ε         }    # For each prime in the list...
   7·            # Push 14 (by doubling 7)
     D(‚         # Push -14 and pair them together to get [14,-14]
        +        # Add [14,-14] to the prime
         y*      # Multiply the prime to compute p(p-14) and p(p+14)
           Q     # Check if the (implicit) input is equal to each element
             Z   # Take the maximum

1
暗黙的な入力}˜såQ}Z使用するように変更することで、バイトを保存できます。Test-Suiteを動作させるには、少しこのように変更する必要があります。また、書き込みのより明白な方法žvÍだろう14;)
Emigna

ありがとう!あなたが最も複雑な方法/手のひらを顔に当てる:)に14を押すことができるのに、なぜ簡単にそれを作る
Wisław


2

Retina 0.8.2, 61 bytes

.+
$*
^((1{14})1(1)+)(?<=(?<!^\4+(..+))\2?)(?<-3>\1)+$(?(3)1)

Try it online! Explanation:

.+
$*

Convert to unary.

^((1{14})1(1)+)

\12つの要因のうち大きい方をキャプチャします。\2定数14をキャプチャして、バイトを保存します。\32つの因子のうち小さい方をマイナス1でキャプチャします。これにより、両方の因子が少なくとも2になることも保証されます。

(?<=(?<!^\4+(..+))\2?)

2つの要素をチェックして、少なくとも1つが素数であることを確認します。使用するというアイデアは\2?、@ Deadcodeの答えから恥知らずに盗まれました。

(?<-3>\1)+

2つの要因のうち小さい方よりも1つ少ない回数に等しい回数、2つの要因のうち大きい方を繰り返します。一度大きなファクターをキャプチャすると、これで2つのファクターの積がキャプチャされます。

$(?(3)1)

製品が指定された数と等しいことを確認してください。

置き換えることにより、網膜1への直接の翻訳$*では、*1同じバイト数を持っているだろうが、バイトはすべて交換することによって保存することができ1て、Sを_S、その後*1に置換することができる*のではなく*_。68バイトの以前のRetina 1の回答:

.+
*
Lw$`^(__+)(?=(\1)+$)
$1 _$#2*
Am` (__+)\1+$
(_+) \1

0m`^_{14}$

オンラインでお試しください!説明:

.+
*

単項に変換します。

Lw$`^(__+)(?=(\1)+$)
$1 _$#2*

すべての因子のペアを見つけます。

Am` (__+)\1+$

1つが素数であることを確認してください。

(_+) \1

絶対差を取る。

0m`^_{14}$

14かどうかを確認します。


1

JavaScript(Babelノード)、69バイト

くそー、私はアーナルドの答えを打つつもりだったけど、いや.....:c

x=>[...Array(x)].some((a,b)=>x/(a=(p=n=>--b-1?n%b&&p(n):n)(b))-a==14)

オンラインでお試しください!

x=>[...Array(x)].some(時間の経過とともに短くなるように、再帰を使用してパーツを削除したい

説明

x=>[...Array(x)]                                                              Creates a range from 0 to x-1 and map:

                .some((a,b)=>                                                 Returns True if any of the following values is true
                             x/                                              Input number divided by
                                (a=(p=n=>--b-1?n%b&&p(n):n)(b))               recursive helper function. Receives a number (mapped value) as parameters and returns 
                                                                              the same number if it is prime, otherwise returns 1. Take this value
                                                                              and assign to variable a
                                                               -a            Subtract a from the result  
                                                                     ==14    Compare result equal to 14

数式を使用します

n/pp==14




1

APL(NARS)16文字、32バイト

{14=∣r-⍵÷r←↑⌽π⍵}

{π⍵}は引数の因数分解を見つけ、結果の最後の要素(nの約数のリスト)がnの最大素数であると仮定します。ここで、Rocco数の1つの同等の定義は次のとおりであると仮定します。nはRocco数<=> nの最大因子素数です。rはtrueである14 = ∣rn÷r / r)Rocco数のこの定義は、1..1000000の範囲でようやく問題ないようです。ok値の範囲は1..maxIntです。テスト:

 f←{14=∣r-⍵÷r←↑⌽π⍵}
 {⍞←{1=f ⍵:' ',⍵⋄⍬}⍵⋄⍬}¨1..10000
32  51  95  147  207  275  351  435  527  627  851  1107  1247  1395  1551  1887  2067  2255  2451  2655  2867  3551  4047  4307  4575  5135  5427  5727  6035  6351  6675  7347  8051  8787  9167  9951   

1

C#(Visual C#Interactive Compiler)、99バイト

n=>Enumerable.Range(2,n).Any(p=>Enumerable.Range(2,p).All(y=>y>=p|p%y>0)&(n==p*(p+14)|n==p*(p-14)))

オンラインでお試しください!

Enumerable.Range 私はバニラソリューションのファンのようなものですが、クレイジーコンパイラフラグを使用すると、物事をかなり減らすことができます。

C#(Visual C#Interactive Compiler) + /u:System.Linq.Enumerable、77バイト

n=>Range(2,n).Any(p=>Range(2,p).All(y=>y>=p|p%y>0)&(n==p*(p+14)|n==p*(p-14)))

オンラインでお試しください!

以下は、かなりクールに思えたArnauldのソリューションの移植版です。現在は最長ですが、おそらくいくつかのゴルフが可能です。

C#(Visual C#Interactive Compiler)、101バイト

n=>{bool g(int k)=>--k<2?n>1:n%k>0&g(k);var d=Math.Sqrt(n+49)-7;return(n=(int)d)==d&(g(n)|g(n+=14));}

オンラインでお試しください!


0

APL(NARS)30文字、60バイト

{∨/{0=1∣⍵:0π⍵⋄0}¨(7,¯7)+√49+⍵}

ここで、0πは、1つの数値が素数であるかどうかをテストする関数です。

 f←{∨/{0=1∣⍵:0π⍵⋄0}¨(7,¯7)+√49+⍵}
 {⍞←{1=f ⍵:' ',⍵⋄⍬}⍵⋄⍬}¨0..700
32  51  95  147  207  275  351  435  527  627

0

F#、2つの回答(非競合)

@Arnauldの回答が本当に好きだったので、翻訳しました。

JavaScriptの回答に基づいて123バイト

fun n->let t=int<|sqrt(float n+49.)in Seq.map(fun n->Seq.filter(fun i->n%i=0)[1..n]|>Seq.length=2)[t-7;t+7]|>Seq.reduce(||)

説明:

fun n->let t=int<|sqrt(float n+49.)in Seq.map(fun n->Seq.filter(fun i->n%i=0)[1..n]|>Seq.length=2)[t-7;t+7]|>Seq.reduce(||) //Lambda which takes an integer, n
       let t=int<|sqrt(float n+49.)                                                                                         //let t be n, converted to float, add 49 and get square root, converted back to int (F# type restrictions)
                                   in                                                                                       //in the following...
                                                                                                  [t-7;t+7]                 //Subtract and add 7 to t in a list of 2 results (Lists and Seqs can be interchanged various places)
                                      Seq.map(fun n->Seq.filter(fun i->n%i=0)[1..n]|>Seq.length=2)                          //See if either are prime (here, if either result has 2 and only 2 divisors)
                                                                                                           |>Seq.reduce(||) //And logically OR the resulting sequence

05AB1E回答に基づいて125バイト

fun n->let l=Seq.filter(fun i->n%i=0)[2..n-1]in let m=Seq.map(fun i->n/i)l in Seq.map2(fun a b->abs(a-b))l m|>Seq.contains 14

説明:

fun n->let l=Seq.filter(fun i->n%i=0)[2..n-1]in let m=Seq.map(fun i->n/i)l in Seq.map2(fun a b->abs(a-b))l m|>Seq.contains 14  //Lambda which takes an integer, n
       let l=Seq.filter(fun i->n%i=0)[2..n-1]                                                                                  //let l be the list of n's primes 
                                             in                                                                                //in...
                                                let m=Seq.map(fun i->n/i)l                                                     //m, which is n divided by each of l's contents
                                                                           in                                                  //and then...
                                                                              Seq.map2(fun a b->abs(a-b))l m                   //take the absolute difference between each pair of items in the two sequences to make a new sequence
                                                                                                            |>Seq.contains 14  //and does the resulting sequence contain the number 14?

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