part2-slow
#!/usr/bin/env php
<?php
/**
* Find numbers on the left that are also on the right. For each match, gain one copy of the next X cards. (If there are four matches, get one copy of each of the next four cards). Process all the cards. Output the total number of cards you processed.
*
* This version does not cache total number of cards added. It's been modified from its original version (see part2.bak2), which looped over the cards in original order, which caused the stack size to grow exponentially, causing incredible slowdowns. It now processes cards in reverse-order, so the stack doesn't grow much at all.
*/
//$input = file_get_contents(__DIR__.'/sample2.txt');
//$input = file_get_contents(__DIR__.'/sample2b.txt');
$input = file_get_contents(__DIR__.'/input2.txt');
$expected_output = 13;
//$game_lines = explode("\n", trim($input));
$lines = explode("\n", trim($input));
$total = 0;
function get_num_matches(string $game): int {
$parts = explode(":",$game);
$games = trim($parts[1]);
$left = explode("|",$games)[0];
$right = explode("|",$games)[1];
$left_nums = array_map('trim',explode(" ", $left));
$left_nums = array_combine($left_nums, $left_nums);
$right_nums = array_map('trim',explode(" ", $right));
$right_nums = array_combine($right_nums, $right_nums);
$card_value = 0;
//echo "\n\n\nLeft Nums:\n";
//print_r($left_nums);
//echo "\n\n\nRight Nums:\n";
//print_r($right_nums);
$num_matches = 0;
foreach ($left_nums as $num){
if (!is_numeric($num))continue;
if (isset($right_nums[$num])){
//echo "\n Match $num";
//if ($card_value == 0) $card_value = 1;
//else $card_value = $card_value * 2;
$num_matches++;
}
}
//echo "\n Card Value: $card_value";
//echo "\n Num Matches: $num_matches";
return $num_matches;
}
function get_subsequent_cards_total($current_card_index, $num_cards_to_get, $pool_of_cards, $solved_cards){
$subsequent_index = $current_card_index+1;
$subsequent_cards = [];
while (
$subsequent_index < count($pool_of_cards)
&& $subsequent_index <= ($current_card_index + $num_cards_to_get)
) {
$subsequent_cards[] = $pool_of_cards[$subsequent_index];
$subsequent_index++;
}
}
$cards_list = $lines;
//var_dump($cards_list);
//exit;
$stack = $lines;
$card_count = 0;
$loop_count = 0;
$match_counts = [];
foreach ($cards_list as $index => $card){
$match_counts[$index] = get_num_matches($card);
}
foreach ($match_counts as $index => $num_matches){
$next_x = $num_matches;
$start_pos = $index+1;
$end_pos = $index+$num_matches;
while ($end_pos > count($cards_list)){
$end_pos--;
}
while ($start_pos<=$end_pos){
$cur_pos = $start_pos;
$num_matches = $match_counts[$cur_pos];
$start_pos++;
}
}
//foreach ($lines as $index => $l){
while (count($stack) > 0){
$card_count++;
$loop_count++;
$l = array_pop($stack);
if (($loop_count%1000) === 0){
echo "\n\n\nLoop $loop_count";
echo "\nStack Size: ".count($stack);
echo "\nLine: $l";
echo "\n\n\n\n";
}
//echo "\n\nProcess $l\n";
$game_text = trim(explode(":",$l)[0]);
//var_dump($game_text);
//exit;
$gn_parts = explode(" ",$game_text);
$game_num = (int)array_pop($gn_parts);
if ($game_num == 0)continue;
$game = $l;
$num_matches = get_num_matches($game);
$first_card = $game_num;
$last_card = $game_num + $num_matches;
$current_card = $first_card;
//echo "\n GameNum:$game_num";
//echo "\n NumMatches:$num_matches";
$new_cards = [];
while ($current_card < $last_card
&&isset($cards_list[$current_card])
){
if ($current_card == $game_num - 1){
$current_card++;
continue;
}
//echo "\n Add Card ".($current_card+1);
//echo "\n Stacksize:".count($stack);
//echo "\n Card: ".$cards_list[$current_card];
//$new_cards[] = $cards_list[$current_card];
$stack[] = $cards_list[$current_card];
$current_card++;
}
//$stack = array_merge($stack,array_reverse($new_cards));
//print_r($stack);
//exit;
//$total += $card_value;
//if ($loop_count > 10)exit;
}
echo "\nCard Count: $card_count";