任何人都可以帮助我为魔术平方度量创建逻辑。在给定的示例中,我创建了一个代码以生成3x3、5x5、7x7度量标准的奇数的Magic Square,但无法找到创建2x2、4x4、6x6、8x8、10x10等的偶数值魔术平方度量标准的正确解决方案。 / p>
在当前实现中,任何人都可以在输入中输入数字(n)并单击Generate按钮,这将创建一个nxn幻方度量。但是用偶数不能很好地工作。
$(function () {
var n;
var main = $('#main');
$("#generate").click(function(){
$("#main").text("");
var val = $("#number").val();
if(val){
n = val;
generateMetric(val); // Generate n x n metric
}
});
function generateMetric(n){
var magicSquare = [];
// Set all metric values to 0
for (var i = 0; i < n; i++) {
magicSquare[i] = [];
for (var j = 0; j < n; j++) {
magicSquare[i].push(0);
main.append('<input type="text" class="values" id="'+ i +'-'+ j +'" readonly />');
}
main.append('<div class="clear"></div>');
}
// Initialize position for 1
var i = parseInt(n/2);
var j = n - 1;
// Put all values in metric
for(var k = 1; k <= n*n;){
if(i == -1 && j == n){
j = n - 2;
i = 0;
}else{
// if value of j is going to higher than n
if(j == n){
j = 0;
}
// if value of i is going in minus
if(i < 0){
i = n - 1;
}
}
if(magicSquare[i][j]){
j -= 2;
i++;
continue;
} else{
// set the value in metric
magicSquare[i][j] = k++;
}
j++; i--;
}
// Append values to all metric inputs
for (var i = 0; i < n; i++){
for (var j = 0; j < n; j++) {
$("#"+i +"-"+ j).val(magicSquare[i][j]);
}
}
}
});
body {
margin: 30px;
}
.values {
width: 30px;
float: left;
margin-right:1px;
}
.clear {
clear: both;
}
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<input type="text" id="number" />
<input type="button" id="generate" value="Generate" />
<div id="main"></div>
答案 0 :(得分:0)
您可以使用以下解决方案来创建所有魔法乡绅。
HTML
<body onload="constructMSquare();">
<h1>Magic Square</h1>
<form class="confbox" onsubmit="constructMSquare(); return false;" method="post">
Size: <input id="size" type="number" min="3" max="32" value="5">
<input type="submit" name="cd" value="Calculate!">
<br>
<input type="button" value="save" name="save" id="save">
</form>
<div class="square">
<div id='quadrat'>
<p class="row"></p>
</div>
</div>
</body>
CSS
body {
background-color: rgb(97,189,255);
text-align: center;
}
.square {
margin: auto;
}
.confbox {
margin: 15px;
}
#quadrat {
display: table;
border: solid;
border-width: thick;
border-radius: 5px;
background-color: rgb(84,156,251);
border-color: rgb(0,34,138);
margin: 0 auto;
}
span {
display: table-cell;
width: 50px;
height: 50px;
margin: 0;
border: solid;
border-width: 5px;
padding: 0;
text-align: center;
vertical-align: middle;
border-color: rgb(0,34,138);
font-weight: bold;
color: rgb(0,34,138);
}
p {
margin: 0;
padding: 0;
}
JavaScript:
var size = 0
var square = []
var constructMSquare = function () {
size = document.getElementById('size').value; // squaresize
// choose generatinalgorithm depending on squaresize( odd, even or doubleeven(evener))
if (size % 2 == 0) {
if (size % 4 == 0) {
square = evenerMSquare(size);
} else {
square = evenMSquare(size);
}
} else {
square = oddMSquare(size);
}
if (check(square)) {
displaySquare(square);
}
document.getElementById('save').addEventListener('click', save)
return false;
}
var isCellempty = function (square, column, row, squaresize, startX, startY) {
// default arguments
// yes inefficient, but otherwise it is not working :( why?
if (squaresize == undefined) {
squaresize = square.length;
}
if (startX == undefined) {
startX = 0;
}
if (startY == undefined) {
startY = 0;
}
// check if the cell is empty
// if column is not in the square put it back in
if (column >= squaresize) {
var column = squaresize % column;
} else if (column < 0) {
if (column < 0) {
column = 0 - column;
}
var column = squaresize - column;
}
// if row is not in the square put it back in
if (row >= squaresize) {
var row = squaresize % row;
} else if (row < 0) {
var row = 0 - row;
var row = squaresize - row;
}
// add start position to column and row to find the position in the big square
var column = column + startX;
var row = row + startY;
// check if this position is empty
var cell = square[row];
if (cell[column] != null) {
return false;
}
return true;
}
function oddMSquare(size) {
// constracts magic squares with an odd size (http://www.1728.org/magicsq1.htm)
// create an empty Square
var square = [];
for (var i = 0; i < size; i++) {
var newRow = [];
for (var u = 0; u < size; u++) {
newRow.push();
}
square.push(newRow);
}
// fill the magic square
var row = 0;
var column = Math.round(size / 2) - 1; //start in the middle
// counts till the number of cells
for (var i = 1; i <= size * size; i++) {
// fill the count in the cell
var c = square[row];
c[column] = i;
// if the cell top right is empty set current "cell" to that position
// else set it to the position below
if (isCellempty(square, column + 1, row - 1)) {
column++;
row--;
} else {
row++;
}
// if column is not in the square put it back in
if (column >= size) {
column = size % column;
} else if (column < 0) {
column = 0 - column;
column = size - column;
}
// if row is not in the square put it back in
if (row >= size) {
row = size % row;
} else if (row < 0) {
row = 0 - row;
row = size - row;
}
}
return square;
}
function evenMSquare(size) {
// constracts magic squares with an even size (http://www.1728.org/magicsq3.htm)
// create an empty square
var square = [];
for (var i = 0; i < size; i++) {
var newRow = [];
for (var u = 0; u < size; u++) {
newRow.push();
}
square.push(newRow);
}
var y = size / 2; // size of the "mini magic squares"
var i = 1; // counter
// counts the mini magic sqaures
for (var b = 1; b <= 4; b++) {
// choose "mini magic square"
switch (b) {
case 1:
// upper left
var startX = 0;
var startY = 0;
break;
case 2:
// lower right
var startX = y;
var startY = y;
break;
case 3:
// upper right
var startX = y;
var startY = 0;
break;
case 4:
// lower left
var startX = 0;
var startY = y;
break;
}
var row = 0;
var column = (Math.round(y / 2) - 1); //start in the middle
// counts till the number of cells of the "mini magic square"
for (var a = 1; a <= y * y; a++ && i++) {
// fill the count in the cell
var c = square[row + startY];
c[column + startX] = i;
// if the cell top right is empty set current "cell" to that position
// else set it to the position below
if (isCellempty(square, column + 1, row - 1, y, startX, startY)) {
column++;
row--;
} else {
row++;
}
// if column is not in the square put it back in
if (column >= y) {
column = y % column;
} else if (column < 0) {
if (column < 0) {
column = 0 - column;
}
column = y - column;
}
// if column is not in the square put it back in
if (row >= y) {
row = y % row;
} else if (row < 0) {
if (row < 0) {
row = 0 - row;
}
row = y - row;
}
}
}
function swapAandB(posX, posY) {
// swap the cell(posX, posY) with the cell at the upper mini magic square
var cRow = square[posX];
var a = cRow[posY];
cRow = square[posX + y];
var b = cRow[posY];
cRow[posY] = a;
cRow = square[posX];
cRow[posY] = b;
}
// swap the right corners
for (var i = 0; i < Math.floor(y / 2); i++) {
for (var row = 0; row < y / 2; row++) {
swapAandB(row, i);
swapAandB(y - row - 1, i);
}
}
// swap in the middle row beginning from the second cell till the lenght of the corners
for (var i = 1; i < y / 2; i++) {
swapAandB(Math.floor(y / 2), i);
}
// swap the last ( (squaresize - 6(size of the first single even magic square))
// / 4(distance to next single even magic square) ) columns
for (var i = 1; i <= (size - 6) / 4; i++) {
for (var row = 0; row < y; row++) {
swapAandB(row, size - i);
}
}
return square;
}
function evenerMSquare(size) {
// create square
var square = [];
// calculate square
for (var i = 0; i < (size * size); i++) {
// if i is greater than the length of the square create a new row
if ((i % size) == 0) {
var newRow = [];
square.push(newRow);
}
/* if i is in a corners(cornersize = squaresize/4)
or in the middle write the count in the square
else write the count backwards in the square */
if (((i % size < size / 4) || i % size >= size - size / 4) && ((square.length <= size / 4) || square.length > size - size / 4)) {
newRow[i % size] = i + 1;
} else if (!((i % size < size / 4) || i % size >= size - size / 4) && !((square.length <= size / 4) || square.length > size - size / 4)) {
newRow[i % size] = i + 1;
} else {
newRow[i % size] = (size * size) - i;
}
}
return square;
}
function check(square) {
// Check if the sum of the rows, columns and diagonals equals the magic number.
// defines the magic number
sum = square.length * (square.length * square.length + 1) / 2;
console.log('magic number: ', sum);
// Check the rows.
for (row in square) {
row = square[row];
var x = 0;
for (i in row) {
i = row[i];
x = x + i;
}
if (x != sum) {
console.log('fehler!!!!!!!!!!');
console.log(x);
console.log(row);
return false;
}
}
// Check the columns.
for (column in square) {
var x = 0;
for (row in square) {
row = square[row];
x = x + row[column];
}
if (x != sum) {
console.log('fehler!!!!!!!!!!');
console.log(x);
console.log(column);
return false;
}
}
// Check the diagonal(from right top to left buttom).
count = 0;
x = 0;
for (row in square) {
row = square[row];
x = x + row[count];
count = count + 1;
}
if (x != sum) {
console.log('fehler!!!!!!!!!!');
return false;
}
// Check the diagonal(from left top to right buttom).
count = 0;
x = 0;
for (row in square) {
row = square[row];
x = x + row[row.length - count - 1];
count = count + 1;
}
if (x != sum) {
console.log('fehler!!!!!!!!!!');
return false;
}
return true;
}
function displaySquare(square) {
// Displays the array square in html.
var quadrat = document.getElementById('quadrat');
// removing the old square
childNodes = quadrat.childNodes;
while (quadrat.childNodes.length != 0) {
for (var i in quadrat.childNodes) {
i = quadrat.childNodes[i];
try {
quadrat.removeChild(i);
}
catch (e) {
console.log('catched');
}
}
}
function addRow(square) {
// Adds rows in the quadrat (html).
addedRow = document.createElement('p');
quadrat.appendChild(addedRow);
addedRow.class = 'row';
addCells(addedRow);
}
function addCells(htmlRow) {
// Adds cells in the added row and fills them with the numbers of square.
// for every cell in the row
for (cell in row) {
cell = row[cell];
addedCell = document.createElement('span');
addedCell.innerHTML = cell;
htmlRow.appendChild(addedCell);
addedCell.class = 'cell';
}
}
// for every row of the square
for (row in square) {
row = square[row];
addRow(square);
}
}
function save() {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
var data = square.reduce((data, row) => data + '\n' + row.join(','), '')
var blob = new Blob([data], {type: "text/csv"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = `magic-square_${size}.csv`;
a.click();
window.URL.revokeObjectURL(url);
}
下载完整的源代码here