Advent of Code, day 14

This December I participated in Advent of Code.

Part 1 is rather easy. Let the robots walk.

Part 2 proved much more challenging. How does one detect a picture? I developed a strategy of trying to sense, whether the robots were “clumping”, and then printing the map, to get a visual check. This worked, and I found the picture. Then a little while later I discovered, that the apparently random output from part 1 could be used to detect the picture, but I didn’t implement that fully. Still, I really liked that elegant solution. This version of the program was actually built partially after I know the solution.

I’m getting a bit more systematic. Having all the values, that change between test and actual data at the top.

Part 1:

<?php
$input = file_get_contents('./d14input2.txt', true);
$mapwid = 101;
$maphei = 103;
// test: 11 x 7
// actual: 101 x 103
$robots = array();
foreach(preg_split("/((\r?\n)|(\r\n?))/", $input) as $line) {
	if(strlen($line)>2) {
		preg_match_all('/-?\d+/', $line, $robot);
		$robots[] = $robot[0];
	}
}
function print_map() {
	global $robots, $mapwid, $maphei;
	$map = array();
	foreach($robots as $robot) {
		$x = $robot[0];
		$y = $robot[1];
		if(isset($map[$x][$y])) {
			$map[$x][$y]++;
		} else {
			$map[$x][$y] = 1;
		}
	}
	for($j=0;$j<$maphei;$j++) {
		for($i=0;$i<$mapwid;$i++) {
			if(isset($map[$i][$j])) {
				echo $map[$i][$j];
			} else {
				echo ".";
			}
		}
		echo "\n";
	}
	echo "\n";
}
for($i=0;$i<100;$i++) {
// print("$i seconds elapsed\n");
  for($j=0;$j<sizeof($robots);$j++) {
    $robots[$j][0] =
      ($robots[$j][0] + $robots[$j][2] + $mapwid) % $mapwid;
    $robots[$j][1] =
      ($robots[$j][1] + $robots[$j][3] + $maphei) % $maphei;
  }
}
$robx0y0 = 0;
$robx0y1 = 0;
$robx1y0 = 0;
$robx1y1 = 0;
for($j=0;$j<sizeof($robots);$j++) {
	if($robots[$j][0] < ($mapwid-1)/2) {
		if($robots[$j][1] < ($maphei-1)/2) {
			$robx0y0++;
		} else {
			if($robots[$j][1] > ($maphei-1)/2) {
				$robx0y1++;
			}
		}
	} else {
		if($robots[$j][0] > ($mapwid-1)/2) {
			if($robots[$j][1] < ($maphei-1)/2) {
				$robx1y0++;
			} else {
				if($robots[$j][1] > ($maphei-1)/2) {
					$robx1y1++;
				}
			}
		}
	}
}
print("$robx0y0 $robx0y1 $robx1y0 $robx1y1\n");
$prod = $robx0y0 * $robx0y1 * $robx1y0 * $robx1y1;
print("$prod\n");
?>

Part 2:

<?php
$input = file_get_contents('./d14input2.txt', true);
$mapwid = 101;
$maphei = 103;
// test: 11 x 7
// actual: 101 x 103
$robots = array();
foreach(preg_split("/((\r?\n)|(\r\n?))/", $input) as $line) {
  if(strlen($line)>2) {
    preg_match_all('/-?\d+/', $line, $robot);
    $robots[] = $robot[0];
  }
}
//print_r($robots);
function print_map() {
  global $robots, $mapwid, $maphei;
  $map = array();
  foreach($robots as $robot) {
    $x = $robot[0];
    $y = $robot[1];
    if(isset($map[$x][$y])) {
      $map[$x][$y]++;
    } else {
      $map[$x][$y] = 1;
    }
  }
  for($j=0;$j<$maphei;$j++) {
    for($i=0;$i<$mapwid;$i++) {
      if(isset($map[$i][$j])) {
        echo $map[$i][$j];
      } else {
        echo ".";
      }
    }
    echo "\n";
  }
  echo "\n";
}
function xmas_tst() {
  global $robots, $mapwid, $maphei;
  $robx0y0 = 0;
  $robx0y1 = 0;
  $robx1y0 = 0;
  $robx1y1 = 0;
  for($j=0;$j<sizeof($robots);$j++) {
    if($robots[$j][0] < ($mapwid-1)/2) {
      if($robots[$j][1] < ($maphei-1)/2) {
        $robx0y0++;
      } else {
        if($robots[$j][1] > ($maphei-1)/2) {
          $robx0y1++;
        }
      }
    } else {
      if($robots[$j][0] > ($mapwid-1)/2) {
        if($robots[$j][1] < ($maphei-1)/2) {
          $robx1y0++;
        } else {
          if($robots[$j][1] > ($maphei-1)/2) {
            $robx1y1++;
          }
        }
      }
    }
  }
  if(max($robx0y0,$robx0y1,$robx1y0,$robx1y1) > 150) {
    return 1;
  } else {
    return 0;
  }
}
$handle = fopen ("php://stdin","r");
for($i=0;$i<8258;$i++) {
  for($j=0;$j<sizeof($robots);$j++) {
    $robots[$j][0] =
      ($robots[$j][0] + $robots[$j][2] + $mapwid) % $mapwid;
    $robots[$j][1] =
      ($robots[$j][1] + $robots[$j][3] + $maphei) % $maphei;
  }
  if(xmas_tst()) {
    print_map();
    print($i+1 . " seconds elapsed\n");
    $line = fgets($handle);
  }
}
fclose($handle);
?>

Skriv en kommentar