Last active
December 18, 2016 16:02
-
-
Save DeepFriedTwinkie/3e29cf3ffa29a1af19a3ae74c3e02438 to your computer and use it in GitHub Desktop.
AdventOfCode.com 2016/Day 5 Solution
This file contains 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
// | |
// ViewController.swift | |
// AdventOfCodeMac | |
// | |
// Created by Scott Atkinson on 12/17/16. | |
// Copyright © 2016 Fathouse Software. All rights reserved. | |
// | |
import Cocoa | |
class ViewController: NSViewController { | |
//: ## Input Processing | |
let testInput = "cxdnnyjw" | |
@IBAction func go(_ sender: Any) { | |
//: ## Solution Execution | |
//: ### Part 1 | |
var doorCode = "" | |
var doorCodeArray: [String?] = [nil, nil, nil, nil, nil, nil, nil, nil] | |
var hashSeed = 0 | |
var foundChars = 0 | |
print("Starting: \(Date())") | |
while (doorCode.characters.count < 8) || (foundChars < 8) { | |
let seed = "\(testInput)\(hashSeed)" | |
let md5 = MD5(seed) | |
if hasLeadingDigits(hash: md5) { | |
// Part 1 | |
if doorCode.characters.count < 8 { | |
doorCode.append(character(at: 5, inHash: md5)) | |
} | |
// Part 2 | |
if let position = Int(character(at: 5, inHash: md5)), position < doorCodeArray.count { | |
if doorCodeArray[position] == nil { | |
doorCodeArray[position] = character(at: 6, inHash: md5) | |
foundChars += 1 | |
} | |
} | |
} | |
hashSeed += 1 | |
} | |
print("Part 1 Answer: \(doorCode)\n") | |
//: ### Part 2 | |
print("Part 2 Answer: \(doorCodeArray.flatMap({$0}).joined())") | |
print("Done: \(Date())") | |
} | |
} | |
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 & Functions | |
func MD5(_ string: String) -> [UInt8] { | |
let context = UnsafeMutablePointer<CC_MD5_CTX>.allocate(capacity: 1) | |
var digest = Array<UInt8>(repeating:0, count:Int(CC_MD5_DIGEST_LENGTH)) | |
CC_MD5_Init(context) | |
CC_MD5_Update(context, string, CC_LONG(string.lengthOfBytes(using: String.Encoding.utf8))) | |
CC_MD5_Final(&digest, context) | |
context.deallocate(capacity: 1) | |
return digest | |
} | |
func hasLeadingDigits(hash:[UInt8]) -> Bool { | |
guard hash.count >= 3 else { return false } | |
return hash[0] == 0 | |
&& hash[1] == 0 | |
&& hash[2] < 0x10 | |
} | |
// Part 2 Solution | |
func character(at position:Int, inHash:[UInt8]) -> String { | |
guard position < inHash.count * 2 else { return "" } | |
let element = position/2 | |
let characterPos = position%2 | |
if characterPos == 0 { | |
return String(String(format:"%02x", inHash[element]).characters.first!) | |
} else { | |
return String(String(format:"%02x", inHash[element]).characters.last!) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Had to use Mac app for this one so I could use CommonCrypto and more speed