Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- open(INPUT, "aoc_7_A_input.txt");
- @input = <INPUT>;
- close(INPUT);
- #The real deal
- @allsteps = ('A'..'Z');
- $finishline = 26;
- $numberofworkers = 5;
- $initialworktime = 60;
- #Description Example
- #@allsteps = ('A'..'F');
- #$finishline = 6;
- #$numberofworkers = 2;
- #$initialworktime = 0;
- ## PART 1
- $usteps = "";
- %stepcompleted = ();
- do {
- %lockedsteps = ();
- foreach $step (@input) {
- #Lock all steps whose previous step has not been completed.
- if ($step =~ m/^Step ([A-Z]) must be finished before step ([A-Z]) can begin.$/) {
- if ($stepcompleted{$1} != 1) {
- $lockedsteps{$2} = 1;
- }
- }
- }
- $nomore = 0;
- for ($z = 0; $z < $#allsteps + 1; $z++) {
- #Find first step whose is neither locked or completed.
- if (($lockedsteps{$allsteps[$z]} != 1)&&($stepcompleted{$allsteps[$z]} != 1)&&($nomore == 0)) {
- $stepcompleted{$allsteps[$z]} = 1;
- $usteps = $usteps . $allsteps[$z];
- $nomore = 1; #We only add one step at a time, then we must parse the locks again if any previous step become available.
- }
- }
- } until (length($usteps) == $finishline);
- # PART 2
- %stepcompleted = ();
- $steps = 0;
- $totaltime = 0;
- @workers = ();
- @workduration = ();
- do {
- %lockedsteps = ();
- foreach $step (@input) {
- #Lock all steps whose previous step has not been completed.
- if ($step =~ m/^Step ([A-Z]) must be finished before step ([A-Z]) can begin.$/) {
- if ($stepcompleted{$1} != 1) {
- $lockedsteps{$2} = 1;
- }
- }
- }
- for ($z = 0; $z < $#allsteps + 1; $z++) { #Scan for new work
- #Find a nonlocked noncompleted step
- if (($lockedsteps{$allsteps[$z]} != 1)&&($stepcompleted{$allsteps[$z]} != 1)) {
- #If we have free workers, start assign process
- if ($#workers < ($numberofworkers - 1)) {
- $alreadyinprogress = 0;
- foreach $wrk (@workers) {
- if ($wrk eq $allsteps[$z]) {
- $alreadyinprogress = 1; #Ensure we don't assign a work whose is already in progress by another elf.
- }
- }
- if ($alreadyinprogress == 0) {
- #Add work to a elf.
- push(@workers, $allsteps[$z]);
- push(@workduration, $initialworktime + int($z + 1));
- #print "$totaltime .. Started work on $allsteps[$z], ". ($initialworktime + int($z + 1)) . " left\n";
- }
- }
- }
- } #For loop - done scanning for new work
- for ($i = 0; $i < $numberofworkers; $i++) {
- if (($workduration[$i] > 0)&&(length($workers[$i]) > 0)) {
- $workduration[$i] = $workduration[$i] - 1; #decrease work in progress timer for all elfes that are currently working.
- }
- }
- #increase total time worked.
- $totaltime++;
- #print "$totaltime .. W1(".$workers[0].",".$workduration[0].") W2(".$workers[1].",".$workduration[1].") W3(".$workers[2].",".$workduration[2].") W4(".$workers[3].",".$workduration[3].") W5(".$workers[4].",".$workduration[4].")\n";
- for ($i = 0; $i < $numberofworkers; $i++) {
- #If there is an assigned work ($workers[$i] with a length larger than 0) with a time left of 0, then that work is now complete.
- if (($workduration[$i] == 0)&&(length($workers[$i]) > 0)) {
- #Add step to completed work, so we know which steps that should not be locked during next iteration.
- $stepcompleted{$workers[$i]} = 1;
- #Increase count of completed steps so we know when we are completely done.
- $steps++;
- #print "$totaltime .. Finished work on $workers[$i]\n";
- splice(@workers, $i, 1); #Delete work from the elf
- splice(@workduration, $i, 1);
- }
- }
- } until ($steps == $finishline);
- print "PART 1: ".$usteps."\n";
- print "PART 2: ".$totaltime."\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement