主な要因


21

整数を指定するとN > 1、素分解がの素分解と同じ桁を持つ他のすべての数値を出力しますN

たとえば、の場合N = 117、出力はでなければなりません[279, 939, 993, 3313, 3331]

117 = 3 × 3 × 13

そのため、可能な数字であり133そして3、私たちは持っています

279  = 3 × 3 × 31
939  = 3 × 313
993  = 3 × 331
3313 = 3313
3331 = 3331

これらの数字の他の組み合わせは、素因数分解の結果とはなり得ない非素数整数を生成するため、これらは唯一の他の可能な数です。

場合Nのいずれかである1172799399933313あるいは3331、出力は他の5つの数字が含まれています:彼らは、素因数の仲間です。

先行ゼロを使用して素数を取得することはできません。たとえば、のN = 107場合、唯一のバディは701017考慮されません)です。

入力と出力

  • 入力および出力バディを取得し、10進数で返す必要があります。

  • Nは常に厳密により大きいです1

  • 出力は、バディとセパレーター/リスト構文要素のみを含む限り、かなり自由にフォーマットできます。

  • 出力の順序は重要ではありません。

  • STDIN関数の引数または同様のものとして、を介して入力を受け取ることができます。

  • 出力をSTDOUTに印刷して、関数から返すか、類似のものを返すことができます。

テストケース

プログラムは、以下のテストケースのいずれかを1分以内に解決する必要があります。

N        Buddies
2        []
4        []
8        []
15       [53]
16       []
23       [6]
42       [74, 146, 161]
126      [222, 438, 483, 674, 746, 851, 1466, 1631, 1679]
204      [364,548,692,762,782,852,868,1268,1626,2474,2654,2921,2951,3266,3446,3791,4274,4742,5426,5462,6233,6434,6542,7037,8561,14426,14642,15491,15833,22547]

得点

これはであるため、バイト単位の最短回答が優先されます。

回答:


4

ゼリー、14 バイト

ÆfVṢṚḌ
ÇÇ€=ÇTḟ

実行時間はのDF代わりに半分にすることができますVが、それでも30秒以内に結合されたテストケースを完了します。

オンラインでお試しください!または、すべてのテストケースを確認します

使い方

ÆfVṢṚḌ   Helper link. Argument: k (integer)

Æf       Decompose k into an array of primes with product k.
  V      Eval. Eval casts a 1D array to string first, so this computes the integer
         that results of concatenating all primes in the factorization.
   Ṣ     Sort. Sort casts a number to the array of its decimal digits.
    Ṛ    Reverse. This yields the decimal digits in descending order.
     Ḍ   Undecimal; convert the digit array from base 10 to integer.


ÇÇ€=ÇTḟ  Main link. Argument: n (integer)

Ç        Call the helper link with argument n.
         This yields an upper bound (u) for all prime factorization buddies since
         the product of a list of integers cannot exceed the concatenated integers.
 ǀ      Apply the helper link to each k in [1, ..., u].
    Ç    Call the helper link (again) with argument n.
   =     Compare each result to the left with the result to the right.
     T   Truth; yield all 1-based indices of elements of [1, ..., u] (which match
         the corresponding integers) for which = returned 1.
      ḟ  Filter; remove n from the indices.

時間の制約を考えると、それÇ€=$よりも少し高速になると思いÇ€=Çます。
エリックアウトゴルファー

感謝しますが、入力117の場合、改善点はヘルパーリンクが3332回ではなく3331回呼び出されることを意味するため、スピードアップは測定できません。とにかく、新しい(より高速な)TIOは、組み合わされたテストケースに20秒も必要としません。
デニス

16

PowerShell v3 +、450バイト

