mirror of
https://github.com/Noettore/AdventOfCode.git
synced 2025-10-14 19:26:39 +02:00
177 lines
4.0 KiB
Go
177 lines
4.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
type step struct {
|
|
ID string
|
|
time int
|
|
next []*step
|
|
prev []*step
|
|
}
|
|
|
|
func alreadyExecuted(executed []string, steps []*step) bool {
|
|
for _, s := range steps {
|
|
found := false
|
|
for _, e := range executed {
|
|
if e == s.ID {
|
|
found = true
|
|
}
|
|
}
|
|
if !found {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func alreadyInQueue(queue []string, s *step) bool {
|
|
for _, q := range queue {
|
|
if s.ID == q {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func main() {
|
|
var queue []string
|
|
var executionOrder []string
|
|
stepAddr := make(map[string]*step)
|
|
|
|
file, err := os.Open("./input_less")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer file.Close()
|
|
|
|
scan := bufio.NewScanner(file)
|
|
for scan.Scan() {
|
|
line := scan.Text()
|
|
|
|
splittedLine := strings.Split(line, " ")
|
|
currentID := splittedLine[1]
|
|
nextID := splittedLine[7]
|
|
|
|
currentStep, csExists := stepAddr[currentID]
|
|
nextStep, nsExists := stepAddr[nextID]
|
|
|
|
if !csExists {
|
|
cs := step{ID: currentID, time: int(currentID[0]) - 64}
|
|
stepAddr[currentID] = &cs
|
|
currentStep = &cs
|
|
}
|
|
if !nsExists {
|
|
ns := step{ID: nextID, time: int(nextID[0]) - 64}
|
|
stepAddr[nextID] = &ns
|
|
nextStep = &ns
|
|
}
|
|
|
|
currentStep.next = append(currentStep.next, nextStep)
|
|
nextStep.prev = append(nextStep.prev, currentStep)
|
|
}
|
|
|
|
for _, s := range stepAddr {
|
|
if len(s.prev) == 0 {
|
|
queue = append(queue, s.ID)
|
|
}
|
|
}
|
|
sort.Strings(queue)
|
|
i := 0
|
|
for i < len(queue) {
|
|
sPrev := stepAddr[queue[i]].prev
|
|
if len(sPrev) == 0 || alreadyExecuted(executionOrder, sPrev) {
|
|
executionOrder = append(executionOrder, queue[i])
|
|
for _, n := range stepAddr[queue[i]].next {
|
|
if !alreadyInQueue(queue, n) {
|
|
queue = append(queue, n.ID)
|
|
}
|
|
}
|
|
|
|
queue = append(queue[:i], queue[i+1:]...)
|
|
|
|
sort.Strings(queue)
|
|
i = 0
|
|
} else {
|
|
i++
|
|
}
|
|
}
|
|
|
|
fmt.Printf("Part One: %v\n", strings.Join(executionOrder, ""))
|
|
|
|
for _, s := range stepAddr {
|
|
if len(s.prev) == 0 {
|
|
queue = append(queue, s.ID)
|
|
fmt.Printf("Added in queue: %v\n", s.ID)
|
|
}
|
|
}
|
|
sort.Strings(queue)
|
|
|
|
currentTime := 0
|
|
var times [2]int
|
|
var workers [2]string
|
|
var availableSteps []*step
|
|
working := false
|
|
executionOrder = make([]string, 0)
|
|
for len(queue) > 0 || len(availableSteps) > 0 || working {
|
|
if len(queue) > 0 {
|
|
for i := 0; i < len(queue); i++ {
|
|
fmt.Printf("Analyzing from queue step %v\t i:%v\n", queue[i], i)
|
|
sPrev := stepAddr[queue[i]].prev
|
|
if len(sPrev) == 0 || alreadyExecuted(executionOrder, sPrev) {
|
|
availableSteps = append(availableSteps, stepAddr[queue[i]])
|
|
for _, n := range stepAddr[queue[i]].next {
|
|
if !alreadyInQueue(queue, n) {
|
|
queue = append(queue, n.ID)
|
|
fmt.Printf("Added in queue: %v\n", n.ID)
|
|
}
|
|
}
|
|
fmt.Printf("Added to availableSteps: %v\n", queue[i])
|
|
fmt.Printf("Removed from queue: %v\n", queue[i])
|
|
queue = append(queue[:i], queue[i+1:]...)
|
|
i = -1
|
|
}
|
|
}
|
|
}
|
|
sort.Slice(availableSteps, func(i, j int) bool {
|
|
return availableSteps[i].ID < availableSteps[j].ID
|
|
})
|
|
if len(availableSteps) > 0 || working {
|
|
for w := 0; w < len(workers); w++ {
|
|
if workers[w] == "" && len(availableSteps) > 0 {
|
|
workers[w] = availableSteps[0].ID
|
|
times[w] = availableSteps[0].time
|
|
working = true
|
|
fmt.Printf("Assigned to worker %v step %v\n", w, availableSteps[0].ID)
|
|
fmt.Printf("Removed from availableSteps: %v\n", availableSteps[0].ID)
|
|
availableSteps = availableSteps[1:]
|
|
} else if workers[w] != "" {
|
|
times[w]--
|
|
fmt.Printf("Decreased time of worker %v to %v\n", w, times[w])
|
|
if times[w] == 0 {
|
|
executionOrder = append(executionOrder, workers[w])
|
|
fmt.Printf("Worker %v has completed step %v\n", w, workers[w])
|
|
workers[w] = ""
|
|
times[w] = 0
|
|
//if times[0]+times[1]+times[2]+times[3]+times[4] == 0 {
|
|
if times[0]+times[1] == 0 {
|
|
working = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if working {
|
|
currentTime++
|
|
fmt.Printf("Increaset currentTime to %v\n", currentTime)
|
|
}
|
|
}
|
|
}
|
|
fmt.Printf("Part Two: %v\t%v\n", currentTime, executionOrder)
|
|
}
|