The input 7|12|1|14|2|13|8|11|16|3|10|5|9|6|15|4
returns 0 by the PHP -code, while 1 by Python code: 1 means that the sums of the 4x4 magic square are the same, while 0 means the reverse. Python code is correct.
The problem of the PHP code seems to be in the function divide's for -loop, since PHP gives too many sums.
How does the logic of PHP code differ from Python's?
PHP
$data = "7|12|1|14|2|13|8|11|16|3|10|5|9|6|15|4";
$array = explode("|", $data);
# Calculate the unique sums of the four figures
# @return array int
function divide ( $array ) {
$sum = array_map('array_sum', array_chunk($array, 4));
$apu_a = array();
for ( $i = 0; $i < count( $sum ); $i++ ) {
if ( $i % 5 == 0 )
$apu_a []= $array[$i];
}
$sum []= array_sum( $apu_a );
$apu_a = array();
for ( $i = 0; $i < count( $sum ); $i++ ) {
if ( $i % 3 == 0 and $i != 15 and $i != 0 )
$apu_a []= $array[$i];
}
$sum []= array_sum( $apu_a );
$result = array_unique($sum);
return $result;
}
Python
data = "7|12|1|14|2|13|8|11|16|3|10|5|9|6|15|4"
lista = map(int,data.split("|"))
def divide( lista ):
summat = [sum(lista[i:i+4]) for i in range(0,len(lista),4)]
summat += [sum(lista[0::5]) for i in range(0, len(lista), 16)]
summat += [sum(a for i,a in enumerate(lista) if i %3==0 and i != 15 and i != 0)]
return set(summat)
The problem is in your PHP line:
for ( $i = 0; $i < count( $sum ); $i++ ) {
you wanted:
for ( $i = 0; $i < count( $array ); $i++ ) {
Fix it in both places, and you get the right answer.
BTW: You are only checking the main diagonals, but you can also check the other wrapping diagonals, and as Greg points out, you never sum the columns.
In your Python code, you have:
summat += [sum(lista[0::5]) for i in range(0, len(lista), 16)]
I'm pretty sure this isn't doing what you intend it to do. len(lista)
is 16, so this range is range(0, 16, 16)
which is [0]
. Then, you're not even using i
in the left hand side of the list comprehension, you're just summing the values along the main diagonal. If this is intended to sum along the main diagonals, you can replace this and the following line with the simpler:
summat += [sum(lista[0::5])]
summat += [sum(lista[3:15:3])]
Finally, you are not calculating the sums of the columns in your magic square at all. You would need something like:
summat += [sum(lista[i::4]) for i in range(4)]
Look to Ned for your answer; this is just to note PHP improvements:
$s = 0;
for ( $i = 0; $i < count( $array ); $i += 5 ) {
$s += $array[$i];
}
$sum[]=$s;
$s=0;
for ( $i = 3; $i < 15; $i+=3 ) {
$s += $array[$i];
}
$sum[]=$s;