-
Notifications
You must be signed in to change notification settings - Fork 1
/
19.go
111 lines (95 loc) · 2.13 KB
/
19.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main
import (
"bufio"
"fmt"
"log"
"os"
"regexp"
"strings"
)
func format(text string) []string {
return strings.Split(text, " => ")
}
type queueItem struct {
molecule string
steps int
}
func main() {
file, err := os.Open("input/19.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
var element string
doneWithElements := false
medicine := make(map[string][]string)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
text := scanner.Text()
// detect break in input
if len(text) == 0 {
doneWithElements = true
continue
}
if doneWithElements {
element = text
} else {
replacement := format(text)
from, to := replacement[0], replacement[1]
if value, found := medicine[from]; found {
medicine[from] = append(value, to)
} else {
medicine[from] = []string{to}
}
}
}
tmpMap := make(map[string]int)
for i := 0; i < len(element); i++ {
j := i
var lookup string
if i+1 < len(element) && strings.ContainsRune("abcdefghijklmnopqrstuvqxyz", rune(element[i+1])) {
lookup = element[i : i+2]
i++
} else {
lookup = element[i : i+1]
}
if to, found := medicine[lookup]; found {
for _, v := range to {
tmpMap[element[:j]+v+element[i+1:]] = 0
}
}
}
possibilities := 0
for range tmpMap {
possibilities++
}
fmt.Println(possibilities)
// part 2
reversed := make(map[string]string)
for key, value := range medicine {
for _, item := range value {
reversed[item] = key
}
}
queue := []queueItem{queueItem{element, 0}}
for {
if len(queue) == 0 {
break
}
var item queueItem
item, queue = queue[0], queue[1:]
if item.molecule == "e" {
fmt.Println(item.steps)
break
}
for key, value := range reversed {
re := regexp.MustCompile(key)
res := re.FindAllStringIndex(item.molecule, -1)
for _, found := range res {
newMolecule := item.molecule[:found[0]] + value + item.molecule[found[1]:]
// depth-first-search
queue = append([]queueItem{queueItem{newMolecule, item.steps + 1}}, queue...)
}
}
}
}