Skip to content

Commit

Permalink
Add AoC 2024 day 07, 09 and 10 solvers
Browse files Browse the repository at this point in the history
  • Loading branch information
h3x4d3c1m4l committed Dec 16, 2024
1 parent 11e914d commit 9141563
Show file tree
Hide file tree
Showing 8 changed files with 233 additions and 0 deletions.
9 changes: 9 additions & 0 deletions assets/advent_of_code/2024_07_sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
190: 10 19
3267: 81 40 27
83: 17 5
156: 15 6
7290: 6 8 6 15
161011: 16 10 13
192: 17 8 14
21037: 9 7 18 13
292: 11 6 16 20
1 change: 1 addition & 0 deletions assets/advent_of_code/2024_09_sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2333133121414131402
8 changes: 8 additions & 0 deletions assets/advent_of_code/2024_10_sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732
3 changes: 3 additions & 0 deletions lib/solvers/advent_of_code/2024/_all_solvers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ export 'day_03_solver.dart';
export 'day_04_solver.dart';
export 'day_05_solver.dart';
export 'day_06_solver.dart';
export 'day_07_solver.dart';
export 'day_09_solver.dart';
export 'day_10_solver.dart';
export 'day_11_solver.dart';
export 'day_12_solver.dart';
export 'day_13_solver.dart';
Expand Down
60 changes: 60 additions & 0 deletions lib/solvers/advent_of_code/2024/day_07_solver.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import 'package:h3x_devtools/solvers/advent_of_code/2024/aoc_2024_solver.dart';

typedef _Equation = ({int total, List<int> factors});

class Day07Solver extends AdventOfCode2024Solver {

@override
final int dayNumber = 7;

@override
String getSolution(String input) {
List<_Equation> equations = input.splitLines().map((line) {
List<String> lineSplit = line.split(': ');
return (
total: int.parse(lineSplit[0]),
factors: lineSplit[1].split(' ').map(int.parse).toList(),
);
}).toList();

// Part 1
int validEqs = 0;
for (_Equation equation in equations) {
if (_canBeTrue(equation.total, equation.factors)) {
validEqs += equation.total;
}
}

// Part 2
int validEqsWith3Ops = 0;
for (_Equation equation in equations) {
if (_canBeTrueWith3Ops(equation.total, equation.factors)) {
validEqsWith3Ops += equation.total;
}
}

return 'Valid with 2 operators: $validEqs, Valid with 3 operators $validEqsWith3Ops';
}

bool _canBeTrue(int total, List<int> factors) {
if (factors.length == 2) {
return factors[0] + factors[1] == total || factors[0] * factors[1] == total;
} else {
return _canBeTrue(total, [factors[0] * factors[1], ...factors.skip(2)]) ||
_canBeTrue(total, [factors[0] + factors[1], ...factors.skip(2)]);
}
}

bool _canBeTrueWith3Ops(int total, List<int> factors) {
if (factors.length == 2) {
return factors[0] + factors[1] == total ||
factors[0] * factors[1] == total ||
int.parse('${factors[0]}${factors[1]}') == total;
} else {
return _canBeTrueWith3Ops(total, [factors[0] * factors[1], ...factors.skip(2)]) ||
_canBeTrueWith3Ops(total, [factors[0] + factors[1], ...factors.skip(2)]) ||
_canBeTrueWith3Ops(total, [int.parse('${factors[0]}${factors[1]}'), ...factors.skip(2)]);
}
}

}
71 changes: 71 additions & 0 deletions lib/solvers/advent_of_code/2024/day_09_solver.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import 'package:characters/characters.dart';
import 'package:h3x_devtools/solvers/advent_of_code/2024/aoc_2024_solver.dart';

