DEV Community

Discussion on: AoC Day 7: The Sum of Its Parts

Collapse
 
carlymho profile image
Carly Ho 🌈

PHP

ohhhhh my god this one took me a really long time for a variety of goofy reasons, mostly not understanding how things were supposed to work correctly

Part 1:

<?php
$input = file_get_contents($argv[1]);
$instructions = explode("\n", trim($input));
$steplist = str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
$steps = array();
$after = array();
foreach ($steplist as $s) {
  $after[$s] = array();
}
foreach ($instructions as $inst) {
  preg_match('/Step ([A-Z]) must be finished before step ([A-Z]) can begin./', $inst, $stepnames);
  array_push($after[$stepnames[2]], $stepnames[1]);
}

foreach($steplist as $i=>$step) {
  if (count($after[$step]) == 0) {
    array_push($steps, $step);
    unset($after[$step]);
    while (count($after)) {
      $next_candidates = array_filter($after, function($v, $k) {
        global $steps;
        if (array_intersect($v, $steps) == $v) {
          return true;
        }
        return false;
      }, ARRAY_FILTER_USE_BOTH);
      ksort($next_candidates);
      if ($next_candidates) {
        $next = array_keys($next_candidates)[0];
        array_push($steps, $next);
        unset($after[$next]);
      } else {
        break;
      }
    }
    break;
  }
}

echo join("", $steps);

die(1);

Part 2:

<?php
$input = file_get_contents($argv[1]);
$instructions = explode("\n", trim($input));
$steplist = str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
$times = array_combine($steplist, array_map(function($x) {
    return $x+61;
}, array_flip($steplist)));
$steps = array();
$after = array();
foreach ($steplist as $s) {
  $after[$s] = array();
}
foreach ($instructions as $inst) {
  preg_match('/Step ([A-Z]) must be finished before step ([A-Z]) can begin./', $inst, $stepnames);
  array_push($after[$stepnames[2]], $stepnames[1]);
}

$completed = array();
$workers = array_fill(0, 5, array(
    'step' => null,
    'start_time' => 0
));
$time = 0;
$next_candidates = array_filter($after, function($v, $k) {
    if (count($v) == 0) {
        return true;
    }
    return false;
}, ARRAY_FILTER_USE_BOTH);

ksort($next_candidates);

if ($next_candidates) {
    foreach(array_keys($next_candidates) as $n) {
        foreach ($workers as $i=>$worker) {
            if (!$worker['step']) {
                echo "assigning ".$n." to worker ".($i+1)." to start at ".$time."\n";
                $workers[$i]['step'] = $n;
                $workers[$i]['start_time'] = $time;
                unset($after[$n]);
                break;
            }
        }
    }
}
while (count($completed) < count($steplist)) {
    $availableWorkers = 0;
    foreach($workers as $i=>$w) {
        if ($w['step'] && $times[$w['step']]+$w['start_time']-1 == $time) {
            array_push($completed, $w['step']);
            echo "Step ".$w['step']." completed by worker ".($i+1)." at ".$time." seconds\n";
            $workers[$i]['step'] = null;
            $availableWorkers++;
            echo join("", $completed)."\n";
        }
    }
    $time++;
    if (count($completed) == count($steplist)) {
        break;
    }
    if (count($completed) > 0 && $availableWorkers > 0) {
        $next_candidates = array_filter($after, function($v, $k) {
            global $completed;
            if (array_intersect($v, $completed) == $v) {
                return true;
            }
            return false;
        }, ARRAY_FILTER_USE_BOTH);
        ksort($next_candidates);
        if ($next_candidates) {
            foreach(array_keys($next_candidates) as $n) {
                foreach ($workers as $i=>$worker) {
                    if (!$worker['step']) {
                        echo "assigning ".$n." to worker ".($i+1)." to start at ".$time."\n";
                        $workers[$i]['step'] = $n;
                        $workers[$i]['start_time'] = $time;
                        unset($after[$n]);
                        break;
                    }
                }
            }
        }
    }
}
echo $time;

die(1);