Skip to content

Commit

Permalink
2024 day 15
Browse files Browse the repository at this point in the history
  • Loading branch information
SewerynKaminski committed Dec 15, 2024
1 parent 8f2f191 commit 49ec02f
Show file tree
Hide file tree
Showing 5 changed files with 367 additions and 2 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,8 @@

<details><summary><a href="year2024">2024</a>
:star: :star: :star: :star: :star: :star: :star: :star: :star: :star:
:star: :star: :star: :star: ✩ ✩ ✩ ✩ ✩
✩ ✩ ✩ ✩
:star: :star: :star: :star: :star: ✩ ✩ ✩ ✩ ✩
✩ ✩ ✩ ✩
</summary>

* [Day 1](year2024/day01) - Historian Hysteria :star:
Expand Down Expand Up @@ -370,6 +370,8 @@
* [Day 13](year2024/day13) - Claw Contraption :star:

* [Day 14](year2024/day14) - Restroom Redoubt :star:

* [Day 15](year2024/day15) - Warehouse Woes :star:
</details>

Legend
Expand Down
1 change: 1 addition & 0 deletions year2024/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ add_subdirectory(day11)
add_subdirectory(day12)
add_subdirectory(day13)
add_subdirectory(day14)
add_subdirectory(day15)
16 changes: 16 additions & 0 deletions year2024/day15/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.29)

set(DAY 15)

project("${YEAR} Day ${DAY}" LANGUAGES CXX)

add_compile_definitions(DAY=day_${DAY})
add_compile_definitions(YEAR=year_${YEAR})

include_directories(..)
include_directories(../..)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(${YEAR}_day_${DAY} ../../main.cpp ../../aoc.cpp day_${DAY}.cpp input)
275 changes: 275 additions & 0 deletions year2024/day15/day_15.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
#include "day"

//---------------------------------------------------------------------------//
namespace aoc::YEAR::DAY {

//---------------------------------------------------------------------------//
// Test data
std::string testinput (
R"(##########
#..O..O.O#
#......O.#
#.OO..O.O#
#[email protected].#
#O#..O...#
#O..O..O.#
#.OO.O.OO#
#....O...#
##########
<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^
vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v
><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<
<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^
^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><
^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^
>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^
<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>
^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>
v^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^
)"
);

//---------------------------------------------------------------------------//
struct P {
int64_t x=0,y=0;
void operator +=( const P& o ) {
x += o.x;
y += o.y;
}
void operator +=( const int64_t o ) {
x+=o;
y+=o;
}
void operator *=( const int64_t o ) {
x*=o;
y*=o;
}
P operator *( const int64_t o ) { return { x * o, y * o }; }
P operator /(const int64_t o ) { return { x / o, y / o }; }
P operator -( const P& o ) const { return { x - o.x, y - o.y }; }
int64_t len_squared() const { return x * x + y * y; }
};

//---------------------------------------------------------------------------//
inline std::istream& test_input() {
static std::stringstream ss;
return ss = std::stringstream ( testinput );;
}

//---------------------------------------------------------------------------//
struct Data{
::std::vector<std::string> map;
::std::string movements;
};

//---------------------------------------------------------------------------//
Data load ( ::std::istream& file ) {
::std::string line;
::std::vector<std::string> map;
while ( ::std::getline ( file, line ) ) {
if( line.empty() ) break;
map.push_back ( line );
}

std::string movements;
while ( ::std::getline ( file, line ) ) {
movements.append( line );
}

return { map, movements };
}

//---------------------------------------------------------------------------//
bool go( ::std::vector<::std::string>& map, int x, int y, int dx, int dy ) {
if ( map[y+dy][x+dx] == '#' ) return false;
if ( map[y+dy][x+dx] == '.' ) {
map[y+dy][x+dx] = 'O';
return true;
}
bool ret = false;
if ( map[y+dy][x+dx] == 'O') {
return go ( map, x+dx, y+dy, dx, dy );
}
return ret;
}

