Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

day 8 finished #25

Merged
merged 6 commits into from
Dec 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions day_6/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#include "../../shared/src/exit_code.hpp"
#include "../../shared/src/file_operations.hpp"
#include "../../shared/src/grid_processor.hpp"
#include "../../shared/src/print_compatibility_layer.hpp"
#include <algorithm>
#include <atomic>
#include <execution>
#include <numeric>
#include <string>

#include "../../shared/src/exit_code.hpp"
#include "../../shared/src/file_operations.hpp"
#include "../../shared/src/grid_processor.hpp"
#include "../../shared/src/print_compatibility_layer.hpp"

#include "../lib/grid_parser.hpp"
#include "../lib/puzzle_map.hpp"

Expand Down
1 change: 1 addition & 0 deletions day_8/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
aoc_day(8)
1 change: 1 addition & 0 deletions day_8/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
aoc_add_library()
68 changes: 68 additions & 0 deletions day_8/lib/antinodes.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#pragma once

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <map>
#include <ranges>
#include <string>
#include <unordered_set>
#include <vector>

#include "../lib/coordinate.hpp"

#include "../../shared/src/ranges_compatibility_layer.hpp"

namespace aoc::day_8 {

namespace detail {
[[nodiscard]] static auto getOtherAntennaPositionsByFrequency(char frequency, coordinate const & exclude_pos,
std::multimap<char, coordinate> const & antenas) {
auto range = antenas.equal_range(frequency);
return std::ranges::subrange(range.first, range.second) |
std::views::transform([](auto const & pair) { return pair.second; }) |
std::views::filter([&exclude_pos](coordinate const & pos) { return pos != exclude_pos; }) |
std::views::common;
}

[[nodiscard]] static auto generateAntinodeSequence(coordinate start, coordinate diff, int64_t max_x, int64_t max_y) {
return std::views::iota(0) | std::views::transform([=](int64_t i) { return start + diff * i; }) |
std::views::take_while([=](coordinate pos) { return pos.inBounds(max_x, max_y); });
}
} // namespace detail

[[nodiscard]] auto determineAntinodes(int64_t max_x_coordinate, int64_t max_y_coordinate,
std::multimap<char, coordinate> const & antenas)
-> std::unordered_set<coordinate> {
return std::views::transform(
antenas,
[&](auto const & entry) {
return detail::getOtherAntennaPositionsByFrequency(entry.first, entry.second, antenas) |
std::views::transform([&entry](coordinate const & other_pos) {
coordinate diff = other_pos - entry.second;
return other_pos + diff;
}) |
std::views::filter([max_x_coordinate, max_y_coordinate](coordinate const & pos) {
return pos.inBounds(max_x_coordinate, max_y_coordinate);
});
}) |
std::views::join | aoc::ranges::to<std::unordered_set<coordinate>>;
}

[[nodiscard]] auto determineAntinodes2(int64_t max_x_coordinate, int64_t max_y_coordinate,
std::multimap<char, coordinate> const & antenas)
-> std::unordered_set<coordinate> {
return std::views::transform(
antenas,
[max_x = max_x_coordinate, max_y = max_y_coordinate, antenas = antenas](auto const & entry) {
return detail::getOtherAntennaPositionsByFrequency(entry.first, entry.second, antenas) |
std::views::transform([start = entry.second, max_x, max_y](coordinate const & other_pos) {
return detail::generateAntinodeSequence(other_pos, other_pos - start, max_x, max_y);
}) |
std::views::join;
}) |
std::views::join | aoc::ranges::to<std::unordered_set<coordinate>>;
}

} // namespace aoc::day_8
55 changes: 55 additions & 0 deletions day_8/lib/coordinate.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once

#include <cstddef>
#include <memory>

namespace aoc::day_8 {

struct coordinate {
int64_t y;
int64_t x;

auto operator!=(coordinate const & other) const -> bool {
return y != other.y || x != other.x;
}

auto operator==(coordinate const & other) const -> bool {
return y == other.y && x == other.x;
}

[[nodiscard]] auto operator-(coordinate const & other) const -> coordinate {
return {y - other.y, x - other.x};
}

[[nodiscard]] auto operator+(coordinate const & other) const -> coordinate {
return {y + other.y, x + other.x};
}

auto operator*(int64_t scalar) const -> coordinate {
return {y * scalar, x * scalar};
}

auto operator+=(coordinate const & other) -> coordinate & {
y += other.y;
x += other.x;
return *this;
}

[[nodiscard]] auto inBounds(int64_t max_x, int64_t max_y) const -> bool {
return y >= 0 && y < max_y && x >= 0 && x < max_x;
}
};

} // namespace aoc::day_8
namespace std {

/// @brief Hash specialization for VisitedPosition to enable use in unordered containers
template <> struct hash<aoc::day_8::coordinate> {
/// @brief Combines the hashes of row, column and direction into a single hash value
/// @param position The position to hash
/// @return A hash value representing the complete state of the position
[[nodiscard]] auto operator()(aoc::day_8::coordinate const position) const -> std::size_t {
return std::hash<int64_t>{}(position.y) ^ std::hash<int64_t>{}(position.x);
}
};
} // namespace std
34 changes: 34 additions & 0 deletions day_8/lib/frequency_map_renderer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <map>
#include <numeric>
#include <ranges>
#include <string>
#include <unordered_set>
#include <vector>

#include "../../shared/src/print_compatibility_layer.hpp"

#include "../lib/coordinate.hpp"

