Add code for Day 8

Day 8: Memory Maneuver
master
Peter 7 years ago
parent 200555b6cb
commit 96d9683eb2

File diff suppressed because one or more lines are too long

@ -0,0 +1,169 @@
//
// Advent of Code 2018 "Day 8: Memory Maneuver"
//
import Foundation
struct Header {
var nChildren = 0
var nMeta = 0
}
struct Node {
var header = Header(nChildren: 0, nMeta: 0)
var children: [Node] = []
var meta: [Int] = []
var length = 2 // Smallest node is only a header with no children or meta data
}
class Maneuver {
var treeData: [Int] = []
var sumMeta = 0
// Supply filename for input ex: '/home/peterr/AOC2018/Sources/AOC2018/data/day08.txt'
init(withFile filename: String) {
let tree = Tools.readFile(fromPath: filename)
let chars = tree.components(separatedBy: " ")
for char in chars {
treeData.append(Int(char) ?? -1)
}
}
// Supply test data in the form of a String
init(withString tree: String) {
let chars = tree.components(separatedBy: " ")
for char in chars {
treeData.append(Int(char) ?? -1)
}
}
// get length of node and sum th meta data for Part 1 as a by-product
func getLength(ofChild childData: ArraySlice<Int>) -> Int {
let nChildren = childData[childData.startIndex]
let nMetaIndex = childData.index(after: childData.startIndex)
let nMeta = childData[nMetaIndex]
var length = 2
if nChildren == 0 {
let start = childData.startIndex + 2
let metaData = Array(childData[start..<start+nMeta])
for meta in metaData {
sumMeta += meta
}
return length + nMeta
} else {
var childIndex = nMetaIndex + 1
for _ in 0..<nChildren {
let childLength = getLength(ofChild: childData[childIndex...])
childIndex += childLength
length += childLength
}
let metaData = Array(childData[childIndex..<childIndex+nMeta])
for meta in metaData {
sumMeta += meta
}
length += nMeta
}
return length
}
func getNode(withChild childData: ArraySlice<Int>) -> Node {
let nChildren = childData[childData.startIndex]
let nMetaIndex = childData.index(after: childData.startIndex)
let nMeta = childData[nMetaIndex]
var metaData: [Int] = []
let children: [Node] = []
var retVal = Node(header: Header(nChildren: nChildren, nMeta: nMeta), children: children, meta: metaData, length: 2)
if nChildren == 0 {
let start = childData.startIndex + 2
metaData = Array(childData[start..<start+nMeta])
} else {
var childIndex = nMetaIndex + 1
for _ in 0..<nChildren {
let childLength = getLength(ofChild: childData[childIndex...])
retVal.children.append(getNode(withChild: childData[childIndex...]))
childIndex += childLength
retVal.length += childLength
}
metaData = Array(childData[childIndex..<childIndex+nMeta])
}
retVal.meta = metaData
retVal.length += nMeta
return retVal
}
func getValue(forNode node: Node) -> Int {
var retVal = 0
if (node.header.nChildren == 0) {
for meta in node.meta {
retVal += meta
}
} else {
for meta in node.meta {
let childIndex = meta - 1
if (0..<node.children.count).contains(childIndex) {
let childNode = node.children[childIndex]
retVal += getValue(forNode: childNode)
}
}
}
return retVal
}
}
class Day08: AOCDay {
lazy var tests: (() -> ()) = day08Tests
lazy var final: (() -> ()) = day08Final
let testData = "2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2"
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
// A----------------16----------------
// B-----5----- C-----6-----
// D-3---
func testManeuverInit() {
var maneu = Maneuver(withString: testData)
XCTAssertEqual(test: "testManeuverInit string", withExpression: (maneu.treeData[3] == 3))
maneu = Maneuver(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day08.txt")
XCTAssertEqual(test: "testManeuverInit file [3]", withExpression: (maneu.treeData[3] == 2))
XCTAssertEqual(test: "testManeuverInit file last", withExpression: (maneu.treeData.last! == 1))
}
func testGetLength() {
let maneu = Maneuver(withString: testData)
let totalLen = maneu.getLength(ofChild: maneu.treeData[0...])
XCTAssertEqual(test: "testGetLength", withExpression: (totalLen == 16))
XCTAssertEqual(test: "testGetLength sum Meta", withExpression: (maneu.sumMeta == 138))
}
func testGetNode() {
let maneu = Maneuver(withString: testData)
let node = maneu.getNode(withChild: maneu.treeData[0...])
XCTAssertEqual(test: "testGetNode", withExpression: (node.length == 16))
}
func testGetValue() {
let maneu = Maneuver(withString: testData)
let node = maneu.getNode(withChild: maneu.treeData[0...])
let value = maneu.getValue(forNode: node)
XCTAssertEqual(test: "testGetValue", withExpression: (value == 66))
}
func day08Tests() {
testManeuverInit()
testGetLength()
testGetNode()
testGetValue()
}
func day08Final() {
var maneu = Maneuver(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day08.txt")
_ = maneu.getLength(ofChild: maneu.treeData[0...])
print("Answer to part 1 is: \(maneu.sumMeta)")
maneu = Maneuver(withFile: "/home/peterr/AOC2018/Sources/AOC2018/data/day08.txt")
let node = maneu.getNode(withChild: maneu.treeData[0...])
let value = maneu.getValue(forNode: node)
print("Answer to part 2 is: \(value)")
}
}

@ -19,6 +19,7 @@ allTests.append(Day04().tests)
allTests.append(Day05().tests) allTests.append(Day05().tests)
allTests.append(Day06().tests) allTests.append(Day06().tests)
allTests.append(Day07().tests) allTests.append(Day07().tests)
allTests.append(Day08().tests)
// Compile list of Answers // Compile list of Answers
allFinal.append(Day01().final) allFinal.append(Day01().final)
@ -28,6 +29,7 @@ allFinal.append(Day04().final)
allFinal.append(Day05().final) allFinal.append(Day05().final)
allFinal.append(Day06().final) allFinal.append(Day06().final)
allFinal.append(Day07().final) allFinal.append(Day07().final)
allFinal.append(Day08().final)
if onlyOneDay > 0 { if onlyOneDay > 0 {
print("\nDay \(onlyOneDay)") print("\nDay \(onlyOneDay)")

Loading…
Cancel
Save