DEV Community

Discussion on: AoC Day 6: Chronal Coordinates

Collapse
 
carlymho profile image
Carly Ho 🌈

PHP

Weird fact I learned about PHP in this puzzle: if you try and splice a very large array into an already very large multidimensional array, at a certain point PHP will throw an overflow error, but it doesn't happen with array_pad?

Anyway for the first one, I ended up just manually increasing the value by which I was expanding the grid and seeing at what point the number I was getting stopped changing, since "is this infinite" is hard to check for. The second part, I checked all the edge spaces to see if any of them were part of the central area, and if they weren't then I knew I could stop.

Part 1:

<?php
$grid;
$coordinates;
$zonesizes;

function expandgrid() {
  global $grid;
  global $coordinates;
  global $zonesizes;

  foreach ($grid as $row) {
    array_pad($row, 1, -1);
    array_pad($row, -1, -1);
  }
  array_pad($grid, 1, array_fill(0, count($grid[0]), -1));
  array_pad($grid, -1, array_fill(0, count($grid[0]), -1));

  $coordinates = array_map(function($x) {
    return array(
      'x' => $x['x']+1,
      'y' => $x['y']+1
    );
  }, $coordinates);

  for($i = 0; $i < count($grid); $i+=(count($grid)-1)) {
    for ($j = 0; $j < count($grid); $j+=(count($grid)-1)) {
      $distances = null;
      $zone = null;
      $distances = array_map(function($x) {
        global $j;
        global $i;
        return (abs($i - $x['y']) + abs($j - $x['x']));
      }, $coordinates);
      $shortest = min($distances);
      $counts = array_count_values($distances);
      if ($counts[$shortest] > 1) {
        $grid[$i][$j] = -1;
        break;
      }
      $zone = array_search($shortest, $distances);
      $grid[$i][$j] = $zone;
      $zonesizes[$zone] += 1;
    }
  }
}

$input = file_get_contents($argv[1]);
$coordinates = array_map(function($x) {
  $expl = explode(", ", $x);
  return array(
    'x' => intval($expl[0]),
    'y' => intval($expl[1])
  );
}, explode("\n", trim($input)));

$largest = array_reduce($coordinates, function($c, $i) {
  if ($c < $i['x']) {
    if ($i['x'] < $i['y']) {
      return $i['y'];
    }
    return $i['x'];
  }
  return $c;
}, 0);

$grid = array_fill(0, $largest+1, array_fill(0, $largest+1, -1));
$zonesizes = array_fill(0, count($coordinates), 0);

for($i = 0; $i < $largest+1; $i++) {
  for ($j = 0; $j < $largest+1; $j++) {
    $distances = null;
    $zone = null;
    $distances = array_map(function($x) {
      global $j;
      global $i;
      return (abs($i - $x['y']) + abs($j - $x['x']));
    }, $coordinates);
    $shortest = min($distances);
    $counts = array_count_values($distances);
    if ($counts[$shortest] > 1) {
      $grid[$i][$j] = -1;
      continue;
    }
    $zone = array_search($shortest, $distances);
    $grid[$i][$j] = $zone;
    $zonesizes[$zone] += 1;
  }
}

for ($k = 0; $k < 5000; $k++) {
  expandgrid();
}

$finalzones = $zonesizes;
$edge_top = array_unique($grid[0]);
$edge_bottom = array_unique($grid[count($grid)-1]);
$edge_left = array_unique(array_column($grid, 0));
$edge_right = array_unique(array_column($grid, 0));
$remove = array_values(array_unique(array_merge($edge_top, $edge_bottom, $edge_left, $edge_right)));

$finalzones = array_filter($finalzones, function($k) {
  global $remove;
  if (in_array($k, $remove)) {
    return 0;
  }
  return 1;
}, ARRAY_FILTER_USE_KEY);

echo max($finalzones);

die(1);

Part 2:

<?php
$grid;
$coordinates;
$size;

function expandgrid() {
  global $grid;
  global $coordinates;
  global $size;

  foreach ($grid as $row) {
    array_pad($row, 1, 0);
    array_pad($row, -1, 0);
  }
  array_pad($grid, 1, array_fill(0, count($grid[0]), 0));
  array_pad($grid, -1, array_fill(0, count($grid[0]), 0));

  $coordinates = array_map(function($x) {
    return array(
      'x' => $x['x']+1,
      'y' => $x['y']+1
    );
  }, $coordinates);

  for($i = 0; $i < count($grid); $i++) {
    for ($j = 0; $j < count($grid); $j++) {
      if ($i != 0 && $i != count($grid) && $j != 0 && $j != count($grid)) {
        continue;
      }
      $distances = null;
      $zone = null;
      $distances = array_map(function($x) {
        global $j;
        global $i;
        return (abs($i - $x['y']) + abs($j - $x['x']));
      }, $coordinates);
      if (array_sum($distances) < 10000) {
        $grid[$i][$j] = 1;
        $size += 1;
      }
    }
  }
}

$input = file_get_contents($argv[1]);
$coordinates = array_map(function($x) {
  $expl = explode(", ", $x);
  return array(
    'x' => intval($expl[0]),
    'y' => intval($expl[1])
  );
}, explode("\n", trim($input)));

$largest = array_reduce($coordinates, function($c, $i) {
  if ($c < $i['x']) {
    if ($i['x'] < $i['y']) {
      return $i['y'];
    }
    return $i['x'];
  }
  return $c;
}, 0);

$grid = array_fill(0, $largest+1, array_fill(0, $largest+1, 0));
$size = 0;

for($i = 0; $i < $largest+1; $i++) {
  for ($j = 0; $j < $largest+1; $j++) {
    $distances = null;
    $zone = null;
    $distances = array_map(function($x) {
      global $j;
      global $i;
      return (abs($i - $x['y']) + abs($j - $x['x']));
    }, $coordinates);
    if (array_sum($distances) < 10000) {
      $grid[$i][$j] = 1;
      $size += 1;
    }
  }
}

do {
  echo "expanding grid"."\n";
  $edge_top = array_unique($grid[0]);
  $edge_bottom = array_unique($grid[count($grid)-1]);
  $edge_left = array_unique(array_column($grid, 0));
  $edge_right = array_unique(array_column($grid, 0));
  $edges = array_merge($edge_top, $edge_bottom, $edge_left, $edge_right);
  expandgrid();
} while(array_sum($edges) > 0);

echo $size;

die(1);