feat(day17): but in javascript :(
Will do this in zig too, but really wanted to know if my strategy worked
This commit is contained in:
1
AdventOfCode2023/.gitignore
vendored
1
AdventOfCode2023/.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
zig-cache
|
zig-cache
|
||||||
zig-out
|
zig-out
|
||||||
input.txt
|
input.txt
|
||||||
|
node_modules
|
||||||
|
175
AdventOfCode2023/src/day17/.gitignore
vendored
Normal file
175
AdventOfCode2023/src/day17/.gitignore
vendored
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
|
||||||
|
logs
|
||||||
|
_.log
|
||||||
|
npm-debug.log_
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Caches
|
||||||
|
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
|
||||||
|
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
|
||||||
|
pids
|
||||||
|
_.pid
|
||||||
|
_.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
|
||||||
|
.temp
|
||||||
|
|
||||||
|
# Docusaurus cache and generated files
|
||||||
|
|
||||||
|
.docusaurus
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
|
|
||||||
|
# IntelliJ based IDEs
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Finder (MacOS) folder config
|
||||||
|
.DS_Store
|
BIN
AdventOfCode2023/src/day17/bun.lockb
Executable file
BIN
AdventOfCode2023/src/day17/bun.lockb
Executable file
Binary file not shown.
182
AdventOfCode2023/src/day17/day17.zig
Normal file
182
AdventOfCode2023/src/day17/day17.zig
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
const graph = @import("../graph/graph.zig");
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const print = std.debug.print;
|
||||||
|
|
||||||
|
fn coord(myX: usize, myY: usize) u128 {
|
||||||
|
return @as(u128, myX) << 64 | @as(u128, myY);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Coord = struct { x: usize, y: usize };
|
||||||
|
|
||||||
|
fn from_coord(c: u128) Coord {
|
||||||
|
const x: usize = @truncate(c >> 64);
|
||||||
|
const y: usize = @truncate(c);
|
||||||
|
|
||||||
|
return Coord{ .x = x, .y = y };
|
||||||
|
}
|
||||||
|
|
||||||
|
const MAX_STRAIGHT_LINE_MOVE = 3;
|
||||||
|
|
||||||
|
fn create_nodes(allocator: std.mem.Allocator, input: [][]const u8, label: []const u8) !std.AutoHashMap(u128, *graph.Node) {
|
||||||
|
var node_map = std.AutoHashMap(u128, *graph.Node).init(allocator);
|
||||||
|
|
||||||
|
for (0..input.len) |y| {
|
||||||
|
for (0..input[0].len) |x| {
|
||||||
|
const c = coord(x, y);
|
||||||
|
|
||||||
|
const node = try allocator.create(graph.Node);
|
||||||
|
node.label = label;
|
||||||
|
node.work_distance = 0;
|
||||||
|
node.out_edges = undefined;
|
||||||
|
|
||||||
|
try node_map.put(c, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return node_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn solve(input: [][]const u8) !void {
|
||||||
|
const allocator = std.heap.page_allocator;
|
||||||
|
|
||||||
|
var h_map = try create_nodes(allocator, input, "h-node");
|
||||||
|
var v_map = try create_nodes(allocator, input, "v-node");
|
||||||
|
|
||||||
|
var clean_h_map = std.AutoHashMap(u128, *graph.Node).init(allocator);
|
||||||
|
var clean_v_map = std.AutoHashMap(u128, *graph.Node).init(allocator);
|
||||||
|
|
||||||
|
var h_map_iter = h_map.iterator();
|
||||||
|
while (h_map_iter.next()) |entry| {
|
||||||
|
const map_c = entry.key_ptr.*;
|
||||||
|
const h_node = entry.value_ptr.*;
|
||||||
|
|
||||||
|
const c = from_coord(map_c);
|
||||||
|
|
||||||
|
var y = c.y;
|
||||||
|
var counter: usize = MAX_STRAIGHT_LINE_MOVE;
|
||||||
|
|
||||||
|
var edge_array = std.ArrayList(graph.Edge).init(allocator);
|
||||||
|
|
||||||
|
var accumulated_distance: usize = 0;
|
||||||
|
|
||||||
|
while (counter > 0) : (counter -= 1) {
|
||||||
|
if (y == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const edge_out_coord = coord(c.x, y);
|
||||||
|
const out_node = v_map.get(edge_out_coord).?;
|
||||||
|
|
||||||
|
accumulated_distance += input[y][c.x] - '0';
|
||||||
|
|
||||||
|
const edge = graph.Edge{ .in_node = h_node, .out_node = out_node, .distance = accumulated_distance };
|
||||||
|
try edge_array.append(edge);
|
||||||
|
|
||||||
|
y -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
y = c.y;
|
||||||
|
counter = MAX_STRAIGHT_LINE_MOVE;
|
||||||
|
accumulated_distance = 0;
|
||||||
|
|
||||||
|
while (counter > 0) : (counter -= 1) {
|
||||||
|
if (y == input.len - 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const edge_out_coord = coord(c.x, y);
|
||||||
|
const out_node = v_map.get(edge_out_coord).?;
|
||||||
|
|
||||||
|
accumulated_distance += input[y][c.x] - '0';
|
||||||
|
|
||||||
|
const edge = graph.Edge{ .in_node = h_node, .out_node = out_node, .distance = accumulated_distance };
|
||||||
|
try edge_array.append(edge);
|
||||||
|
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
h_node.out_edges = try edge_array.toOwnedSlice();
|
||||||
|
try clean_h_map.put(map_c, h_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
h_map.deinit();
|
||||||
|
|
||||||
|
var v_map_iter = v_map.iterator();
|
||||||
|
while (v_map_iter.next()) |entry| {
|
||||||
|
const map_c = entry.key_ptr.*;
|
||||||
|
const v_node = entry.value_ptr.*;
|
||||||
|
|
||||||
|
const c = from_coord(map_c);
|
||||||
|
|
||||||
|
var x = c.x;
|
||||||
|
var counter: usize = MAX_STRAIGHT_LINE_MOVE;
|
||||||
|
|
||||||
|
var edge_array = std.ArrayList(graph.Edge).init(allocator);
|
||||||
|
var accumulated_distance: usize = 0;
|
||||||
|
|
||||||
|
while (counter > 0) : (counter -= 1) {
|
||||||
|
if (x == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const edge_out_coord = coord(x, c.y);
|
||||||
|
const out_node = clean_h_map.get(edge_out_coord).?;
|
||||||
|
|
||||||
|
accumulated_distance += input[c.y][x] - '0';
|
||||||
|
|
||||||
|
const edge = graph.Edge{ .in_node = v_node, .out_node = out_node, .distance = accumulated_distance };
|
||||||
|
try edge_array.append(edge);
|
||||||
|
|
||||||
|
x -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = c.x;
|
||||||
|
counter = MAX_STRAIGHT_LINE_MOVE;
|
||||||
|
accumulated_distance = 0;
|
||||||
|
|
||||||
|
while (counter > 0) : (counter -= 1) {
|
||||||
|
if (x == input[0].len - 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const edge_out_coord = coord(x, c.y);
|
||||||
|
const out_node = clean_h_map.get(edge_out_coord).?;
|
||||||
|
|
||||||
|
accumulated_distance += input[c.y][x] - '0';
|
||||||
|
|
||||||
|
const edge = graph.Edge{ .in_node = v_node, .out_node = out_node, .distance = accumulated_distance };
|
||||||
|
try edge_array.append(edge);
|
||||||
|
|
||||||
|
x += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
v_node.out_edges = try edge_array.toOwnedSlice();
|
||||||
|
try clean_v_map.put(map_c, v_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
v_map.deinit();
|
||||||
|
|
||||||
|
var all_nodes = try allocator.alloc(*graph.Node, input.len * input[0].len * 2);
|
||||||
|
var index: usize = 0;
|
||||||
|
|
||||||
|
var node_iter = clean_h_map.valueIterator();
|
||||||
|
while (node_iter.next()) |n| {
|
||||||
|
all_nodes[index] = n.*;
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
node_iter = clean_v_map.valueIterator();
|
||||||
|
while (node_iter.next()) |n| {
|
||||||
|
all_nodes[index] = n.*;
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const g = graph.Graph{ .nodes = all_nodes };
|
||||||
|
|
||||||
|
const start = clean_v_map.get(coord(0, 0)).?;
|
||||||
|
const end = clean_v_map.get(coord(input[0].len - 1, input.len - 1)).?;
|
||||||
|
|
||||||
|
const part1 = try graph.dijkstra(allocator, g, start, end);
|
||||||
|
print("Part 1: {}\n", .{part1});
|
||||||
|
}
|
266
AdventOfCode2023/src/day17/index.ts
Normal file
266
AdventOfCode2023/src/day17/index.ts
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
const input = await Bun.file("./input.txt").text();
|
||||||
|
const processed_input = input
|
||||||
|
.split("\n")
|
||||||
|
.slice(0, -1)
|
||||||
|
.map((s) => s.split("").map(Number));
|
||||||
|
|
||||||
|
class Node {
|
||||||
|
public id: string;
|
||||||
|
public x: number;
|
||||||
|
public y: number;
|
||||||
|
public weight: number;
|
||||||
|
|
||||||
|
constructor(id: string, x: number, y: number, weight: number) {
|
||||||
|
this.id = `${id}-${x}-${y}`;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.weight = weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NodeWithWork extends Node {
|
||||||
|
public work_distance: number;
|
||||||
|
|
||||||
|
constructor(node: Node, work_distance: number) {
|
||||||
|
super(node.id.split("-")[0], node.x, node.y, node.weight);
|
||||||
|
this.work_distance = work_distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_from_id(n: NodeWithWork[], id: string): NodeWithWork | undefined {
|
||||||
|
return n.find((n) => n.id === id);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Edge {
|
||||||
|
public from: string;
|
||||||
|
public to: string;
|
||||||
|
public weight: number;
|
||||||
|
|
||||||
|
constructor(from: string, to: string, weight: number) {
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
this.weight = weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Graph {
|
||||||
|
public nodes: Node[];
|
||||||
|
public edges: Edge[];
|
||||||
|
|
||||||
|
constructor(nodes: Node[], edges: Edge[]) {
|
||||||
|
this.nodes = nodes;
|
||||||
|
this.edges = edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get_node_from_id(id: string): Node {
|
||||||
|
const node = this.nodes.find((n) => n.id === id);
|
||||||
|
if (node == null) {
|
||||||
|
throw new Error("Could not find node");
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get_node_or_throw(x: number, y: number): Node {
|
||||||
|
const node = this.nodes.find((n) => n.x === x && n.y === y);
|
||||||
|
if (node == null) {
|
||||||
|
throw new Error("Could not find node");
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get_node_out_edges(node: Node): Edge[] {
|
||||||
|
return this.edges.filter((e) => e.from === node.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public add_edge(edge: Edge): void {
|
||||||
|
this.edges.push(edge);
|
||||||
|
}
|
||||||
|
|
||||||
|
public add_node(node: Node): void {
|
||||||
|
this.nodes.push(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public print(): void {
|
||||||
|
for (const n of this.nodes) {
|
||||||
|
console.log(`Node: ${n.id}`);
|
||||||
|
for (const e of h_nodes.get_node_out_edges(n)) {
|
||||||
|
console.log(` Edge: ${e.from} --- ${e.to} | Weight: ${e.weight}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public dijkstras(source: Node, destination: Node): number {
|
||||||
|
const work_map = new Map<string, string>();
|
||||||
|
const distances = new Map<string, number>();
|
||||||
|
|
||||||
|
const work_queue = this.nodes.map((n) => new NodeWithWork(n, 9999999999));
|
||||||
|
|
||||||
|
work_queue.find((n) => n.id === source.id)!.work_distance = 0;
|
||||||
|
|
||||||
|
while (work_queue.length > 0) {
|
||||||
|
work_queue.sort((a, b) => a.work_distance - b.work_distance);
|
||||||
|
const closent_node = work_queue[0];
|
||||||
|
|
||||||
|
distances.set(closent_node.id, closent_node.work_distance);
|
||||||
|
|
||||||
|
work_queue.splice(0, 1);
|
||||||
|
|
||||||
|
for (const e of this.get_node_out_edges(closent_node)) {
|
||||||
|
const neighbor = get_from_id(work_queue, e.to);
|
||||||
|
if (neighbor == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const alternative_path = closent_node.work_distance + e.weight;
|
||||||
|
|
||||||
|
if (alternative_path < neighbor.work_distance) {
|
||||||
|
neighbor.work_distance = alternative_path;
|
||||||
|
work_map.set(neighbor.id, closent_node.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return distances.get(destination.id)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static from_graphs(...graphs: Graph[]) {
|
||||||
|
return new Graph(
|
||||||
|
graphs.flatMap((g) => g.nodes),
|
||||||
|
graphs.flatMap((g) => g.edges),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_graph(id: string, input: number[][]): Graph {
|
||||||
|
const nodes: Node[] = [];
|
||||||
|
|
||||||
|
for (const [y, row] of input.entries()) {
|
||||||
|
for (const [x, n] of row.entries()) {
|
||||||
|
nodes.push(new Node(id, x, y, n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Graph(nodes, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_interlaced_edges(
|
||||||
|
first: Graph,
|
||||||
|
second: Graph,
|
||||||
|
offset: number,
|
||||||
|
distance: number,
|
||||||
|
) {
|
||||||
|
for (const n of first.nodes) {
|
||||||
|
let accumulated_weight = 0;
|
||||||
|
for (let i = 1; i < offset && n.x + i < processed_input[0].length; i++) {
|
||||||
|
accumulated_weight += processed_input[n.y][n.x + i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right
|
||||||
|
for (
|
||||||
|
let i = offset;
|
||||||
|
i <= distance && n.x + i < processed_input[0].length;
|
||||||
|
i++
|
||||||
|
) {
|
||||||
|
accumulated_weight += processed_input[n.y][n.x + i];
|
||||||
|
const out_node = second.get_node_or_throw(n.x + i, n.y);
|
||||||
|
|
||||||
|
first.add_edge(new Edge(n.id, out_node.id, accumulated_weight));
|
||||||
|
}
|
||||||
|
|
||||||
|
accumulated_weight = 0;
|
||||||
|
for (let i = -1; i > -offset && n.x + i >= 0; i--) {
|
||||||
|
accumulated_weight += processed_input[n.y][n.x + i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Left
|
||||||
|
for (let i = -offset; -i <= distance && n.x + i >= 0; i--) {
|
||||||
|
accumulated_weight += processed_input[n.y][n.x + i];
|
||||||
|
const out_node = second.get_node_or_throw(n.x + i, n.y);
|
||||||
|
|
||||||
|
first.add_edge(new Edge(n.id, out_node.id, accumulated_weight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const n of second.nodes) {
|
||||||
|
let accumulated_weight = 0;
|
||||||
|
for (let i = 1; i < offset && n.y + i < processed_input.length; i++) {
|
||||||
|
accumulated_weight += processed_input[n.y + i][n.x];
|
||||||
|
}
|
||||||
|
// Right
|
||||||
|
for (
|
||||||
|
let i = offset;
|
||||||
|
i <= distance && n.y + i < processed_input.length;
|
||||||
|
i++
|
||||||
|
) {
|
||||||
|
accumulated_weight += processed_input[n.y + i][n.x];
|
||||||
|
const out_node = first.get_node_or_throw(n.x, n.y + i);
|
||||||
|
|
||||||
|
first.add_edge(new Edge(n.id, out_node.id, accumulated_weight));
|
||||||
|
}
|
||||||
|
|
||||||
|
accumulated_weight = 0;
|
||||||
|
for (let i = -1; i > -offset && n.y + i >= 0; i--) {
|
||||||
|
accumulated_weight += processed_input[n.y + i][n.x];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Left
|
||||||
|
for (let i = -offset; -i <= distance && n.y + i >= 0; i--) {
|
||||||
|
accumulated_weight += processed_input[n.y + i][n.x];
|
||||||
|
const out_node = first.get_node_or_throw(n.x, n.y + i);
|
||||||
|
|
||||||
|
first.add_edge(new Edge(n.id, out_node.id, accumulated_weight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const v_nodes = create_graph("v", processed_input);
|
||||||
|
const h_nodes = create_graph("h", processed_input);
|
||||||
|
|
||||||
|
// create_interlaced_edges(h_nodes, v_nodes, 1, 3);
|
||||||
|
create_interlaced_edges(h_nodes, v_nodes, 4, 10);
|
||||||
|
|
||||||
|
const full_graph = Graph.from_graphs(h_nodes, v_nodes);
|
||||||
|
|
||||||
|
// full_graph.print();
|
||||||
|
|
||||||
|
const INITIAL = "initial-0-0";
|
||||||
|
const FINAL = `final-${processed_input[0].length - 1}-${
|
||||||
|
processed_input.length - 1
|
||||||
|
}`;
|
||||||
|
|
||||||
|
full_graph.add_node(new Node("initial", 0, 0, 0));
|
||||||
|
full_graph.add_node(
|
||||||
|
new Node(
|
||||||
|
"final",
|
||||||
|
processed_input[0].length - 1,
|
||||||
|
processed_input.length - 1,
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
full_graph.add_edge(new Edge(INITIAL, "v-0-0", 0));
|
||||||
|
full_graph.add_edge(new Edge(INITIAL, "h-0-0", 0));
|
||||||
|
|
||||||
|
full_graph.add_edge(
|
||||||
|
new Edge(
|
||||||
|
`v-${processed_input[0].length - 1}-${processed_input.length - 1}`,
|
||||||
|
FINAL,
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
full_graph.add_edge(
|
||||||
|
new Edge(
|
||||||
|
`h-${processed_input[0].length - 1}-${processed_input.length - 1}`,
|
||||||
|
FINAL,
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const shortest_path = full_graph.dijkstras(
|
||||||
|
full_graph.get_node_from_id(INITIAL),
|
||||||
|
full_graph.get_node_from_id(FINAL),
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(shortest_path);
|
11
AdventOfCode2023/src/day17/package.json
Normal file
11
AdventOfCode2023/src/day17/package.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "day17",
|
||||||
|
"module": "index.ts",
|
||||||
|
"type": "module",
|
||||||
|
"devDependencies": {
|
||||||
|
"bun-types": "latest"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5.0.0"
|
||||||
|
}
|
||||||
|
}
|
22
AdventOfCode2023/src/day17/tsconfig.json
Normal file
22
AdventOfCode2023/src/day17/tsconfig.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["ESNext"],
|
||||||
|
"module": "esnext",
|
||||||
|
"target": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"composite": true,
|
||||||
|
"strict": true,
|
||||||
|
"downlevelIteration": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"types": [
|
||||||
|
"bun-types" // add Bun global
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -5,21 +5,21 @@ const print = std.debug.print;
|
|||||||
const log = std.log;
|
const log = std.log;
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
|
|
||||||
const Edge = struct {
|
pub const Edge = struct {
|
||||||
in_node: *Node,
|
in_node: *Node,
|
||||||
out_node: *Node,
|
out_node: *Node,
|
||||||
|
|
||||||
distance: usize,
|
distance: usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Node = struct {
|
pub const Node = struct {
|
||||||
out_edges: []const Edge,
|
out_edges: []const Edge,
|
||||||
|
|
||||||
label: []const u8,
|
label: []const u8,
|
||||||
work_distance: usize,
|
work_distance: usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Graph = struct {
|
pub const Graph = struct {
|
||||||
nodes: []*Node,
|
nodes: []*Node,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ fn find_shortest_index(list: *std.ArrayList(*const Node)) usize {
|
|||||||
return shortestIndex;
|
return shortestIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dijkstra(allocator: std.mem.Allocator, graph: Graph, source: *Node, destination: *Node) !usize {
|
pub fn dijkstra(allocator: std.mem.Allocator, graph: Graph, source: *Node, destination: *Node) !usize {
|
||||||
var work_map = std.AutoHashMap(*const Node, *const Node).init(allocator);
|
var work_map = std.AutoHashMap(*const Node, *const Node).init(allocator);
|
||||||
|
|
||||||
// this is for sure the wrong data structure
|
// this is for sure the wrong data structure
|
||||||
@ -73,6 +73,8 @@ fn dijkstra(allocator: std.mem.Allocator, graph: Graph, source: *Node, destinati
|
|||||||
const closest_node_index = find_shortest_index(&work_queue);
|
const closest_node_index = find_shortest_index(&work_queue);
|
||||||
const closest_node = work_queue.orderedRemove(closest_node_index);
|
const closest_node = work_queue.orderedRemove(closest_node_index);
|
||||||
|
|
||||||
|
print("Current node: {}\n", .{closest_node.work_distance});
|
||||||
|
|
||||||
for (closest_node.out_edges) |edge| {
|
for (closest_node.out_edges) |edge| {
|
||||||
const neighbor = edge.out_node;
|
const neighbor = edge.out_node;
|
||||||
const alternative_path = closest_node.work_distance + edge.distance;
|
const alternative_path = closest_node.work_distance + edge.distance;
|
||||||
|
@ -13,7 +13,8 @@ const std = @import("std");
|
|||||||
// const day14 = @import("./day14/day14.zig");
|
// const day14 = @import("./day14/day14.zig");
|
||||||
// const day13 = @import("./day13/day13.zig");
|
// const day13 = @import("./day13/day13.zig");
|
||||||
// const day15 = @import("./day15/day15.zig");
|
// const day15 = @import("./day15/day15.zig");
|
||||||
const day16 = @import("./day16/day16.zig");
|
// const day16 = @import("./day16/day16.zig");
|
||||||
|
const day17 = @import("./day17/day17.zig");
|
||||||
// const day18 = @import("./day18/day18.zig");
|
// const day18 = @import("./day18/day18.zig");
|
||||||
// const day19 = @import("./day19/day19.zig");
|
// const day19 = @import("./day19/day19.zig");
|
||||||
// const day21 = @import("./day21/day21.zig");
|
// const day21 = @import("./day21/day21.zig");
|
||||||
@ -23,8 +24,8 @@ const utils = @import("utils.zig");
|
|||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
const allocator = std.heap.page_allocator;
|
const allocator = std.heap.page_allocator;
|
||||||
const input = try utils.getInput("./src/day16/input.txt", allocator);
|
const input = try utils.getInput("./src/day17/input.txt", allocator);
|
||||||
defer allocator.free(input);
|
defer allocator.free(input);
|
||||||
|
|
||||||
try day16.solve(input);
|
try day17.solve(input);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user