param($n)function f{param($a)for($i=2;$a-gt1){if(!($a%$i)){$i;$a/=$i}else{$i++}}}
$y=($x=@((f $n)-split'(.)'-ne''|sort))|?{$_-eq(f $_)}
$a,$b=$x
$a=,$a
while($b){$z,$b=$b;$a=$a+($a+$y|%{$c="$_";0..$c.Length|%{-join($c[0..$_]+$z+$c[++$_..$c.Length])};"$z$c";"$c$z"})|select -u}
$x=-join($x|sort -des)
$l=@();$a|?{$_-eq(f $_)}|%{$j=$_;for($i=0;$i-le$x;$i+=$j){if(0-notin($l|%{$i%$_})){if(-join((f $i)-split'(.)'|sort -des)-eq$x){$i}}}$l+=$j}|?{$_-ne$n}

最後に!

PowerShellには、素数性チェック、因数分解、順列の組み込み機能がないため、これは完全に手作業で行われます。私はを通じて働いたくさん試してみて、挑戦の制限に収まる何かまでの時間の複雑さを軽減するために、最適化のトリックの、と私は私が最終的に成功したことを言って満足しています-

PS C:\Tools\Scripts\golfing> Measure-Command {.\prime-factors-buddies.ps1 204}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 27
Milliseconds      : 114
Ticks             : 271149810
TotalDays         : 0.000313830798611111
TotalHours        : 0.00753193916666667
TotalMinutes      : 0.45191635
TotalSeconds      : 27.114981
TotalMilliseconds : 27114.981

説明

ここでは多くのことが行われているので、これを分析してみます。

最初の行は入力かかる$nと定義functionf。この関数は累積試行除算を使用して、素因数のリストを作成します。入力が小さい場合はかなり高速ですが、入力が大きい場合は明らかに動きが取れなくなります。ありがたいことに、すべてのテストケースは小さいため、これで十分です。

次の行は取得f俳優のを$n-split任意の空の結果を無視して、すべての数字の上にそれらをS(これは、PowerShellは正規表現のマッチングとどのようにそれが入力によってポインタを移動し、ゴルフの目的のためにちょっと面倒ですがどうするかによるが必要である)、その後、sort結果をよ昇順で。その数字の配列をに格納し$x、それを|?{...}フィルターへの入力として使用して、それ自体が素数であるもののみを引き出します。これらの素数は$y後で使用するために保存されます。

次に$x、2つのコンポーネントに分割します。最初の(つまり、最小の)数字はに格納され$a、残りはに渡され$bます。$x1桁しかない場合、$b空/ヌルになります。その後$a、配列として再キャストする必要があります。そのため、カンマ演算子を使用してクイックキャストを行います。

次に、数字の可能なすべての順列を作成する必要があります。私たちの部門のテストは、後にスキップするようにするために必要ですたくさんより速く、全体的な数字やメイク、物事のを。

要素が残っている$b限り、最初の数字を剥がし$zて残りをのままにし$bます。次に、$a文字列のスライスとダイシングの結果に蓄積する必要があります。私たちは取る$a+$y配列の連結として、各要素のために私たちは、新しい文字列の構築$cを通じて、その後、ループ$c.length、挿入$z前に付けるなど、あらゆる位置に、$z$c及び付加し$c$zた後、select唯一のINGの-uniqueの要素を。それは再び配列連結され$a、に再格納され$aます。はい、これは間抜けなことを起こしてしまいます。あなたが3333入力を得ることができるように117、これは実際には順列ではありませんが、これは明示的にそれらを除外するよりもはるかに短く、すべての順列を確実に取得し、非常にわずかに遅いだけです。

その$aため、因子の桁の可能なすべての(そしていくつかの)順列の配列ができました。数字を昇順で並べ、それらを元に戻すこと$xにより、可能な結果の上限になるように再設定する必要があります。明らかに、この値よりも大きい出力値はありません。|sort-des-join

ヘルパー配列$lを、以前に見た値の配列に設定します。次に、$a素数である(つまり、それらの順列)からすべての値を引き出し、プログラム全体の最大のタイムシンクであるループに入ります...

繰り返しごとに、現在の要素でインクリメントしながら0上限からループします。検討している値が前の値の倍数(セクション)でない限り、出力の潜在的な候補です。のアクター、それら、およびそれらのualを取得する場合、パイプラインに値を追加します。ループの最後で、現在の要素を配列に追加して、次回使用できるようにします。これらの値はすべて検討済みです。$x$j$i0-notin($l|%{$i%$_})f$isort-eq$x$j$l

