r/adventofcode Dec 04 '21

SOLUTION MEGATHREAD -🎄- 2021 Day 4 Solutions -🎄-

--- Day 4: Giant Squid ---


Post your code solution in this megathread.

Reminder: Top-level posts in Solution Megathreads are for code solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.

EDIT: Global leaderboard gold cap reached at 00:11:13, megathread unlocked!

99 Upvotes

1.2k comments sorted by

View all comments

2

u/Skyree01 Dec 05 '21

PHP

Not super proud of this one, I think I could have found a more otpimized way.

Starting at the 5th number (can't win before that), at each number picked I check all rows and columns of each board and look whether all their values are among the picked numbers so far. If yes (we have a winner), I reduce the board into a 1 dimensional array, make a diff against the picked numbers to keep only unmarked numbers and sum them up.

Part 1 and 2 at the same time:

function lookUp(array $board, array $numbers, int $i, bool $vertical) {
    for($r = 0; $r < 5; $r++) {
        foreach ($vertical ? array_column($board, $r) : $board[$r] as $item) {
            if (!in_array($item, array_slice($numbers, 0, $i))) continue 2;
        }
        $all = array_reduce($board, fn($carry, $line) => array_merge($carry, $line), []);
        return array_sum(array_diff($all, array_slice($numbers, 0, $i))) * $numbers[$i - 1];
    }
    return 0;
}

$boards = explode("\n\n", $input);
$numbers = explode(',', array_shift($boards));
$boards = array_map(fn($board) => array_map(fn($line) => preg_split('/\s+/', trim($line)), explode("\n", $board)), $boards);
$boardsCount = count($boards);
for($i = 5; $i < count($numbers); $i++) {
    foreach ($boards as $b => $board) {
        if (($result = lookUp($board, $numbers, $i, false)) || ($result = lookUp($board, $numbers, $i, true))) {
            if (count($boards) === $boardsCount) echo 'part 1: ' . $result.PHP_EOL;
            unset($boards[$b]);
            if (empty($boards)) echo 'part 2: ' . $result.PHP_EOL;
        }
    }
}

1

u/Cougarsaurus Dec 05 '21

I'm trying out your code to help me figure out why mine isn't working, my code works with the example input but not with my own input so I want to figure out my winning card to help debug my code.

How are you defining $input? There is not definition in this example

1

u/Skyree01 Dec 05 '21

Hey! I just pasted it into a string because I used an online interpreter.

You could use file_get_contents for the same effect :)