Skip to content

Instantly share code, notes, and snippets.

@DeepFriedTwinkie
Created December 14, 2016 20:31
Show Gist options
  • Save DeepFriedTwinkie/ba5bb6032e9959eadf7ae1aa056525f0 to your computer and use it in GitHub Desktop.
Save DeepFriedTwinkie/ba5bb6032e9959eadf7ae1aa056525f0 to your computer and use it in GitHub Desktop.
AdventOfCode.com 2016 Day 1 Solution (http://adventofcode.com/2016/day/1) (Part 2)
import Foundation
enum Axis {
case X
case Y
}
enum Instruction {
case left (distance:Int)
case right (distance:Int)
init?(instructionString:String) {
guard instructionString.characters.count >= 2 else { return nil }
let firstIndex = instructionString.index(after: instructionString.startIndex)
let direction = instructionString.substring(to: firstIndex).uppercased()
let distance = instructionString.substring(from: firstIndex)
guard let distanceInt = Int(distance), distanceInt > 0 else { return nil }
switch direction {
case "R":
self = .right(distance: distanceInt)
case "L":
self = .left(distance: distanceInt)
default:
return nil
}
}
var distance: Int {
get {
switch self {
case let .left(dist): return dist
case let .right(dist): return dist
}
}
}
}
enum Direction {
case North
case South
case East
case West
func turn(instruction:Instruction) -> Direction {
if case .left(_) = instruction {
switch self {
case .North: return .West
case .South: return .East
case .East: return .North
case .West: return .South
}
} else {
switch self {
case .North: return .East
case .South: return .West
case .East: return .South
case .West: return .North
}
}
}
var axisMultiplier: (Axis, Int) {
get {
switch self {
case .North: return (.X, 1)
case .South: return (.X, -1)
case .East: return (.Y, 1)
case .West: return (.Y, -1)
}
}
}
}
struct Location{
let x: Int
let y: Int
let direction: Direction
}
// Implement Hashable so that Locations can be stored in a Set
extension Location: Hashable, Equatable {
public var hashValue: Int {
return x^y
}
}
func ==(lhs: Location, rhs: Location) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
// Day 1:
let inputString = "R5, L2, L1, R1, R3, R3, L3, R3, R4, L2, R4, L4, R4, R3, L2, L1, L1, R2, R4, R4, L4, R3, L2, R1, L4, R1, R3, L5, L4, L5, R3, L3, L1, L1, R4, R2, R2, L1, L4, R191, R5, L2, R46, R3, L1, R74, L2, R2, R187, R3, R4, R1, L4, L4, L2, R4, L5, R4, R3, L2, L1, R3, R3, R3, R1, R1, L4, R4, R1, R5, R2, R1, R3, L4, L2, L2, R1, L3, R1, R3, L5, L3, R5, R3, R4, L1, R3, R2, R1, R2, L4, L1, L1, R3, L3, R4, L2, L4, L5, L5, L4, R2, R5, L4, R4, L2, R3, L4, L3, L5, R5, L4, L2, R3, R5, R5, L1, L4, R3, L1, R2, L5, L1, R4, L1, R5, R1, L4, L4, L4, R4, R3, L5, R1, L3, R4, R3, L2, L1, R1, R2, R2, R2, L1, L1, L2, L5, L3, L1"
let inputs = inputString.components(separatedBy: ", ")
let instructions = inputs.flatMap { (insString) -> Instruction? in
return Instruction(instructionString: insString)
}
// Just move one step in a certain direction
func performStep(direction:Direction, currentLocation:Location) -> Location {
let axisMultiplier = direction.axisMultiplier
let distanceOffset = axisMultiplier.1
if axisMultiplier.0 == .Y {
return Location(x: currentLocation.x, y: currentLocation.y + distanceOffset, direction: direction)
} else {
return Location(x: currentLocation.x + distanceOffset, y: currentLocation.y, direction: direction)
}
}
var currentLocation = Location(x: 0, y: 0, direction: .North)
var visitedLocations:Set = [currentLocation] // Saves all of the unique locations that have been visisted
loopThroughInstructions: for instruction in instructions {
let direction = currentLocation.direction.turn(instruction: instruction)
for _ in 1...instruction.distance {
currentLocation = performStep(direction: direction, currentLocation: currentLocation)
if visitedLocations.contains(currentLocation) {
break loopThroughInstructions // We've found the current location in our list of visited places, so this is the answer
} else {
visitedLocations.insert(currentLocation) // We haven't been here before, record that we have
}
}
}
let distance = abs(currentLocation.x) + abs(currentLocation.y)
print("Distance: \(distance)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment