回答:
f=(s,v)=>(p=n=>--n-1?s%n&&p(n):1)(s)||[...s].map((_,i)=>!(n=i&&(a=f(s.slice(0,i)))&&(b=f(s.slice(i)))&&a+b)|n>v?0:v=n)|v
@Neilのおかげで1バイト節約できました!
入力として単一の文字列を受け取ります。プライムチェック方式(再帰試行分割)により、安全にチェックできる最大数は13840
です。これを超える数値の一部は、最大呼び出しスタックサイズを超えているため失敗します。ただし、処理できるすべてのケースで即座に終了します。
f=(s,v)=>
(p=n=>--n-1?s%n&&p(n):1)(s) // if s is prime, return 1
||[...s].map((_,i)=> // else for each index in s, split s into 2
!(n=i&& // v = return value (initialised to undefined)
(a=f(s.slice(0,i)))&&
(b=f(s.slice(i)))&&
a+b
)|n>v?0:v=n // if i, a, b and n are all > 0 and !(n > v), v = n
)|v // cast v to an integer and return it
// Test
var testCases = [ "252", "235", "92", "3149", "24747" ];
document.write("<pre>" + testCases.map(c => c + ": " + f(c)).join("\n"));
i?(a=...)&&(b=...)&&a+b:0
にi&&(a=...)&&(b=...)&&a+b
?
0in:"GUtZq@Z^V10ZA=a?x@.
一部のテストケースでは数秒かかります。
0 % Push 0
in: % Take input. Generate array [1,2,...,N] where N is input length
" % For each. In each iteration the number of used primes is increased
GU % Push input. Convert to number
tZq % Duplicate. Array of primes smaller than the input
@ % Push number of primes to bes tested in this iteration
Z^ % Cartesian power
V % Convert to 2D array. Each row is a combination of primes
10ZA % Convert each row to base 10, disregarding spaces
=a % Do any of the results equal the input number?
? % If so
x % Remove the 0 that's at the bottom of the stack
. % Break for each loop
% Implicitly end if
% Implicitly end for each
% Implicitly display
c()
{
test $1||echo a
for i in `seq ${#1}`
do factor ${1::$i}|grep -q ': \w*$'&&printf b%s\\n `c ${1:$i}`
done
}
c $1|sort|sed '/a/!d;s/..//;q'|wc -c
単項で数え、b
各素数ごとに1行を出力し、行a
の終わりで終了します(そのため、処理printf
するトークンがあります)。
素数性テストはfactor $n | grep -q ': \w*$'
であり、これは数に正確に1つの素因数があるかどうかを決定します。
入力を再帰的に分割します。左半分が素数の場合、各値に1を加算して右半分の結果をフィルター処理します。a
長さがゼロの入力を返すと、再帰が終了します。
最後に、すべての結果を取得してソートし、最短を見つけます(a
成功を示す必要がないものは無視します)。2つ(挿入a
用と改行用)を削除してから、文字を数えて結果を出す必要があります。
$ for i in 252 235 92 31149 111; do echo "$i:"$'\t'"$(./77623.sh $i)"; done
252: 3
235: 2
92: 0
31149: 2
111: 0
111
テストに追加して、1
正しく非プライムと見なされることを示しました。
c
最終版を生成するのが好き0
です。しかし、豊富な標準エラーにはそれほど熱心ではありません。必要に応じて、私の回答(のバージョン)を独自の基礎として使用してください。
Min[Length/@Select[Join@@@Permutations/@IntegerPartitions@Length[a=#],And@@PrimeQ@*FromDigits/@a~Internal`PartitionRagged~#&]]/.∞->0&
ご覧のとおり、Mathematicaはこのタスク用に構築されたものではありません。数字のリストを取得します。
And@@
代わりに使用できますAllTrue
か?4〜5バイトを節約する必要があります。
Flatten[#,1]
=Join@@@#