Skip to content

Commit

Permalink
feat: day05
Browse files Browse the repository at this point in the history
  • Loading branch information
martabal committed Dec 5, 2024
1 parent c91b93a commit 4cb1c8c
Show file tree
Hide file tree
Showing 13 changed files with 1,749 additions and 64 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
[workspace]
resolver = "2"
members = [
"crates/helpers",
"crates/day01",
"crates/day02",
"crates/day03",
"crates/day04",
"crates/day05",
"crates/helpers",
]

[workspace.dependencies]
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ Ideally, the solution does not use external crates/dependencies.
| 1 |||||||
| 2 |||||||
| 3 |||||||
| 4 |||||||
| 5 |||||||
48 changes: 27 additions & 21 deletions cpp/day01.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,33 +31,39 @@ read_file(const std::string &input) {
}

int main() {
// --- Part One ---
auto [left_column, right_column] = read_file("crates/day01/input.txt");
unsigned int sum = 0;
try {
// --- Part One ---
auto [left_column, right_column] = read_file("crates/day01/input.txt");
unsigned int sum = 0;

if (left_column.size() != right_column.size()) {
throw std::runtime_error("Column sizes do not match");
}
if (left_column.size() != right_column.size()) {
throw std::runtime_error("Column sizes do not match");
}

std::sort(left_column.begin(), left_column.end());
std::sort(right_column.begin(), right_column.end());
std::sort(left_column.begin(), left_column.end());
std::sort(right_column.begin(), right_column.end());

for (size_t i = 0; i < left_column.size(); i++) {
sum +=
(static_cast<unsigned int>(std::abs(left_column[i] - right_column[i])));
}
for (size_t i = 0; i < left_column.size(); i++) {
sum += (static_cast<unsigned int>(
std::abs(left_column[i] - right_column[i])));
}

std::cout << "Part One solution: sum is " << sum << std::endl;

std::cout << "Part One solution: sum is " << sum << std::endl;
// --- Part Two ---
sum = 0;
std::vector<unsigned int> appear;
for (const auto &e : left_column) {
unsigned int count =
std::count(right_column.begin(), right_column.end(), e);
sum += static_cast<unsigned int>(e) * count;
}
std::cout << "Part Two solution: sum is " << sum << std::endl;

// --- Part Two ---
sum = 0;
std::vector<unsigned int> appear;
for (const auto &e : left_column) {
unsigned int count =
std::count(right_column.begin(), right_column.end(), e);
sum += static_cast<unsigned int>(e) * count;
} catch (const std::exception &e) {
std::cerr << "Error: " << e.what() << '\n';
return 1;
}
std::cout << "Part Two solution: sum is " << sum << std::endl;

return 0;
}
47 changes: 26 additions & 21 deletions cpp/day02.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,35 +42,40 @@ std::vector<std::vector<int>> read_file(const std::string &input) {
}

int main() {
// --- Part One ---
auto report = read_file("crates/day02/input.txt");
unsigned int safe = 0;
try {
// --- Part One ---
auto report = read_file("crates/day02/input.txt");
unsigned int safe = 0;

for (const auto &e : report) {
if (is_safe(e)) {
safe++;
for (const auto &e : report) {
if (is_safe(e)) {
safe++;
}
}
}
std::cout << "Part One solution: sum is " << safe << std::endl;
std::cout << "Part One solution: sum is " << safe << std::endl;

// --- Part Two ---
safe = 0;
for (const auto &e : report) {
if (is_safe(e)) {
safe++;
} else {
for (size_t pos = 0; pos < e.size(); pos++) {
std::vector<int> new_e = e;
new_e.erase(new_e.begin() + pos);
// --- Part Two ---
safe = 0;
for (const auto &e : report) {
if (is_safe(e)) {
safe++;
} else {
for (size_t pos = 0; pos < e.size(); pos++) {
std::vector<int> new_e = e;
new_e.erase(new_e.begin() + pos);

if (is_safe(new_e)) {
safe++;
break;
if (is_safe(new_e)) {
safe++;
break;
}
}
}
}
std::cout << "Part Two solution: sum is " << safe << std::endl;
} catch (const std::exception &e) {
std::cerr << "Error: " << e.what() << '\n';
return 1;
}
std::cout << "Part Two solution: sum is " << safe << std::endl;

return 0;
}
24 changes: 14 additions & 10 deletions cpp/day03.cc
Original file line number Diff line number Diff line change
Expand Up @@ -154,16 +154,20 @@ std::string readFile(const std::string &filePath) {
}

int main() {

std::string message = readFile("crates/day03/input.txt");

// --- Part One ---
int count = count_mul(message);
std::cout << "Part One solution: sum is " << count << std::endl;

// --- Part Two ---
count = parseWithRules(message);
std::cout << "Part Two solution: sum is " << count << std::endl;
try {
std::string message = readFile("crates/day03/input.txt");

// --- Part One ---
int count = count_mul(message);
std::cout << "Part One solution: sum is " << count << std::endl;

// --- Part Two ---
count = parseWithRules(message);
std::cout << "Part Two solution: sum is " << count << std::endl;
} catch (const std::exception &e) {
std::cerr << "Error: " << e.what() << '\n';
return 1;
}

return 0;
}
144 changes: 144 additions & 0 deletions cpp/day05.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>

class PrintQueueChecker {
public:
PrintQueueChecker(const std::string &puzzle) { parsePuzzle(puzzle); }

int checkPageOrder() const {
int sum = 0;
for (const auto &order : pageNumbers) {
if (checkValid(order)) {
sum += order[order.size() / 2];
}
}
return sum;
}

int checkAndSortPageOrder() {
int sum = 0;
for (const auto &order : pageNumbers) {
if (!checkValid(order)) {
auto orderClone = order; // Create a modifiable copy
while (!checkValid(orderClone)) {
bool foundRuleBreak = false;
int oldIdx = 0;
int newIdx = 0;
int replaceVal = 0;

for (size_t idx = 0; idx < orderClone.size(); ++idx) {
auto it = rules.find(orderClone[idx]);
if (it == rules.end())
continue;

const auto &rule = it->second;

for (int checkIdx = orderClone.size() - 1;
checkIdx >= static_cast<int>(idx); --checkIdx) {
if (std::find(rule.begin(), rule.end(), orderClone[checkIdx]) !=
rule.end()) {
newIdx = checkIdx;
foundRuleBreak = true;
oldIdx = static_cast<int>(idx);
replaceVal = orderClone[idx];
break;
}
}
if (foundRuleBreak)
break;
}

if (foundRuleBreak) {
orderClone.erase(orderClone.begin() + oldIdx);
orderClone.insert(orderClone.begin() + newIdx, replaceVal);
}
}
sum += orderClone[orderClone.size() / 2];
}
}
return sum;
}

private:
std::unordered_map<int, std::vector<int>> rules;
std::vector<std::vector<int>> pageNumbers;

void parsePuzzle(const std::string &puzzle) {
std::istringstream stream(puzzle);
std::string line;

while (std::getline(stream, line) && !line.empty()) {
auto delimiterPos = line.find('|');
if (delimiterPos == std::string::npos)
continue;

int left = std::stoi(line.substr(0, delimiterPos));
int right = std::stoi(line.substr(delimiterPos + 1));
rules[right].push_back(left);
}

// Read page numbers
while (std::getline(stream, line)) {
if (line.empty())
continue;
std::vector<int> numbers;
std::istringstream numberStream(line);
std::string number;
while (std::getline(numberStream, number, ',')) {
numbers.push_back(std::stoi(number));
}
pageNumbers.push_back(numbers);
}
}

bool checkValid(const std::vector<int> &order) const {
for (size_t idx = 0; idx < order.size(); ++idx) {
auto it = rules.find(order[idx]);
if (it == rules.end())
continue;

const auto &rule = it->second;
for (int ruleVal : rule) {
if (std::find(order.begin() + idx, order.end(), ruleVal) !=
order.end()) {
return false;
}
}
}
return true;
}
};

std::string readFile(const std::string &filename) {
std::ifstream file(filename);
if (!file)
throw std::runtime_error("Unable to open file");

std::ostringstream ss;
ss << file.rdbuf();
return ss.str();
}

int main() {
try {
std::string message = readFile("crates/day05/input.txt");

// --- Part One ---
PrintQueueChecker checker(message);
std::cout << "Part One solution: " << checker.checkPageOrder() << std::endl;

// --- Part Two ---
std::cout << "Part Two solution: " << checker.checkAndSortPageOrder()
<< std::endl;
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
}

return 0;
}
3 changes: 3 additions & 0 deletions crates/day04/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ edition = "2021"

[lints]
workspace = true

[dependencies]
helpers = { path = "../helpers"}
15 changes: 4 additions & 11 deletions crates/day04/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ use std::{
io::{BufRead, BufReader},
};

use helpers::floored_division;

fn main() {
let message = read_file("crates/day04/input.txt").unwrap();
// --- Part One ---
let mut count = count_word(&message, "XMAS");
println!("{count}");
println!("Part One solution: {count}");

// --- Part Two ---
count = count_x_pattern(&message, "MAS").unwrap();
println!("{count}");
println!("Part Two solution: {count}");
}

fn read_file(input: &str) -> Result<Vec<Vec<char>>, Box<dyn std::error::Error>> {
Expand All @@ -26,15 +28,6 @@ fn read_file(input: &str) -> Result<Vec<Vec<char>>, Box<dyn std::error::Error>>
Ok(vec_of_vecs)
}

const fn floored_division(a: i32, b: i32) -> i32 {
let quotient = a / b;
if (a % b != 0) && ((a < 0) != (b < 0)) {
quotient - 1
} else {
quotient
}
}

fn count_x_pattern(grid: &[Vec<char>], word: &str) -> Result<usize, String> {
let rows = grid.len();
let cols = if rows > 0 {
Expand Down
10 changes: 10 additions & 0 deletions crates/day05/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "day05"
version = "0.1.0"
edition = "2021"

[lints]
workspace = true

[dependencies]
helpers = { path = "../helpers"}
Loading

0 comments on commit 4cb1c8c

Please sign in to comment.