ModelFormSetはsave()できない。FormSetから一個ずつFormを取り出してsave()しろということ。
参考ページはこちら↓。
https://groups.google.com/group/django-users/browse_thread/thread/fd20b860b7d9b00e?hl=en&pli=1
いやいや、公式ドキュメントにはformset.save()を使えと書いてあるだろ。そりゃ皆はまるわ。
ModelFormSetはsave()できない。FormSetから一個ずつFormを取り出してsave()しろということ。
参考ページはこちら↓。
https://groups.google.com/group/django-users/browse_thread/thread/fd20b860b7d9b00e?hl=en&pli=1
いやいや、公式ドキュメントにはformset.save()を使えと書いてあるだろ。そりゃ皆はまるわ。
べつに計算量がシビアな問題でもないんだが、全パターンを調べるのは非効率なので、プログラマーのプライドで処理を見直した。
角から始まるパターン、エッジから始まるパターン、真ん中から始まるパターンの3つに分けて数えて、後で合計する形にした。
<html>
<head>
<script type="text/javascript">
// 1~9の数字が使われたかどうか。
// used[1]~[9]を使う。used[0]はtrueにしておく。
var used = new Array(10);
// 順列を入れる箱。
// p[0]~[8]を使う。
var p = new Array(9);
// カウンタ。
var c = 0;
// middle
// 7 8 9
// 4 5 6
// 1 2 3
var middle = new Array(10);
for(var i = 1; i <= 9; i++) {
middle[i] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
}
middle[7][9] = middle[9][7] = 8;
middle[7][1] = middle[1][7] = 4;
middle[7][3] = middle[4][6] = middle[1][9] = middle[2][8] = middle[3][7] = middle[6][4] = middle[9][1] = middle[8][2] = 5;
middle[9][3] = middle[3][9] = 6;
middle[1][3] = middle[3][1] = 2;
function put(pos, k, len) {
// 場所posに数値kを入れる
p[pos] = k;
if(pos == len - 1) {
count(len);
}
else {
used[k] = true;
for(var j = 1; j <= 9; j++) {
if(!used[j] && used[middle[k][j]]) {
put(pos + 1, j, len);
}
}
used[k] = false;
}
}
function count(len) {
c++;
}
function show() {
for(var i = 1; i <= 9; i++) {
used[i] = false;
}
used[0] = true;
// l: 順列の長さ
for(var l = 4; l <= 9; l++) {
// 角から始まるパターン
put(0, 1, l);
// エッジから始まるパターン
put(0, 2, l);
var c1 = 4 * c;
c = 0;
// 真ん中から始まるパターン
put(0, 5, l);
var c1 = c1 + c;
c = 0;
var s = 'Length ' + l.toString() + ': Number of valid patterns is ' + c1.toString() + '.<br/>';
document.getElementById('ans' + l.toString()).innerHTML = s;
}
}
</script>
</head>
<body onLoad="show()">
<div id='ans4'>thinking...</div>
<div id='ans5'></div>
<div id='ans6'></div>
<div id='ans7'></div>
<div id='ans8'></div>
<div id='ans9'></div>
</body>
</html>
Androidのアンロックパターンは、写真のような画面で、点を一筆書きで結んでいくというもの。
可能な結び方は次の通り。
a) 縦か横か斜めで隣接している場合
b) 桂馬飛びでつながる場合
c) すでに通過済みの点を飛び越えてつながる場合 (未通過の点を飛び越えようとすると、その点が先につながってしまう)
各点に、下記のように番号をつけて点の結び方の例を示すと、
789
456
123
a) 7-8, 7-4, 7-5など
b) 7-2, 4-3など
c) 8-9-7, 5-6-8-2など
こういったつなぎ方で、一筆書きで、4つ以上の点を結ぶというのがアンロックパターンのルール。
有効なパターンが何通りあるかプログラムで数えてみた。で、結果はタイトルの通り、389,112通り。
つまり、5桁から6桁の暗証番号と同じ安全性ということ。
内訳は以下の通り。
長さ4: 1624
長さ5: 7152
長さ6: 26016
長さ7: 72912
長さ8: 140704
長さ9: 140704
それぞれが8の倍数になっているのは、1つのパターンに対して、90°ずつ回転して4パターン、左右反転してから90°ずつ回転して4パターンと、合計8パターンが作れるから。
同じ計算をしている人がここ↓にもいた。
http://beust.com/weblog2/archives/000497.html
おいらのプログラムは下記の通り。
「C言語による最新アルゴリズム事典」(奥村晴彦著)の順列生成を参考にした。この本いいわ。
<script type="text/javascript">//
// 1~9の数字が使われたかどうか。
// used[1]~[9]を使う。used[0]はtrueにしておく。
var used = new Array(10);
// 順列を入れる箱。
// p[0]~[8]を使う。
var p = new Array(9);
// カウンタ。
// valid[4]~[9]を使う。
var valid = new Array(10);
// middle
// 7 8 9
// 4 5 6
// 1 2 3
var middle = new Array(10);
for(var i = 1; i
middle[i] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
}
middle[7][9] = middle[9][7] = 8;
middle[7][1] = middle[1][7] = 4;
middle[7][3] = middle[4][6] = middle[1][9] = middle[2][8] = middle[3][7] = middle[6][4] = middle[9][1] = middle[8][2] = 5;
middle[9][3] = middle[3][9] = 6;
middle[1][3] = middle[3][1] = 2;
function put(pos, k, len) {
// 場所posに数値kを入れる
p[pos] = k;
if(pos == len - 1) {
count(len);
}
else {
used[k] = true;
for(var j = 1; j
if(!used[j] && used[middle[k][j]]) {
put(pos + 1, j, len);
}
}
used[k] = false;
}
}
function count(len) {
valid[len]++;
}
function show() {
for(var i = 1; i
used[i] = false;
valid[i] = 0;
}
used[0] = true;
// l: 順列の長さ
for(var l = 4; l
// m: 最初の箱に入れる数値
for(var m = 1; m
put(0, m, l);
}
}
for(var i = 4; i
var s = 'Length ' + i.toString() + ': Number of valid patterns is ' + valid[i].toString() + '.
';
document.getElementById('ans' + i.toString()).innerHTML = s;
}
}
// ]]></script>
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="./jquery-1.4.2.min.js"></script> <script type="text/javascript"> $(function(){ $("p#first").html("<strong>変更後</strong>"); $("p#red").css("color", "red"); $("button#btn1").click(function(){ $("img#img1").attr("src", "./1.jpg"); }); $("button#btn2").click(function(){ $("div#anm1").show("slow"); }); $("dd:not(:first)").css("display", "none"); $("dl dt").click(function(){ if($("+dd", this).css("display")=="none"){ $("dd").slideUp("slow"); $("+dd",this).slideDown("slow"); } }); }); </script> <style type="text/css"> div#anm1 { width:200px; height:200px; background:red; display:none; } dl { width:400px; margin:50px auto; padding:0; } dl dt { background:#7CADB6; border-bottom:1px solid #FFFFFF; cursor:pointer; margin:0; padding:0; } dl dd { border:1px solid #7CADB6; border-top:none; height:300px; margin:0; padding:0; } </style> </head> <body> <p id="first">変更前</p> <p id="red">テキスト</p> <button id="btn1">画像変更ボタン</button> <img id="img1" src="./pumpkin_64.png" alt="" /> <button id="btn2">アニメーションボタン</button> <div id="anm1"></div> <dl> <dt>見出し1</dt> <dd>テキスト1テキスト1テキスト1</dd> <dt>見出し2</dt> <dd>テキスト2テキスト2テキスト2</dd> <dt>見出し3</dt> <dd>テキスト3テキスト3テキスト3</dd> </dl> </body> </html>