2014年5月22日木曜日

MySQLの魔法陣の4×4:ルーチン、ループ、変数

Original post: http://anothermysqldba.blogspot.com/2014/05/mysql-magic-square-4x4-routines-loop.html

私は魔方陣で遊んで今日横道それはMySQLのルーチン、ループとか否かをチェックする使用例を与えるために良い機会かもしれないと思ってしまった。 

あなたは魔方陣が何であるかを知らないのであれば、私はいくつかのリンクが含まれている。それはあなたのGoogle検索を保存し、それ以外の例として、数独を考えるかもしれない。 
これもルーチン&ループとIFチェックを使用する方法の例の詳細ですので、私は4×4のマスに魔方陣が限られている。 
私はその方法を示すために日常的に4の値を渡しています。 それは私が一生懸命とにかく4平方コーディングおりますので、不必要なステップですが、それは例のために働く。 

DROP PROCEDURE IF EXISTS magic_sq; 
DROP TABLE IF EXISTS `magic_sq` ; 

delimiter // 
CREATE PROCEDURE magic_sq( N int(11)) 
BEGIN 
DECLARE nXn INT; 
DECLARE SQ_SUM INT; 
DECLARE _passfail_ INT; 
DECLARE min INT; 
DECLARE max INT; 

-- DRAW THE TEMPLATE FOR THE SQUARE MAX of 8 FOR NOW 
DROP TABLE IF EXISTS `magic_sq` ; 
CREATE TABLE `magic_sq` ( 
`xy_id` int(11) NOT NULL AUTO_INCREMENT, 
`1` int(11) NULL DEFAULT NULL, 
`2` int(11) NULL DEFAULT NULL, 
`3` int(11) NULL DEFAULT NULL, 
`4` int(11) NULL DEFAULT NULL, 
PRIMARY KEY (`xy_id`) , 
UNIQUE KEY `Y1` (`1`), 
UNIQUE KEY `Y2` (`2`), 
UNIQUE KEY `Y3` (`3`), 
UNIQUE KEY `Y4` (`4`) 
) ENGINE= MEMORY; 


-- n X n 
SET @nXn = N + N; 
-- SQ_SUM This is the formula for what the total should equal 
SET @SQ_SUM = ( N * (POW(N,2) + 1) ) / 2; 
-- MIN Value 
SET @min=1; 
-- MAX Value 
SET @max=POW(N,2); 

-- BUILD THE SQUARE 
WHILE ( @min <= @nXn ) 
DO 

-- TEST VALUES 
SET _passfail_ = IF ( (@min + (@min +1) + ( @max - 1) +@max) = @SQ_SUM ,1 , 0 ) ; 

-- IF VALID RESULTS THEN SAVE THEM 
IF _passfail_ = 1 THEN 
INSERT INTO magic_sq VALUES (NULL,@min ,(@min +1),( @max - 1) , @max ); 
END IF; 

-- CONTINUE 
SET @min= @min +2; 
SET @max= @max -2; 

END WHILE; 

END// 
delimiter ; 


今私は、ルーチンを内蔵していることを、私は有効な結果を得るのですか? これが可能なすべてのオプション、うまくいくかもしれない単なるオプションではない点に注意してください。 924オプション 4×4の正方形EXISTため。 

CALL magic_sq(4); 
select * from magic_sq; 
+-------+------+------+------+------+ 
| xy_id | 1 | 2 | 3 | 4 | 
+-------+------+------+------+------+ 
| 1 | 1 | 2 | 15 | 16 | 
| 2 | 3 | 4 | 13 | 14 | 
| 3 | 5 | 6 | 11 | 12 | 
| 4 | 7 | 8 | 9 | 10 | 
+-------+------+------+------+------+
 

+-------+---------+ 
| xy_id | per_row | 
+-------+---------+ 
| 1 | 34 | 
| 2 | 34 | 
| 3 | 34 | 
| 4 | 34 | 
+-------+---------+ 
違う! 彼らは、行ではなく列のために働く。 これはルーチン、ループやIF文を使用する方法を示し、例がそれを失敗している間、それは私が何を望むか用意されていません。 だから私は、末尾の場合はチェックの詳細と、挿入だけでなく、スワップいくつかの数字を手直ししなければならなかった。 

DROP PROCEDURE IF EXISTS magic_sq; 
DROP TABLE IF EXISTS `magic_sq` ; 

delimiter // 
CREATE PROCEDURE magic_sq( N int(11)) 
BEGIN 
DECLARE nXn INT; 
DECLARE SQ_SUM INT; 
DECLARE _passfail_ INT; 
DECLARE _io_ INT; 
DECLARE min INT; 
DECLARE max INT; 

