Skip to content

Instantly share code, notes, and snippets.

@rotelstift
Last active August 3, 2018 10:07
Show Gist options
  • Save rotelstift/683d5b8c0f54b1e06482c55cddd3684c to your computer and use it in GitHub Desktop.
Save rotelstift/683d5b8c0f54b1e06482c55cddd3684c to your computer and use it in GitHub Desktop.
<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