Skip to content

Commit

Permalink
Day 22 Part 2 solution
Browse files Browse the repository at this point in the history
  • Loading branch information
dancarroll committed Dec 22, 2024
1 parent d6a28be commit cbcdfff
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 1 deletion.
3 changes: 2 additions & 1 deletion bin/day22.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import 'package:aoc_2024/lib.dart';
import 'package:aoc_2024/day22/part_1.dart' as part1;
import 'package:aoc_2024/day22/part_2.dart' as part2;

Future<void> main(List<String> arguments) async {
await runDay(
day: Day.day22,
part1: part1.calculate,
part2: (_) => Future.value(0),
part2: part2.calculate,
);
}
78 changes: 78 additions & 0 deletions lib/day22/part_2.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import 'dart:collection';
import 'dart:io';

import 'shared.dart';

/// Continuing from part 1, determine the best instructions for selling.
/// Monkeys can only be told to sell based on the a sequence of four
/// price changes. Prices are the final digit of the secret number.
///
/// Monkeys will sell as soon as they see the specified sequence of four
/// prices.
///
/// For all the secret numbers in the input (each representing a buyer),
/// deterime the price change sequence that will result in the highest
/// total sales. It is possible that the sequence does not appear in the
/// first 2000 prices for certain buyers (which is ok, as long as the
/// total value is highest).
Future<int> calculate(File file) async {
final data = await loadData(file);
totalPriceForSequence.clear();

// First, run through all 2000 numbers per buyer, during which
// [totalPriceForSequence] will maintain the total value of sales
// given that sequence.
for (final start in data) {
_simulate(start, 2000);
}

// Then, iterate through all of the sequences, and find the highest
// total sales..
int max = 0;
for (final entry in totalPriceForSequence.entries) {
if (entry.value > max) {
max = entry.value;
}
}

return max;
}

/// Stores the total sales price for a given sequence.
/// Each secret number simulation should only contribute once per
/// key to this map.
HashMap<String, int> totalPriceForSequence = HashMap();

/// Generate the secret numbers up to [iterations], starting at
/// the given [starting] secret number. The first time each
/// sequence of four price changes is encountered, the sales price
/// is added to [totalPriceForSequence].
void _simulate(int starting, int iterations) {
// Keep track of the sequences seen for this starting number simulation.
Set<String> seenSequences = {};
List<int> trailingFourChanges = [];

int secret = starting;
int lastPrice = starting % 10;
for (int i = 0; i < iterations; i++) {
secret = nextSecret(secret);
final newPrice = secret % 10;

trailingFourChanges.add(newPrice - lastPrice);
if (i >= 4) {
trailingFourChanges.removeAt(0);
final key = trailingFourChanges.join(',');

// If this is the first time we have seen this sequence, add the
// price to the sales map.
if (!seenSequences.contains(key)) {
seenSequences.add(key);

totalPriceForSequence.update(key, (x) => x + newPrice,
ifAbsent: () => newPrice);
}
}

lastPrice = newPrice;
}
}
9 changes: 9 additions & 0 deletions test/day22_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:aoc_2024/lib.dart';
import 'package:aoc_2024/day22/part_1.dart' as part1;
import 'package:aoc_2024/day22/part_2.dart' as part2;
import 'package:test/test.dart';

void main() {
Expand All @@ -12,6 +13,10 @@ void main() {
test('part1', () async {
expect(await part1.calculate(file), 37327623);
});

test('part2', () async {
expect(await part2.calculate(file), 24);
});
});

group('real data', tags: 'real-data', () {
Expand All @@ -21,5 +26,9 @@ void main() {
test('part1', () async {
expect(await part1.calculate(file), 15608699004);
});

test('part2', () async {
expect(await part2.calculate(file), 1791);
});
});
}

0 comments on commit cbcdfff

Please sign in to comment.