最も近い7-Distinct-Prime製品


14

チャット経由)

OEISエントリA123321には、7つの異なる素数の積である一連の数字がリストされています。簡潔にするために、これを7DP番号と呼びます。最初のいくつかの数字とそれに対応する除数は以下のとおりです。

510510 = 2 * 3 * 5 * 7 * 11 * 13 * 17
570570 = 2 * 3 * 5 * 7 * 11 * 13 * 19
690690 = 2 * 3 * 5 * 7 * 11 * 13 * 23
746130 = 2 * 3 * 5 * 7 * 11 * 17 * 19

ここでの課題は、指定された入力から、絶対距離の観点から最も近い7DP番号を見つけることです。

入力

任意の便利な形式の単一の正の整数n

出力

nに最も近い7DP番号。これも便利な形式です。2つの7DP番号が最も近くに結び付けられている場合、どちらかまたは両方を出力できます。

ルール

  • 数値は、言語のデフォルトの[int]データ型(または同等のもの)に収まると見なすことができます。
  • 完全なプログラムまたは機能のいずれかが受け入れられます。
  • 標準的な抜け穴は禁止されています。
  • これはであるため、通常のゴルフルールがすべて適用され、最短のコードが優先されます。

5 -> 510510
860782 -> 870870
1425060 -> 1438710 (or 1411410, or both)

回答:


11

Python、89 86 85バイト

f=lambda n,k=0:126^sum(1>>n%i<<7*(n/i%i<1)for i in range(2,n))and f(n+k,k%2*2+~k)or n

アルゴリズムは最初はO(怖い)であり、再帰は実際には役に立たないが、nが7DP数に十分に近い限りうまく機能する。

3バイトのゴルフを楽しんでくれた@xnorに感謝します!

repl.itでテストします

使い方

Pythonには素数性や因数分解が組み込まれていませんが、除数の量と性質によって7DP番号を識別できます。

乗算の原理により、整数の約数は、その素因数分解の増分指数の積として計算できます。したがって、σ 0(N) 約数関数は)は2 m個たびN MDP番号です。

σ 0(N)= 128ことが必要条件であるが、それは十分ではありません。例えば、σ 0(2 127)= 128が、2 127は明確7DP番号ではありません。しかしながら、両方の場合にσ 0(N)= 128と完璧な正方形分割N均等、次いでN 7DP番号です。

入力nの場合、アルゴリズムは整数nn-1n + 1n-2n + 2などを検査し、7DP番号である最初の整数を返します。

ときfは引数で呼び出されたN、次の処理が行われます。

  • コード

    126^sum(1>>n%i<<7*(n/i%i<1)for i in range(2,n))

    次のように、nが7DP番号でないかどうかをテストします。

    1 <i <nであるようなすべての整数iについて、評価されます。1>>n%i<<7*(n/i%i<1)

    • 場合nがで割り切れるIなくによって、I 21>>n%i収率1及び(n/i%i<1)収量0で、その結果、
      1・2 7・0 = 1

    • 場合nがで割り切れるI 21>>n%i及び(n/i%i<1)両方収率1で得られた、1・2 7・1 = 128

    • もしNで割り切れないないI1>>n%i収率が0になり、・2 0 7・X = 0


    得られた整数であろうとの合計2 m個 - 2あればnは MDPの数である(その2 m個除いた除数、1およびN)よりも数も大きい127場合Nは完全な方形係数を有します。したがって、nが7DP番号の場合にのみ、合計は126になります。

  • 7DP番号について、合計は126そうでそれをXOR、126の歩留まり0 falsyあります。したがって、ラムダの一部または一部が実行され、fnの現在の値を返します。

  • nが7DP番号でない場合、XORはゼロ以外の真実の値を返します。したがって、ラムダのとの部分が実行されます。

    f(n+k,k%2*2+~k)

    n(次の潜在的な7DP番号)とk(新しい候補とその後の候補との差)の更新された値で再帰的にfを呼び出します。

    場合kがあっても、負でない整数であり、k%2*2得られる0及び~k収率(K + 1) - 。両方の結果の合計は-(k + 1)です。これは、kより絶対値が1大きい奇数の負の整数です。

    場合kが奇数の、負の整数であり、k%2*2得られる2及び~k収率(K + 1) - 。両方の結果の合計は2-(k + 1)=-(k-1)です。これは、kよりも絶対値が1単位大きい偶数の非負整数です。

    これは、kが値0、-1、2、-3、4、⋯を取ることを意味します。

    累積的に添加した場合、N 0(初期値N)、得られた整数であります

    • n 0 + 0
    • N 0 + 0) - 1 = N 0 - 1
    • n 0-1)+ 2 = n 0 + 1
    • N 0 + 1) - 3 = N 0 - 2
    • n 0-2)+ 4 = n 0 + 2


    作りは確かに私たちが遭遇する最初の7DP番号は、近くにあるnは0できるだけ。


