Skip to content

Commit 592331d

Browse files
committed
2024/03
1 parent 23bfe7c commit 592331d

File tree

7 files changed

+153
-4
lines changed

7 files changed

+153
-4
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
![php v8.4](https://shields.io/badge/php-8.4-blue?logo=php)
44
![build](https://img.shields.io/github/actions/workflow/status/tbali0524/advent-of-code-solutions/qa.yml)
5-
![AoC stars](https://img.shields.io/badge/total%20AoC%20⭐-454-green)
5+
![AoC stars](https://img.shields.io/badge/total%20AoC%20⭐-456-green)
66
![license](https://img.shields.io/github/license/tbali0524/advent-of-code-solutions)
77

88
* [AoC website](https://adventofcode.com/)

input/2024/Aoc2024Day03.txt

Lines changed: 6 additions & 0 deletions
Large diffs are not rendered by default.

input/2024/Aoc2024Day03ex1.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))

input/2024/Aoc2024Day03ex2.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))

puzzles.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
|[2021](#2021)|![+](https://img.shields.io/badge/stars%20⭐-50-green) |
1414
|[2022](#2022)|![+](https://img.shields.io/badge/stars%20⭐-50-green) |
1515
|[2023](#2023)|![+](https://img.shields.io/badge/stars%20⭐-50-green) |
16-
|[2024](#2024)|![+](https://img.shields.io/badge/stars%20⭐-4-yellow) |
17-
|__Total__ |![total](https://img.shields.io/badge/stars%20⭐-454-green) |
16+
|[2024](#2024)|![+](https://img.shields.io/badge/stars%20⭐-6-yellow) |
17+
|__Total__ |![total](https://img.shields.io/badge/stars%20⭐-456-green) |
1818

1919
## Puzzles
2020

@@ -312,7 +312,7 @@ Hint from `subreddit` was used for Day 12 part 2, Day 24 part 2 and Day 25.
312312
|:---:|----|--:|:-----------------------------------------|:--------------------------------------------------------|
313313
| + |2024| 1|Historian Hysteria | |
314314
| + |2024| 2|Red-Nosed Reports | |
315-
| - |2024| 3| | |
315+
| + |2024| 3|Mull It Over | |
316316
| - |2024| 4| | |
317317
| - |2024| 5| | |
318318
| - |2024| 6| | |

src/Aoc2024/Aoc2024Day03.php

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TBali\Aoc2024;
6+
7+
use TBali\Aoc\SolutionBase;
8+
9+
/**
10+
* AoC 2024 Day 3: Mull It Over.
11+
*
12+
* Part 1: What do you get if you add up all of the results of the multiplications?
13+
* Part 2: What do you get if you add up all of the results of just the enabled multiplications?
14+
*
15+
* @see https://adventofcode.com/2024/day/3
16+
*/
17+
final class Aoc2024Day03 extends SolutionBase
18+
{
19+
public const YEAR = 2024;
20+
public const DAY = 3;
21+
public const TITLE = 'Mull It Over';
22+
public const SOLUTIONS = [174561379, 106921067];
23+
public const EXAMPLE_SOLUTIONS = [[161, 0], [0, 48]];
24+
25+
/**
26+
* Solve both parts of the puzzle for a given input, without IO.
27+
*
28+
* @param array<int, string> $input The lines of the input, without LF
29+
*
30+
* @return array<int, string> The answers for Part 1 and Part 2 (as strings)
31+
*
32+
* @phpstan-return array{string, string}
33+
*/
34+
public function solve(array $input): array
35+
{
36+
// ---------- Part 1 + 2
37+
$ans1 = 0;
38+
$ans2 = 0;
39+
$is_enabled = true;
40+
foreach ($input as $row) {
41+
$dos = [];
42+
$start = 0;
43+
while ($start < strlen($row)) {
44+
$i = strpos($row, 'do()', $start);
45+
if ($i === false) {
46+
break;
47+
}
48+
$dos[] = [$i, true];
49+
$start = $i + 1;
50+
}
51+
$donts = [];
52+
$start = 0;
53+
while ($start < strlen($row)) {
54+
$i = strpos($row, "don't()", $start);
55+
if ($i === false) {
56+
break;
57+
}
58+
$donts[] = [$i, false];
59+
$start = $i + 1;
60+
}
61+
$commands = array_merge($dos, $donts);
62+
usort($commands, static fn (array $a, array $b): int => $a[0] <=> $b[0]);
63+
$start = 0;
64+
while ($start < strlen($row)) {
65+
$next_start = strpos($row, 'mul(', $start);
66+
if ($next_start === false) {
67+
break;
68+
}
69+
$start = $next_start + 4;
70+
$comma = strpos($row, ',', $start + 1);
71+
if ($comma === false) {
72+
break;
73+
}
74+
$close = strpos($row, ')', $comma + 2);
75+
if ($close === false) {
76+
break;
77+
}
78+
$op1s = substr($row, $start, $comma - $start);
79+
if (!array_all(str_split($op1s), static fn ($x) => ctype_digit($x))) {
80+
continue;
81+
}
82+
$op1 = intval($op1s);
83+
$op2s = substr($row, $comma + 1, $close - $comma - 1);
84+
if (!array_all(str_split($op2s), static fn ($x) => ctype_digit($x))) {
85+
continue;
86+
}
87+
$op2 = intval($op2s);
88+
$ans1 += $op1 * $op2;
89+
$i = count($commands) - 1;
90+
while (($i >= 0) and ($commands[$i][0] >= $start)) {
91+
--$i;
92+
}
93+
if ($i >= 0) {
94+
$is_enabled = $commands[$i][1];
95+
}
96+
if ($is_enabled) {
97+
$ans2 += $op1 * $op2;
98+
}
99+
$start = $close + 1;
100+
}
101+
if (count($commands) > 0) {
102+
$is_enabled = $commands[count($commands) - 1][1];
103+
}
104+
}
105+
return [strval($ans1), strval($ans2)];
106+
}
107+
}

tests/Aoc2024Test.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PHPUnit\Framework\TestCase;
1111
use TBali\Aoc2024\Aoc2024Day01;
1212
use TBali\Aoc2024\Aoc2024Day02;
13+
use TBali\Aoc2024\Aoc2024Day03;
1314

1415
/**
1516
* Unit tests for Advent of Code season 2024.
@@ -24,6 +25,7 @@
2425
#[RequiresPhpunit('^11.4')]
2526
#[CoversClass(Aoc2024Day01::class)]
2627
#[CoversClass(Aoc2024Day02::class)]
28+
#[CoversClass(Aoc2024Day03::class)]
2729
final class Aoc2024Test extends TestCase
2830
{
2931
// --------------------------------------------------------------------
@@ -79,4 +81,36 @@ public function testDay02(): void
7981
}
8082

8183
// --------------------------------------------------------------------
84+
85+
public function testDay03Example1(): void
86+
{
87+
$solver = new Aoc2024Day02();
88+
$input = $solver->readInput($solver->inputBaseFileName() . 'ex1.txt');
89+
[$ans1, $ans2] = $solver->solve($input);
90+
[$expected1, $expected2] = $solver::EXAMPLE_SOLUTIONS[0];
91+
self::assertSame(strval($expected1), $ans1);
92+
// self::assertSame(strval($expected2), $ans2);
93+
}
94+
95+
public function testDay03Example2(): void
96+
{
97+
$solver = new Aoc2024Day02();
98+
$input = $solver->readInput($solver->inputBaseFileName() . 'ex2.txt');
99+
[$ans1, $ans2] = $solver->solve($input);
100+
[$expected1, $expected2] = $solver::EXAMPLE_SOLUTIONS[0];
101+
// self::assertSame(strval($expected1), $ans1);
102+
self::assertSame(strval($expected2), $ans2);
103+
}
104+
105+
public function testDay03(): void
106+
{
107+
$solver = new Aoc2024Day03();
108+
$input = $solver->readInput($solver->inputBaseFileName() . '.txt');
109+
[$ans1, $ans2] = $solver->solve($input);
110+
[$expected1, $expected2] = $solver::SOLUTIONS;
111+
self::assertSame(strval($expected1), $ans1);
112+
self::assertSame(strval($expected2), $ans2);
113+
}
114+
115+
// --------------------------------------------------------------------
82116
}

0 commit comments

Comments
 (0)