最後に、|?{$_-ne$n}入力要素ではないものを取り出すために取り組みます。それらはすべてパイプラインに残されており、出力は暗黙的です。

PS C:\Tools\Scripts\golfing> 2,4,8,15,16,23,42,117,126,204|%{"$_ --> "+(.\prime-factors-buddies $_)}
2 --> 
4 --> 
8 --> 
15 --> 53
16 --> 
23 --> 6
42 --> 74 146 161
117 --> 279 939 993 3313 3331
126 --> 222 438 674 746 1466 483 851 1679 1631
204 --> 782 2921 3266 6233 3791 15833 2951 7037 364 868 8561 15491 22547 852 762 1626 692 548 1268 2654 3446 2474 5462 4742 5426 4274 14426 6542 6434 14642

それは私が今まで見た中で最も多くのドルです!
16

1
@Fatalizeこれは450のうち64にすぎません。PowerShellの回答では、驚くほど低い割合で割合(14.22%)です。
AdmBorkBork

8

CJam26 23バイト

{_mfs$:XW%i){mfs$X=},^}

オンラインで試す

説明

2つの数値を連結すると、乗算するよりも常に大きな結果が得られます。したがって、おそらく考慮する必要がある最大数は、入力の素因数分解の桁から形成できる最大数です。これは、すべての桁が降順にソートされているだけです。与えられた数値に対して、この上限は簡単に十分小さいため、範囲内のすべての数値を素因数相棒であるかどうかを徹底的にチェックできます。

_mf    e# Duplicate input N and get a list of its prime factors.
s$     e# Convert the list to a (flattened) string and sort it.
:X     e# Store this in X for later.
W%     e# Reverse it. This is now a string repesentation of the largest 
       e# possible output M.
i)     e# Convert to integer and increment.
{      e# Get a list of all integers i in [0 1 ... M] for which the following
       e# block gives a truthy result.
  mf   e#   Get list of prime factors of i.
  s$   e#   Get a sorted list of the digits appearing in the factorisation.
  X=   e#   Check for equality with X.
},
^      e# Symmetric set difference: removes N from the output list.

6

05AB1E、17バイト

コード:

