Skip to content

Instantly share code, notes, and snippets.

@neetsdkasu
Last active September 13, 2016 18:01
Show Gist options
  • Save neetsdkasu/daf306806ba9fad5ebb99d2bc2dcfff6 to your computer and use it in GitHub Desktop.
Save neetsdkasu/daf306806ba9fad5ebb99d2bc2dcfff6 to your computer and use it in GitHub Desktop.
[JavaScript] Permutationsとかいう順列(?)の総並べ替えをイテレーションする感じ?(ショボくて使えましぇんよ) ※ https://git.io/vi2Rx が必須
// permutation
// author : Leonardone @ NEETSDKASU
// license: MIT
createPermutationIter = (function() {
var funcName = "createPermutationIter";
function errmsg(s) { return "[" + funcName + "] Error! " + s; }
var defaultMethod_getNext = "getNext";
var defaultMethod_hasNext = "hasNext";
if (parseArguments === undefined) { throw errmsg("require parseArguments function"); }
return function() {
var method_getNext = defaultMethod_getNext;
var method_hasNext = defaultMethod_hasNext;
var size = 0;
parseArguments(arguments, [
{ /* getNext method name */
"vartype" : "string",
"optional" : true,
"proc" : function (a) {
var obj = new Object();
method_getNext = a;
if (method_getNext === "") { method_getNext = defaultMethod_getNext; }
if (obj[method_getNext]) { throw errmsg("invalid method name of getNext"); }
}
},
{ /* hasNext method name */
"vartype" : "string",
"optional" : true,
"proc" : function (a) {
var obj = new Object();
method_hasNext = a;
if (method_hasNext === "") { method_hasNext = defaultMethod_hasNext; }
if (obj[method_hasNext]) { throw errmsg("invalid method name of hasNext"); }
if (method_hasNext === method_getNext) {
throw errmsg("same method name both getNext and hasNext");
}
}
},
{ /* update default method names */
"vartype" : "boolean",
"optional" : true,
"dependent": [0, 1],
"proc" : function (a) {
defaultMethod_getNext = method_getNext;
defaultMethod_hasNext = method_hasNext;
}
},
{ /* permutation size */
"vartype" : "number",
"errmsg" : errmsg("require permutation size value"),
"proc" : function (a) { size = a; }
}
]);
if (size < 2) {
throw errmsg("illigal size value");
}
// create permutation iterator
var flag = new Array(size);
var indx = new Array(size);
var dest = new Array(size);
var existsNext = true;
var i;
for (i = 0; i < size; i++) {
flag[i] = 0;
indx[i] = i;
}
function calcNext() {
if (!existsNext) { throw errmsg("no next"); }
if ((dest instanceof Array) === false) {
dest = new Array(size);
}
var i, pos;
for (i = 0; i < size; i++) {
dest[i] = indx[i];
}
pos = size - 1;
flag[indx[pos]]++;
for (;;) {
pos--;
if (pos < 0) {
existsNext = false;
break;
}
flag[indx[pos]]++;
for (i = indx[pos] + 1; i < size; i++) {
if (flag[i] > 0) { break; }
}
if (i < size) {
flag[i]--;
indx[pos] = i;
pos++;
i = 0;
while (pos < size && i < size) {
if (flag[i] === 0) {
i++;
continue;
}
flag[i]--;
indx[pos] = i;
pos++;
}
break;
}
}
return dest;
}
return new function() {
this[method_getNext] = function() {
return calcNext();
};
this[method_hasNext] = function() {
return existsNext;
};
};
};
})();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8" />
<title>Permutation Demo</title>
<script type="text/javascript" src="./parsearguments.js"></script>
<script type="text/javascript" src="./permutation.js"></script>
</head>
<body>
<h1> Permutation Demo</h1>
<script type="text/javascript">
var piyo = {"log": function(s) {
document.write("<" + "div" + ">" + s + "<" + "/" + "div" + ">");
}};
var x = createPermutationIter('hoge', 4);
var i;
for (i = 0; i < 30; i++) {
if (x.hasNext()) { piyo.log(x.hoge()); }
else { piyo.log('none'); }
}
/* result
0,1,2,3
0,1,3,2
0,2,1,3
0,2,3,1
0,3,1,2
0,3,2,1
1,0,2,3
1,0,3,2
1,2,0,3
1,2,3,0
1,3,0,2
1,3,2,0
2,0,1,3
2,0,3,1
2,1,0,3
2,1,3,0
2,3,0,1
2,3,1,0
3,0,1,2
3,0,2,1
3,1,0,2
3,1,2,0
3,2,0,1
3,2,1,0
none
none
none
none
none
none
*/
</script>
</body>
</html>
@neetsdkasu
Copy link
Author

でも一応これ未完成なんよなー
https://git.io/vi2zu ←こっちでやってた並べ替えパターン生成もやりたいしにゃあ
たしかrubyのpermutationも似たようなことできたと思ったけどー

@neetsdkasu
Copy link
Author

あー、Javaでもやってたわー
https://git.io/vi226
俺何度車輪やれば気が済むんだぜー

@neetsdkasu
Copy link
Author

うお、なんかJavaでやったやつnextPattern()がめっちゃシンプルにまとまってんですけど・・・やはり老化で脳みそがダメになったか俺・・・

@neetsdkasu
Copy link
Author

https://git.io/vi226
このJavaのやつシンプルにまとまってるけど、すっげー非効率なやりかたしてんだな・・・

@neetsdkasu
Copy link
Author

まぁ今回のJS版のほうがめっちゃ効率いいってほどでもないけど・・・前回のJava版よりはマシなはず・・・!?

@neetsdkasu
Copy link
Author

何で前回のJavaのEnumeratorやIteratorのインターフェースとか使わなかったのだろうか・・・謎

@neetsdkasu
Copy link
Author

おいおい、前回のJavaのやつ去年末やんけ・・・まだ1年経っとらんやんけ・・・

@neetsdkasu
Copy link
Author

new Object()を維持してる意味なさそう

@neetsdkasu
Copy link
Author

頻繁にメソッド名変えるとかないしね(そもメソッド名変える意味などあるのか)

@neetsdkasu
Copy link
Author

JS見てて思う
クロージャ(Closure)やべえ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment