与えられた因子の積としての最小整数


17

最近、素数/素数の因数分解に関連する多くの課題がありました。

与えられた:

  • 正の整数n、および
  • 正の整数の空でないリスト f

およびが要素の非負の整数乗の積であるiような最小の整数を見つける完全なプログラムまたは関数を記述します。i >= nif

例:

  • としn = 11, f = [2, 3, 5]ます。

    最初のいくつかの製品は次のとおりです。

    1   = 2^0 * 3^0 * 5^0
    2   = 2^1 * 3^0 * 5^0
    3   = 2^0 * 3^1 * 5^0
    5   = 2^0 * 3^0 * 5^1
    4   = 2^2 * 3^0 * 5^0
    6   = 2^1 * 3^1 * 5^0
    10  = 2^1 * 3^0 * 5^1
    9   = 2^0 * 3^2 * 5^0
    15  = 2^0 * 3^1 * 5^1
    25  = 2^0 * 3^0 * 5^2
    8   = 2^3 * 3^0 * 5^0
    12  = 2^2 * 3^1 * 5^0 => smallest greater than (or equal to) 11, so we output it.
    20  = 2^2 * 3^0 * 5^1
    18  = 2^1 * 3^2 * 5^0
    30  = 2^1 * 3^1 * 5^1
    50  = 2^1 * 3^0 * 5^2
    27  = 2^0 * 3^3 * 5^0
    45  = 2^0 * 3^2 * 5^1
    75  = 2^0 * 3^1 * 5^2
    125 = 2^0 * 3^0 * 5^3
    
  • としn=14, f=[9, 10, 7]ます。

    繰り返しますが、最初のいくつかの製品:

    1 = 7^0 * 9^0 * 10^0
    7 = 7^1 * 9^0 * 10^0
    9 = 7^0 * 9^1 * 10^0
    10 = 7^0 * 9^0 * 10^1
    49 = 7^2 * 9^0 * 10^0  => smallest greater than (or equal to) 14, so we output it.
    63 = 7^1 * 9^1 * 10^0
    70 = 7^1 * 9^0 * 10^1
    81 = 7^0 * 9^2 * 10^0
    90 = 7^0 * 9^1 * 10^1
    100 = 7^0 * 9^0 * 10^2
    

テストケース:

n, f -> output
10, [2, 3, 5]              -> 10
17, [3, 7]                 -> 21
61, [3,5,2,7]              -> 63
23, [2]                    -> 32
23, [3]                    -> 27
23, [2, 3]                 -> 24
31, [3]                    -> 81
93, [2,2,3]                -> 96
91, [2,4,6]                -> 96
1,  [2,3,5,7,11,13,17,19]  -> 1
151, [20,9,11]             -> 180
11616, [23,32]             -> 12167
11616, [23,32,2,3]         -> 11664 = 2^4 * 3^6
5050, [3,6,10,15,21,28,36,45,55,66,78,91,105,120,136,153,171,190,210] -> 5103 = 3^6 * 7
12532159, [57, 34, 12, 21] -> 14183424 = 12^5 * 57

ルール

  • これにfは少なくとも1つの要素が含まれ、すべての要素がf1より大きいと仮定できます。
  • 必要に応じて、必要に応じてf、降順または昇順でソートされていると想定することもできます(ただし指定してください)。
  • 必要に応じて、オプションで要素の数を取得できますf
  • 文字列としての出力が許可されています。
  • これはなので、各言語のバイト単位の最短回答が勝ちです!
  • デフォルトのI / Oルールが適用され、標準の抜け穴は禁止されています。
  • 説明が奨励されます。

回答:


10

、8バイト

ḟṠ€ȯmΠṖṘ

非常に遅い。 オンラインでお試しください!

説明

ḟṠ€ȯmΠṖṘ  Implicit inputs, say L=[3,4] and n=5.
ḟ         Find the lowest integer k≥n that satisfies:
       Ṙ   Replicate L by k: [3,3,3,3,3,4,4,4,4,4]
      Ṗ    Powerset: [[],[3],[4],..,[3,3,3,3,3,4,4,4,4,4]]
    mΠ     Product of each: [1,3,4,..,248832]
 Ṡ€ȯ       k is in this list.

7

Wolfram言語(Mathematica)68 65 62 61バイト

