順列を求める
Javascriptで順列を求める
考えたコード
function permutations (ary = [ ], r = ary.length) { function recursion (ary, r, A = []) { if (r == 0) return ary.map (a=> A.concat(a)); let result = []; for (let i = 0; i < ary.length; i++) { let aaa = [...ary], a = aaa.splice (i,1); result = result.concat (recursion (aaa, r-1, A.concat(a))); } return result; } return recursion (ary, r -1); }
短く1行で
let permutations=((f=(A,B=A.length,C=[])=>--B?A.reduce((a,b,c,[...d],_=d.splice(c,1))=>[...a,...f(d,B,[...C,b])],[]):A.map(a=>[...C,a]))=>f)(); console.log (permutation([0,1,2,3]));
- 再帰処理が必要なため、呼び出す関数をfにする
- [...d] は複写したものを使わないと元を破壊してしまう
- _=d.splice(c,1)) で配列から1つ削除するが、ここでは配列を返してしまうので使われない。その代わり同等の b を使う。
classで焼き直し(書きかけ)
class Permutation { constructor (ary = [ ], r = ary.length) { this.ary = ary; this.r = r; } get n () { return this.ary.length; } get length () { const fx = this.constructor.factorial; let {n, r} = this; return fx (n) / fx (n - r); } *generator (n = 0) { for (let i = 0, I = this.length; i < I; i++) { yield this.pattern (i); } } pattern (n) { if (n < 0 || this.length < n) throw new Error ('値が範囲外です'); /*書きかけ*/ return n; } patternAll () { return this.constructor.pattern (this.ary, this.r); } static factorial (n = 1) { let r = 1; for (let i = n; i > 1; r *= i--) ; return r; } static pattern (ary = [ ], r = ary.length) { function recursion (ary, r, A = []) { if (r == 0) { return ary.map (a=> A.concat(a)); } let result = []; for (let i = 0; i < ary.length; i++) { let aaa = [...ary], a = aaa.splice (i,1); result = result.concat (recursion (aaa, r-1, A.concat(a))); } return result; } return recursion (ary, r - 1); } }