除数をカウントする素晴らしいアイデアです!私はあなたがゴルフ更新することで、交流歩くことができると考えるkように直接f(n+k,k%2*2+~k)で始まります、k=0
-xnor

大幅な改善。ありがとう!
デニス

9

Brachylog44 40 16バイト

取り消し線44は、まだ規則的な44です;(

:I=+.>0,.$pPdPl7

例:

?- run_from_atom(':I=+.>0,.$pPdPl7',1425060,Z).
Z = 1438710 .

この言語が常に悪いとは限りませんか?私はゼリーとMATLを打ちました!

テストケース5は最長で、私のマシンでは約10秒かかります。

$pバグがない場合、これは12バイトになります(この>0,.部分は必要ありません)

説明

Brachylogは、すべての整数演算にデフォルトで制約論理プログラミングを使用します。さらに、組み込みのラベル付けは=、おそらく無限のドメインで機能します。

次のように、制約なしで(つまり、(-inf, inf))変数を連続的に統合します0, 1, -1, 2, -2, 3, …

したがって、(自動バックトラッキングを使用して)I統合された最初の番号(-inf, inf)(7DP番号)を探すことで、最も近い7DP番号を取得できますInput + I

:I=                Label variables in [Input, I]. I has no constraints and Input is known
   +.              Unify Output with Input + I
     >0,           Output > 0 (wouldn't be needed if $p failed for numbers less than 1)
        .$pP       Unify P with the list of prime factors of Output
            dP     Check that P with duplicates removed is still P
              l7   Check that the length of P is 7

1
私はゼリーとMATLを打ちました!しかし、0バイトのみ:-P
ルイスメンドー

1
@LuisMendoでバグを修正すると13バイトになります$p。理論的には>0,、私は必要ありませんが、私の実装はバグがあります:P-
致命的な

1
@DavidCはい、それは入力で始まり、すべての数値をそのように試行するInput+1, Input-1, Input+2, Input-2, Input+3, ...ためです。したがって、そのメソッドで見つかった最初の7DPが最も近くなります。
16年

1
@matチャレンジが投稿された後にバグを修正すると、回答が競合しなくなるため、16バイトのままにします(>0,.必要ない場合)
16年

1
codegolf.stackexchange.com/a/111998/59995取り消し線 444はまだ444です。取り消し線4444を見ると感動します
。– NoSeatbelts

7

ゼリー、17バイト

Pµạ³,
×⁹ÆRœc7Ç€ṂṪ

理論的には機能しますが、完了するには何年もかかります。


以下は、指定された入力に対して実際に機能するバージョンですが、理論的には大きな入力に対しては機能しません。

Pµạ³,
50ÆRœc7Ç€ṂṪ

ここで試してみてください。これにより、最大50個の素数がすべて生成され、そのリスト内の素数の7つの組み合わせがすべて検索され、次にすべての積が検索されます。最後に、リストから指定された引数に最も近い要素を見つけます。

もちろん、7DPに50を超える素数が含まれると、これは失敗します。理論的なバージョンは、入力nに対して最大256nまでの素数をすべて生成しますが、それ以外は同じように機能します。

証明

p(x)の次の素数を示しましょうx。xに最も近い7DP製品の(非常に緩やかな)上限は次のとおりです。

p(x) * p(p(x)) * p(p(p(x))) * ... * p(p(p(p(p(p(p(x)))))))

したがって、[2…p(p(p(p(p(p(p(x())))))))の素数のみをチェックする必要があります。Bertrandの仮定では、p(x)≤2xであるため、128xまでのすべての素数をチェックするだけで十分です


×⁹ÆRœc7P€µạ³ỤḢịまたは×⁹ÆRœc7P€µạ³NMịすべてのソリューションの配列を印刷する)は、数バイトを節約します。また、効率を改善するために×⁹変更できます+⁴
デニス

5

MATL21 17 16 14 13バイト

4バイトを削除する提案をしてくれたDennisと、もう1バイト節約した別の提案に感謝します!

t17*Zq7XN!pYk

これは理論的には機能しますが、上記の入力に対してメモリが不足します6(オンラインコンパイラ)。

より効率的なバージョンでは21バイトを使用し、すべてのテストケースを約1秒で計算します。

t3e4/k16+_YqZq7XN!pYk

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

説明

メモリ効率の高いバージョン

例として入力N = 860782を取り上げます。Nを超える最初の素数であるM = までの素数を考慮するだけで十分です。この例では、。次の素数はです。その素数以上を含む積は少なくともであり、そのため、Nを超えるものを超えるため、解ではないことが保証されます。292*3*5*7*11*132*3*5*7*11*13*29 = 870870312*3*5*7*11*13*31 = 930930870870

Mは、より大きい最初の素数として計算されmax(N/(2*3*5*7*11*13), 16)ます。このmax関数は、少なくとも17選択されていることを確認するために使用されます。数バイトを節約するために、コードはに置き換え2*3*5*7*11*13 = 30030られ30000、機能maxは追加されます。これらの変更は、より大きな値を与えるため有効です。

t      % Take input implicitly. Duplicate
3e4/k  % Divide input by 30000 and round down (rounding here is only needed
       % due to a bug in the "next prime" function)
16+    % Add 16
_Yq    % Next prime
Zq     % Prime numbers up to that value
7XN    % Combinations of those primes taken 7 at a time. Gives a 2D array
       % with each combination on a different row
!p     % Product of each row
Yk     % Output product that is closest to the input. Implicitly display

メモリ効率の悪いバージョン

バイト数をさらに減らすために、除算を削除できます。実際、乗算するだけで十分です17(ありがとう、@ Dennis)。これにより、次の素数が(Bertrandの仮定により)含まれ、結果が少なくともであることが保証され17ます。これは理論的には機能しますが、約より大きい入力ではメモリ不足になり6ます。

コードでは、セクション

3e4/k  % Divide input by 30000 and round down (rounding here is only needed
       % due to a bug in the "next prime" function)
16+    % Add 16
_Yq    % Next prime

に置き換えられます

17*    % Multiply by 17

3

Pyke、32バイト

#PDl 7q.ID}lRlqi*(#)DF-X,)R],She

ここで試してみてください!

これはオンラインでは機能しないことに注意してください-タイムアウトします。このバージョンは2つの異なる素数のみをチェックし、より高速に動作するはずです。ターゲットから同じ距離の数値が2つある場合、低い方が選択されます。

これは、入力よりも大きく、7DPである番号が見つかるまで、すべての番号を調べます。各番号について、7DPでない場合はそれを取り除きます。次に、入力までの7DPのリストとそれより大きいものがあります。次に、入力に最も近いものを選択します。


3

ジュリア、59バイト

!n=sort(map(prod,combinations(17n|>primes,7))-n,by=abs)[]+n

これは非常に非効率的ですが、実際の最初のテストケースと理論上の他のテストケースで機能します。

さらに5バイト(合計64バイト)のコストで、効率を劇的に改善できます。

!n=sort(map(prod,combinations(n>>14+17|>primes,7))-n,by=abs)[]+n

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

バックグラウンド

@LuisMendoの回答で述べたように、最も近い7DP数について考慮しなければならない素数の集合は非常に小さいです。入力よりも大きい7DP番号含有することがセットで十分N、それが素数含まれている場合にのみ場合に真となり、pは≥17ように2 = 30300p・3・5・7・11・13・P ≥N

少なくとも一つの素数を含む間隔に間隔ことを証明している[X、1.5倍)は少なくとも一つの素数たびに含まX≥8 。以降1.83≈30030/16384、手段は素数が存在しなければならないことPにおける(N / 30030、N / 16384)たびに、N> 8・30300 = 242400

最後に、n <510510の場合、p = 17で十分であるため、n / 16384 + 17までの素数のみを考慮する必要があります。

効率を犠牲にして、代わりに最大17nの素数を考慮することができます。これは、n = 1のときに機能し、nの値が大きい場合はn / 16384 + 17よりも大幅に大きくなります。

使い方

17n|>primes及びn>>14+17|>primes(ビットシフトにより除算と等価である2 14 = 16384)前の段落で述べたプライム範囲を計算します。次に、combinations(...,7)その範囲内の7つの異なる素数のすべての配列をprod計算し、それらをマッピングするとそれらの積、つまり答えを選択する7DP数が計算されます。

次に、7DP番号ごとにn個の promを-n減算し、それらの差を絶対値でソートします。最後に、との最初の差を選択し、nnを追加して対応する7DP番号を計算します。sort(...,by=abs)[]+n


2

Pyth、30バイト

L&{IPbq7lPby#.W!syMH,hhZa0teZ,

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

テストスイート。

(5は実行に時間がかかりすぎます)

説明

L&{IPbq7lPby#.W!syMH,hhZa0teZ,

L&{IPbq7lPb     Defines a function y, whose argument is b:
 &                  Return if both the following are true:
  {IPb                  the prime factorization contains no duplicate; and:
      q7lPb             the number of prime factors is 7

           y#.W!syMH,hhZa0teZ,   The main programme. Input as Q.
                             ,QQ Implicit arguments, yield [Q,Q].
             .W                  While
               !syMH                   both numbers do not satisfy y:
                    ,hhZ             increment the first number
                          teZ        and decrement the second number
                        a0           while making it non-negative.

1

Mathematica 136 80 75バイト

これは簡単なアプローチで、から外側に向かって働きnます。

nは、素因数の数が7(PrimeNu@#==7)であり、これらの要素のいずれも2回以上出現しない場合()の場合、7固有素数の積SquareFreeQ@#&です。

g@n_:=(k=1;While[!(PrimeNu@#==7&&SquareFreeQ@#&)⌊z=n-⌊k/2](-1)^k⌋,k++];z)

以前の提出(136バイト)では、最初の7-distinct-prime製品nと、存在する場合は最初の7-distinct-prime製品の両方が見つかりましたn。次に、どちらがより近いかを単純に判断しましたn。製品が等距離の場合、両方を返しました。

現在のバージョンは、最初の7-distinct-prime製品に到達するまでn-1、n + 1、n-2、n + 2 ...をチェックします。このより効率的なバージョンでは、デニスが採用したアプローチを採用しています。

重要な進歩は、使用中⌊k/2](-1)^k⌋、1、0、シリーズを戻すために-1、2、-2 ...ゼロかどうかを確認するために使用されるn7-異なるプライム製品そのものです。このため、の代わりにFloor(つまり、⌊...⌋)が使用されますCeiling


g[5]
g[860782]
g[1425060]

510510

870870

1438710


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