Skip to content

Instantly share code, notes, and snippets.

@DeepFriedTwinkie
Last active December 17, 2016 15:02
Show Gist options
  • Save DeepFriedTwinkie/97199334be11447bd89bf10b346170cc to your computer and use it in GitHub Desktop.
Save DeepFriedTwinkie/97199334be11447bd89bf10b346170cc to your computer and use it in GitHub Desktop.
AdventOfCode.com 2016/Day 4 Solution
import Foundation
//: ## Helpers
func string(fromFile name:String, fileExtension:String) -> String? {
if let filePath = Bundle.main.path(forResource:name, ofType:fileExtension) {
if let inputData = FileManager.default.contents(atPath: filePath) {
return String(data: inputData, encoding: .utf8)
}
}
return nil
}
//: ## Solution Objects
struct Room {
let sectorID: Int
let checksum: String
let name: String
// Used in Part 2
var decryptedName:String {
return String(name.characters.map({ return $0.rotate(by: sectorID) } ))
}
let characterCounts: [Character:Int]
let isReal:Bool
static func countCharacters(characterArray:[String]) -> [Character:Int] {
let singleString = characterArray.joined().characters.sorted()
return singleString.reduce([:]) { (counts: [Character : Int], element) in
var counts = counts
counts[element] = counts[element]?.advanced(by: 1) ?? 1
return counts
}
}
init?(string:String) {
let components = string.components(separatedBy: "-")
guard components.count >= 2 else { return nil }
// Get the SectorID and Checksum
guard let numbers = components.last else { return nil }
// Get the indexes
guard let openBracketIndex = numbers.characters.index(of:"["),
let closeBracketIndex = numbers.characters.index(of:"]") else { return nil }
// Figure out the sectorID
guard let sector = Int(numbers.substring(to: openBracketIndex)) else {
return nil
}
sectorID = sector
let tempChecksum = numbers[numbers.index(after: openBracketIndex)..<closeBracketIndex]
checksum = tempChecksum
// Count up unique characters
let tempCharacterCounts = Room.countCharacters(characterArray: Array(components.dropLast()))
characterCounts = tempCharacterCounts
// Create the name
name = components.dropLast().joined(separator: "-")
// Check if Real
isReal = {
let topCounts = tempCharacterCounts.sorted(by: {
if $0.value == $1.value { return $0.key < $1.key }
return $0.value > $1.value
})
let topCharsString = String(topCounts.map({$0.key}).prefix(tempChecksum.characters.count))
return topCharsString == tempChecksum
}()
}
}
// Part 2 Solution
extension Character {
static let zAscii = "z".unicodeScalars.first!.value
static let aAscii = "a".unicodeScalars.first!.value
func rotate(by: Int) -> Character {
switch self {
case "a"..."z":
let remainder = UInt32(by % 26)
let scalars = String(self).unicodeScalars
let currentAscii = scalars[scalars.startIndex].value
if (currentAscii + remainder) > Character.zAscii {
let fromTop = remainder - (Character.zAscii - currentAscii) - 1
return Character(UnicodeScalar(Character.aAscii + fromTop)!)
}
return Character(UnicodeScalar(currentAscii + remainder)!)
default:
return " "
}
}
}
//: ## Input Processing
let day = "Day4"
let testInput = ["qzmt-zixmtkozy-ivhz-343"]
let testInputs = ["qzmt-zixmtkozy-ivhz-343[abcde]",
"aaaaa-bbb-z-y-x-123[abxyz]",
"a-b-c-d-e-f-g-h-987[abcde]",
"not-a-real-room-404[oarel]",
"totally-real-room-200[decoy]"]
func prepareInput() -> [Room] {
if let inputString = string(fromFile: day, fileExtension: "txt") {
let roomStrings = inputString.components(separatedBy: "\n")
return roomStrings.flatMap ( { return Room(string: $0) } )
}
return [Room]()
}
//let rooms = prepareInput()
let rooms = testInputs.flatMap( { return Room(string:$0) } )
//: ## Solution Execution
//: ### Part 1
let sectorSum = rooms.filter( { return $0.isReal })
.reduce(0, {$0 + $1.sectorID} )
print("Part 1 Answer: \(sectorSum)\n")
//: ### Part 2
print("Part 2 Answers:")
for room in rooms {
print("\(room.decryptedName) - \(room.sectorID)")
}
@DeepFriedTwinkie
Copy link
Author

DeepFriedTwinkie commented Dec 15, 2016

These things are slow with the large input files.

@DeepFriedTwinkie
Copy link
Author

Updated for part 2 solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment