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)")
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue