How to divide UInt8 into 3 bits and 5 bits - ios

I am wondering how to input UInt8 divided into 3bit and 5bit.
Var val: UInt8 = 0
Val.bit3 = 0x06 // 110
Val.bit5 = 0x11 // 10000
i want result:
11010000 or 10000110 (3bit / 5bit or 5bit / 3bit)
extension UInt8 {
var bit3 : UInt8 {
get {
??
}
set(newValue) {
??
}
}
var bit5 : UInt8 {
get {
??
}
set(newValue) {
??
}
}
}
How do I do bitwise operations to get the result above?
... Thank you

You can do something like that
extension UInt8 {
var bit3 : UInt8 {
get {
return (self & 0b1110_0000) >> 5
}
set(newValue) {
self &= 0b0001_1111
self |= ((newValue << 5) & 0b1110_0000)
}
}
var bit5 : UInt8 {
get {
return self & 0b0001_1111
}
set(newValue) {
self &= 0b1110_0000
self |= (newValue & 0b0001_1111)
}
}
}
bit3 here is "top" and bit5 is "bottom".
EDIT: Forgot to clean bits before setting

Related

Fastest way to save structs iOS / Swift

I have structs like
struct RGBA: Codable {
var r: UInt8
var g: UInt8
var b: UInt8
var a: UInt8
}
I want save large amount of this structs (>1_000_000)
Decode
guard let history = try? JSONDecoder().decode(HistoryRGBA.self, from: data) else { return }
Encode
guard let jsonData = try? encoder.encode(dataForSave) else { return false }
How can I improve encoding/decoding time and amount of RAM memory?
The performance of JSONEncoder/Decoder performance is...not great. ZippyJSON is a drop-in replacement that is supposedly about 4 times faster than Foundation's implmenetation, and if you're going for better performance and lower memory usage, you'll probably want to Google for some kind of streaming JSON decoder library.
However, you said in the comments that you don't need the JSON format. That's great, because we can store the data much more efficiently as just an array of raw bytes rather than a text-based format such as JSON:
extension RGBA {
static let size = 4 // the size of a (packed) RGBA structure
}
// encoding
var data = Data(count: history.rgba.count * RGBA.size)
for i in 0..<history.rgba.count {
let rgba = history.rgba[i]
data[i*RGBA.size] = rgba.r
data[i*RGBA.size+1] = rgba.g
data[i*RGBA.size+2] = rgba.b
data[i*RGBA.size+3] = rgba.a
}
// decoding
guard data.count % RGBA.size == 0 else {
// data is incomplete, handle error
return
}
let rgbaCount = data.count / RGBA.size
var result = [RGBA]()
result.reserveCapacity(rgbaCount)
for i in 0..<rgbaCount {
result.append(RGBA(r: data[i*RGBA.size],
g: data[i*RGBA.size+1],
b: data[i*RGBA.size+2],
a: data[i*RGBA.size+3]))
}
This is already about 50 times faster than using JSONEncoder on my machine (~100ms instead of ~5 seconds).
You can get even faster by bypassing some of Swift's safety checks and memory management and dropping down to raw pointers:
// encoding
let byteCount = history.rgba.count * RGBA.size
let rawBuf = malloc(byteCount)!
let buf = rawBuf.bindMemory(to: UInt8.self, capacity: byteCount)
for i in 0..<history.rgba.count {
let rgba = history.rgba[i]
buf[i*RGBA.size] = rgba.r
buf[i*RGBA.size+1] = rgba.g
buf[i*RGBA.size+2] = rgba.b
buf[i*RGBA.size+3] = rgba.a
}
let data = Data(bytesNoCopy: rawBuf, count: byteCount, deallocator: .free)
// decoding
guard data.count % RGBA.size == 0 else {
// data is incomplete, handle error
return
}
let result: [RGBA] = data.withUnsafeBytes { rawBuf in
let buf = rawBuf.bindMemory(to: UInt8.self)
let rgbaCount = buf.count / RGBA.size
return [RGBA](unsafeUninitializedCapacity: rgbaCount) { resultBuf, initializedCount in
for i in 0..<rgbaCount {
resultBuf[i] = RGBA(r: data[i*RGBA.size],
g: data[i*RGBA.size+1],
b: data[i*RGBA.size+2],
a: data[i*RGBA.size+3])
}
}
}
Benchmark results on my machine (I did not test ZippyJSON):
JSON:
Encode: 4967.0ms; 32280478 bytes
Decode: 5673.0ms
Data:
Encode: 96.0ms; 4000000 bytes
Decode: 19.0ms
Pointers:
Encode: 1.0ms; 4000000 bytes
Decode: 18.0ms
You could probably get even faster by just writing your array directly from memory to disk without serializing it at all, although I haven't tested that either. And of course, when you're testing performance, be sure you're testing in Release mode.
Considering that all your properties are UInt8 (bytes) you can make your struct conform to ContiguousBytes and save its raw bytes:
struct RGBA {
let r, g, b, a: UInt8
}
extension RGBA: ContiguousBytes {
func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
try Swift.withUnsafeBytes(of: self) { try body($0) }
}
}
extension ContiguousBytes {
init<T: ContiguousBytes>(_ bytes: T) {
self = bytes.withUnsafeBytes { $0.load(as: Self.self) }
}
}
extension RGBA: ExpressibleByArrayLiteral {
typealias ArrayLiteralElement = UInt8
init(arrayLiteral elements: UInt8...) {
self.init(elements)
}
}
extension Array {
var bytes: [UInt8] { withUnsafeBytes { .init($0) } }
var data: Data { withUnsafeBytes { .init($0) } }
}
extension ContiguousBytes {
var bytes: [UInt8] { withUnsafeBytes { .init($0) } }
var data: Data { withUnsafeBytes { .init($0) } }
}
extension ContiguousBytes {
func object<T>() -> T { withUnsafeBytes { $0.load(as: T.self) } }
func objects<T>() -> [T] { withUnsafeBytes { .init($0.bindMemory(to: T.self)) } }
}
extension ContiguousBytes {
var rgba: RGBA { object() }
var rgbaCollection: [RGBA] { objects() }
}
extension UIColor {
convenience init<T: Collection>(_ bytes: T) where T.Index == Int, T.Element == UInt8 {
self.init(red: CGFloat(bytes[0])/255,
green: CGFloat(bytes[1])/255,
blue: CGFloat(bytes[2])/255,
alpha: CGFloat(bytes[3])/255)
}
}
extension RGBA {
var color: UIColor { .init(bytes) }
}
let red: RGBA = [255, 0, 0, 255]
let green: RGBA = [0, 255, 0, 255]
let blue: RGBA = [0, 0, 255, 255]
let redBytes = red.bytes // [255, 0, 0, 255]
let redData = red.data // 4 bytes
let rgbaFromBytes = redBytes.rgba // RGBA
let rgbaFromData = redData.rgba // RGBA
let colorFromRGBA = red.color // r 1.0 g 0.0 b 0.0 a 1.0
let rgba: RGBA = [255,255,0,255] // RGBA yellow
let yellow = rgba.color // r 1.0 g 1.0 b 0.0 a 1.0
let colors = [red, green, blue] // [{r 255, g 0, b 0, a 255}, {r 0, g 255, b 0, a 255}, {r 0, g 0, b 255, a 255}]
let colorsData = colors.data // 12 bytes
let colorsFromData = colorsData.rgbaCollection // [{r 255, g 0, b 0, a 255}, {r 0, g 255, b 0, a 255}, {r 0, g 0, b 255, a 255}]
edit/update:
struct LayerRGBA {
var canvas: [[RGBA]]
}
extension LayerRGBA {
var data: Data { canvas.data }
init(_ data: Data) { canvas = data.objects() }
}
struct AnimationRGBA {
var layers: [LayerRGBA]
}
extension AnimationRGBA {
var data: Data { layers.data }
init(_ data: Data) {
layers = data.objects()
}
}
struct HistoryRGBA {
var layers: [LayerRGBA] = []
var animations: [AnimationRGBA] = []
}
extension HistoryRGBA {
var data: Data {
let layersData = layers.data
return layersData.count.data + layersData + animations.data
}
init(data: Data) {
let index = Int(Data(data.prefix(8))).advanced(by: 8)
self.init(layers: data.subdata(in: 8..<index).objects(),
animations: data.subdata(in: index..<data.endIndex).objects())
}
}
extension Numeric {
var data: Data {
var bytes = self
return .init(bytes: &bytes, count: MemoryLayout<Self>.size)
}
}
extension Numeric {
init<D: DataProtocol>(_ data: D) {
var value: Self = .zero
let _ = withUnsafeMutableBytes(of: &value, { data.copyBytes(to: $0)} )
self = value
}
}
Playground testing:
let layer1: LayerRGBA = .init(canvas: [colors,[red],[green, blue]])
let layer2: LayerRGBA = .init(canvas: [[red],[green, rgba]])
let loaded: LayerRGBA = .init(layer1.data)
loaded.canvas[0]
loaded.canvas[1]
loaded.canvas[2]
let animationRGBA: AnimationRGBA = .init(layers: [layer1,layer2])
let loadedAnimation: AnimationRGBA = .init(animationRGBA.data)
loadedAnimation.layers.count // 2
loadedAnimation.layers[0].canvas[0]
loadedAnimation.layers[0].canvas[1]
loadedAnimation.layers[0].canvas[2]
loadedAnimation.layers[1].canvas[0]
loadedAnimation.layers[1].canvas[1]
let hRGBA: HistoryRGBA = .init(layers: [loaded], animations: [animationRGBA])
let loadedHistory: HistoryRGBA = .init(data: hRGBA.data)
loadedHistory.layers[0].canvas[0]
loadedHistory.layers[0].canvas[1]
loadedHistory.layers[0].canvas[2]
loadedHistory.animations[0].layers[0].canvas[0]
loadedHistory.animations[0].layers[0].canvas[1]
loadedHistory.animations[0].layers[0].canvas[2]
loadedHistory.animations[0].layers[1].canvas[0]
loadedHistory.animations[0].layers[1].canvas[1]
If anyone else like me was wondering if using PropertyListEncoder/Decoder or writing custom encoding/decoding methods for Codable structs can make any difference in performance then I made some tests to check it and the answer is that they can improve it a little bit compared to standard JSONEncoder/Decoder but not much. I can't really recommended this as there are far faster ways of doing it in other answers but I think it might be useful in some cases so I'm putting the results here. Using unkeyedContainer for encoding/decoding Codable made encoding about 2x faster in my tests but it had minimal impact on decoding and using PropertyListEncoder/Decoder made only minimal difference as pasted below. Test code:
struct RGBA1: Codable {
var r: UInt8
var g: UInt8
var b: UInt8
var a: UInt8
}
struct RGBA2 {
var r: UInt8
var g: UInt8
var b: UInt8
var a: UInt8
}
extension RGBA2: Codable {
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(r)
try container.encode(g)
try container.encode(b)
try container.encode(a)
}
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
r = try container.decode(UInt8.self)
g = try container.decode(UInt8.self)
b = try container.decode(UInt8.self)
a = try container.decode(UInt8.self)
}
}
class PerformanceTests: XCTestCase {
var rgba1: [RGBA1] = {
var rgba1: [RGBA1] = []
for i in 0..<1_000_000 {
rgba1.append(RGBA1(r: UInt8(i % 256), g: UInt8(i % 256), b: UInt8(i % 256), a: UInt8(i % 256)))
}
return rgba1
}()
var rgba2: [RGBA2] = {
var rgba2: [RGBA2] = []
for i in 0..<1_000_000 {
rgba2.append(RGBA2(r: UInt8(i % 256), g: UInt8(i % 256), b: UInt8(i % 256), a: UInt8(i % 256)))
}
return rgba2
}()
func testRgba1JsonEncoding() throws {
var result: Data?
self.measure { result = try? JSONEncoder().encode(rgba1) }
print("rgba1 json size: \(result?.count ?? 0)")
}
func testRgba1JsonDecoding() throws {
let result = try? JSONEncoder().encode(rgba1)
self.measure { _ = try? JSONDecoder().decode([RGBA1].self, from: result!) }
}
func testRgba1PlistEncoding() throws {
var result: Data?
self.measure { result = try? PropertyListEncoder().encode(rgba1) }
print("rgba1 plist size: \(result?.count ?? 0)")
}
func testRgba1PlistDecoding() throws {
let result = try? PropertyListEncoder().encode(rgba1)
self.measure { _ = try? PropertyListDecoder().decode([RGBA1].self, from: result!) }
}
func testRgba2JsonEncoding() throws {
var result: Data?
self.measure { result = try? JSONEncoder().encode(rgba2) }
print("rgba2 json size: \(result?.count ?? 0)")
}
func testRgba2JsonDecoding() throws {
let result = try? JSONEncoder().encode(rgba2)
self.measure { _ = try? JSONDecoder().decode([RGBA2].self, from: result!) }
}
func testRgba2PlistEncoding() throws {
var result: Data?
self.measure { result = try? PropertyListEncoder().encode(rgba2) }
print("rgba2 plist size: \(result?.count ?? 0)")
}
func testRgba2PlistDecoding() throws {
let result = try? PropertyListEncoder().encode(rgba2)
self.measure { _ = try? PropertyListDecoder().decode([RGBA2].self, from: result!) }
}
}
Results on my device:
testRgba1JsonEncoding average 5.251 sec 32281065 bytes
testRgba1JsonDecoding average 7.749 sec
testRgba1PlistEncoding average 4.811 sec 41001610 bytes
testRgba1PlistDecoding average 7.529 sec
testRgba2JsonEncoding average 2.546 sec 16281065 bytes
testRgba2JsonDecoding average 7.906 sec
testRgba2PlistEncoding average 2.710 sec 25001586 bytes
testRgba2PlistDecoding average 6.432 sec

