次はJSの私の解決策です。私は最初に最小限のギャップを見つけて、元の値を変更することなく、それに応じて各アイテムとプロセスの間に収まるギャップの数を見つけようとします。
明らかに、このアルゴリズムを動作させるには、入力アレイを昇順でソートする必要があります。
var arr = [0, 99, 299, 498, 901],
gap = Math.min(...Array(arr.length-1).fill().map((_,i) => arr[i+1]-arr[i])), // Find the minimum gap
res = arr.reduce((p,c,i) => { var n = Math.round((c-p[p.length-1])/gap); // Find howmany gaps are inbetween according to the minimum gap
g = Math.round((c-p[p.length-1])/n); // Calculate the average gap top apply
return i ? p.concat(Array(Math.round(n-1)).fill().map((_,i) => p[p.length-1] + (i+1)*g),c)
: p.concat(c);
},[]);
console.log(res);
は説明:
gap = Math.min(...Array(arr.length-1).fill().map((_,i) => arr[i+1]-arr[i])),
まず、入力配列よりも1小さいサイズで新しい配列を設定します。 (Array(arr.length-1)
)まず、定義されていない要素でそれを初期化し(.fill()
)、次に.map()
すべての要素をarr[i+1]-arr[i]
で初期化します。今はギャップ配列があります。それを引数としてMath.min()
の関数に展開します。それはMath.min(...Array(
部分です。したがって、上記の場合、最小間隔は99となります。
res = arr.reduce((p,c,i) => { var n = Math.round((c-p[p.length-1])/gap);
g = Math.round((c-p[p.length-1])/n);
return i ? p.concat(Array(Math.round(n-1)).fill().map((_,i) => p[p.length-1] + (i+1)*g),c)
: p.concat(c);
},[]);
.reduce()
部分はややタフですが、それは簡単です。私たちの.reduce()
オペレーションは、その引数(主にコールバック関数と呼ばれます)として関数をとり、配列アイテムのすべての反復でそれを実行します。このコールバック関数は、(p,c,i) => {... }
で始まる部分です。これは矢印の機能です。基本的な機能と本質的に同じです。 x => x
は、function(x) { return x;}
またはx => {return x;}
を意味します。我々のケースでは、(複数のステートメントのために)関数の本体を定義するために中かっこを使用しているので、return
命令を使用する必要があります。
私たちの.reduce()
は、空の配列である初期値を使用します。最後の部分は,[]);
です。配列の項目ごとに呼び出されるコールバック関数は、3つの引数を渡します。(p,c,i)
最初の空の配列はp
(前の)引数に割り当てられ、現在の項目はc
引数に割り当てられ、現在のインデックスはi
に割り当てられます。コールごとの引数。
コールバックの本文では、2つの変数を定義しています。 n
およびg
。
n = Math.round((c-p[p.length-1])/gap);
p[p.length-1]
p
配列の最後の要素を返します。だから最初のターン。 i
= 0の場合、p[0]
はundefined
であり、Math.round((c-p[p.length-1])/gap);
はNaN
(数字ではありません)ですが、私たちは気にしません。
return i ? p.concat(Array(Math.round(n-1)).fill().map((_,i) => p[p.length-1] + (i+1)*g),c)
: p.concat(c);
三項条件とは、
result = condition ? if true do this
: if false do this
状態に応じて、いずれかの手順が実行され、結果が返されます。この場合、結果はp
の値として返されます。私たちの場合はそう
i
== 0(JSでfalse
値)のみp.concat(c)
を行い、新しいp
値を返し、次の反復を続ける場合は、(新しいp
、c
とi
値でコールバックを呼び出します。
i
がfalse
ギャップに多くの中間要素を取る大きさの配列を作成する手段(0以外の値)を
p.concat(Array(Math.round(n-1)).fill().map((_,i) => p[p.length-1] + (i+1)*g),c)
ように行う、のinitiない場合undefineds
で配列をalizeし、各要素をp[p.length-1] + (i+1)*g
にマップし、この配列をp
配列に連結し、最後にc
を追加してp
配列を返します。
p.concat(whatever...)
命令は、p
の要素と、引数として含まれる配列の「items」またはar引数を含む項目そのものからなる新しい配列を返します。というのは;
[1,2,3].concat([4,5,6],[7,8],9)
だから、これはそれを説明する必要があります[1,2,3,4,5,6,7,8,9]
をもたらすであろう。
おそらく結果を丸めたいと思うでしょう。 99,98,297とは対照的に100,200,300となります。 – Bathsheba
ええと、希望のエラーレベルに丸めることができます。したがって、私が10に近づくと、最小のGCD値は10になります。 – elprl