If[#^#2<=1,1~Max~-Log@#2,Min[#0[#,#2-1,##4],#0[#/#3,##2]#3]]&

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

使い方

入力を[n,k,f1,f2,f3,...,fk](例:)として取ります[11,3,2,3,5]:最初の値はtarget nで、2番目は因子の数で、すべてのfrctorが続きます。

他の数論の課題は最近、すべてが派手なビルトインになっています(少なくとも、使用されていますFactorInteger)。したがって、基本的なツールのみを使用するものを試してみると思いました。この解決策は基本的nに、因子の積として書くために、最初の因子を使用しf1(そしてで再帰しn/f1、次に乗算するf1)、またはしないで(そしてより短い因子のリストで再帰して)最小を取ると言います。

再帰は、ターゲットが1未満の場合、または因子の数が0の場合にボトムアウトします。これを#^#2<=1一度に確認し、最初の場合と1の場合に1を生成Infinity1~Max~-Log@#2ます。

この関数は、を使用して実行しない限りQuiet、大量の警告を表示します(ただし、引き続き機能します)。最終的に#3存在しない場合に再帰し、未使用の2番目のブランチをIfsadにします。


-3バイト:要因の数を入力として使用します。

@ngenisisのおかげで-3バイト:を使用しています。

-1バイト、あいまいさなし:#^#2チェック。


2
非常に素晴らしい!Tr [1 ^ {##}] `のバイト数を節約し3ます。-Log@0 (doesn't work on TIO, but works fine on desktop Mathematica). Also, Length@{##}
ngenisis

TIOが気に入らない最適化の使用についてどう思うかは完全にはわかりませんが、追加します。そして#2、さらに短いですTr[1^{##}]。:)
ミシャラヴロフ

1
Quietあなたはメインコードに含めるべきだと思います。この答えは間違ったメッセージをたくさん出力します。少なくともOPに大丈夫かどうか尋ねます
-J42161217

2
これは、STDERRがされている別の言語でなり無視とほとんど同じようで練習を受け入れました
ミシャラヴロフ

2
問題は、バグのように見えます。私はそれを修正しようとします。
デニス



4

ゼリー、13 バイト

L⁹ṗ’⁸*P€ḟ⁹Ḷ¤Ṃ

f左側のリストを取りn、右側の番号を取得するダイアディックリンクは、番号を生成します。

オンラインでお試しください!Golfily非効率-より高いnおよび/またはより長い入力でタイムアウトしfます。

どうやって?

個々の(厳密に肯定的な)要因の力が絶対に超える必要はないことを知っていますn-1
...それでは、考えられるすべての方法を調べてみましょう!

L⁹ṗ’⁸*P€ḟ⁹Ḷ¤Ṃ - Link: list, f; number, n
 ⁹            - chain's right argument, n
L             - length of f
  ṗ           - Cartesian power  ...e.g.: len(f)=2; n=3 -> [[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3]]
   ’          - decrement (vectorises)
    ⁸         - chain's left argument, f
     *        - exponentiate (vectorises) - that is [f1^a, f2^b, ...] for each [a, b, ...] in the list formed from the Cartesian power
      P€      - product for €ach - that is f1^a * f2^b * ... for each [a, b, ...] in the list formed from the Cartesian power
           ¤  - nilad followed by link(s) as a nilad:
         ⁹    -   chain's right argument, n
          Ḷ   -   lowered range -> [0,1,2,3,...,n-1]
        ḟ     - filter discard - that is remove values less than n
            Ṃ - minimum



2

Mathematica、85バイト

Min@Select[Flatten[1##&@@(s^#)&/@Tuples[0~Range~⌈Log[Min[s=#],d=#2]⌉,#3]],#>=d&]&

入力

[{list f}、n、fの要素数]
[{57、34、12、21}、12532159、4]


{d,s}Min@Select[Flatten[1##&@@(s^#)&/@0~Range~9~Tuples~Tr[1^s]],#>=d&]
ngenisis

@ngenisis表示されない記号は何ですか?代わりにTIOリンクを作成できますか?
J42161217

P:私は「Mathematicaの」と「TIO」は、同じポストに使用された日に見たいと思ったことはありません
caird coinheringaahing

@Jenny_mathyそれはU+F4A1、長い名前\[Function]です。
ngenisis

使用0~Range~9は非常に保守的なようです。g[{2,3,5},1001]本当にスキップし1024て戻る必要があり1080ますか?これは特に大きな入力ではありません。
ミシャラヴロフ

2

Japt、10バイト

_k e!øV}aU

オンラインでテストしてください!

インタプリタが永久に実行されないように設計された反復制限のため、最後のテストケースでは機能しません(ただし、ブラウザが1時間フリーズしたため、ここではあまり役に立ちませんでした...)

説明

_k e!øV}aU    Implicit: U = input integer, V = array of factors
_      }aU    Starting at U, find the next integer Z where
 k              the factors of Z
   e            are such that every factor
    !øV         is contained in V (e!øV -> eX{VøX}, where VøX means "V contains X").
              Implicit: output result of last expression



1

Mathematica、73バイト

1±_=1>0;n_±f_:=Or@@(#∣n&&n/#±f&/@f);n_·f_:=NestWhile[#+1&,n,!#±f&]

本質的にはRodのPython 回答の移植版です。2つの二項演算子±とを定義し·ます。の要素の積である場合とそうでない場合をn±f返します。最小の整数を返します。分割可能性テストを排除する方法を誰かが見つけ出すことができれば、ISO 8859-1エンコードを使用して10バイト節約できます。TruenfFalsen·fi

説明

1±_=1>0;                         (* If the first argument is 1, ± gives True. *)
n_±f_:=Or@@(#∣n&&n/#±f&/@f);     (* Recursively defines ±. *)
                                 (* For each element of f, check to see if it divides n. *)
                                 (* For each element # that does, check if n/# is a product of elements of f. *)
n_·f_:=NestWhile[#+1&,n,!#±f&]   (* Starting with n, keep incrementing until we find an i that satisfies i±f. *)

1

R、52バイト

function(n,f)min((y=(x=outer(f,0:n,"^"))%o%x)[y>=n])

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

3週間が経過したので、最終的に自分のソリューションを投稿すると思いました。これはブルートフォースアプローチです。

ただし、ビルトインがあります:

R、5バイト

nextn

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

Rドキュメントから:

nextnは、以上の最小の整数を返しますn。これは、に含まれる値の累乗の積として取得できますfactorsnextnfft、変換が迅速に計算されるように、to の引数をゼロで埋めるのに適した長さを見つけるために使用されることを意図しています。のデフォルト値factorsはこれを保証します。

ただし、上記のTIOリンクが示すように、一部のテストでは実装のバグが明らかになりました。

nextn(91,c(2,6))96を返すはずですが、代わりに128を返します。これは、明らかにfactorsすべてが互いに素でない場合にのみ発生します。実際、それnextn支えるCコードは、貪欲にそれぞれfactor1到達するまで順番に分割しようとすることを明らかにしています

static Rboolean ok_n(int n, int *f, int nf)
{
    int i;
    for (i = 0; i < nf; i++) {
    while(n % f[i] == 0) {
        if ((n = n / f[i]) == 1)
        return TRUE;
    }
    }
    return n == 1;
}

static int nextn0(int n, int *f, int nf) { while(!ok_n(n, f, nf)) n++; return n; }

これは、入力を降順で取得することで解決できます。


1

JavaScript(ES6)、53 50バイト

@DanielIndieのおかげで3バイト節約

カリー化構文の入力を受け取ります(n)(a)

n=>m=a=>(g=k=>k<n?a.map(x=>g(k*x)):k>m?0:m=k)(1)|m

テストケース

どうやって?

n => a => (                 // given n and a
  g = k =>                  // g = recursive function taking k
    k < n ?                 // if k is less than n:
      a.map(x => g(k * x))  //   recursive calls to g with x * k for each x in a
    :                       // else:
      k > m ?               //   if k is greater than m and m is not set to NaN:
        0                   //     ignore this result
      :                     //   else:
        m = k               //     update m to k
  )(                        // initial call to g with:
    1,                      //   k = 1
    m = +a                  //   m = either NaN or the single integer contained in a
  ) | m                     // return m

n => m = a =>(g = k => k <n?a.map(x => g(k * x)):k> m?0:m = k)(1)| mm =関数最初の実行では常にfalseが生成されるため、基本的に+ aを入力した場合と同じです。これは現在51バイト
です-DanielIndie

@DanielIndie実際には50バイトです。どうもありがとう!
アーナルド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.