Add solution for 2021 day 15 part 2
This commit is contained in:
parent
622c739c81
commit
491e2f3afa
@ -18,7 +18,7 @@
|
|||||||
| 12 | ✓ | ✓ | [Python] |
|
| 12 | ✓ | ✓ | [Python] |
|
||||||
| 13 | ✓ | ✓ | [C++] |
|
| 13 | ✓ | ✓ | [C++] |
|
||||||
| 14 | ✓ | ✓ | [Erlang] |
|
| 14 | ✓ | ✓ | [Erlang] |
|
||||||
| 15 | ✓ | | [D] |
|
| 15 | ✓ | ✓ | [D] |
|
||||||
| 16 | | | |
|
| 16 | | | |
|
||||||
| 17 | | | |
|
| 17 | | | |
|
||||||
| 18 | | | |
|
| 18 | | | |
|
||||||
|
@ -4,6 +4,8 @@ import std.algorithm.iteration : filter, map;
|
|||||||
import std.algorithm.searching : minElement, canFind;
|
import std.algorithm.searching : minElement, canFind;
|
||||||
import std.array : split;
|
import std.array : split;
|
||||||
import std.container.array : Array;
|
import std.container.array : Array;
|
||||||
|
import std.container.rbtree : redBlackTree;
|
||||||
|
import std.container.binaryheap : BinaryHeap;
|
||||||
import std.conv : to;
|
import std.conv : to;
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
import std.string : stripRight;
|
import std.string : stripRight;
|
||||||
@ -14,12 +16,64 @@ private alias Buffer = Array!(Array!(uint));
|
|||||||
struct CaveMap
|
struct CaveMap
|
||||||
{
|
{
|
||||||
private Buffer positions;
|
private Buffer positions;
|
||||||
|
private const ulong tile_width;
|
||||||
|
private const ulong tile_height;
|
||||||
|
|
||||||
this(string path)
|
this(string path)
|
||||||
{
|
{
|
||||||
positions = parseFile(path);
|
positions = parseFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this(string path, uint tiles)
|
||||||
|
{
|
||||||
|
auto buffer = parseFile(path);
|
||||||
|
tile_height = buffer.length;
|
||||||
|
tile_width = buffer[0].length;
|
||||||
|
|
||||||
|
tileRight(buffer, tiles);
|
||||||
|
tileDown(buffer, tiles);
|
||||||
|
|
||||||
|
positions = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tileRight(Buffer buffer, uint tiles)
|
||||||
|
{
|
||||||
|
foreach (tile_x; 1 .. tiles)
|
||||||
|
{
|
||||||
|
foreach (y; 0 .. tile_height)
|
||||||
|
{
|
||||||
|
foreach (x; 0 .. tile_width)
|
||||||
|
{
|
||||||
|
auto next_val = (buffer[y][x] + tile_x - 1) % 9;
|
||||||
|
next_val = next_val == 0 ? 1 : next_val + 1;
|
||||||
|
buffer[y].insertBack(next_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tileDown(Buffer buffer, uint tiles)
|
||||||
|
{
|
||||||
|
foreach (tile_y; 1 .. tiles)
|
||||||
|
{
|
||||||
|
const tile_y_begin = tile_y * tile_height;
|
||||||
|
foreach (y; 0 .. tile_height)
|
||||||
|
{
|
||||||
|
buffer.insertBack(Array!uint());
|
||||||
|
foreach (tile_x; 0 .. tiles)
|
||||||
|
{
|
||||||
|
const tile_x_begin = tile_x * tile_width;
|
||||||
|
foreach (x; 0 .. tile_width)
|
||||||
|
{
|
||||||
|
auto next_val = (buffer[y][tile_x_begin + x] + tile_y - 1) % 9;
|
||||||
|
next_val = next_val == 0 ? 1 : next_val + 1;
|
||||||
|
buffer[tile_y_begin + y].insertBack(next_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Array!(Array!uint) parseFile(string path)
|
private Array!(Array!uint) parseFile(string path)
|
||||||
{
|
{
|
||||||
auto file = File(path, "r");
|
auto file = File(path, "r");
|
||||||
@ -41,6 +95,16 @@ struct CaveMap
|
|||||||
return buffer;
|
return buffer;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void toString(scope void delegate(const(char)[]) sink) const
|
||||||
|
{
|
||||||
|
foreach (y; 0 .. positions.length)
|
||||||
|
{
|
||||||
|
foreach (x; 0 .. positions[y].length)
|
||||||
|
sink(to!string(positions[y][x]));
|
||||||
|
sink("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private alias NodeId = Tuple!(uint, uint);
|
private alias NodeId = Tuple!(uint, uint);
|
||||||
@ -93,10 +157,45 @@ struct Cave
|
|||||||
|
|
||||||
uint lowestRisk()
|
uint lowestRisk()
|
||||||
{
|
{
|
||||||
auto safest_path = dijkstraSlow();
|
auto safest_path = dijkstraFaster();
|
||||||
return safest_path[1][end_node];
|
return safest_path[1][end_node];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Tuple!(NodeId[NodeId], uint[NodeId]) dijkstraFaster()
|
||||||
|
{
|
||||||
|
uint[NodeId] distance;
|
||||||
|
NodeId[NodeId] previous;
|
||||||
|
|
||||||
|
foreach (node_id; nodes.byKey())
|
||||||
|
distance[node_id] = uint.max;
|
||||||
|
|
||||||
|
distance[start_node] = 0;
|
||||||
|
|
||||||
|
auto queue = redBlackTree(tuple(distance[start_node], start_node));
|
||||||
|
|
||||||
|
foreach (_, node; queue)
|
||||||
|
{
|
||||||
|
if (node == end_node)
|
||||||
|
break;
|
||||||
|
|
||||||
|
foreach (neighbor; nodes[node])
|
||||||
|
{
|
||||||
|
auto total_distance = distance[node] + neighbor.weight;
|
||||||
|
|
||||||
|
if (total_distance < distance[neighbor.id])
|
||||||
|
{
|
||||||
|
queue.removeKey(tuple(distance[neighbor.id], neighbor.id));
|
||||||
|
distance[neighbor.id] = total_distance;
|
||||||
|
previous[neighbor.id] = node;
|
||||||
|
queue.insert(tuple(distance[neighbor.id], neighbor.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuple(previous, distance);
|
||||||
|
}
|
||||||
|
|
||||||
private Tuple!(NodeId[NodeId], uint[NodeId]) dijkstraSlow()
|
private Tuple!(NodeId[NodeId], uint[NodeId]) dijkstraSlow()
|
||||||
{
|
{
|
||||||
bool[NodeId] unvisited;
|
bool[NodeId] unvisited;
|
||||||
|
13
2021/day-15/part_two.d
Normal file
13
2021/day-15/part_two.d
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import std.stdio;
|
||||||
|
import common : CaveMap, Cave;
|
||||||
|
|
||||||
|
void main(string[] args)
|
||||||
|
{
|
||||||
|
auto immutable path = args[1];
|
||||||
|
|
||||||
|
auto cave_map = CaveMap(path, 5);
|
||||||
|
|
||||||
|
auto graph = Cave(cave_map);
|
||||||
|
|
||||||
|
writeln(graph.lowestRisk());
|
||||||
|
}
|
@ -8,4 +8,4 @@
|
|||||||
- [2018](2018/README.md) (0% completed)
|
- [2018](2018/README.md) (0% completed)
|
||||||
- [2019](2019/README.md) (0% completed)
|
- [2019](2019/README.md) (0% completed)
|
||||||
- [2020](2020/README.md) (20% completed)
|
- [2020](2020/README.md) (20% completed)
|
||||||
- [2021](2021/README.md) (58% completed)
|
- [2021](2021/README.md) (60% completed)
|
||||||
|
Loading…
Reference in New Issue
Block a user