セミプライムの因子を明らかにする最小の乗数


16

与えられた半素数 N、最小の正の整数見つけるMの二つの要因の一つのバイナリ表現ようにNがバイナリ表現に見出すことができるN * Mを

半素数N = 9799を考えてみましょう。

1から始まるmの異なる値を試します。

 m |  N * m |   N * m in binary
---+--------+------------------
 1 |   9799 |    10011001000111
 2 |  19598 |   100110010001110
 3 |  29397 |   111001011010101
 4 |  39196 |  1001100100011100
 5 |  48995 |  1011111101100011
 6 |  58794 |  1110010110101010
 7 |  68593 | 10000101111110001
 8 |  78392 | 10011001000111000
 9 |  88191 | 10101100001111111
10 |  97990 | 10111111011000110
11 | 107789 | 11010010100001101

最後の製品101001のバイナリ表現には、9799の2つの因子の1つ(239)の2つの表現である41のバイナリ表現が含まれているため、ここで停止します。

例

したがって、答えは11になります。

ルールとメモ

  • mの偶数の値を試しても無意味です。これらは、完全を期すために上記の例で示されています。
  • プログラムは、N * mが言語の計算能力の範囲内にあるすべてのNをサポートする必要があります。
  • あなたは因数分解することが許可されているNをのバイナリ表現の可能な各サブしようとするよりも、事前にむしろN * Mを、それが要因であることが判明したかどうかを確認するためにN
  • 以下のようMitchellSpectorによって証明されmは常に存在します。
  • これはコードゴルフなので、バイト単位の最短回答が勝ちです。標準的な抜け穴は禁止されています。

テストケース

最初の列は入力です。2列目は予想される出力です。

         N |    m |         N * m |                              N * m in binary | Factor
-----------+------+---------------+----------------------------------------------+-------
         9 |    3 |            27 |                                      [11]011 |      3
        15 |    1 |            15 |                                       [11]11 |      3
        49 |    5 |           245 |                                   [111]10101 |      7
        91 |    1 |            91 |                                    10[1101]1 |     13
       961 |   17 |         16337 |                             [11111]111010001 |     31
      1829 |    5 |          9145 |                             1000[111011]1001 |     59
      9799 |   11 |        107789 |                          1[101001]0100001101 |     41
     19951 |   41 |        817991 |                       1[1000111]101101000111 |     71
    120797 |   27 |       3261519 |                     11000[1110001]0001001111 |    113
   1720861 |  121 |     208224181 |               11000110100[100111111101]10101 |   2557
 444309323 |  743 |  330121826989 |    100110011011100110010[1101010010101011]01 |  54443
 840000701 | 4515 | 3792603165015 | 11011100110000[1000110000111011]000101010111 |  35899
1468255967 |   55 |   80754078185 |      1001011001101010100010[1110001111]01001 |    911

うーん、私たちはあなたのブラックジャックのシーケンス挑戦...で使用されるものと同様のアルゴリズム臭い
ETHproductions

@ETHproductionsうーん、本当に?彼らは正直に完全に無関係であることになっています。
アーナルド

まあ、それらは主に特定のプロパティのすべての連続した部分文字列をチェックする必要があるという点で似ています。それ以外は、実際にはかなり無関係です。
ETHproductions

「そしておそらく奨励されている」-ごめんなさい。コードの速度は気にしません。
ジョンドヴォルザーク

@JanDvorakまあまあ。削除されました。
アーナルド

回答:


6

Pyth、13バイト

ff}.BY.B*TQPQ

デモンストレーション

説明:

ff}.BY.B*TQPQ
f                Find the first integer >= to 1 where the following is true
 f         PQ    Filter the prime factors of the input
        *TQ      Multiply the input by the outer integer
      .B         Convert to a binary string
   .BY           Convert the prime factor to a binary string
  }              Check whether the factor string is in the multiple string.

6

05AB1E18 16 15バイト

ライリーのおかげで-2バイト!

Emignaのおかげで-1バイト!

