Last active
August 3, 2018 10:07
-
-
Save rotelstift/683d5b8c0f54b1e06482c55cddd3684c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"> | |
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script> | |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script> | |
<style> | |
td{ | |
width: 3em; | |
text-align: center; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="printMSs" class="container"> | |
</div> | |
<script> | |
/////////////////////////////////////////////////////////// | |
//// https://techplay.jp/column/298?utm_source=column_298&utm_medium=social&utm_campaign=feed&utm_content=tw0 | |
//// に載っている問題を解くためのプログラム | |
//// 【今月の問題】 | |
//// 3×3の魔方陣は1〜9までを一つずつ配置したものですが、 | |
//// n〜n+8を配置したものを求めるプログラムを作成してください。 | |
//// ここで、nは1以上10以下の整数とします。 | |
/////////////////////////////////////////////////////////// | |
// nを幾つにするのかの設定 | |
// 1以上で設定する | |
let limit = 10; | |
// 表示用のHTMLのテンプレートを作る | |
printTemplate(limit); | |
// 魔方陣を作るロジック | |
// まずn=1の時の魔方陣を作る。 | |
//// n=1の時の魔方陣の作り方 | |
// まず[1,2,3,4,5,6,7,8,9]の配列を作る。 | |
// 5を中心にして両端から数を取って[[1,5,9],[2,5,8],[3,5,7],[4,5,6]]を作る。 | |
// そうすると15が出てくるので、それが奇数だから、3つの奇数か2個の偶数+1個の奇数の組み合わせで | |
// 作ることに着目する。 | |
// すると2個の偶数+1個の奇数の組み合わせである[2,5,8]と[4,5,6]は斜めに配置される。 | |
// あと空いた4つの辺は計算で算出される。 | |
// あとはこれを90度回転を3回して、裏に返して、さらにそれを3回90度回転させる。 | |
// そうすると8つの魔方陣ができる。 | |
//// n=2以降の時の魔方陣の作り方 | |
// n=1の時の魔方陣にひとマスづつn-1を足していくだけ | |
var origin = [1,2,3,4,5,6,7,8,9]; | |
var pursed = []; | |
var resultOrigin = [[0,0,0],[0,0,0],[0,0,0]]; | |
// 5を中心にして両端から数を取る | |
purseArray(origin, pursed); | |
// 一行の合計を求める | |
var sumMagic = 0; | |
for (var i in pursed[0]) { | |
sumMagic += pursed[0][i]; | |
}; | |
// sumMagicが15で奇数なので、2個の偶数+1個の奇数の組み合わせである | |
// [2,5,8]と[4,5,6]を斜めに配置する | |
// 右下がりの斜め | |
rightToBottom(resultOrigin, pursed[1]); | |
// 右上がりの斜め | |
rightToTop(resultOrigin, pursed[3]); | |
// 残りの4箇所の値を算出する | |
for (var i in resultOrigin) { | |
if(i % 2 == 0){ | |
resultOrigin[i][1] = sumMagic - sumWidth(resultOrigin, i); | |
} | |
} | |
for(var j in resultOrigin){ | |
if(j % 2 == 0){ | |
resultOrigin[1][j] = sumMagic - sumHeight(resultOrigin, j); | |
} | |
} | |
//// ここまでで、他の答えの元になる魔方陣resultOriginが完成する。 | |
// ここから、n=1のときのresultsをセット | |
var results = []; | |
results.push(resultOrigin); | |
for(var i = 0; i < 3; i++){ | |
results.push(rotate(results[results.length - 1])); | |
} | |
results.push(revarse(resultOrigin)); | |
for(var i = 0; i < 3; i++){ | |
results.push(rotate(results[results.length - 1])); | |
} | |
// n=1のときのresultsを表示 | |
for (var i = 0; i < results.length; i++) { | |
printMS(results[i], 1); | |
} | |
//// n=2以降について //// | |
for(var n = 2; n <= limit; n++){ | |
var resultsN = []; | |
for(var i in results){ | |
resultsN.push(msPlus(results[i], n - 1)) | |
} | |
for(var i in resultsN){ | |
printMS(resultsN[i], n) | |
} | |
} | |
////////////////////// ここから下、必要な関数 ////////////////////////////// | |
// originから5を中心にして両端から数を取る関数 | |
function purseArray(origin, pursed) { | |
while(origin.length > 1){ | |
var ary = []; | |
ary.push(origin.shift()); | |
ary.push(origin[origin.length / 2 - 1]); | |
ary.push(origin.pop()); | |
pursed.push(ary); | |
}; | |
} | |
// 右下がりの斜めに配置する | |
function rightToBottom(result, ary) { | |
for (var i = 0; i < result.length; i++) { | |
for (var j = 0; j < result[i].length; j++) { | |
if(i == j) result[i][j] = ary[j] | |
} | |
} | |
} | |
// 右上がりの斜めに配置する | |
function rightToTop(result, ary) { | |
for (var i = 0; i < result.length; i++) { | |
for (var j = 0; j < result[i].length; j++) { | |
if((i + j) == (result.length-1)) result[i][j] = ary[j] | |
} | |
} | |
} | |
// r行目の横の合計を求める | |
function sumWidth(result, r) { | |
var sum = 0; | |
for (var i = 0; i < result[r].length; i++) { | |
sum += result[r][i]; | |
} | |
return sum | |
} | |
// d列目の縦の合計を求める | |
function sumHeight(result, d) { | |
var sum = 0; | |
for (var i = 0; i < result.length; i++) { | |
sum += result[i][d]; | |
} | |
return sum | |
} | |
// 結果を反転させる | |
function revarse(matrix) { | |
var tmp = [["","",""],["","",""],["","",""]]; | |
for (var i in matrix) { | |
for (var j in matrix[i]) { | |
tmp[i][j] = matrix[j][i]; | |
} | |
} | |
return tmp; | |
} | |
// 結果を90度回転させる | |
function rotate(matrix) { | |
var tmp = [["","",""],["","",""],["","",""]]; | |
for (var i in matrix) { | |
for (var j in matrix[i]) { | |
tmp[i][j] = matrix[matrix[i].length -1 - j][i] | |
} | |
} | |
return tmp; | |
} | |
// 結果にn足す | |
function msPlus(matrix, n) { | |
var tmp = [["","",""],["","",""],["","",""]]; | |
for (var i in matrix) { | |
for (var j in matrix[i]) { | |
tmp[i][j] = matrix[i][j] + n | |
} | |
} | |
return tmp; | |
} | |
function printTemplate(limit){ | |
var printMSs = document.getElementById("printMSs"); | |
for(var i = 1; i <= limit; i++){ | |
var h1 = document.createElement("h1"); | |
printMSs.appendChild(h1); | |
h1.textContent = "n = " + i + "の時の魔方陣"; | |
var divForPrint = document.createElement("div"); | |
divForPrint.classList.add("row"); | |
divForPrint.setAttribute("id", "printMS" + i); | |
printMSs.appendChild(divForPrint); | |
} | |
} | |
function printMS(ms2DArray, n) { | |
var printMS = document.getElementById("printMS" + n); | |
var divMS = document.createElement("div"); | |
var formMS = document.createElement("form"); | |
for (var ary of ms2DArray) { | |
// console.log(ary); | |
var tr = document.createElement("tr"); | |
for (var i in ary) { | |
// console.log(ary[i]); | |
var td = document.createElement("td"); | |
tr.appendChild(td); | |
td.textContent = ary[i]; | |
}; | |
formMS.appendChild(tr); | |
}; | |
divMS.classList.add('col-3'); | |
divMS.appendChild(formMS); | |
printMS.appendChild(divMS); | |
}; | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment