• + 0 comments

    C# solution:

    using MagicSquare = System.Collections.Generic.List>; using Row = System.Collections.Generic.List;

    class Result {

    const int MAGIC_CONSTANT = 15;
    private static MagicSquare[]? allMagicSquares = null;
    public static int formingMagicSquare(MagicSquare s)
    {
        allMagicSquares ??= GetAllMagicSquares();
        int minCost = allMagicSquares.Min(square => Cost(square, s));
        return minCost;
    }
    
    private static int Cost(MagicSquare first, MagicSquare second)
    {
        int cost = 0;
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                cost += Math.Abs(first[i][j] - second[i][j]);
            }
        }
        return cost;
    }
    
    private static HashSet<int> Union(HashSet<int> source, int i)
    {
        HashSet<int> result = new HashSet<int>(source);
        result.Add(i);
        return result;
    }
    
    private static MagicSquare[] GetAllMagicSquares()
    => (
        from c1 in Enumerable.Range(1, 9)
        let set1 = new HashSet<int>() { c1 }
    
        from c2 in Enumerable.Range(1, 9)
        where !set1.Contains(c2)
        let set2 = Union(set1, c2)
    
        let c3 = MAGIC_CONSTANT - (c1 + c2)
        where !set2.Contains(c3)
        let set3 = Union(set2, c3)
    
        from c4 in Enumerable.Range(1, 9)
        where !set3.Contains(c4)
        let set4 = Union(set3, c4)
    
        from c5 in Enumerable.Range(1, 9)
        where !set4.Contains(c5)
        let set5 = Union(set4, c5)
    
        let c6 = MAGIC_CONSTANT - (c4 + c5)
        where !set5.Contains(c6)
        let set6 = Union(set5, c6)
    
        let c7 = MAGIC_CONSTANT - (c1 + c4)
        where !set6.Contains(c7)
        let set7 = Union(set6, c7)
    
        let c8 = MAGIC_CONSTANT - (c2 + c5)
        where !set7.Contains(c8)
        let set8 = Union(set7, c8)
    
        let c9 = MAGIC_CONSTANT - (c7 + c8)
        where !set8.Contains(c9)
        && c3 + c6 + c9 == MAGIC_CONSTANT
        // diagonals
        && c1 + c5 + c9 == MAGIC_CONSTANT
        && c3 + c5 + c7 == MAGIC_CONSTANT
        select new MagicSquare()
        {
            new Row(){c1, c2, c3},
            new Row(){c4, c5, c6},
            new Row(){c7, c8, c9}
        }).ToArray();
    

    } `