Last active
August 29, 2015 14:07
-
-
Save pragmaticlogic/b1ee39ba014fc0198cde to your computer and use it in GitHub Desktop.
Swift Tower interactive
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Foundation | |
| enum ClockDirection { | |
| case Clockwise | |
| case CounterClockwise | |
| } | |
| enum DirectionOfDiskMoved { | |
| case ToTower | |
| case FromTower | |
| } | |
| func getDirection(#tower:Tower) -> (clockwiseTower: Tower, counterclockwiseTower: Tower) { | |
| switch tower { | |
| case .Tower1: | |
| return (.Tower2, .Tower3) | |
| case .Tower2: | |
| return (.Tower3, .Tower1) | |
| default: | |
| return (.Tower1, .Tower2) | |
| } | |
| } | |
| //if direction is FromTower, this func returns the non-empty stack or smaller top of the 2 stacks. Stack is source | |
| //if direction is ToTower, this func returns the empty stack or the larger top of the 2 stacks. Stack is dest | |
| func getStackSourceOrDest(towerA:Tower, towerB:Tower, towerStacks: [Tower: Stack<Int>], direction:DirectionOfDiskMoved) -> Tower { | |
| var stackA:Stack<Int> = towerStacks[towerA]! | |
| var stackB:Stack<Int> = towerStacks[towerB]! | |
| switch (direction) { | |
| case .FromTower: | |
| if (stackA.isEmty()) { | |
| return towerB | |
| } else if (stackB.isEmty()) { | |
| return towerA | |
| } else { | |
| return stackA.peek() < stackB.peek() ? towerA : towerB | |
| } | |
| default: | |
| if (stackA.isEmty()) { | |
| return towerA | |
| } else if (stackB.isEmty()) { | |
| return towerB | |
| } else { | |
| return stackA.peek() > stackB.peek() ? towerA : towerB | |
| } | |
| } | |
| } | |
| func getTowerWhereToGetDiskFrom(#referenceTower:Tower, towerStacks: [Tower: Stack<Int>]) -> Tower { | |
| switch (referenceTower) { | |
| case .Tower1: | |
| return getStackSourceOrDest(.Tower2, .Tower3, towerStacks, DirectionOfDiskMoved.FromTower) | |
| case .Tower2: | |
| return getStackSourceOrDest(.Tower1, .Tower3, towerStacks, DirectionOfDiskMoved.FromTower) | |
| default: | |
| return getStackSourceOrDest(.Tower1, .Tower2, towerStacks, DirectionOfDiskMoved.FromTower) | |
| } | |
| } | |
| func getTowerWhereToMoveDiskTo(#referenceTower:Tower, towerStacks: [Tower: Stack<Int>]) -> Tower { | |
| switch (referenceTower) { | |
| case .Tower1: | |
| return getStackSourceOrDest(.Tower2, .Tower3, towerStacks, DirectionOfDiskMoved.ToTower) | |
| case .Tower2: | |
| return getStackSourceOrDest(.Tower1, .Tower3, towerStacks, DirectionOfDiskMoved.ToTower) | |
| default: | |
| return getStackSourceOrDest(.Tower1, .Tower2, towerStacks, DirectionOfDiskMoved.ToTower) | |
| } | |
| } | |
| func towerInteractive(numberOfDisks: Int, towerStacks: [Tower: Stack<Int>]) { | |
| var towerWhere1Is = Tower.Tower1 | |
| let iterations: Int = Int(pow(Double(2),Double(numberOfDisks))) - 1 | |
| for index in 1 ... iterations { | |
| if (index % 2 == 1) { | |
| let stack:Stack<Int> = towerStacks[towerWhere1Is]! | |
| let (clockwiseTower: Tower, counterclockwiseTower: Tower) = getDirection(tower:towerWhere1Is) | |
| let newStack = towerStacks[counterclockwiseTower]! | |
| let disk1 = stack.pop()! | |
| newStack.push(disk1) | |
| println("Move \(disk1) from \(towerWhere1Is.toRaw()) to \(counterclockwiseTower.toRaw())") | |
| //update the tower where we move disk1 to | |
| towerWhere1Is = counterclockwiseTower | |
| } else { | |
| let towerWhereToGetDiskFrom = getTowerWhereToGetDiskFrom(referenceTower:towerWhere1Is, towerStacks) | |
| let stack:Stack<Int> = towerStacks[towerWhereToGetDiskFrom]! | |
| let disk = stack.pop()! | |
| let towerWhereToMoveDiskTo = getTowerWhereToMoveDiskTo(referenceTower:towerWhereToGetDiskFrom, towerStacks) | |
| let newStack = towerStacks[towerWhereToMoveDiskTo]! | |
| newStack.push(disk) | |
| println("Move \(disk) from \(towerWhereToGetDiskFrom.toRaw()) to \(towerWhereToMoveDiskTo.toRaw())") | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment