diff --git a/Sources/AOC2018/data/day02.txt b/Sources/AOC2018/data/day02.txt new file mode 100644 index 0000000..deb7779 --- /dev/null +++ b/Sources/AOC2018/data/day02.txt @@ -0,0 +1,250 @@ +fonbsmjyqugrapsczckghtvdxl +fonpsmjyquwrnpeczikghtvdxw +fonbsmdymuwrapexzikghtvdxl +fonwsmjyquwrapeczikghttdpl +fonbsmjkquwrapeczjkghtvdxx +yonbsmjyquwrapecgikghtvdxc +donbsmjyquqrapeczikghtadxl +monbsmjyquprgpeczikghtvdxl +fonbsmjyquwvapecqgkghtvdxl +fonbsmjyquwrkphczikghsvdxl +fonbomjyeuwvapeczikghtvdxl +fonwsmjyjuwrapoczikghtvdxl +foybsmjyquwcapeczikghsvdxl +fonbsmjyquwrtaeczikgptvdxl +ponbsmpyquwjapeczikghtvdxl +flnbcmjyquwrqpeczikghtvdxl +fonbsmjyquwrapegzikvbtvdxl +fonbjmjyqgwrazeczikghtvdxl +zoabsmjyquwkapeczikghtvdxl +fonbsmjyquwrapecziktxkvdxl +fonbsxjyrpwrapeczikghtvdxl +fonbsmjbquwqapeciikghtvdxl +lonbsmjyquwraphczikghtvdul +ftnbsmjyquwrapcczikghtxdxl +fonbsmjyqgwrapeczikghtldxc +fonbsmjsquwmapeyzikghtvdxl +fonbsmjyqfwrapecziqghtgdxl +yonbsmjyquwraveczikgftvdxl +fovbsmjyquwrapeczikggkvdxl +fonbsmjyquwrapezzikghbvdvl +fonzsmxyquwrapeczukghtvdxl +fonbemjyquwrapevzikghtvrxl +conbsxjxquwrapeczikghtvdxl +fonbsmjsmewrapeczikghtvdxl +folbsmjyqhwrapqczikghtvdxl +fonbsmjyquwrzneczikghtvdxn +fonbsmjyquirapeczikjhtvdll +fontsmgyquwrgpeczikghtvdxl +fonbsmjyauwrapeczbfghtvdxl +ftnbsmjyquwrapecpifghtvdxl +fonvsmjyqewrapeczikghlvdxl +fonbsljyquwrapecziklhtvdxw +fonbbmjyquwrapeczikghvadxl +ponbsmjyquwrspeczikghivdxl +fonbsmjcquwrapeccikghtvuxl +fonbsmjnquwrapetzikghtvlxl +fonbsmjymuwrapeczieghtvdxr +ffnbsxnyquwrapeczikghtvdxl +fonbsmjytuwrajeczzkghtvdxl +fonssmjyquwhapeczikghkvdxl +fonbsajyuuwrapeczikghlvdxl +fonbsmjyquwrapeczihghtcixl +fohbsmjyquwrapzczirghtvdxl +fonbsmjyquwrapecjqnghtvdxl +fonbsmjytuhrapeczihghtvdxl +foabumjyquwrapeczikghtvdxz +conbsmjyqtwrapeczikggtvdxl +fonbsmjyiqwrapeczokghtvdxl +fondsmjypuwrapeczikghtvjxl +fonbswjyquwrapeczikgvtydxl +fonbsmjyqqwrapeczikkhtvdbl +fonbsmjyquwrapemzitghtvdsl +fonbsmjyquwrspecziegxtvdxl +fonbsmpyquwrgpeczikghtwdxl +fodbsmjqquwrapeczmkghtvdxl +fonbsmjkquwrapeczikghpvdxr +fonbsmjyquwrapeczikshzvmxl +fznbsmjyqulrapeczikghkvdxl +fonbsmjyquwripeczikghtbdjl +fcnbsmjyquzrapecyikghtvdxl +ronbxmjyquwrapeczikghgvdxl +fonbsmuyvuwrgpeczikghtvdxl +fonbsmjyyuwraplczikghtudxl +poxbsmjyqewrapeczikghtvdxl +foabsmjyquwrapecziqghtvpxl +ponbsmjrquwrapeczikchtvdxl +fonzzmjyquwrapeczikghtvdxs +wonbsmjyquwghpeczikghtvdxl +fofbsejyquwrapeczikgctvdxl +ponbsmjyquwrayegzikghtvdxl +fonbumjyquwripeczikghtvdxf +fonbsmqyquwrapeczikgftvdxv +qonbsmjyquwraplczitghtvdxl +fmnbsajdquwrapeczikghtvdxl +fonbsrjyquwrapempikghtvdxl +fonbsmjyquwrapeczikgotudxw +fonbsmtyquwrapeflikghtvdxl +fzqbsmjyquwrapecjikghtvdxl +fdnbsmjyquwraqeclikghtvdxl +fvnbsijyquwrapechikghtvdxl +fovbsmjyquwsapeczikghqvdxl +ffjbsmjyqgwrapeczikghtvdxl +fonbsmjyquwrapeczvkhhivdxl +forbamjjquwrapeczikghtvdxl +fonbwmjyquwtapeyzikghtvdxl +fonvsmjyquwrapeczikglnvdxl +fonnsmjyguwrapeczikghtvxxl +fopbsmjyquwrapeczikghtvaxz +fonbsmjyquwiapeczikrhavdxl +fonbsujyquwrapeczikthtvdjl +fonpsmkyeuwrapeczikghtvdxl +fonbsmjyquwrapeczqkgttvdxk +fonbsmjyqzwrapeczikgrtddxl +fokbsmjiquwrapeczikgltvdxl +fonbsmjyqbwrapeczikghttdxo +fonbsejyquwrapeczikghbvdal +fonblmjyquwyaveczikghtvdxl +fonbsmjyquwlzpepzikghtvdxl +fonbsmjyqulrapbczigghtvdxl +fonbsmjyxuwrapecziyghtvsxl +fonbyjjyquwrapeczikghtvdxn +fonbhmjyquwrapeczikghtjhxl +fonbspjykuwraieczikghtvdxl +aonbsmjyquwwapeczikchtvdxl +fombsmjyquwyapeczikghtvdll +fonbsmjynuwrapeczivgbtvdxl +xonbsmjfquwrapeczikghqvdxl +fonbyzjyquwzapeczikghtvdxl +fbnbsmjyquwrapeczimgvtvdxl +qonbsmjyquwraoeczikgftvdxl +fonbsrjyquwrapeczikghtvjxm +fonbsmjyquwrapxjzykghtvdxl +fonbwgjyquwrapecziklhtvdxl +fonjcmjyouwrapeczikghtvdxl +fonbsmjyquwrapefzisuhtvdxl +fonbsmjyqywrspeczikghtvnxl +qonbsmjyquwrapeczlkuhtvdxl +fonbsmjyqlprapeczikghtvdbl +fonbsmjzquwrapedzikfhtvdxl +fonbsmjyquwrapeczizghtvjxq +fonbsmxyquwrrpeczikghtvcxl +fonpsmjyquwoapeczikghjvdxl +fonbshkyauwrapeczikghtvdxl +fonbsmjysuwrapeczilghpvdxl +fovwsxjyquwrapeczikghtvdxl +fonbsmjyquwrppecnikghmvdxl +fonbkmjyiuwrrpeczikghtvdxl +gonbsmjyquwrapeczikphtudxl +foncsmjyqlwrapeczimghtvdxl +fonbsmjhquwrtpeczikghtvdxg +fogbsmjyquarapeczikghtvdil +fonbsmjyquwraperzekghwvdxl +fonbstjyquwrapeczicghtedxl +fonbsmjoquhrapeczikgotvdxl +fonbsmjykuwrareczikgdtvdxl +fonbsmjyvuwrayeczivghtvdxl +fonbzmgyquwraptczikghtvdxl +fonbsmjyqubrapeczikgftvdxb +fonbgmjyjuwrapeczikghtvdul +fonbsmjzqurrapeczikghtvfxl +fonbsmjyiuwrapeczikgstvtxl +fpnbstjyquwrapeczikghtvdcl +fonbpmjyquwrapeczivghtndxl +fonbsmjyquwrapeczilgptvvxl +fonbsmjyqdwripecbikghtvdxl +fonbsmjytuwgapnczikghtvdxl +fonbsejyquwrapedzikghtvdml +fonbsojyqdwrapeczikghtgdxl +fonbsmjykuwrayeczicghtvdxl +foubsmtyquwrapeczikchtvdxl +fonbqmjyqukrapeyzikghtvdxl +fonbsmjyquwaapenzikghtvdwl +fonbsmeyquwrapeyzixghtvdxl +fonusmjyquhrapeczikgytvdxl +fonbsmjyquwrapwazikqhtvdxl +fonwsmeyquwrapeczikghhvdxl +fonmsmjyquxrspeczikghtvdxl +fonqsmjyqxwrapeczikghtvdml +fonfsmjyquwrapeuzikgatvdxl +fonvsmjyquwrapeczikgrtvdul +fonbsmayquwrapeczikihtvdxm +fonbsmnyquwrapecdifghtvdxl +fonbsmjyeuwraseczikghtvdxo +fonbvvjyquwrapeczikghtvdxi +fonbsmjyquwrapeczbkghtorxl +tonbsmjyqvwrapeczikghtvdcl +fonbsmjyquwrapeczhkgbtvdkl +fonqsmjyquwrapenzibghtvdxl +fontsmeyqudrapeczikghtvdxl +qonbsmjyauwrapeczikghtvdbl +fynbsmjyluwrapeczekghtvdxl +fonbsmjhquwrappczikghtvdxt +conbsmjyquwrapeczikahtvdxz +fonbsmjyquorapeczikvftvdxl +fonbsriyquwrapeczikchtvdxl +yonfsmjyquwrapeczikghtvdxq +fonaomjyquwrapecziwghtvdxl +fonbsxsyqdwrapeczikghtvdxl +fonbsqjyouwrapeczikgltvdxl +fonbstsyquwraleczikghtvdxl +fonbsmjyquwraoecztkghtvdsl +fonbsmjyquwrapezzjkghmvdxl +fonbwmjyqnwrapecpikghtvdxl +fonbsmvyqbwrapeczikghtvdsl +fonbsijyquwrazeczikghtvdwl +fonbsmjyouwrapewzikghtldxl +xonbsmjyqcwrapeczikghtvdul +fonbgmjxquwrajeczikghtvdxl +fokbsmjyquwrapechikghtrdxl +fonbqmjyqawrapeczikghtrdxl +fonbwmjzquwtapeyzikghtvdxl +fonbsmjyquwrapecdikgatvdnl +fonbsmjyqowrkpeczikghtvdxj +fonbsmjyquwkapejzikuhtvdxl +fonbsmjyquwrabeozikghtmdxl +fonbsijyeuwrapeczikghtvdxh +fonbsmjhquprapeczizghtvdxl +fonesmjyquwrapcczikghtvdxh +fonbamjyquwrapeczifrhtvdxl +foabsmjyquwpapeczikghtvdxs +fonbsmjyquwrapeczukghivdxh +fonbsejyoulrapeczikghtvdxl +fonbsmjyquwraceczikgdmvdxl +eonbsmjyquerppeczikghtvdxl +ffnzsmjyquwgapeczikghtvdxl +donbsmyyquwrapeczirghtvdxl +fjnbsmjyqufrapeczikghtwdxl +fonfsmjyquwrareczigghtvdxl +fonusmjyquwrapeczikgetvexl +tonbsmjyqpwrapeczikghtjdxl +fonbsmjhqukkapeczikghtvdxl +fonbsmjyqusraseczikghtvzxl +fonbsmjyquygapeczxkghtvdxl +folbsmjyquwraqeczikghjvdxl +fonbsmjyquwrppecjinghtvdxl +fonbsmjyquwraepczhkghtvdxl +fonbfmjyquwrapeczisghtrdxl +fsnbsmjwqubrapeczikghtvdxl +fonbspjyquwrapjczikghtedxl +fowbsmjyquwrapeczikghtbdbl +fonbymjyquwrapeczikghlvdrl +fonbsmjyruwrapecbikghtvixl +fonyqmjyqufrapeczikghtvdxl +focbscjyquwrapeczmkghtvdxl +fonbsmjyqtwnkpeczikghtvdxl +eonbsmjyquwrameczizghtvdxl +zonbsmjyqcwrapeczikghtvhxl +foubsmjyquwrapehzikghtvnxl +ffnbsmjyquwrapetzikghtjdxl +fonbjgjyquwrapkczikghtvdxl +fonbwmjyquwqapeczdkghtvdxl +forbsmjyquwrapeczikkhtvdml +fonbsmjyiuwrapeczivghevdxl +fonbsmjyquwrapeglikghwvdxl +fopgsmjyquwrapegzikghtvdxl +fonbsmjyqzwrajeczikghtldxl +fonbsmjyruwrapexzmkghtvdxl +fonbsmjyquwrdpeczikxstvdxl +fonbsmjyquwrapeezivghtvdql +fonbdmjyqujsapeczikghtvdxl diff --git a/Sources/AOC2018/day02.swift b/Sources/AOC2018/day02.swift new file mode 100644 index 0000000..1141aa1 --- /dev/null +++ b/Sources/AOC2018/day02.swift @@ -0,0 +1,206 @@ +// +// Advent of Code 2018 "Day 2: Inventory Management System" +// + +import Foundation + +class Inventory { + var IDarray: [String] = [] + var IDarrayOfdict: [[Character : Int]] = [] + var validIDs: [String] = [] + + // Supply filename for input ex: '/home/peterr/AOC2018/Sources/AOC2018/data/day02.txt' + init(withFile filename: String) { + let IDs = Tools.readFile(fromPath: filename) + IDarray = IDs.components(separatedBy: "\n") + // This gurd statement is just an excuse to use guard + // I'm assuming the last string is an empty string, if not DON'T remove the last string + guard let lastStr = IDarray.last, lastStr.count == 0 else { return } + IDarray.removeLast() // empty string + } + + // Supply test data in the form of a String + init(withString IDs: String) { + IDarray = IDs.components(separatedBy: "\n") + } + + func createDictionaryCount(withID ID: String) -> [Character : Int] { + var retVal: [Character : Int] = [:] + for idChar in ID { + + if let count = retVal[idChar] { + retVal[idChar] = count + 1 + } else { + retVal[idChar] = 1 + } + } + return retVal + } + + func createArrayOfDicts() { + for idStr in IDarray { + IDarrayOfdict.append( createDictionaryCount(withID: idStr)) + } + } + + func countExactlyNLetters(number: Int) -> Int { + var retVal = 0 + if IDarrayOfdict.count < 1 { + createArrayOfDicts() + } + // Set up new dictionary of combination of all + for index in 0.. Int { + let twos = countExactlyNLetters(number: 2) + let threes = countExactlyNLetters(number: 3) + return twos * threes + } + + // Find IDs that differ by only one character at the identical location + // Use a diff filter on the output of 'zip' (zip : Creates a sequence of pairs built out of two underlying sequences) + // Only add the indicies of the IDs if there is only one diff + func determineListOfCandidates() -> (box1: Int, box2: Int) { + var retVal: (box1: Int, box2: Int) = (0,0) + var difference: [(Character, Character)] = [] + for index in 0.. ()) = day02Tests + lazy var final: (() -> ()) = day02Final + + let testString = """ + abcdef + bababc + abbcde + abcccd + aabcdd + abcdee + ababab + """ + let testStringPart2 = """ + abcde + fghij + klmno + pqrst + fguij + axcye + wvxyz + """ + + func testInventoryInitWithFile() { + let inv = Inventory(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day02.txt") + XCTAssertEqual(test: "testInventoryInitWithFile count", withExpression: (inv.IDarray.count == 250)) + XCTAssertEqual(test: "testInventoryInitWithFile [3]", withExpression: (inv.IDarray[3] == "fonwsmjyquwrapeczikghttdpl")) + if let lastString = inv.IDarray.last { + XCTAssertEqual(test: "testInventoryInitWithFile [last]", withExpression: (lastString == "fonbdmjyqujsapeczikghtvdxl")) + } + } + + // abcdef contains no letters that appear exactly two or three times. + // bababc contains two a and three b, so it counts for both. + // abbcde contains two b, but no letter appears exactly three times. + // abcccd contains three c, but no letter appears exactly two times. + // aabcdd contains two a and two d, but it only counts once. + // abcdee contains two e. + // ababab contains three a and three b, but it only counts once. + func testInventoryInitWithString() { + let inv = Inventory(withString: testString) + XCTAssertEqual(test: "testInventoryInitWithString count", withExpression: (inv.IDarray.count == 7)) + XCTAssertEqual(test: "testInventoryInitWithString [3]", withExpression: (inv.IDarray[3] == "abcccd")) + if let lastString = inv.IDarray.last { + XCTAssertEqual(test: "testInventoryInitWithString [last]", withExpression: (lastString == "ababab")) + } + } + + func testCreateDictionaryCount() { + let inv = Inventory(withString: testString) + var dict = inv.createDictionaryCount(withID: inv.IDarray[0]) + XCTAssertEqual(test: "testCreateDictionaryCount [0][a]", withExpression: (dict["a"] == 1)) + dict = inv.createDictionaryCount(withID: inv.IDarray[1]) + XCTAssertEqual(test: "testCreateDictionaryCount [1][a]", withExpression: (dict["a"] == 2)) + XCTAssertEqual(test: "testCreateDictionaryCount [1][b]", withExpression: (dict["b"] == 3)) + dict = inv.createDictionaryCount(withID: inv.IDarray[6]) + XCTAssertEqual(test: "testCreateDictionaryCount [6][a]", withExpression: (dict["a"] == 3)) + XCTAssertEqual(test: "testCreateDictionaryCount [6][b]", withExpression: (dict["b"] == 3)) + } + + func testCreateArrayOfDicts() { + let inv = Inventory(withString: testString) + inv.createArrayOfDicts() //inv.IDarrayOfdict[][] + + XCTAssertEqual(test: "testCreateArrayOfDicts count", withExpression: (inv.IDarrayOfdict.count == 7)) + if inv.IDarrayOfdict.count > 6 { + XCTAssertEqual(test: "testCreateArrayOfDicts [0][a]", withExpression: (inv.IDarrayOfdict[0]["a"] == 1)) + XCTAssertEqual(test: "testCreateArrayOfDicts [1][a]", withExpression: (inv.IDarrayOfdict[1]["a"] == 2)) + XCTAssertEqual(test: "testCreateArrayOfDicts [1][b]", withExpression: (inv.IDarrayOfdict[1]["b"] == 3)) + XCTAssertEqual(test: "testCreateArrayOfDicts [6][a]", withExpression: (inv.IDarrayOfdict[6]["a"] == 3)) + XCTAssertEqual(test: "testCreateArrayOfDicts [6][b]", withExpression: (inv.IDarrayOfdict[6]["b"] == 3)) + } + } + + func testCountExactlyNLetters() { + let inv = Inventory(withString: testString) + let twos = inv.countExactlyNLetters(number: 2) + XCTAssertEqual(test: "testCountExactlyNLetters 2", withExpression: (twos == 4)) + let threes = inv.countExactlyNLetters(number: 3) + XCTAssertEqual(test: "testCountExactlyNLetters 3", withExpression: (threes == 3)) + } + + func testComputeChecksum() { + let inv = Inventory(withString: testString) + let checksum = inv.computeChecksum() + XCTAssertEqual(test: "testComputeChecksum", withExpression: (checksum == 12)) + } + + func testDetermineListOfCandidates() { + let inv = Inventory(withString: testStringPart2) + let candidate = inv.determineListOfCandidates() + XCTAssertEqual(test: "testDetermineListOfCandidates", withExpression: (candidate == (1, 4))) + } + + func day02Tests() { + testInventoryInitWithFile() + testInventoryInitWithString() + testCreateDictionaryCount() + testCreateArrayOfDicts() + testCountExactlyNLetters() + testComputeChecksum() + testDetermineListOfCandidates() + } + + func day02Final() { + // let retVal = "None" + let inv = Inventory(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day02.txt") + let checksum = inv.computeChecksum() + let ID = inv.determineListOfCandidates() + print("Answer to part 1 is: \(checksum)") + + var answer = "" + let answerChars = zip(inv.IDarray[ID.box1], inv.IDarray[ID.box2]).filter{ $0 == $1 } + for tuple in answerChars { + answer.append(tuple.0) + } + print("Answer to part 2 is: \(answer)") + } +} diff --git a/Sources/AOC2018/main.swift b/Sources/AOC2018/main.swift index 5eebbac..1802f18 100644 --- a/Sources/AOC2018/main.swift +++ b/Sources/AOC2018/main.swift @@ -13,9 +13,11 @@ print("Advent of Code 2018") // Compile list of Tests allTests.append(Day01().tests) +allTests.append(Day02().tests) // Compile list of Answers allFinal.append(Day01().final) +allFinal.append(Day02().final) if onlyOneDay > 0 { print("\nDay \(onlyOneDay)")