Skip to content

Commit

Permalink
day 19 part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
K20shores committed Dec 20, 2024
1 parent 54676ff commit b068147
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 0 deletions.
59 changes: 59 additions & 0 deletions 2024/include/aoc/2024/trie.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#pragma once

#include <stddef.h>
#include <string>
#include <queue>
#include <unordered_map>

class Trie
{
struct Node
{
std::unordered_map<char, Node *> children;
bool terminal;

Node() : children(), terminal(false)
{
}
};
Node *root;

public:
Trie() : root(new Node())
{
}

void insert(std::string key)
{
Node *x = root;
for (const auto &c : key)
{
if(x->children.find(c) == x->children.end())
{
x->children[c] = new Node();
}
x = x->children[c];
}
x->terminal = true;
}

std::vector<int> search(const std::string_view &s) const
{
const Node *x = root;
std::vector<int> matches;
for(size_t i = 0; i < s.size(); ++i)
{
char c = s[i];
if (x->children.find(c) == x->children.end())
{
break;
}
x = x->children.at(c);
if (x->terminal)
{
matches.push_back(i+1);
}
}
return matches;
}
};
1 change: 1 addition & 0 deletions 2024/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ create_standard_test(NAME 2024_day15 SOURCES day15.cpp LIBRARIES aoc2024)
create_standard_test(NAME 2024_day16 SOURCES day16.cpp LIBRARIES aoc2024)
create_standard_test(NAME 2024_day17 SOURCES day17.cpp LIBRARIES aoc2024)
create_standard_test(NAME 2024_day18 SOURCES day18.cpp LIBRARIES aoc2024)
create_standard_test(NAME 2024_day19 SOURCES day19.cpp LIBRARIES aoc2024)

################################################################################
# Copy input data
Expand Down
141 changes: 141 additions & 0 deletions 2024/src/day19.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#include <iostream>
#include <filesystem>
#include <fstream>
#include <string>
#include <vector>
#include <benchmark/benchmark.h>
#include <format>
#include <aoc/2024/split.h>
#include <aoc/2024/trie.h>

struct Data {
std::vector<std::string> patterns;
std::vector<std::string> designs;
};

bool check_design(std::string_view design, const Trie& t, std::unordered_map<std::string_view, bool>& memo) {
if (design.empty()) {
return true; // If we matched the whole design, it's valid.
}

if (memo.count(design)) {
return memo[design]; // Return cached result.
}

// Get all matching prefixes for the current design.
std::vector<int> match = t.search(design);
for (auto m : match) {
if (check_design(design.substr(m), t, memo)) {
return memo[design] = true; // Cache and return success.
}
}

return memo[design] = false; // Cache and return failure.
}

int part1(const Data &data)
{
Trie t;
std::unordered_map<std::string_view, bool> cache;
for(const auto& pattern : data.patterns) {
t.insert(pattern);
}

int possible = 0;
for(auto& design : data.designs) {
if (check_design(design, t, cache)) {
++possible;
}
}
return possible;
}

int part2(const Data &data)
{
return 0;
}

Data parse()
{
std::ifstream file(std::filesystem::path("inputs/day19.txt"));
if (!file.is_open())
{
throw std::runtime_error("file not found");
}
std::string line;
Data data;

bool patterns = true;
while (std::getline(file, line))
{
if (line.size() == 0)
{
patterns = false;
continue;
}
if (patterns) {
data.patterns = split(line, ", ");
}
else {
data.designs.push_back(line);
}
}

return data;
}

class BenchmarkFixture : public benchmark::Fixture
{
public:
static Data data;
};

Data BenchmarkFixture::data = parse();

BENCHMARK_DEFINE_F(BenchmarkFixture, Part1Benchmark)
(benchmark::State &state)
{
for (auto _ : state)
{
auto s = part1(data);
benchmark::DoNotOptimize(s);
}
}

BENCHMARK_DEFINE_F(BenchmarkFixture, Part2Benchmark)
(benchmark::State &state)
{
for (auto _ : state)
{
auto s = part2(data);
benchmark::DoNotOptimize(s);
}
}

BENCHMARK_REGISTER_F(BenchmarkFixture, Part1Benchmark)->Unit(benchmark::kMillisecond);
BENCHMARK_REGISTER_F(BenchmarkFixture, Part2Benchmark)->Unit(benchmark::kMillisecond);

int main(int argc, char **argv)
{
Data data = parse();

int answer1 = 0;
int answer2 = 0;

auto first = part1(data);
std::cout << "Part 1: " << first << std::endl;

auto second = part2(data);
std::cout << "Part 2: " << second << std::endl;

first != answer1 ? throw std::runtime_error("Part 1 incorrect") : nullptr;
second != answer2 ? throw std::runtime_error("Part 2 incorrect") : nullptr;

for (int i = 1; i < argc; ++i) {
if (std::string(argv[i]) == "--benchmark") {
benchmark::Initialize(&argc, argv);
benchmark::RunSpecifiedBenchmarks();
return 0;
}
}
}

0 comments on commit b068147

Please sign in to comment.