Advertisement
Guest User

Untitled

a guest
Dec 9th, 2023
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 4.36 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "os"
  6.     "strings"
  7.     "bufio"
  8.     "sort"
  9. )
  10.  
  11. type TeleportValue struct {
  12.     node int
  13.     steps int
  14. }
  15.  
  16. type TeleportKey struct {
  17.     startNode int
  18.     startOrder int
  19. }
  20.  
  21. type CurrentT struct {
  22.     totalSteps int
  23.     key TeleportKey
  24. }
  25.  
  26. func main() {
  27.     args := os.Args[1:]
  28.  
  29.     file, err := os.Open(args[0])
  30.     if err != nil {
  31.         panic(err)
  32.     }
  33.     defer file.Close()
  34.  
  35.     s := bufio.NewScanner(file)
  36.     var inputs []string;
  37.     for s.Scan() {
  38.         line := s.Text()
  39.         if line != "" {
  40.             inputs = append(inputs, line)
  41.         }
  42.     }
  43.     order := inputs[0]
  44.  
  45.     // Generate string -> int mappings for better search performance
  46.     nextId := 1
  47.     mappings := make(map[string]int)
  48.     backMappings := make(map[int]string)
  49.     for i := 1; i < len(inputs); i++ {
  50.         line := inputs[i]
  51.         splitted := strings.Split(line, "=")
  52.         node := strings.TrimSpace(splitted[0])
  53.         mappings[node] = nextId
  54.         backMappings[nextId] = node
  55.         nextId++
  56.     }
  57.  
  58.     // Create initial graph
  59.     T := make(map[string][]string)
  60.     var currents []CurrentT
  61.     for i := 1; i < len(inputs); i++ {
  62.         line := inputs[i]
  63.         splitted := strings.Split(line, "=")
  64.         node := strings.TrimSpace(splitted[0])
  65.         leftPath := line[7:10]
  66.         rightPath := line[12:15]
  67.  
  68.         T[node] = make([]string, 2)
  69.         T[node][0] = leftPath
  70.         T[node][1] = rightPath
  71.  
  72.         if node[2] == 'A' {
  73.             currents = append(currents, CurrentT{0, TeleportKey{mappings[node], 0}})
  74.         }
  75.     }
  76.  
  77.     // Generate distances to the closest __Z node
  78.     teleports := make(map[TeleportKey]TeleportValue)
  79.     done := 0
  80.     maxStep := len(T) * len(order) // avoid inifnite loops
  81.     for node := range T {
  82.         done++
  83.         for i := 0; i < len(order); i++ {
  84.             currentNode := node
  85.             totalSteps := 0
  86.             idx := i
  87.             for true {
  88.                 // try to use precalculated results first
  89.                 v, find := teleports[TeleportKey{mappings[currentNode], idx}]
  90.                 if find {
  91.                     currentNode = backMappings[v.node]
  92.                     if totalSteps != -1 {
  93.                         totalSteps += v.steps
  94.                     } else {
  95.                         totalSteps = -1
  96.                     }
  97.                     break
  98.                 }
  99.  
  100.                 if idx == len(order) {
  101.                     idx = 0
  102.                 }
  103.  
  104.                 paths, _ := T[currentNode]
  105.                 if order[idx] == 'L' {
  106.                     currentNode = paths[0]
  107.                 }
  108.                 if order[idx] == 'R' {
  109.                     currentNode = paths[1]
  110.                 }
  111.                 idx++
  112.                 totalSteps++
  113.                 if currentNode[2] == 'Z' {
  114.                     break
  115.                 }
  116.  
  117.                 // if we exceed maxStep it means we are in the infinite loop
  118.                 if totalSteps > maxStep {
  119.                     totalSteps = -1
  120.                     currentNode = ""
  121.                     break
  122.                 }
  123.             }
  124.             teleports[TeleportKey{mappings[node], i}] = TeleportValue{mappings[currentNode], totalSteps}
  125.         }
  126.     }
  127.  
  128.     // Travers graph
  129.     nextPrintStep := 100 * 1000 * 1000 * 1000
  130.     nextPrint := 0
  131.     maxSteps := 1
  132.     expGoods := len(currents)
  133.     good := 0
  134.     run := true
  135.     for run {
  136.         if currents[0].totalSteps > nextPrint {
  137.             fmt.Println(nextPrint / nextPrintStep, currents)
  138.             nextPrint += nextPrintStep
  139.         }
  140.  
  141.         for i := range currents {
  142.             if currents[i].totalSteps >= maxSteps {
  143.                 continue
  144.             }
  145.             v, _ := teleports[currents[i].key]
  146.             currents[i].totalSteps += v.steps
  147.             currents[i].key.startNode = v.node
  148.             currents[i].key.startOrder = (v.steps + currents[i].key.startOrder) % len(order)
  149.  
  150.             if maxSteps < currents[i].totalSteps {
  151.                 maxSteps = currents[i].totalSteps
  152.                 good = 1
  153.             } else if maxSteps == currents[i].totalSteps {
  154.                 good++
  155.                 if good == expGoods {
  156.                     run = false
  157.                     break
  158.                 }
  159.             }
  160.         }
  161.  
  162.     }
  163.  
  164.     fmt.Println(currents, maxSteps)
  165. }
Tags: #aoc8
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement