Skip to content

Commit

Permalink
Add day 18 of year 2024 🧝‍♀️
Browse files Browse the repository at this point in the history
  • Loading branch information
letelete committed Dec 18, 2024
1 parent c1ee057 commit 91f712a
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 12 deletions.
21 changes: 21 additions & 0 deletions 2024/days/day-18/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Benchmark

```
Platform: darwin arm64
CPU: Apple M3 Pro 11 Cores
Memory: 18.00 GB
```

## Sample 1

| part | time (~) | μs |
| ---- | -------- | ------------------- |
| 1 | 0.21ms | 0.20554199999999945 |
| 2 | 0.22ms | 0.21991700000000058 |

## Answer

| part | time (~) | μs |
| ---- | -------- | ----------------- |
| 1 | 7.46ms | 7.464041999999999 |
| 2 | 7.82ms | 7.820166999999998 |
25 changes: 25 additions & 0 deletions 2024/days/day-18/in.sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
5,4
4,2
4,5
3,0
2,1
6,3
2,4
1,5
0,6
3,3
2,6
5,1
1,2
5,5
2,5
6,5
1,4
0,4
6,4
1,1
6,1
1,0
0,5
1,6
2,0
113 changes: 101 additions & 12 deletions 2024/days/day-18/main.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,116 @@
function parse(source) {
return source.trim().split('\n');
const bytes = source
.match(/(\d+)/g)
.map(Number)
.reduce((acc, _, i, arr) => {
if (i % 2 === 0) {
acc.push([arr[i + 1], arr[i]]);
}
return acc;
}, []);

const size = Math.max(...bytes.flat()) + 1;
const start = [0, 0];
const end = [size - 1, size - 1];

return { bytes, size, start, end };
}

Array.prototype.sum = function () {
return this.reduce((sum, value) => sum + value, 0);
const dirs = {
orthogonal: [
[0, -1],
[-1, 0],
[0, 1],
[1, 0],
],
};

Array.prototype.product = function () {
return this.reduce((x, value) => x * value, 1);
};
function hash(row, col) {
return `${row},${col}`;
}

Array.prototype.equals = function (arr) {
return (
this.length === arr.length && this.every((e, i) => Object.is(e, arr[i]))
);
function inRange(size, row, col) {
return row >= 0 && row < size && col >= 0 && col < size;
}

const findShortestPath = (size, obstacles, start, end) => {
const visited = new Set();
const distance = new Map();
distance.set(hash(start[0], start[1]), 0);

const q = [[0, ...start]];

while (q.length) {
q.sort(([acost], [bcost]) => bcost - acost);

const [cost, row, col] = q.pop();
visited.add(hash(row, col));

if (row === end[0] && col === end[1]) {
break;
}

dirs.orthogonal.forEach(([drow, dcol]) => {
const nextRow = row + drow;
const nextCol = col + dcol;
const nextHash = hash(nextRow, nextCol);
if (
inRange(size, nextRow, nextCol) &&
!obstacles.has(nextHash) &&
!visited.has(nextHash)
) {
const nextCost = cost + 1;
if (!distance.has(nextHash) || nextCost < distance.get(nextHash)) {
distance.set(nextHash, nextCost);
q.push([nextCost, nextRow, nextCol]);
}
}
});
}
return distance.get(hash(end[0], end[1]));
};

function buildPathFinder(size, bytes, start, end) {
const hashedBytes = bytes.map(([row, col]) => hash(row, col));
return (n) => {
return findShortestPath(size, new Set(hashedBytes.slice(0, n)), start, end);
};
}

function findFirstByteToBlockExit(size, bytes, start, end) {
const getShortestPath = buildPathFinder(size, bytes, start, end);
let index = -1;

for (let l = 0, r = bytes.length - 1, mid; l <= r; ) {
mid = l + Math.floor((r - l) / 2);
if (getShortestPath(mid) === undefined) {
r = mid - 1;
} else {
l = mid + 1;
index = Math.max(index, mid);
}
}

return index;
}

function part1(data) {
return null;
return buildPathFinder(data.size, data.bytes, data.start, data.end)(1024);
}

function part2(data) {
return null;
const byteIndex = findFirstByteToBlockExit(
data.size,
data.bytes,
data.start,
data.end
);

if (byteIndex === -1) {
throw new Error('No byte blocks the exit');
}

return [...data.bytes[byteIndex]].reverse().join(',');
}

module.exports = { parse, part1, part2 };

0 comments on commit 91f712a

Please sign in to comment.