Cannot assign to property: 'self' is immutable swift error

Inside my app I created a Protocol called "Positions" and extended the UIView class to conform to this protocol in order to add some properties to the UIView class. I used the code below.
import Foundation
import UIKit
protocol Positions {
var initialPositions: [CGRect] {get set}
var finalPositions: [CGRect] {get set}
var positionsAreDefined: Bool {get}
}
public enum PositionsType {
case initial
}
private var initialPositionKey: UInt = 0
private var finalPositionKey: UInt = 0
extension Positions {
var initialPositions: [CGRect] {
get {
if objc_getAssociatedObject(self, &initialPositionKey) != nil {
return objc_getAssociatedObject(self, &initialPositionKey) as! [CGRect]
} else {
return [] as! [CGRect]
}
}
set {
objc_setAssociatedObject(self, &initialPositionKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
var finalPositions: [CGRect] {
get {
if objc_getAssociatedObject(self, &finalPositionKey) != nil {
return objc_getAssociatedObject(self, &finalPositionKey) as! [CGRect]
} else {
return [] as! [CGRect]
}
}
set {
objc_setAssociatedObject(self, &finalPositionKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
var positionsAreDefined: Bool {
get {return initialPositions.count != 0 && finalPositions.count != 0 && initialPositions.count == finalPositions.count}
}
var positionsCount: Int {
get {return initialPositions.count}
}
}
extension UIView: Positions {}
Well, today I tried to extend the UIView class with a new method that changes the added-by-me properties but the compiler gave me this error on the line where I tried to modify the properties value:
Cannot assign to property: 'self' is immutable
Here's the method:
public func horizontallyInContainer(withShift shift: CGFloat, forExpansionNumber index: Int, forPositionType type: PositionsType) {
if self.positionsAreDefined && self.superview != nil {
if type == .initial {
var newPositions = self.initialPositions
newPositions[index].origin.x = self.superview!.bounds.width * 0.5 - self.bounds.width + shift
self.initialPositions = newPositions //Here happens the error
} else {
var newPositions = self.finalPositions
newPositions[index].origin.x = self.superview!.bounds.width * 0.5 - self.bounds.width + shift
self.finalPositions = newPositions //Also here happens
}
}
}
Can anyone explain me the nature of that error?
Make the protocol become reference type
protocol Positions: AnyObject {

How to reimplement a class with sets instead of arrays in Swift

I am trying to redevelop the Colony class I wrote for Conway's Game of Life with Sets instead of arrays but am having trouble doing so. Here's what I've got so far:
P.S. I am assuming a fixed Colony size of 20x20.
import Foundation
struct Array2DB {
var values: [Int]
var rows: Int
var cols: Int
init(rows: Int, cols: Int){
self.rows = rows
self.cols = cols
values = [Int](repeating: 0, count: (rows + 2) * (cols + 2) )
}
//allows uasge of the syntax [row, col] for get/set access
subscript(row:Int, col: Int) -> Int {
get {
return values[getIndex(row, col)]
}
set(val) {
values[getIndex(row, col)] = val
}
}
//converts 2D indices to index in data (terminates if out of bounds)
func getIndex(_ row: Int, _ col: Int) -> Int {
assert((row >= -1) && (row <= rows), "row \(row) is out of bounds")
assert((col >= -1) && (col <= cols), "col \(col) is out of bounds")
return (row + 1) * cols + col + 1
}
var description: String {
var desc = "Matrix:\n"
for row in 0 ..< rows {
for col in 0 ..< cols {
desc += " \(values[getIndex(row, col)]) "
}
desc += "\n"
}
return desc
}
}
class Colony: CustomStringConvertible {
let colony: Set = Array2DB[rows, cols, values]
func setCellAlive(xCoor: Int, yCoor: Int) {
colony[xCoor, yCoor] = 1
}
func setCellDead(xCoor:Int, yCoor: Int) {
colony[xCoor, yCoor] = 0
}
func resetColony() {
for i in 0..<colony.rows {
for e in 0..<colony.cols {
colony[i, e] = 0
}
}
}
var description: String {
var desc = ""
for i in 0..<colony.rows {
for e in 0..<colony.cols {
if colony[i, e] == 1 {
desc += "*"
} else {
desc += "-"
}
}
desc += "\n"
}
return desc
}
func isCellALive( xCoor: Int, yCoor: Int) -> Bool{
return colony[xCoor, yCoor] == 1
}
func evolve() {
var colonyUpdate: Array2DB = colony
for i in 0..<colony.rows {
for e in 0..<colony.cols {
let cGen = rules(xCoor: i, yCoor: e)
if ((cGen < 2) || (cGen > 3)) {
colonyUpdate[i, e] = 0
} else if cGen == 3 {
colonyUpdate[i, e] = 1
} else {
if colony[i, e] == 1 {
colonyUpdate[i, e] = 1
} else {
colonyUpdate[i, e] = 0
}
}
}
}
colony = colonyUpdate
}
}
I'm sure that I've implemented it wrong, but how would I turn the arrays to sets? I'm really confused and would appreciate any guidance or feedbac
Your data type Array2DB is not an Array. It is a Struct that contains an array. You can't assign an Array2DB to a variable that you've declared to be of type Set. It won't work.
You also can't use a Set as the storage for Conway's game of life. The Swift Set data type is an unordered collection. It is unsuitable to serve as the storage for the data in the game of life. You want an array, period.
A very little help for you to show an example of using Set in Game of Life.
struct Cell: Hashable {
var x: Int
var y: Int
}
class Colony: CustomStringConvertible {
var aliveCells: Set = Set<Cell>()
let numberOfRows: Int
let numberOfColumns: Int
init(colonySize: Int) {
self.numberOfRows = colonySize
self.numberOfColumns = colonySize
}
func setCellAlive(xCoor: Int, yCoor: Int) {
aliveCells.insert(Cell(x: xCoor, y: yCoor))
}
func setCellDead(xCoor:Int, yCoor: Int) {
aliveCells.remove(Cell(x: xCoor, y: yCoor))
}
func resetColony() {
aliveCells.removeAll(keepingCapacity: true)
}
var description: String {
var desc = ""
for i in 0..<numberOfRows {
for e in 0..<numberOfColumns {
if aliveCells.contains(Cell(x: e, y: i)) { //Usually `x` represents column, and `y` for row
desc += "*"
} else {
desc += "-"
}
}
desc += "\n"
}
return desc
}
//Implement other methods you need
//...
}
As already noted, Set is not a good data type for Game of Life. But you can implement it using Set. Good luck.

How can I put multiple value inputs in an UITextField to get their outputs?

I'm building an iOS app that deals with binary and decimal outputs when a user types in a binary or decimal number. I have it to where a user can calculate one value, but how can I get it to where they can calculate multiple values in the same UITextField? Like they can type in 145, 10010110, 10011101, etc. and it can return the opposite binary or decimal.
My existing code is:
class BinaryDecimal {
var bits: [Int]?
var integer: Int?
init(_ bits: [Int]) {
self.bits = bits
}
init(_ decimal: Int) {
self.integer = decimal
}
func calculateBinaryValueForInt() -> String {
var newInt = integer!
let rows = [128, 64, 32, 16, 8, 4, 2, 1]
var binaryRows: [Int] = []
for row in rows {
let binaryDigit = oneOrZero(forValue: newInt, withBitValue: row)
binaryRows.append(binaryDigit)
if binaryDigit == 1 {
newInt = newInt - row
}
}
let stringFromIntArray = binaryRows.map { String($0) }
return stringFromIntArray.joined()
}
func calculateIntValueForBinary() -> String {
var value = 0
var multiplier = 1
guard let bits = bits else { return "Error" }
for bit in bits.reversed() {
let newValue = bit * multiplier
value = value + newValue
multiplier = multiplier * 2
}
return String(value)
}
func oneOrZero(forValue value: Int, withBitValue bitvalue: Int) -> Int {
if value - bitvalue >= 0 {
return 1
} else {
return 0
}
}
}

Recursive n Queens on nxn chess board implementation in Swift

I am trying to create a recursive Swift implementation for the solution of the classic puzzle: "How can we distribute n queens on a chess grid of n × n so that no queen can threaten another".
With existing code I encountered the following problems:
Code does not produce all the solutions for n<=8
Code does not product ANY solution for n>=9
Can't seem to compare solutions for n=8 (8x8) and larger because I compute the hash for each Solution class (board) by shifting bits which represent existence of queen or empty tile:
public override var hash: Int {
var hash = 0
for i in 0...self.board.count-1 {
for j in 0...self.board.count-1 {
if self.board[i][j].state == .Queen {
hash |= 1
hash <<= 1
} else {
hash <<= 1
}
}
}
return hash
}
when board is >8x8 value gets corrupted as it is larger than 64 bits (swift Int is Int64). What's a good solution for that?
My current code:
import UIKit
public typealias Board = Array<Array<Cell>>
#objc protocol QueenPlacementDelegate : class {
func solutionsFound(numOfSolutions : Int)
}
class QueenPlacement: NSObject {
var boardView : TTTBoardView?
var boardSize : Int = 0
var solutions : Set<Solution>?
weak var delegate : QueenPlacementDelegate?
private var startCondX : Int = 0
private var startCondY : Int = 0
func start() {
if boardSize == 0 {
print("Board size was not initialized")
return
}
self.solutions = Set<Solution>()
var done = false
self.startCondX = 0; self.startCondY = 0;
while (!done) {
let solution = Solution(boardSize: self.boardSize)
let board = solution.board
self.placeQueen(startCondX, yLoc: startCondY, board: board)
let solutionBoard = self.findSolutionForBoard(board)
if self.numOfQueensOnBoard(solutionBoard) == self.boardSize {
print("solution found")
solution.board = solutionBoard
self.solutions!.insert(solution)
}
done = self.advanceStartConditionsAndCheckIfDone()
if (done) {
if self.solutions!.count > 0 {
self.delegate!.solutionsFound(self.solutions!.count)
}
}
}
}
func advanceStartConditionsAndCheckIfDone() -> Bool {
startCondX++
if startCondX >= self.boardSize {
startCondX = 0
startCondY++
if startCondY >= self.boardSize {
return true
}
}
return false
}
func placeQueen(xLoc : Int, yLoc : Int, board : Board) {
board[xLoc][yLoc].state = .Queen
}
func findSolutionForBoard(board : Board) -> Board
{
let queensPlaced = self.numOfQueensOnBoard(board)
if queensPlaced == self.boardSize {
return board
}
else
{
for i in 0...self.boardSize-1 {
for j in 0...self.boardSize-1 {
if self.canPlaceQueen(xLoc: i, yLoc: j, board: board) {
self.placeQueen(i, yLoc: j, board: board)
}
}
}
let newQueensPlaced = self.numOfQueensOnBoard(board)
// recursion exit conditions: could not place any new queen
if newQueensPlaced > queensPlaced {
self.findSolutionForBoard(board)
} else {
return board
}
}
return board
}
func numOfQueensOnBoard(board : Board) -> Int {
var queensPlaced = 0
for i in 0...self.boardSize-1 {
for j in 0...self.boardSize-1 {
if board[i][j].state == .Queen {
queensPlaced++
}
}
}
return queensPlaced
}
func canPlaceQueen(xLoc xLoc : Int, yLoc : Int, board: Board) -> Bool {
for i in 0...self.boardSize-1 {
if board[i][yLoc].state == .Queen {
return false;
}
if board[xLoc][i].state == .Queen {
return false;
}
}
var x : Int
var y : Int
x = xLoc; y = yLoc;
while ++x < self.boardSize && ++y < self.boardSize {
if board[x][y].state == .Queen {
return false
}
}
x = xLoc; y = yLoc;
while --x >= 0 && ++y < self.boardSize {
if board[x][y].state == .Queen {
return false
}
}
x = xLoc; y = yLoc;
while ++x < self.boardSize && --y >= 0 {
if board[x][y].state == .Queen {
return false
}
}
x = xLoc; y = yLoc;
while --x >= 0 && --y >= 0 {
if board[x][y].state == .Queen {
return false
}
}
return true
}
// singleton!
static let sharedInstance = QueenPlacement()
private override init() {}
}
What is wrong here?
P.S.
for easier reading - full code repo can be found here
It's not an answer in a way that I don't know what is the problem with your version, but here is another one (looks working as I tested it), a little bit simplier (based on Scala By Example - The N-Queens Problem).
func queens(n: Int) -> [[Int]] {
guard n > 3 else {
return [[Int]]()
}
func placeQueens(k: Int) -> [[Int]] {
guard k > 0 else {
return [[-1]] //stupid hack to let the app go to the for-loop in the * marked place
}
var res = [[Int]]()
for var q in placeQueens(k - 1) { //* marked place
if let first = q.first where first == -1 { //this is for removing the hacky -1
q.removeAll()
}
for column in 1...n {
if isSafe(column, queens: q) {
var solution = q
solution.append(column)
res.append(solution)
}
}
}
return res
}
return placeQueens(n)
}
func isSafe(column: Int, queens: [Int]) -> Bool {
for (index, q) in queens.enumerate() {
let dy = (index + 1) - (queens.count + 1)
let dx = q - column
let isDiagonal = dy * dy == dx * dx
if q == column || isDiagonal {
return false
}
}
return true
}
And if you want to draw the solutions out:
func drawTable(table: [Int]) -> String {
var res = ""
table.forEach {
for column in 1...table.count {
if $0 == column {
res += "X "
} else {
res += ". "
}
}
res += "\n"
}
return res
}
And
queens(4).forEach {
print(drawTable($0))
}
Computing the 73712 solutions of n = 13 took some minutes, above that you would probably run out of memory this way.

Resources