part1
#!/usr/bin/env php
<?php
/**
*
*/
if (@$argv[1] == 'sample'){
$input = file_get_contents(__DIR__.'/sample.txt');
} else {
$input = file_get_contents(__DIR__.'/input.txt');
}
$lines = explode("\n", trim($input));
$expected_output = null;
# start with seeds:
# 79 14 55 13
# convert seeds into soil, using soil map:
# seed-to-soil map:
# 50 98 2
# 52 50 48
#
# Seed 79
# uses the 52 50 48 map bc that covers seed 50-97
# 52 - 50 = 2, so soil = seed(79) + 2 = 81
# soil is 81
#
# map_from:
# map_to:
# range_start
# range_end
# diff (amount to add to source)
#
# seed:
# soil:
# range_start: 98
# range_end: 99
# diff: -48
# ,
# range_start: 50
# range_end: 97
# diff: 2
#
# soil:
# fertilizer ...
#
# Notes:
# Seed 98 corresponds to soil 50
# Seed 98 corresponds to soil 51
#
# Seed 50 corresponds to soil 52
# Seed 51 corresponds to soil 53
# ...
# Seed 97 corresponds to soil 99
//
//
// Okay, then we have to parse it too
$seed_line = array_shift($lines);
$seed_line_parts = explode(": ", $seed_line);
$seed_numbers = explode(" ",trim($seed_line_parts[1]));
$maps_lines = trim(implode("\n", $lines));
$maps_texts = explode(":", $maps_lines);
$maps_texts = preg_split("/(:|\n\n)/", $maps_lines);
$key = null;
$map_texts = [];
foreach ($maps_texts as $index=>$map_text){
if ($index%2===0){
$map_parts = explode(" map",trim($map_text));
$map_fromto = explode("-to-", $map_parts[0]);
$from = $map_fromto[0];
$to = $map_fromto[1];
continue;
}
$map_texts[$from][$to] = $map_text;
continue;
$map_lines = explode("\n",trim($map_text));
}
$maps = [];
foreach ($map_texts as $from => $to_list){
foreach ($to_list as $to => $map_text){
$map_text_lines = explode("\n", $map_text);
foreach ($map_text_lines as $line){
$line = trim($line);
if ($line=='')continue;
$parts = explode(" ",$line);
$range_start = (int)$parts[1];
$range_end = $parts[2] + $range_start - 1;
$diff = $range_start - $parts[0];
$maps[$from][$to][] =
[
'range_start'=>$range_start,
'range_end'=>$range_end,
'diff'=>-1 * $diff, // add_to_source
];
}
}
}
function generate_outputs(string $input_name, int $input_value, array $maps){
if (!isset($maps[$input_name])) return [];
$outputs = [];
foreach ($maps[$input_name] as $to => $map_list){
foreach ($map_list as $index=>$map){
if ($input_value >= $map['range_start']
&& $input_value <= $map['range_end']){
$output = $input_value + $map['diff'];
break 2;
}
$output = $input_value;
}
}
//$outputs = [
//$to => $output
//];
//$sub_outputs = ;
$all_outputs = array_merge(
[ $to => $output],
generate_outputs($to, $output, $maps)
);
return $all_outputs;
}
$outputs = [];
foreach ($seed_numbers as $number){
$outputs[$number] = generate_outputs('seed', $number, $maps);
}
$lowest_location = PHP_INT_MAX;
foreach ($outputs as $seed_number => $outputs){
if ($outputs['location'] < $lowest_location)$lowest_location = $outputs['location'];
}
//print_r($outputs);
//print_r($maps);
echo "\n\nLowest location is: $lowest_location\n\n";