Skip to content

Commit

Permalink
Cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
SewerynKaminski committed Dec 15, 2024
1 parent c6ab09a commit 65704d6
Showing 1 changed file with 93 additions and 126 deletions.
219 changes: 93 additions & 126 deletions year2024/day15/day_15.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,19 @@ 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; }
int x = 0, y = 0;
void operator +=( const P& o ) { x += o.x; y += o.y; }
void operator +=( const int o ) { x += o; y += o; }
void operator *=( const int o ) { x *= o; y *= o; }
P operator +( const P& o ) const { return { x + o.x, y + o.y }; }
P operator -( const P& o ) const { return { x + o.x, y + o.y }; }
P operator *( const int o ) { return { x * o, y * o }; }
P operator /(const int o ) { return { x / o, y / o }; }
int len_squared() const { return x * x + y * y; }
};

//---------------------------------------------------------------------------//
inline std::istream& test_input() {
inline ::std::istream& test_input() {
static std::stringstream ss;
return ss = std::stringstream ( testinput );;
}
Expand All @@ -68,11 +60,11 @@ Data load ( ::std::istream& file ) {
::std::string line;
::std::vector<std::string> map;
while ( ::std::getline ( file, line ) ) {
if( line.empty() ) break;
if ( line.empty() ) break;
map.push_back ( line );
}

std::string movements;
::std::string movements;
while ( ::std::getline ( file, line ) ) {
movements.append( line );
}
Expand All @@ -81,17 +73,25 @@ Data load ( ::std::istream& file ) {
}

//---------------------------------------------------------------------------//
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 );
static P UP{0,-1};
static P DOWN{0,1};
static P LEFT{-1,0};
static P RIGHT{1,0};
static P ZERO{0,0};

//---------------------------------------------------------------------------//
bool go( ::std::vector<::std::string>& map, P p, P d ) {
P pd = p+d;
if ( map[pd.y][pd.x] == '.' ) return true;

if ( map[pd.y][pd.x] == 'O') {
if ( go ( map, pd, d ) ) {
map[pd.y+d.y][pd.x+d.x] = map[pd.y][pd.x];
map[pd.y][pd.x] = '.';
return true;
}
}
return ret;
return false;
}

//---------------------------------------------------------------------------//
Expand All @@ -103,89 +103,70 @@ void Task_1 ( ::std::istream& puzzle_input ) {
auto& file = aoc::is_test_enabled() ? test_input() : puzzle_input;
auto data = load ( file );

int x=0,y=0;

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

P dir;
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;
case '^': dir = UP; break;
case 'v': dir = DOWN; break;
case '<': dir = LEFT; break;
case '>': dir = RIGHT; break;
default : dir = ZERO; break;
}
if ( go ( data.map, p, dir ) )
p += dir;
}

y=0;
p.y=0;
for( const auto& l : data.map ) {
//::std::cout << l << '\n';
int x=0;
p.x=0;
for ( const auto c : l ) {
if ( c=='O' )
ans += 100 * y + x;
x++;
if ( c=='O' ) ans += 100 * p.y + p.x;
p.x++;
}
y++;
p.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] = '.';
bool go_wide ( ::std::vector<::std::string>& map, P p, P d, bool move=false ) {
P pd = p + d;
if ( map[pd.y][pd.x] == '#' ) return false;
if ( map[pd.y][pd.x] == '.' ) return true;

if ( d.y == 0 ) {
if ( go_wide ( map, pd, d, move ) ) {
if ( move ) {
map[pd.y][pd.x+d.x] = map[pd.y][pd.x];
map[pd.y][pd.x] = '.';
}
return true;
}
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] = '.';
} else if ( d.x == 0 ) {
P dir = map[pd.y][pd.x] == '[' ? RIGHT : LEFT;
if ( go_wide ( map, pd, d, move )
&& go_wide ( map, pd+dir, d, move ) ) {
if ( move ) {
map[pd.y+d.y][pd.x] = map[pd.y][pd.x];
map[pd.y+d.y][pd.x+dir.x] = map[pd.y][pd.x+dir.x];
map[pd.y][pd.x] = '.';
map[pd.y][pd.x+dir.x] = '.';
}
return true;
}
return ret;
}
return false;
}
Expand All @@ -204,66 +185,52 @@ void Task_2 ( ::std::istream& puzzle_input ) {
::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;
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;
P p;
for ( const auto& m : data.map ) {
auto i = m.find ( '@' );
if ( i != ::std::string::npos ) {
x = (int)i;
data.map[y][x] = '.';
p.x = (int)i;
data.map[p.y][p.x] = '.';
break;
}
y++;
p.y++;
}

// do the movement
P dir;
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;
case '^': dir = UP; break;
case 'v': dir = DOWN; break;
case '<': dir = LEFT; break;
case '>': dir = RIGHT; break;
default : dir = ZERO; break;
}
if ( go_wide ( data.map, p, dir ) ) {
go_wide ( data.map, p, dir, true );
p += dir;
}
}

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

OUT ( ans );
Expand Down

0 comments on commit 65704d6

Please sign in to comment.