I cannot add or subtract anything from this.
I cannot add or subtract anything from this.
This is heapsort in a Swift playground. I needed a stable sort, so naturally I wrote an… unstable sort.
Of course, you can just use sort()
or sorted()
, but if you are inclined to roll your own, the Swifty way to do it is to create an extension. Note that an Array extension with a Generic Where Clause is needed to make element comparisons > < ==
work.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
//: Playground - noun: a place where people can play import Cocoa // var elements = [0, 6, 0, 6, 4, 0, 6, 0, 6, 0, 4, 3, 0, 1, 5, 1, 2, 4, 2, 4] var elements = [10, 6, 0, 1, 2, 5, 4, 3, 7, 8, 9] extension Array where Element: Comparable { func heapSorted() -> Array { var r = self func parent(_ i: Int) -> Int { return ((i+1) / 2) - 1 } func leftChild(_ i: Int) -> Int { return ((i + 1) * 2) - 1 } func rightChild(_ i: Int) -> Int { return leftChild(i) + 1 } func descend(i: Int, limit: Int) { let lindex = leftChild(i) let rindex = rightChild(i) if rindex > limit || r[lindex] > r[rindex] { if lindex <= limit && r[lindex] > r[i] { (r[lindex],r[i]) = (r[i],r[lindex]) descend(i: lindex, limit: limit) } } else if rindex <= limit { if r[rindex] > r[i] { (r[rindex],r[i]) = (r[i],r[rindex]) descend(i: rindex, limit: limit) } } } func maxHeapify() { let lastParent = parent(r.count - 1) for i in (0...lastParent).reversed() { descend(i: i, limit: r.count - 1) } } func sortFromHeap() { for i in (1..<r.count).reversed() { (r[0],r[i]) = (r[i],r[0]) descend(i: 0, limit: i-1) } } maxHeapify() sortFromHeap() return r } } elements.heapSorted().forEach{print($0, terminator: " ")} print() |
On to writing mergesort (stable).
Sigh.
I recently completed 10 Days of Statistics on HackerRank. Yay!
In the process, I needed some matrix operations for a medium-difficulty problem. And here they are, code style be damned :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
func transpose(_ matrix: [[Double]]) -> [[Double]] { let rowCount = matrix.count let colCount = matrix[0].count var transposed : [[Double]] = Array(repeating: Array(repeating: 0.0, count: rowCount), count: colCount) for rowPos in 0..<matrix.count { for colPos in 0..<matrix[0].count { transposed[colPos][rowPos] = matrix[rowPos][colPos] } } return transposed } func multiply(_ A: [[Double]], _ B: [[Double]]) -> [[Double]] { let rowCount = A.count let colCount = B[0].count var product : [[Double]] = Array(repeating: Array(repeating: 0.0, count: colCount), count: rowCount) for rowPos in 0..<rowCount { for colPos in 0..<colCount { for i in 0..<B.count { product[rowPos][colPos] += A[rowPos][i] * B[i][colPos] } } } return product } // gauss jordan inversion func inverse(_ matrix: [[Double]]) -> [[Double]] { // augment matrix var matrix = matrix var idrow = Array(repeating: 0.0, count: matrix.count) idrow[0] = 1.0 for row in 0..<matrix.count { matrix[row] += idrow idrow.insert(0.0, at:0) idrow.removeLast() } // partial pivot for row1 in 0..<matrix.count { for row2 in row1..<matrix.count { if abs(matrix[row1][row1]) < abs(matrix[row2][row2]) { (matrix[row1],matrix[row2]) = (matrix[row2],matrix[row1]) } } } // forward elimination for pivot in 0..<matrix.count { // multiply let arg = 1.0 / matrix[pivot][pivot] for col in pivot..<matrix[pivot].count { matrix[pivot][col] *= arg } // multiply-add for row in (pivot+1)..<matrix.count { let arg = matrix[row][pivot] / matrix[pivot][pivot] for col in pivot..<matrix[row].count { matrix[row][col] -= arg * matrix[pivot][col] } } } // backward elimination for pivot in (0..<matrix.count).reversed() { // multiply-add for row in 0..<pivot { let arg = matrix[row][pivot] / matrix[pivot][pivot] for col in pivot..<matrix[row].count { matrix[row][col] -= arg * matrix[pivot][col] } } } // remove identity for row in 0..<matrix.count { for _ in 0..<matrix.count { matrix[row].remove(at:0) } } return matrix } let X = [ [1.0, 2.0, 3.0], [4.0, 5.0, 11.0], [7.0, 8.0, 9.0] ] let XI = inverse(X) let I = multiply(X,XI) print(I) |
That’s the identity matrix popping out at the end, which validates my implementation.
But what’s this? A 60-line method? Uncle Bob would not be pleased.
Comments should not take the place of good variable/method names. Those section comments give clues as to where my methods should be :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
func augment(_ matrix: [[Double]]) -> [[Double]] { var augmented = matrix var idrow = Array(repeating: 0.0, count: matrix.count) idrow[0] = 1.0 for row in 0..<matrix.count { augmented[row] += idrow idrow.insert(0.0, at:0) idrow.removeLast() } return augmented } func deaugment(_ matrix: [[Double]]) -> [[Double]] { var deaugmented = matrix for row in 0..<matrix.count { for _ in 0..<matrix.count { deaugmented[row].remove(at:0) } } return deaugmented } func partialPivot(_ matrix: inout [[Double]]) { for row1 in 0..<matrix.count { for row2 in row1..<matrix.count { if abs(matrix[row1][row1]) < abs(matrix[row2][row2]) { (matrix[row1],matrix[row2]) = (matrix[row2],matrix[row1]) } } } } func scaleRow(_ matrix: inout [[Double]], row: Int, scale: Double) { for col in 0..<matrix[row].count { matrix[row][col] *= scale } } func addRow(_ matrix: inout [[Double]], row: Int, scaledBy: Double, toRow: Int) { for col in 0..<matrix[row].count { matrix[toRow][col] += scaledBy * matrix[row][col] } } func pivot(_ matrix: inout [[Double]], row pivotRow: Int, col pivotCol: Int, forward: Bool) { let scale = 1.0 / matrix[pivotRow][pivotCol] scaleRow(&matrix, row: pivotRow, scale: scale) if forward { for toRow in (pivotRow+1)..<matrix.count { let scaleBy = -1.0 * matrix[toRow][pivotCol] addRow(&matrix, row: pivotRow, scaledBy: scaleBy, toRow: toRow) } } else { for toRow in (0..<pivotRow).reversed() { let scaleBy = -1.0 * matrix[toRow][pivotCol] addRow(&matrix, row: pivotRow, scaledBy: scaleBy, toRow: toRow) } } } func gaussJordanInverse(_ matrix: [[Double]]) -> [[Double]] { var matrix = augment(matrix) partialPivot(&matrix) for p in 0..<matrix.count { pivot(&matrix, row: p, col: p, forward: true) } for p in (0..<matrix.count).reversed() { pivot(&matrix, row: p, col: p, forward: false) } matrix = deaugment(matrix) return matrix } let X = [ [1.0, 2.0, 3.0], [4.0, 5.0, 11.0], [7.0, 8.0, 9.0] ] let XI = gaussJordanInverse(X) let I = multiply(X,XI) print(I) |
Better. Uncle Bob would be proud (or give me credit for trying, anyway).
One more thing : Thanks to StackOverflow user Alexander, I have an even better way to express that pivot loop :
1 2 3 4 5 6 7 8 9 10 11 |
func pivot(_ matrix: inout [[Double]], row pivotRow: Int, col pivotCol: Int, forward: Bool) { let scale = 1.0 / matrix[pivotRow][pivotCol] scaleRow(&matrix, row: pivotRow, scale: scale) let range = forward ? AnyCollection((pivotRow+1)..<matrix.count) : AnyCollection((0..<pivotRow).reversed()) for toRow in range { let scaleBy = -1.0 * matrix[toRow][pivotCol] addRow(&matrix, row: pivotRow, scaledBy: scaleBy, toRow: toRow) } } |
Do you want to learn Swift syntax, have fun, and meet an enthusiastic group of developers? Come by the Williamsburg Library at 515 Scotland Street, Williamsburg, VA, on Saturday, August 12, 2017. We will be going over Swift basics. We have many experienced developers who are eager to share tips and help newcomers.
I hope to see you there!
It’s tomorrow! See you at iOS Dev Camp DC on Friday, August 3, 2017.
I am looking forward to meeting many talented developers and learning all about who you are and what you do.
If you are near the Williamsburg Library on Scotland St. this Saturday, July 22 2017, at 10AM, and you have an interest in iOS development using the Swift programming language, please stop by. I will be giving a presentation on language basics and the development environment. We have a diverse group of enthusiasts with newbies and app store veterans alike.
There is a lovely article by Luna An describing ArraySlice objects in more detail than I do here. It covers Swift 3 at the moment, and you should note that Swift 4 includes support for single-ended ranges, so you can create slices ala [..<count].
I found a good use for an ArraySlice while trying to find quartiles in a set of data.
The problem of finding each quartile is essentially the same problem of finding the median from three different data sets, one being the original input set, the other two being the upper and lower half of the set after removing the original median element, if it exists.
Here, I use findMedian to perform all three tasks. I found that I had to do a bit of extra work because the array slice is not indexed starting at zero. I wonder why they chose to implement slices in this way?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import Foundation func findMedian(_ data: ArraySlice<Int>) -> (Int, Int, Int) { let index1 = (data.count-1)/2 let index2 = data.count/2 let sliceIndex1 = index1 + data.startIndex let sliceIndex2 = index2 + data.startIndex let median = (data[sliceIndex1]+data[sliceIndex2])/2 return (sliceIndex1, sliceIndex2, median) } let data = [0, 1, 2, 5, 11, 17, 19, 21] let X = data[0..<data.count] let (q2Index1, q2Index2, Q2) = findMedian(X) let L = data[0..<q2Index2] let U = data[(q2Index1+1)..<data.count] let (_, _, Q1) = findMedian(L) let (_, _, Q3) = findMedian(U) print(Q1) print(Q2) print(Q3) |
It is the summer of Swift.
I was perusing some wonderful design patterns from Oktawian Chojnacki, and I decided to play around with the Command pattern. The Command pattern represents commands as objects to go between a Caller, which references the commands, and a Receiver, which is referenced by the commands.
I’m reminded of a game :
Here, each command object operates on a Robo, telling it to make a single move. The commands are collected into a program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
//: Command - Represents commands as objects. import Cocoa class Robo : CustomStringConvertible { let name : String var description: String { return name } init(name: String) { self.name = name } } protocol RoboCommand { func execute(robo: Robo) } class TurnRight : RoboCommand { func execute(robo: Robo) { print("\(robo) turns right ➡️") } } class TurnLeft : RoboCommand { func execute(robo: Robo) { print("\(robo) turns left ⬅️") } } class GoForward : RoboCommand { func execute(robo: Robo) { print("\(robo) goes forward ⬆️") } } class RoboProgram { let robo : Robo var commands : [RoboCommand] = [] init(robo: Robo) { self.robo = robo } init(robo: Robo, commands: [RoboCommand]) { self.robo = robo self.commands = commands } func execute() { for command in commands { command.execute(robo: robo) } } } let robo = Robo(name: "Mikey") let program = RoboProgram(robo: robo) program.commands.append(GoForward()) program.commands.append(TurnLeft()) program.commands.append(GoForward()) program.commands.append(GoForward()) program.commands.append(TurnRight()) program.commands.append(GoForward()) program.execute() |
The first draft of this code had the Commands store their target Robo in a property. I realized a problem with this in that my program would accept commands for any Robo, when only one Robo belongs to the program. My solution for this was to give control of the command target to the program itself.
Of course, now the commands are little more than glorified functions, which can be stored in arrays in Swift anyway.
Why is it so hard to find examples of Swift dictionary reduce operations? Examples for arrays abound :
1 2 3 4 |
let countme = [1, 2, 3, 4, 5] let sumall = countme.reduce(0){$0+$1} // sumall is now 15 |
See this if you’re looking for a detailed HowTo.
But dictionary is the more advanced problem. How do I reduce when I have keys and values?
The key here is to note that a dictionary yields the contents of its sequence in tuples containing pairs of values. We still have our familiar $0, $1 arguments from reduce as above, where $0 is the partial sum and $1 is the individual element value. But now $0 and $1 are both tuples, and you get to their contents through $0.0, $0.1, $1.0, and $1.1.
1 2 3 4 |
let namesNumbers = ["Mike":21, "Bruce":25, "Alice":27] let (bigname,bignumber) = namesNumbers.reduce(("",0)) {return ($0.0 + $1.0, $0.1 + $1.1)} |
This example concatenates the strings and adds the integers, and the two separate data types just happen to use the same symbol for the two operations.
React and Angular are popping up a lot in job interviews these days. I decided to try React, since it is rumored to be the simpler of the two. So I created the old Chinese stone game Go in a Codepen. Normally I post code and talk about it in this case, but I think I will just let the Codepen speak for itself. Here, I report my experiences.
There is a lot of learning material out there, but the best resources start out right away with productive examples that get you working quickly. This tutorial video from Traversy Video does a very good job. I used this React demo from Facebook to model my architecture after.
The least trivial part of the game was the capture algorithm. The game engine must figure out if a newly placed stone results in another stone being surrounded. To figure this out, I implemented a recursive breadcrumb algorithm. The method searches recursively in four directions, resulting in a wide descending tree, but marks visited spots on the matrix to prevent infinite recursion. If at any point an empty space (liberty, in game terms) is found, the call stack starts bubbling up with that information. The recursive call will say whether or not a liberty was ever found. If it was, I run a second method to erase all visited points on the matrix, otherwise I run a different method to restore the marked spots back to original.
Here is my reaction (?) to React :
Hidden inherited methods are traps waiting to happen. My IDE (Codepen) did not alert me to inherited methods, so this may be my own fault for not using a JetBrains tool or some such. Pick unique method names just in case.
I don’t really see the payoff. I understand the principle of data flow and limiting state on classes, but a real class-driven language does this in a more flexible way without need of a framework.
I know a little bit of CSS and HTML, so I was able to decorate it a bit, so that it kind of looks like an old wood board.