Changed the method for Day 5

Reduce as we're building the array vs. pulling elements out of an array bit by bit.
master
Peter 7 years ago
parent 904a46cc3c
commit c780f42f1d

@ -4,13 +4,9 @@
import Foundation import Foundation
// Traverse the string
// Find pairs of like letters, but opposite capitalization - < recursive? >
// -- reduce -- and repeat
class Reduction { class Reduction {
var polymer: [Character] = [] var polymer: [Character] = []
var acc: [Character] = []
// Supply filename for input ex: '/home/peterr/AOC2018/Sources/AOC2018/data/day05.txt' // Supply filename for input ex: '/home/peterr/AOC2018/Sources/AOC2018/data/day05.txt'
init(withFile filename: String) { init(withFile filename: String) {
@ -20,84 +16,48 @@ class Reduction {
guard polymerString.count > 0 else { return } guard polymerString.count > 0 else { return }
polymerString.removeLast() // new-line polymerString.removeLast() // new-line
polymer = Array(polymerString) polymer = Array(polymerString)
acc = Array(repeating: " ", count: polymer.count)
} }
// Supply test data in the form of a String // Supply test data in the form of a String
init(withString poly: String) { init(withString poly: String) {
polymer = Array(poly) polymer = Array(poly)
} acc = Array(repeating: " ", count: polymer.count)
}
// return an array of indicies of the first in an opposing pair
func getOpposites()-> [Int] { func reducer() {
var retVal: [Int] = [] var aIdx = 0
acc[aIdx] = polymer[0]
if polymer.count > 1 { for index in 1..<polymer.count {
var hit = false if (aIdx > -1 && acc[aIdx] != polymer[index]) && (String(acc[aIdx]).lowercased() == String(polymer[index]).lowercased()) {
for index in 0..<polymer.count-1 { acc[aIdx] = " "
if hit { aIdx -= 1
hit = false } else {
} else { aIdx += 1
if (polymer[index] != polymer[index+1]) && (String(polymer[index]).lowercased() == String(polymer[index+1]).lowercased()) { acc[aIdx] = polymer[index]
hit = true
retVal.append(index)
}
}
}
}
return retVal
}
// blast the units and then "compact" the ploymer
func reduce(withRanges ranges: [Int]) {
for range in ranges {
polymer[range] = " "
polymer[range+1] = " "
}
polymer = polymer.filter {$0 != " "}
}
func reducePolymer() {
var opp = getOpposites()
while opp.count > 0 {
reduce(withRanges: opp)
opp = getOpposites()
}
}
func removeUnit(withType unit: Character) {
for index in 0..<polymer.count {
if polymer[index] == unit {
polymer[index] = " "
} }
} }
let upperUnit = Character(String(unit).uppercased()) polymer = acc.filter {$0 != " "}
for index in 0..<polymer.count {
if polymer[index] == upperUnit {
polymer[index] = " "
}
}
polymer = polymer.filter {$0 != " "}
} }
func findSmallestFullyReactedAndRemovedPolymer() -> Int { func findSmallestFullyReactedAndRemovedPolymer() -> Int {
let start = Unicode.Scalar("a").value let start = Unicode.Scalar("a").value
let end = Unicode.Scalar("z").value let end = Unicode.Scalar("z").value
let myrange = start...end
let polyCopy = polymer let polyCopy = polymer
var minLen = polymer.count var minLen = polymer.count
for i in myrange { for i in start...end {
polymer = polyCopy polymer = polyCopy
acc = Array(repeating: " ", count: polymer.count)
if let type = Unicode.Scalar(i) { if let type = Unicode.Scalar(i) {
let unit = Character(type) let unit = Character(type)
removeUnit(withType: unit) let upperUnit = Character(String(unit).uppercased())
reducePolymer() polymer = polymer.filter { $0 != unit && $0 != upperUnit }
reducer()
minLen = min(minLen, polymer.count) minLen = min(minLen, polymer.count)
} }
} }
return minLen return minLen
} }
} }
class Day05: AOCDay { class Day05: AOCDay {
@ -119,99 +79,55 @@ class Day05: AOCDay {
XCTAssertEqual(test: "testReductionInit with File", withExpression: (reduc.polymer.last == "Y")) XCTAssertEqual(test: "testReductionInit with File", withExpression: (reduc.polymer.last == "Y"))
} }
func testGetOpposites() {
var reduc = Reduction(withString: "aA")
var opp = reduc.getOpposites()
XCTAssertEqual(test: "testGetOpposites count", withExpression: (opp.count == 1))
XCTAssertEqual(test: "testGetOpposites range", withExpression: (opp == [0]))
reduc = Reduction(withString: "abBA")
opp = reduc.getOpposites()
XCTAssertEqual(test: "testGetOpposites count", withExpression: (opp.count == 1))
XCTAssertEqual(test: "testGetOpposites range", withExpression: (opp == [1]))
reduc = Reduction(withString: "abAB")
opp = reduc.getOpposites()
XCTAssertEqual(test: "testGetOpposites count", withExpression: (opp.count == 0))
reduc = Reduction(withString: "aabAAB")
opp = reduc.getOpposites()
XCTAssertEqual(test: "testGetOpposites count", withExpression: (opp.count == 0))
reduc = Reduction(withString: testData)
opp = reduc.getOpposites()
XCTAssertEqual(test: "testGetOpposites count", withExpression: (opp.count == 2))
XCTAssertEqual(test: "testGetOpposites range", withExpression: (opp == [4, 10]))
}
func testReduce() {
var reduc = Reduction(withString: "aA")
var opp = reduc.getOpposites()
reduc.reduce(withRanges: opp)
XCTAssertEqual(test: "testReduce count after", withExpression: (reduc.polymer.count == 0))
reduc = Reduction(withString: "abBA")
opp = reduc.getOpposites()
reduc.reduce(withRanges: opp)
XCTAssertEqual(test: "testReduce count after", withExpression: (reduc.polymer.count == 2))
reduc = Reduction(withString: "abAB")
opp = reduc.getOpposites()
reduc.reduce(withRanges: opp)
XCTAssertEqual(test: "testReduce count after", withExpression: (reduc.polymer.count == 4))
reduc = Reduction(withString: "aabAAB")
opp = reduc.getOpposites()
reduc.reduce(withRanges: opp)
XCTAssertEqual(test: "testReduce count after", withExpression: (reduc.polymer.count == 6))
reduc = Reduction(withString: testData)
opp = reduc.getOpposites()
reduc.reduce(withRanges: opp)
XCTAssertEqual(test: "testReduce count after", withExpression: (reduc.polymer.count == 12))
}
func testReducePolymer() { func testReducePolymer() {
var reduc = Reduction(withString: "aA") var reduc = Reduction(withString: "aA")
reduc.reducePolymer() reduc.reducer()
XCTAssertEqual(test: "testReducePolymer", withExpression: (String(reduc.polymer) == "")) XCTAssertEqual(test: "testReducePolymer", withExpression: (String(reduc.polymer) == ""))
reduc = Reduction(withString: "abBA") reduc = Reduction(withString: "abBA")
reduc.reducePolymer() reduc.reducer()
XCTAssertEqual(test: "testReducePolymer", withExpression: (String(reduc.polymer) == "")) XCTAssertEqual(test: "testReducePolymer", withExpression: (String(reduc.polymer) == ""))
reduc = Reduction(withString: "abAB") reduc = Reduction(withString: "abAB")
reduc.reducePolymer() reduc.reducer()
XCTAssertEqual(test: "testReducePolymer", withExpression: (String(reduc.polymer) == "abAB")) XCTAssertEqual(test: "testReducePolymer", withExpression: (String(reduc.polymer) == "abAB"))
reduc = Reduction(withString: "aabAAB") reduc = Reduction(withString: "aabAAB")
reduc.reducePolymer() reduc.reducer()
XCTAssertEqual(test: "testReducePolymer", withExpression: (String(reduc.polymer) == "aabAAB")) XCTAssertEqual(test: "testReducePolymer", withExpression: (String(reduc.polymer) == "aabAAB"))
reduc = Reduction(withString: testData) reduc = Reduction(withString: testData)
reduc.reducePolymer() reduc.reducer()
XCTAssertEqual(test: "testReducePolymer", withExpression: (String(reduc.polymer) == "dabCBAcaDA")) XCTAssertEqual(test: "testReducePolymer", withExpression: (String(reduc.polymer) == "dabCBAcaDA"))
} }
func testRemoveUnit() { func testRemoveUnit() {
var reduc = Reduction(withString: testData) var reduc = Reduction(withString: testData)
reduc.removeUnit(withType: "a") reduc.polymer = reduc.polymer.filter { $0 != "a" && $0 != "A" }
XCTAssertEqual(test: "testRemoveOneType", withExpression: (String(reduc.polymer) == "dbcCCBcCcD")) XCTAssertEqual(test: "testRemoveOneType", withExpression: (String(reduc.polymer) == "dbcCCBcCcD"))
reduc = Reduction(withString: testData) reduc = Reduction(withString: testData)
reduc.removeUnit(withType: "b") reduc.polymer = reduc.polymer.filter { $0 != "b" && $0 != "B" }
XCTAssertEqual(test: "testRemoveOneType", withExpression: (String(reduc.polymer) == "daAcCaCAcCcaDA")) XCTAssertEqual(test: "testRemoveOneType", withExpression: (String(reduc.polymer) == "daAcCaCAcCcaDA"))
reduc = Reduction(withString: testData) reduc = Reduction(withString: testData)
reduc.removeUnit(withType: "c") reduc.polymer = reduc.polymer.filter { $0 != "c" && $0 != "C" }
XCTAssertEqual(test: "testRemoveOneType", withExpression: (String(reduc.polymer) == "dabAaBAaDA")) XCTAssertEqual(test: "testRemoveOneType", withExpression: (String(reduc.polymer) == "dabAaBAaDA"))
reduc = Reduction(withString: testData) reduc = Reduction(withString: testData)
reduc.removeUnit(withType: "d") reduc.polymer = reduc.polymer.filter { $0 != "d" && $0 != "D" }
XCTAssertEqual(test: "testRemoveOneType", withExpression: (String(reduc.polymer) == "abAcCaCBAcCcaA")) XCTAssertEqual(test: "testRemoveOneType", withExpression: (String(reduc.polymer) == "abAcCaCBAcCcaA"))
} }
func testRemoveAndReact() { func testRemoveAndReact() {
var reduc = Reduction(withString: testData) var reduc = Reduction(withString: testData)
reduc.removeUnit(withType: "a") reduc.polymer = reduc.polymer.filter { $0 != "a" && $0 != "A" }
reduc.reducePolymer() reduc.reducer()
XCTAssertEqual(test: "testRemoveAndReact a", withExpression: (String(reduc.polymer) == "dbCBcD")) XCTAssertEqual(test: "testRemoveAndReact a", withExpression: (String(reduc.polymer) == "dbCBcD"))
reduc = Reduction(withString: testData) reduc = Reduction(withString: testData)
reduc.removeUnit(withType: "b") reduc.polymer = reduc.polymer.filter { $0 != "b" && $0 != "B" }
reduc.reducePolymer() reduc.reducer()
XCTAssertEqual(test: "testRemoveAndReact b", withExpression: (String(reduc.polymer) == "daCAcaDA")) XCTAssertEqual(test: "testRemoveAndReact b", withExpression: (String(reduc.polymer) == "daCAcaDA"))
reduc = Reduction(withString: testData) reduc = Reduction(withString: testData)
reduc.removeUnit(withType: "c") reduc.polymer = reduc.polymer.filter { $0 != "c" && $0 != "C" }
reduc.reducePolymer() reduc.reducer()
XCTAssertEqual(test: "testRemoveAndReact c", withExpression: (String(reduc.polymer) == "daDA")) XCTAssertEqual(test: "testRemoveAndReact c", withExpression: (String(reduc.polymer) == "daDA"))
reduc = Reduction(withString: testData) reduc = Reduction(withString: testData)
reduc.removeUnit(withType: "d") reduc.polymer = reduc.polymer.filter { $0 != "d" && $0 != "D" }
reduc.reducePolymer() reduc.reducer()
XCTAssertEqual(test: "testRemoveAndReact d", withExpression: (String(reduc.polymer) == "abCBAc")) XCTAssertEqual(test: "testRemoveAndReact d", withExpression: (String(reduc.polymer) == "abCBAc"))
} }
@ -223,8 +139,6 @@ class Day05: AOCDay {
func day05Tests() { func day05Tests() {
testReductionInit() testReductionInit()
testGetOpposites()
testReduce()
testReducePolymer() testReducePolymer()
testRemoveUnit() testRemoveUnit()
testRemoveAndReact() testRemoveAndReact()
@ -232,13 +146,10 @@ class Day05: AOCDay {
} }
func day05Final() { func day05Final() {
// var reduc = Reduction(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day05.txt") var reduc = Reduction(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day05.txt")
// Run test data as the real data takes too long reduc.reducer()
var reduc = Reduction(withString: testData)
reduc.reducePolymer()
print("Answer to part 1 is: \(reduc.polymer.count)") print("Answer to part 1 is: \(reduc.polymer.count)")
// reduc = Reduction(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day05.txt") reduc = Reduction(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day05.txt")
reduc = Reduction(withString: testData)
let answer = reduc.findSmallestFullyReactedAndRemovedPolymer() let answer = reduc.findSmallestFullyReactedAndRemovedPolymer()
print("Answer to part 2 is: \(answer)") print("Answer to part 2 is: \(answer)")
} }

Loading…
Cancel
Save