ÒJ{©RƒNÒJ{®QN¹Ê*–

説明:

Ò                  # Get the factorization with duplicates, e.g. [3, 3, 13]
 J                 # Join the array, e.g. 3313
  {©               # Sort and store in ©, e.g. 1333
    R              # Reverse the number, e.g. 3331. This is the upperbound for the range
     ƒ             # For N in range(0, a + 1), do...
      NÒ           # Push the factorization with duplicates for N
        J          # Join the array
         {         # Sort the string
          ®Q       # Check if equal to the string saved in ©
            N¹Ê    # Check if not equal to the input
               *   # Multiply, acts as a logical AND
                –  # If 1, print N

CP-1252エンコードを使用します。オンラインでお試しください!


4

Pyth、17

LSjkPb-fqyTyQSs_y

テストスイート

Martinの投稿と同じ観察結果を使用します。

拡張:

LSjkPb        ##  Define a function y(b) to get the sorted string of digits
              ##  of the prime factors of b
    Pb        ##  prime factors
  jk          ##  join to a string with no separator
 S            ##  Sort

-fqyTyQSs_yQQ ##  Auto-fill variables
         _yQ  ##  get reversed value of y(input)
       Ss     ##  convert that string to a list [1 ... y(input)]
 fqyTyQ       ##  keep numbers T from the list that satisfy y(T)==y(input)
-           Q ##  remove the input from the result

3

JavaScript(ES6)、163 158バイト

編集:23などの素数は空の結果セットではなく[6]を返す必要があることが明確になりました。-意図的に-それが起こらないようにした、今では役に立たないルールを削除することで5バイトを節約しました。

最後のテストケースは、このスニペットが十分に高速に実行されるようにコメントされていますが、1分以内に完了する必要があります。

let f =

n=>[...Array(+(l=(p=n=>{for(i=2,m=n,s='';i<=m;n%i?i++:(s+=i,n/=i));return s.split``.sort().reverse().join``})(n))+1)].map((_,i)=>i).filter(i=>i&&i-n&&p(i)==l)

console.log(JSON.stringify(f(2)));
console.log(JSON.stringify(f(4)));
console.log(JSON.stringify(f(8)));
console.log(JSON.stringify(f(15)));
console.log(JSON.stringify(f(16)));
console.log(JSON.stringify(f(23)));
console.log(JSON.stringify(f(42)));
console.log(JSON.stringify(f(126)));
//console.log(JSON.stringify(f(204)));


1

PHP 486バイト

本ではそうではないアルゴリズムでおそらく短くなる可能性があります。
(しかし、私は現在のバイト数が好きです)

function p($n){for($i=1;$i++<$n;)if($n%$i<1&&($n-$i?p($i)==$i:!$r))for($x=$n;$x%$i<1;$x/=$i)$r.=$i;return $r;}function e($s){if(!$n=strlen($s))yield$s;else foreach(e(substr($s,1))as$p)for($i=$n;$i--;)yield substr($p,0,$i).$s[0].substr($p,$i);}foreach(e(p($n=$argv[1]))as$p)for($m=1<<strlen($p)-1;$m--;){$q="";foreach(str_split($p)as$i=>$c)$q.=$c.($m>>$i&1?"*":"");foreach(split("\*",$q)as$x)if(0===strpos($x,48)|p($x)!=$x)continue 2;eval("\$r[$q]=$q;");}unset($r[$n]);echo join(",",$r);

壊す

// find and concatenate prime factors
function p($n)
{
    for($i=1;$i++<$n;)  // loop $i from 2 to $n
        if($n%$i<1      // if $n/$i has no remainder
            &&($n-$i    // and ...
                ?p($i)==$i  // $n!=$i: $i is a prime
                :!$r        // $n==$i: result so far is empty ($n is prime)
            )
        )
            for($x=$n;      // set $x to $n
                $x%$i<1;    // while $x/$i has no remainder
                $x/=$i)     // 2. divide $x by $i
                $r.=$i;     // 1. append $i to result
    return $r;
}

// create all permutations of digits
function e($s)
{
    if(!$n=strlen($s))yield$s;else  // if $s is empty, yield it, else:
    foreach(e(substr($s,1))as$p)    // for all permutations of the number w/o first digit
        for($i=$n;$i--;)            // run $i through all positions around the other digits
            // insert removed digit at that position and yield
            yield substr($p,0,$i).$s[0].substr($p,$i);
}

// for each permutation
foreach(e(p($n=$argv[1]))as$p)
    // create all products from these digits: binary loop through between the digits
    for($m=1<<strlen($p)-1;$m--;)
    {
        // and insert "*" for set bits
        $q="";
        foreach(str_split($p)as$i=>$c)$q.=$c.($m>>$i&1?"*":"");
        // test all numbers in the expression
        foreach(split("\*",$q)as$x)
            if(
                0===strpos($x,48)   // if number has a leading zero
                |p($x)!=$x          // or is not prime
            )continue 2; // try next $m
        // evaluate expression and add to results (use key to avoid array_unique)
        eval("\$r[$q]=$q;");
    }

// remove input from results
unset($r[$n]);

// output
#sort($r);
echo join(",",$r);

1

実際には、27バイト

これは、MartinAdnanFryAmTheEggman、およびDennisが使用しているのと同じアルゴリズムを使用します。ゴルフの提案を歓迎します。オンラインでお試しください!

`w"i$n"£MΣSR≈`╗╜ƒ;╝R`╜ƒ╛=`░

アンゴルフ

          Implicit input n.
`...`╗    Define a function and store it in register 0. Call the function f(x).
  w         Get the prime factorization of x.
  "..."£M   Begin another function and map over the [prime, exponent] lists of w.
    i         Flatten the list. Stack: prime, exponent.
    $n        Push str(prime) to the stack, exponent times.
               The purpose of this function is to get w's prime factors to multiplicity.
  Σ         sum() the result of the map.
             On a list of strings, this has the same effect as "".join()
  SR≈       Sort that string, reverse it and convert to int.
╜ƒ        Now push the function stored in register 0 and call it immediately.
           This gives the upper bound for any possible prime factor buddy.
;╝        Duplicate this upper bound and save a copy to register 1.
R         Push the range [0..u]
`...`░    Filter the range for values where the following function returns a truthy.
           Variable k.
  ╜ƒ        Push the function in register 0 and call it on k.
  ╛=        Check if f(k) == f(n).
          Implicit return every value that is a prime factor buddy with n, including n.

1

Powershell、147バイト(CodeGolfバージョン)

param($n)filter d{-join($(for($i=2;$_-ge$i*$i){if($_%$i){$i++}else{"$i"
$_/=$i}}if($_-1){"$_"})|% t*y|sort -d)}2..($s=$n|d)|?{$_-$n-and$s-eq($_|d)}

注:スクリプトは、私のローカルノートブックで3分未満の最後のテストケースを解決します。以下の「パフォーマンス」ソリューションを参照してください。

ゴルフの少ないテストスクリプト:

$g = {

param($n)
filter d{                       # in the filter, Powershell automatically declares the parameter as $_
    -join($(                    # this function returns a string with all digits of all prime divisors in descending order
        for($i=2;$_-ge$i*$i){   # find all prime divisors
            if($_%$i){
                $i++
            }else{
                "$i"            # push a divisor to a pipe as a string
                $_/=$i
            }
        }
        if($_-1){
            "$_"                # push a last divisor to pipe if it is not 1
        }
    )|% t*y|sort -d)            # t*y is a shortcut to toCharArray method. It's very slow.
}
2..($s=$n|d)|?{                 # for each number from 2 to number with all digits of all prime divisors in descending order
    $_-$n-and$s-eq($_|d)        # leave only those who have the 'all digits of all prime divisors in descending order' are the same
}

}

@(
    ,(2   ,'')
    ,(4   ,'')
    ,(6   ,23)
    ,(8   ,'')
    ,(15  ,53)
    ,(16  ,'')
    ,(23  ,6)
    ,(42  ,74, 146, 161)
    ,(107 ,701)
    ,(117 ,279, 939, 993, 3313, 3331)
    ,(126 ,222, 438, 483, 674, 746, 851, 1466, 1631, 1679)
    ,(204 ,364,548,692,762,782,852,868,1268,1626,2474,2654,2921,2951,3266,3446,3791,4274,4742,5426,5462,6233,6434,6542,7037,8561,14426,14642,15491,15833,22547)
) | % {
    $n,$expected = $_

    $sw = Measure-Command {
        $result = &$g $n
    }

    $equals=$false-notin(($result|%{$_-in$expected})+($expected|?{$_-is[int]}|%{$_-in$result}))
    "$sw : $equals : $n ---> $result"
}

出力:

00:00:00.0346911 : True : 2 --->
00:00:00.0662627 : True : 4 --->
00:00:00.1164648 : True : 6 ---> 23
00:00:00.6376735 : True : 8 --->
00:00:00.1591527 : True : 15 ---> 53
00:00:03.8886378 : True : 16 --->
00:00:00.0441986 : True : 23 ---> 6
00:00:01.1316642 : True : 42 ---> 74 146 161
00:00:01.0393848 : True : 107 ---> 701
00:00:05.2977238 : True : 117 ---> 279 939 993 3313 3331
00:00:12.1244363 : True : 126 ---> 222 438 483 674 746 851 1466 1631 1679
00:02:50.1292786 : True : 204 ---> 364 548 692 762 782 852 868 1268 1626 2474 2654 2921 2951 3266 3446 3791 4274 4742 5426 5462 6233 6434 6542 7037 8561 14426 14642 15491 15833 22547

Powershell、215バイト(「パフォーマンス」バージョン)

param($n)$p=@{}
filter d{$k=$_*($_-le3e3)
($p.$k=-join($(for($i=2;!$p.$_-and$_-ge$i*$i){if($_%$i){$i++}else{"$i"
$_/=$i}}if($_-1){($p.$_,"$_")[!$p.$_]})-split'(.)'-ne''|sort -d))}2..($s=$n|d)|?{$_-$n-and$s-eq($_|d)}

注:パフォーマンス要件はGodeGolfの原則と矛盾していると思います。しかし、ルールがあるYour program should solve any of the test cases below in less than a minuteため、ルールを満たすために2つの変更を加えました。

  • -split'(.)'-ne''代わりに短いコード|% t*y
  • 文字列をキャッシュするためのハッシュテーブル。

変更ごとに評価時間が半分に短縮されます。パフォーマンスを改善するためにすべての機能を使用したとは思わないでください。ルールを満たすにはそれらだけで十分でした。

ゴルフの少ないテストスクリプト:

$g = {

param($n)
$p=@{}                          # hashtable for 'all digits of all prime divisors in descending order'
filter d{                       # this function returns a string with all digits of all prime divisors in descending order
    $k=$_*($_-le3e3)            # hashtable key: a large hashtable is not effective, therefore a key for numbers great then 3000 is 0
                                # and string '-le3e3' funny
    ($p.$k=-join($(             # store the value to hashtable
        for($i=2;!$p.$_-and$_-ge$i*$i){
            if($_%$i){$i++}else{"$i";$_/=$i}
        }
        if($_-1){
            ($p.$_,"$_")[!$p.$_] # get a string with 'all digits of all prime divisors in descending order' from hashtable if it found
        }
    )-split'(.)'-ne''|sort -d)) # split each digit. The "-split'(.)-ne''" code is faster then '|% t*y' but longer.
}
2..($s=$n|d)|?{                 # for each number from 2 to number with all digits of all prime divisors in descending order
    $_-$n-and$s-eq($_|d)        # leave only those who have the 'all digits of all prime divisors in descending order' are the same
}

}

@(
    ,(2   ,'')
    ,(4   ,'')
    ,(6   ,23)
    ,(8   ,'')
    ,(15  ,53)
    ,(16  ,'')
    ,(23  ,6)
    ,(42  ,74, 146, 161)
    ,(107 ,701)
    ,(117 ,279, 939, 993, 3313, 3331)
    ,(126 ,222, 438, 483, 674, 746, 851, 1466, 1631, 1679)
    ,(204 ,364,548,692,762,782,852,868,1268,1626,2474,2654,2921,2951,3266,3446,3791,4274,4742,5426,5462,6233,6434,6542,7037,8561,14426,14642,15491,15833,22547)
) | % {
    $n,$expected = $_

    $sw = Measure-Command {
        $result = &$g $n
    }

    $equals=$false-notin(($result|%{$_-in$expected})+($expected|?{$_-is[int]}|%{$_-in$result}))
    "$sw : $equals : $n ---> $result"
}

出力:

00:00:00.0183237 : True : 2 --->
00:00:00.0058198 : True : 4 --->
00:00:00.0181185 : True : 6 ---> 23
00:00:00.4389282 : True : 8 --->
00:00:00.0132624 : True : 15 ---> 53
00:00:04.4952714 : True : 16 --->
00:00:00.0128230 : True : 23 ---> 6
00:00:01.4112716 : True : 42 ---> 74 146 161
00:00:01.3676701 : True : 107 ---> 701
00:00:07.1192912 : True : 117 ---> 279 939 993 3313 3331
00:00:07.6578543 : True : 126 ---> 222 438 483 674 746 851 1466 1631 1679
00:00:50.5501853 : True : 204 ---> 364 548 692 762 782 852 868 1268 1626 2474 2654 2921 2951 3266 3446 3791 4274 4742 5426 5462 6233 6434 6542 7037 8561 14426 14642 15491 15833 22547

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