[N¹*b¹Ñ¦¨båOiNq

説明:

[                   # Infinite loop start
 N                  # Push the amount of times we have iterated
  ¹*               # Multiplied by input
    b              # Convert to binary
     ¹Ñ¦¨b         # Calculate the proper divisors of the input in binary excluding one
          åO       # Check if a substring of N * m in binary is in the divisors
            iNq    # If so, print how many times we have iterated and terminate the program

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


¹Ñ¦¨båO各サブストリングをチェックする代わりに機能するはずです。
ライリー

@Rileyはそれを見つけてくれてありがとう!
Okx

2
¼および¾で置き換える別のバイトを保存できますN
エミグナ

@Emignaそのトリックについて知らなかった、ありがとう!
Okx

4

JavaScript(ES6)、96 95 80バイト

n=>F=m=>(k=p=>p&&(q=1,g=x=>1<x&&x<n&n%x<1|g(x>>1,q*=2))(p)|k(p-q))(n*m)?m:F(-~m)

再帰関数を使用する再帰関数を使用する再帰関数を返す関数。私は本当に.toString(2)ルートが短くなるのだろうかと思い始めています...

例えば変数に割り当てf=n=>...、余分なペアのペアで呼び出しますf(9)()。それが許可されていない場合(メタ投稿が+ 6 / -2にある場合)、この83バイトバージョンを標準呼び出しで使用できます。

f=(n,m)=>(k=p=>p&&(q=1,g=x=>1<x&&x<n&n%x<1|g(x>>1,q*=2))(p)|k(p-q))(n*m)?m:f(n,-~m)

両方のバージョンは、最後の3つのテストケースを除くすべてで機能します。あなたは、変更することにより、同様にこれらのテストケースを試すことができますx>>1(x-x%2)/2


それについて本当にコンセンサスがあるかどうかはわかりませんが(投稿の時点で+ 6 / -2です)、私に関する限り、最初の入力形式は問題ありません。
アーナルド

3

Bash + Unixユーティリティ、85 84バイト

for((;;m++)){ dc -e2o$[$1*m]n|egrep -q $(dc "-e2o`factor $1`nBEPn")&&break;}
echo $m

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


また、セミプライムnに対しては常にmが存在することを指摘します。その理由は次のとおりです。

n = pqと書きます。pとqは素数で、p <= qです。

bをn-1のバイナリ表現の桁数とします。次に、0からn-1までの任意のkに対して、バイナリのp *(2 ^ b)+ kは、pのバイナリ表現とそれに続くkを表すb個の追加ビットで構成されます。

したがって、0 <= k <= n-1の場合の数値p *(2 ^ b)+ kは、バイナリで記述された場合、すべてpのバイナリ表現で始まります。ただし、これらはn個の連続した数字であるため、そのうちの1つはnの倍数でなければなりません。

その結果、バイナリ表現がpのバイナリ表現で始まるnの多重mnができます。

これに基づいて、mの上限は2 sqrt(n)になります。(おそらくこれよりもはるかに厳しい上限を得ることができます。)


2

Haskell、161バイト

import Data.List
(!)=mod
a#b|a!b==0=b|0<1=a#(b+1)
g 0=[]
g n=g(n`div`2)++show(n!2)
(a%b)c|g b`isInfixOf`g(a*c)=c|0<1=a%b$c+1
f n=min(n%(n#2)$1)$n%(n`div`(n#2))$1

簡単なチェック。最初に因数分解し、次に1から線形に検索し、両方の因子の値の最小値を取得します。

最後のテストケース(1468255967)に数秒かかり、ラップトップghciについて報告(15.34 secs, 18,610,214,160 bytes)します。



2

Brachylog(2)、14バイト

ḋḃᵐD∧?:.×ḃs∈D∧

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

Brachylogでこれを14バイトで記述する方法は複数あるため、最も効率的な方法を選びました。Brachylogの提出でよくあるように、これは関数の提出です。その入力はセミプライムであり、その出力は乗数です。

説明

ḋḃᵐD∧?:.×ḃs∈D∧
ḋ               Prime decomposition (finds the two prime factors)
 ḃᵐ             Convert each factor to binary
   D            Name this value as D
    ∧?          Restart with the user input
      :.×       The output is something that can be multiplied by it
         ḃ      to produce a number which, when expressed in binary
          s     has a substring
           ∈D   that is an element of D
             ∧  (suppress an implicit constraint that D is the output; it isn't)

PrologおよびBrachylogの評価順序は、入力からすぐには推測できない最初の制約によって設定されます。このプログラムでは、それが乗算の結果に対する制約であるため、インタープリターは乗算のオペランドを可能な限り0に近づけることを目指します。一方のオペランドともう一方が出力であることがわかっているため、可能な限り最小の出力を見つけます。


1

PowerShell、136バイト

param($n)$a=2..($n-1)|?{!($n%$_)}|%{[convert]::ToString($_,2)};for(){$b=[convert]::toString(++$m*$n,2);if($a|?{$b-like"*$_*"}){$m;exit}}

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

PowerShellでのバイナリへの変換の仕組みのため、非常に時間がかかります。:-/

入力かかり$nを通して、ループ2$n-1と要因引き出します!($n%$_)。ループにそれらを送信|%{...}し、convertバイナリ(ベースにそれらのそれぞれをだ2)文字列。それらのバイナリ文字列をに保存し$aます。

次に、無限for(){...}ループに入ります。繰り返しごとに、をインクリメントし++$m、乗算し$nconvertそれをバイナリ文字列に乗算し、に格納し$bます。次に、ifその文字列はの文字列の正規表現-likeであり$a、とを出力$mexitます。


0

Perl 6、66バイト

->\n{first {(n*$_).base(2)~~/@(grep(n%%*,2..^n)».base(2))/},^∞}

正規表現ベース。

超低速。試行されるすべての数値のすべての正規表現の一致位置で、nの要素を総当たり攻撃するためです。

係数を1回だけ計算すると、パフォーマンスは向上しますが、72バイトになります。

->\n{my @f=grep(n%%*,2..^n)».base(2);first {(n*$_).base(2)~~/@f/},^∞}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.