Skip to content

Instantly share code, notes, and snippets.

@willeccles
Created May 21, 2019 20:33
Show Gist options
  • Save willeccles/f48e8d7c6f18bf31146ff7c76b58423d to your computer and use it in GitHub Desktop.
Save willeccles/f48e8d7c6f18bf31146ff7c76b58423d to your computer and use it in GitHub Desktop.
Day 8 of 2018 advent of code. Loads input from file instead of stdin so that's very slow, and I put almost no effort into making it faster after it was done.
#include <chrono>
#include <cstdio>
#include <fstream>
#include <string>
#include <vector>
#include "tree.h" // for TreeNode
using namespace std::chrono;
TreeNode* root = nullptr;
std::vector<short> input;
int totalmetadata;
void prnt(TreeNode* n) {
static char lbl = 'A';
std::printf("%c:\n children: %d\n metadatasum: %d\n\n", lbl++, n->childcount, n->metadatasum);
for (int i = 0; i < n->children.size(); i++) {
prnt(n->children[i]);
}
}
int parse(int begin = 0, TreeNode* parent = nullptr) {
// starting at 0 should be the beginning of a new node
TreeNode* ptr = nullptr;
if (parent == nullptr) {
root = new TreeNode(nullptr, input[begin]);
ptr = root;
}
else {
parent->children.push_back(new TreeNode(parent, input[begin]));
ptr = parent->children.back();
}
int totalparsed = 2; // parsing at least two things for each node
for (int i = 0; i < input[begin]; i++) {
totalparsed += parse(begin + totalparsed, ptr);
}
for (int i = 0; i < input[begin + 1]; i++) {
ptr->metadatasum += input[begin + totalparsed + i];
ptr->metadata.push_back(input[begin + totalparsed + i]);
}
totalmetadata += ptr->metadatasum;
return totalparsed + input[begin + 1]; // add number of metadata items to this
}
int val(TreeNode* n) {
int sum = 0;
if (n->childcount) {
for (int i : n->metadata) {
if (i <= n->childcount) {
sum += val(n->children[i - 1]);
}
}
}
else {
for (int i : n->metadata) {
sum += i;
}
}
return sum;
}
int main() {
{ // load input
std::puts("Loading file...");
std::ifstream infile("bqgnir");
short nval;
while (infile >> nval) input.push_back(nval);
}
// did this to compete with people who use stdin for the input unlike me
std::puts("File loaded, starting parsing and puzzle solving.");
steady_clock::time_point t1 = steady_clock::now();
parse();
int rootval = val(root);
steady_clock::time_point t2 = steady_clock::now();
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
std::printf("Took %.2f seconds to parse nodes into tree and perform calculations.\n", time_span.count());
std::printf("Part 1: %d\n", totalmetadata);
std::printf("Part 2: %d\n", rootval);
delete root;
return 0;
}
#ifndef TREE_H
#define TREE_H
#include <vector>
class TreeNode {
public:
TreeNode* parent; // nullptr if root
std::vector<TreeNode*> children;
int childcount;
int metadatasum;
std::vector<int> metadata;
TreeNode(TreeNode* _parent, int _childcount):
parent(_parent),
childcount(_childcount),
metadatasum(0)
{};
TreeNode(int _childcount):
parent(nullptr),
childcount(_childcount),
metadatasum(0)
{};
~TreeNode() {
if (childcount) {
for (int i = 0; i < childcount; i++) {
delete children[i];
}
}
};
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment