How to resolve the algorithm Magic squares of odd order step by step in the Swift programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Magic squares of odd order step by step in the Swift programming language

Table of Contents

Problem Statement

A magic square is an   NxN   square matrix whose numbers (usually integers) consist of consecutive numbers arranged so that the sum of each row and column,   and   both long (main) diagonals are equal to the same sum (which is called the   magic number   or   magic constant). The numbers are usually (but not always) the first   N2   positive integers. A magic square whose rows and columns add up to a magic number but whose main diagonals do not, is known as a semimagic square.

For any odd   N,   generate a magic square with the integers   1 ──► N,   and show the results here. Optionally, show the magic number.
You should demonstrate the generator by showing at least a magic square for   N = 5.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Magic squares of odd order step by step in the Swift programming language

Source code in the swift programming language

extension String: Error {}

struct Point: CustomStringConvertible {
    var x: Int
    var y: Int
    
    init(_ _x: Int,
         _ _y: Int) {
        self.x = _x
        self.y = _y
    }
    
    var description: String {
        return "(\(x), \(y))\n"
    }
}

extension Point: Equatable,Comparable {
    static func == (lhs: Point, rhs: Point) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
    static func < (lhs: Point, rhs: Point) -> Bool {
        return lhs.y != rhs.y ? lhs.y < rhs.y : lhs.x < rhs.x
    }
}

class MagicSquare: CustomStringConvertible {
    var grid:[Int:Point] = [:]
    var number: Int = 1
    init(base n:Int) {
        grid = [:]
        number = n
    }
    
    func createOdd() throws -> MagicSquare {
        guard number < 1 || number % 2 != 0 else {
            throw "Must be odd and >= 1, try again"
            return self
        }
        var x = 0
        var y = 0
        let middle = Int(number/2)
        x = middle
        grid[1] = Point(x,y)
        for i in 2 ... number*number {
            let oldXY = Point(x,y)
            x += 1
            y -= 1
            
            if x >= number {x -= number}
            if y < 0 {y +=  number}
            
            var tempCoord = Point(x,y)
            if let _ = grid.firstIndex(where: { (k,v) -> Bool in
                v == tempCoord
            })
            {
                x = oldXY.x
                y = oldXY.y + 1
                if y >= number {y -= number}
                tempCoord = Point(x,y)
            }
            grid[i] = tempCoord
        }
        print(self)
        return self
    }
    
    fileprivate func gridToText(_ result: inout String) {
        let sorted = sortedGrid()
        let sc = sorted.count
        var i = 0
        for c in sorted {
            result += " \(c.key)"
            if c.key < 10 && sc > 10 { result += " "}
            if c.key < 100 && sc > 100 { result += " "}
            if c.key < 1000 && sc > 1000 { result += " "}
            if i%number==(number-1) { result += "\n"}
            i += 1
        }
        result += "\nThe magic number is \(number * (number * number + 1) / 2)"
        result += "\nRows and Columns are "
        
        result += checkRows() == checkColumns() ? "Equal" : " Not Equal!"
        result += "\nRows and Columns and Diagonals are "
        let allEqual = (checkDiagonals() == checkColumns() && checkDiagonals() == checkRows())
        result += allEqual ? "Equal" : " Not Equal!"
        result += "\n"
    }
    
    var description: String {
        var result = "base \(number)\n"
        gridToText(&result)
        return result
    }
}

extension MagicSquare {
    private func sortedGrid()->[(key:Int,value:Point)] {
        return grid.sorted(by: {$0.1 < $1.1})
    }
    
    private func checkRows() -> (Bool, Int?)
    {
        var result = Set<Int>()
        var index = 0
        var rowtotal = 0
        for (cell, _) in sortedGrid()
        {
            rowtotal += cell
            if index%number==(number-1)
            {
                result.insert(rowtotal)
                rowtotal = 0
            }
            index += 1
        }
        return (result.count == 1, result.first ?? nil)
    }
    
    private func checkColumns() -> (Bool, Int?)
    {
        var result = Set<Int>()
        var sorted = sortedGrid()
        for i in 0 ..< number {
            var rowtotal = 0
            for cell in stride(from: i, to: sorted.count, by: number) {
                rowtotal += sorted[cell].key
            }
            result.insert(rowtotal)
        }
        return (result.count == 1, result.first)
    }

    private func checkDiagonals() -> (Bool, Int?)
    {
        var result = Set<Int>()
        var sorted = sortedGrid()
        
        var rowtotal = 0
        for cell in stride(from: 0, to: sorted.count, by: number+1) {
            rowtotal += sorted[cell].key
        }
        result.insert(rowtotal)
        rowtotal = 0
        for cell in stride(from: number-1, to: sorted.count-(number-1), by: number-1) {
            rowtotal += sorted[cell].key
        }
        result.insert(rowtotal)
        
        return (result.count == 1, result.first)
    }
}

try MagicSquare(base: 3).createOdd()
try MagicSquare(base: 5).createOdd()
try MagicSquare(base: 7).createOdd()

  

You may also check:How to resolve the algorithm Count in octal step by step in the VBA programming language
You may also check:How to resolve the algorithm Respond to an unknown method call step by step in the Racket programming language
You may also check:How to resolve the algorithm Knuth's algorithm S step by step in the PARI/GP programming language
You may also check:How to resolve the algorithm 4-rings or 4-squares puzzle step by step in the PL/M programming language
You may also check:How to resolve the algorithm Percentage difference between images step by step in the AutoHotkey programming language