class Day09Solver extends AdventOfCode2024Solver {

@override
final int dayNumber = 9;

@override
String getSolution(String input) {
List<String> fileSystem = input.trim().characters.mapIndexed((i, c) => List.filled(int.parse(c), i.isEven ? (i ~/ 2).toString(): '.')).flattened.toList();

// Part 1
for (int i = fileSystem.length - 1; i >= 0; i--) {
if (fileSystem[i] == '.') continue;

bool done = false;
for (int j = 0; j < fileSystem.length; j++) {
if (i == j - 1) {
done = true;
break;
}

if (fileSystem[j] == '.') {
fileSystem[j] = fileSystem[i];
fileSystem[i] = '.';
break;
}
}

if (done) break;
}
int checksumPart1 = _calculateChecksum(fileSystem);

// Part 2 (Note: It's slow, e.g. takes about 1m30 on Apple M2 Pro in debug mode)
List<(int?, int)> fileSystemParts = input.trim().characters.mapIndexed((i, c) => i.isEven ? (i ~/ 2, int.parse(c)) : (null, int.parse(c))).toList();
for (int i = fileSystemParts.length - 1; i >= 0; i--) {
if (fileSystemParts[i] case (null, _)) continue;

for (int j = 0; j < i; j++) {
if (fileSystemParts[j] case (null, int emptySpaceLength)) {

if (emptySpaceLength >= fileSystemParts[i].$2) {
int fileLength = fileSystemParts[i].$2;
fileSystemParts[j] = fileSystemParts[i];
fileSystemParts[i] = (null, fileSystemParts[i].$2);
if (emptySpaceLength > fileLength) {
fileSystemParts.insert(j + 1, (null, emptySpaceLength - fileLength));
i++;
}
break;
}
}
}
}
fileSystem = fileSystemParts.expand((part) => part.$1 == null ? List.filled(part.$2, '.') : List.filled(part.$2, part.$1!.toString())).toList();
int checksumPart2 = _calculateChecksum(fileSystem);

return 'Checksum part 1: $checksumPart1, checksum part 2: $checksumPart2';
}

int _calculateChecksum(List<String> fileSystem) {
int checksum = 0;
for (int i = 0; i < fileSystem.length; i++) {
if (fileSystem[i] == '.') continue;
checksum += i * int.parse(fileSystem[i]);
}
return checksum;
}

}
65 changes: 65 additions & 0 deletions lib/solvers/advent_of_code/2024/day_10_solver.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import 'package:h3x_devtools/solvers/advent_of_code/2024/aoc_2024_solver.dart';

class Day10Solver extends AdventOfCode2024Solver {

@override
final int dayNumber = 10;

@override
String getSolution(String input) {
Grid<int> grid = Grid.fromString(input, int.parse);

// Part 1
int sumOfScores = 0;
for (Coordinates coordinates in grid.coordinatesOf(0)) {
sumOfScores += _getHikingScore(grid, coordinates).length;
}

// Part 2
int alternativeSumOfScores = 0;
for (Coordinates coordinates in grid.coordinatesOf(0)) {
alternativeSumOfScores += _getAlternativeHikingScore(grid, coordinates);
}

return 'Sum of scores: $sumOfScores, alternative sum of scores: $alternativeSumOfScores';
}

Set<Coordinates> _getHikingScore(Grid<int> grid, Coordinates startCoordinates) {
int startValue = grid[startCoordinates].obj;
Set<Coordinates> validTrailEnds = {};
for (CardinalDirection direction in CardinalDirection.values) {
if (startCoordinates.canGoCDirection(direction)) {
Coordinates nextStep = startCoordinates.goToCDirection(direction);
int nextValue = grid[nextStep].obj;
if (nextValue == startValue + 1) {
if (nextValue == 9) {
validTrailEnds.add(nextStep);
} else {
validTrailEnds.addAll(_getHikingScore(grid, nextStep));
}
}
}
}
return validTrailEnds;
}

int _getAlternativeHikingScore(Grid<int> grid, Coordinates startCoordinates) {
int startValue = grid[startCoordinates].obj;
int totalRating = 0;
for (CardinalDirection direction in CardinalDirection.values) {
if (startCoordinates.canGoCDirection(direction)) {
Coordinates nextStep = startCoordinates.goToCDirection(direction);
int nextValue = grid[nextStep].obj;
if (nextValue == startValue + 1) {
if (nextValue == 9) {
totalRating++;
} else {
totalRating += _getAlternativeHikingScore(grid, nextStep);
}
}
}
}
return totalRating;
}

}
16 changes: 16 additions & 0 deletions lib/solvers/helpers/grid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,22 @@ class Grid<T> {
return null;
}

Iterable<Coordinates> coordinatesOf(T item) sync* {
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
if (rows[y][x].obj == item) yield Coordinates(x, y, this);
}
}
}

Iterable<Coordinates> coordinatesWhere(bool Function(T) test) sync* {
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
if (test(rows[y][x].obj)) yield Coordinates(x, y, this);
}
}
}

// //// //
// Flip //
// //// //
Expand Down

0 comments on commit 9141563

Please sign in to comment.