namespace aoc::day_8 {
auto renderResult(std::vector<std::string_view> lines, std::unordered_set<aoc::day_8::coordinate> antinodes,
int64_t max_x_coordinate, int64_t max_y_coordinate) -> void {
std::string output = "";
for (auto x : std::views::iota(int64_t{0}, max_y_coordinate)) {
for (auto y : std::views::iota(int64_t{0}, max_x_coordinate)) {
if (antinodes.contains({x, y})) {
output += '#';
} else {
output += lines[x][y];
}
}
output += '\n';
}
std::println("Result:\n{}Found {} antinodes", output, antinodes.size());
}
} // namespace aoc::day_8
1 change: 1 addition & 0 deletions day_8/performance/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
aoc_add_benchmark()
2 changes: 2 additions & 0 deletions day_8/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
aoc_add_executable()
configure_file(input.txt input.txt COPYONLY)
50 changes: 50 additions & 0 deletions day_8/src/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
...............e.........................i........
...............................1.......i.0........
..............................s.0......d..........
........................i....B.I............d.....
.............................s....................
................J.................................
.....................L.....0i.......4...d.........
.N...e...........................s..R.....4.....I.
........e.........v................1......R....I..
.............G..............0.....1...............
..2...N.............B......................4...R..
..............2...................N..........4s...
..p...................................1..b..I.....
..................p...........B........b...R......
....................................b.............
........W.......C.....w...........................
............7....u.............B..................
...W.................u......................bw....
.......p.2...........v......................9.....
.E.....C....u................................9....
E....Y................u.D........9...........J....
.......2..........................................
............................J.................c...
.............7...K..D..............J..............
.....C.Wq........t.................T..............
............Yt......v.............................
..W......................3...............w........
..7.....j................T...D.....n......8.....c.
.........E...............nTD......................
...r....E..........Y............n.......P........c
......K........G......L...........................
......................G.....L....v................
..............G...t......q.............l.8........
......................q............l..............
...6........r.............................w..c....
..6.........3.......Qk........T...................
......Y...............j.................n.........
..K.....S.....r......j.....U......9.l......8......
........................U......................P..
.....................q............................
.......K......5..N.....j.7.Q......................
...................p..k...U..........L.Q..........
.r......3...S.......k........y....8U....Q.......P.
.......S....g..3..................................
.....S..........gk................................
................5...................yP............
.......................g......yV..l...............
.........6.5...............V......................
..................6..5..V.........................
.............g.......................y..........V.
58 changes: 58 additions & 0 deletions day_8/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <execution>
#include <map>
#include <ranges>
#include <string>
#include <unordered_set>
#include <vector>

#include "../../shared/src/exit_code.hpp"
#include "../../shared/src/file_operations.hpp"
#include "../../shared/src/grid_processor.hpp"
#include "../../shared/src/print_compatibility_layer.hpp"

#include "../lib/antinodes.hpp"
#include "../lib/coordinate.hpp"
#include "../lib/frequency_map_renderer.hpp"

auto main(int argc, char const ** argv) -> int {
std::expected<std::string, std::error_code> input = aoc::file_operations::read("input.txt");
if (!input) [[unlikely]] {
std::println(stderr, "Could not open file: {}", input.error().message());
return aoc::EXIT_CODE_IO_ERROR;
}

std::vector<std::string_view> lines = aoc::grid_processor::processLines(*input);
if (!aoc::grid_processor::validateGrid(lines)) {
std::println(stderr, "Lines have different lengths");
return aoc::EXIT_CODE_DATA_ERROR;
}

int64_t max_y_coordinate = lines.size();
int64_t max_x_coordinate = lines[0].size();

std::multimap<char, aoc::day_8::coordinate> antenas;
for (auto x : std::views::iota(int64_t{0}, max_y_coordinate)) {
for (auto y : std::views::iota(int64_t{0}, max_x_coordinate)) {
if (std::isalnum(lines[x][y])) {
antenas.insert({lines[x][y], {x, y}});
}
}
}

// Part 1
std::unordered_set<aoc::day_8::coordinate> antinodes =
aoc::day_8::determineAntinodes(max_x_coordinate, max_y_coordinate, antenas);

aoc::day_8::renderResult(lines, antinodes, max_x_coordinate, max_y_coordinate);

// Part 2
std::unordered_set<aoc::day_8::coordinate> antinodes2 =
aoc::day_8::determineAntinodes2(max_x_coordinate, max_y_coordinate, antenas);

aoc::day_8::renderResult(lines, antinodes2, max_x_coordinate, max_y_coordinate);

return 0;
}
1 change: 1 addition & 0 deletions day_8/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
aoc_add_test()
2 changes: 1 addition & 1 deletion shared/src/column_splitter.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @file multiset_column_lexer.hpp
* @file column_splitter.hpp
* @brief Implementation of a lexer that parses the input data into columnar container structures
* @details Provides interfaces for parsing input data containing columns of numbers.
* Includes utilities for parsing individual lines and complete input files,
Expand Down
4 changes: 2 additions & 2 deletions shared/src/line_splitter.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @file line_lexer.hpp
* @brief Implementation of a line-based lexer for tokenizing input text
* @file line_splitter.hpp
* @brief Implementation of a line-based splitter for tokenizing input text
* @details Provides interfaces for parsing input data line by line into configurable containers.
* Supports both sequential and parallel processing modes with error handling through std::expected.
* Container types can be specified through template parameters, with std::vector as the default.
Expand Down
Loading