//---------------------------------------------------------------------------//
void Task_1 ( ::std::istream& puzzle_input ) {
auto ans=0ull;

//aoc::test_enable();

auto& file = aoc::is_test_enabled() ? test_input() : puzzle_input;
auto data = load ( file );

int x=0,y=0;

for ( const auto& m : data.map ) {
auto i = m.find ( '@' );
if ( i != ::std::string::npos ) {
x = (int)i;
data.map[y][x] = '.';
break;
}
y++;
}

for ( auto m : data.movements ) {
switch ( m ) {
case '^':
if ( go ( data.map, x, y, 0, -1 ) ) {
y--;
data.map[y][x]='.';
}
break;
case 'v':
if ( go ( data.map, x, y, 0, 1 ) ) {
y++;
data.map[y][x]='.';
}
break;
case '<':
if ( go ( data.map, x, y, -1, 0 ) ) {
x--;
data.map[y][x]='.';
}
break;
case '>':
if ( go ( data.map, x, y, 1, 0 ) ) {
x++;
data.map[y][x]='.';
}
break;
}
}

y=0;
for( const auto& l : data.map ) {
//::std::cout << l << '\n';
int x=0;
for ( const auto c : l ) {
if ( c=='O' )
ans += 100 * y + x;
x++;
}
y++;
}

OUT ( ans );
}

//---------------------------------------------------------------------------//
bool go_wide ( ::std::vector<::std::string>& map, int x, int y, int dx, int dy, bool move=false ) {
if ( map[y+dy][x+dx] == '#' ) return false;
if ( map[y+dy][x+dx] == '.' ) return true;

if ( dy == 0 ) {
auto ret = go_wide ( map, x+dx, y, dx, 0, move );
if ( ret && move ) {
//map[y][x+dx*3] = map[y][x+dx*2];
map[y][x+dx*2] = map[y][x+dx*1];
map[y][x+dx*1] = '.';
}
return ret;
}
if ( dx == 0 ) {
auto ret = false;
int d = -1;
if ( map[y+dy][x] == '[' ) d=1;
ret = go_wide ( map, x, y+dy, 0, dy, move )
&& go_wide ( map, x+d, y+dy, 0, dy, move );
if ( ret && move ) {
map[y+dy*2][x] = map[y+dy][x];
map[y+dy*2][x+d] = map[y+dy][x+d];
map[y+dy][x] = '.';
map[y+dy][x+d] = '.';
}
return ret;
}
return false;
}

//---------------------------------------------------------------------------//
void Task_2 ( ::std::istream& puzzle_input ) {
int64_t ans = 0;

//aoc::test_enable();

auto& file = aoc::is_test_enabled() ? test_input() : puzzle_input;
auto data = load ( file );

// double map width
for ( auto& row : data.map ) {
::std::string new_row;
for ( auto c : row )
switch ( c ) {
case '#': new_row.append("##");break;
case '.': new_row.append("..");break;
case '@': new_row.append("@.");break;
case 'O': new_row.append("[]");break;
}
row = new_row;
}

// find start position
int x=0,y=0;
for ( const auto& m : data.map ) {
auto i = m.find ( '@' );
if ( i != ::std::string::npos ) {
x = (int)i;
data.map[y][x] = '.';
break;
}
y++;
}

// do the movement
for ( auto m : data.movements ) {
switch ( m ) {
case '^':
if ( go_wide ( data.map, x, y, 0, -1 ) ) {
go_wide ( data.map, x, y, 0, -1, true );
y--;
}
break;
case 'v':
if ( go_wide ( data.map, x, y, 0, 1 ) ) {
go_wide ( data.map, x, y, 0, 1, true );
y++;
}
break;
case '<':
if ( go_wide ( data.map, x, y, -1, 0 ) ) {
go_wide ( data.map, x, y, -1, 0, true );
x--;
}
break;
case '>':
if ( go_wide ( data.map, x, y, 1, 0 ) ) {
go_wide ( data.map, x, y, 1, 0, true );
x++;
}
break;
}
}

// Sum GPS coordinate
y=0;
for( const auto& row : data.map ) {
//::std::cout << row << '\n'; // show map
x=0;
for ( auto c : row ) {
if ( c=='[' ) ans += 100 * y + x;
x++;
}
y++;
}

OUT ( ans );
}

//---------------------------------------------------------------------------//

}
//---------------------------------------------------------------------------//
Loading

0 comments on commit 49ec02f

Please sign in to comment.