= (int)$matches[1][$i] and $number <= (int)$matches[2][$i]) || ($number >= (int)$matches[3][$i] and $number <= (int)$matches[4][$i]); if ($comparison === true) { return true; } return $number; }; } return $compares; } $compares = parseInstructions($instructions); // check valid others $others = explode("\n", $others); array_shift($others); $others = array_map(static function($other) { return explode(',', $other); }, $others); // filter by valid tickets $valid_tickets = []; foreach ($others as $other) { $is_valid = 0; foreach ($other as $number) { foreach ($compares as $compare) { if ($compare((int)$number) === true) { $is_valid++; break; } } } if ($is_valid === 20) { $valid_tickets[] = $other; } } // filter columns by what they CAN'T be $cant_be = []; foreach ($valid_tickets as $valid_ticket) { foreach ($valid_ticket as $row => $number) { foreach ($compares as $name => $compare) { if ($compare((int)$number) !== true) { if ( !array_key_exists($row, $cant_be) || (array_key_exists($row, $cant_be) && !in_array($name, $cant_be[$row], true)) ) { $cant_be[$row][] = $name; } } } } } $columns = []; $labels = array_keys($compares); uasort($cant_be, static function($a, $b) { return count($a) >= count($b) ? -1 : 1; }); // label columns foreach ($cant_be as $row => $labels_cant_be) { foreach ($labels as $i => $label_cant_be) { if (!in_array($label_cant_be, $labels_cant_be, true)) { $columns[$row] = $label_cant_be; unset($labels[$i]); break; } } } ksort($columns); // compare to mine $mine = explode("\n", $mine); array_shift($mine); $mine = explode(',', current($mine)); $departure_fields = []; foreach ($columns as $row => $column) { if (strpos($column, 'departure') === 0) { $departure_fields[] = $mine[$row]; } } echo array_product($departure_fields);