-- DRAW THE TEMPLATE FOR THE SQUARE MAX of 8 FOR NOW 
DROP TABLE IF EXISTS `magic_sq` ; 
CREATE TABLE `magic_sq` ( 
`xy_id` int(11) NOT NULL AUTO_INCREMENT, 
`1` int(11) NULL DEFAULT NULL, 
`2` int(11) NULL DEFAULT NULL, 
`3` int(11) NULL DEFAULT NULL, 
`4` int(11) NULL DEFAULT NULL, 
PRIMARY KEY (`xy_id`) , 
UNIQUE KEY `Y1` (`1`), 
UNIQUE KEY `Y2` (`2`), 
UNIQUE KEY `Y3` (`3`), 
UNIQUE KEY `Y4` (`4`) 
) ENGINE= MEMORY; 


-- n X n 
SET @nXn = N + N; 
-- SQ_SUM This is the formula for what the total should equal 
SET @SQ_SUM = ( N * (POW(N,2) + 1) ) / 2; 
-- MIN Value 
SET @min=1; 
-- MAX Value 
SET @max=POW(N,2); 

-- insert_options 
SET _io_ =0; 

-- BUILD THE SQUARE 
WHILE ( @min <= @nXn ) 
DO 

-- TEST VALUES 
SET _passfail_ = IF ( (@min + (@min +1) + ( @max - 1) +@max) = @SQ_SUM ,1 , 0 ) ; 

-- IF VALID RESULTS THEN SAVE THEM 
IF _passfail_ = 1 THEN 

IF _io_ = 0 THEN 
INSERT INTO magic_sq VALUES (NULL,@min ,(@min +1),( @max - 1) , @max ); 
SET _io_ =1; 
ELSEIF _io_ = 1 THEN 
INSERT INTO magic_sq VALUES (NULL,( @max - 1),@max , @min , (@min +1) ); 
SET _io_ =2; 
ELSEIF _io_ = 2 THEN 
INSERT INTO magic_sq VALUES (NULL,@max ,(@min +1) , ( @max - 1) , @min ); 
SET _io_ =4; 
ELSEIF _io_ = 4 THEN 
INSERT INTO magic_sq VALUES (NULL, (@min +1) , @max , @min ,( @max - 1) ); 
SET _io_ =0; 
END IF; 

END IF; 

-- CONTINUE 
SET @min= @min +2; 
SET @max= @max -2; 

END WHILE; 
SELECT @x3y2 := `2` FROM magic_sq WHERE xy_id = 3; 
SELECT @x3y3 := `3` FROM magic_sq WHERE xy_id = 3; 
SELECT @x4y2 := `2` FROM magic_sq WHERE xy_id = 4; 
SELECT @x4y3 := `3` FROM magic_sq WHERE xy_id = 4; 


UPDATE magic_sq SET `2` = @x4y3 , `3` = @x4y2 WHERE xy_id = 3; 
UPDATE magic_sq SET `2` = @x3y3 , `3` = @x3y2 WHERE xy_id = 4; 
select * from magic_sq; 
select SUM(`1`),SUM(`2`),SUM(`3`),SUM(`4`) from magic_sq; 
select xy_id, SUM(`1` +`2` +`3` + `4`) as per_row from magic_sq GROUP BY xy_id; 

END// 
delimiter ;


今、この仕事していますか? 

CALL magic_sq(4); 
+-------+------+------+------+------+ 
| xy_id | 1 | 2 | 3 | 4 | 
+-------+------+------+------+------+ 
| 1 | 1 | 2 | 15 | 16 | 
| 2 | 13 | 14 | 3 | 4 | 
| 3 | 12 | 7 | 10 | 5 | 
| 4 | 8 | 11 | 6 | 9 | 
+-------+------+------+------+------+ 
4 rows in set (0.22 sec) 

+----------+----------+----------+----------+ 
| SUM(`1`) | SUM(`2`) | SUM(`3`) | SUM(`4`) | 
+----------+----------+----------+----------+ 
| 34 | 34 | 34 | 34 | 
+----------+----------+----------+----------+ 
1 row in set (0.22 sec) 

+-------+---------+ 
| xy_id | per_row | 
+-------+---------+ 
| 1 | 34 | 
| 2 | 34 | 
| 3 | 34 | 
| 4 | 34 | 
+-------+---------+ 
[OK]を私はちょうど周りに列を移動することによって、少しだまされていますが、アイデアを得る。