DEV Community

Cover image for Forming a Magic Square (Day 2 of 365)
xdmarttt
xdmarttt

Posted on

Forming a Magic Square (Day 2 of 365)

Challenge link: https://www.hackerrank.com/challenges/magic-square-forming/problem

This is my day 2 of the challenge. What I'm trying to solve is the forming a magic square problem from Hackerrank. So here's the break down on how I solve the problem:

Predefined Magic Squares: First, I define all possible configurations of a 3x3 magic square. Each configuration is represented as a one-dimensional array consisting of nine integers. These integers range from 1 to 9, with each number appearing exactly once. This step establishes the set of target magic squares we aim to compare against.

const magicSquares = [
    [8, 1, 6, 3, 5, 7, 4, 9, 2],
    [4, 3, 8, 9, 5, 1, 2, 7, 6],
    [2, 9, 4, 7, 5, 3, 6, 1, 8],
    [6, 7, 2, 1, 5, 9, 8, 3, 4],
    [6, 1, 8, 7, 5, 3, 2, 9, 4],
    [8, 3, 4, 1, 5, 9, 6, 7, 2],
    [4, 9, 2, 3, 5, 7, 8, 1, 6],
    [2, 7, 6, 9, 5, 1, 4, 3, 8]
];
Enter fullscreen mode Exit fullscreen mode

Merging the Input Matrix: The input function takes a 3x3 square (denoted as s). To simplify operations on this matrix, I merge it into a one-dimensional array. This flattening process facilitates easier access and comparison of the input square's elements with those of the predefined magic squares.

const allInOne = [...s[0], ...s[1], ...s[2]];
Enter fullscreen mode Exit fullscreen mode

Calculating the Transformation Cost: For each predefined magic square, I calculate the cost of transforming the input square into this magic square. The reduce method accumulates the absolute differences between corresponding elements of the input square and a magic square. After iterating through all possible magic squares, the minimum transformation cost is determined.

let lesserCost = Number.MAX_SAFE_INTEGER;
magicSquares.forEach(x => {
    let totalCost = x.reduce((acc, magicValue, index) => {
        return acc + Math.abs(magicValue - allInOne[index]);
    }, 0);
    lesserCost = Math.min(totalCost, lesserCost);
});
Enter fullscreen mode Exit fullscreen mode

Here's the final output

function formingMagicSquare(s) {
    // will convert this one programatically
    const magicSquares = [
        [8, 1, 6, 3, 5, 7, 4, 9, 2],
        [4, 3, 8, 9, 5, 1, 2, 7, 6],
        [2, 9, 4, 7, 5, 3, 6, 1, 8],
        [6, 7, 2, 1, 5, 9, 8, 3, 4],
        [6, 1, 8, 7, 5, 3, 2, 9, 4],
        [8, 3, 4, 1, 5, 9, 6, 7, 2],
        [4, 9, 2, 3, 5, 7, 8, 1, 6],
        [2, 7, 6, 9, 5, 1, 4, 3, 8]
    ];

    const allInOne = [...s[0], ...s[1], ...s[2]]
    let lesserCost = Number.MAX_SAFE_INTEGER;
    magicSquares.forEach(x => {
        let totalCost = x.reduce((acc, magicValue, index) => {
            return acc + Math.abs(magicValue - allInOne[index]);
        }, 0);
        lesserCost = Math.min(totalCost, lesserCost);
    })    

    return lesserCost;
}

Enter fullscreen mode Exit fullscreen mode

Voilà! That's it. I hope you like my solution :)

Top comments (0)