123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- package main
- import (
- "bufio"
- "fmt"
- "log"
- "os"
- "regexp"
- "strconv"
- "strings"
- )
- type Bag struct {
- count int64
- name string
- }
- func getBags(line string, bags map[string][]Bag) {
- bugNameRegex := regexp.MustCompile(`(\w+\s\w+) bags contain `)
- result := bugNameRegex.FindStringSubmatch(line)
- if len(result) != 2 {
- return
- }
- bagName := result[1]
- bugContainsRegex := regexp.MustCompile(`(\d+)\s(\w+\s\w+)`)
- subStrings := strings.Split(line, ", ")
- for _, sub := range subStrings {
- subResult := bugContainsRegex.FindStringSubmatch(sub)
- if len(subResult) != 3 {
- continue
- }
- number, err := strconv.ParseInt(subResult[1], 10, 32)
- if err != nil {
- continue
- }
- bags[bagName] = append(bags[bagName], Bag{name: subResult[2], count: number})
- }
- }
- func readFile(filePath string, bags map[string][]Bag) {
- file, err := os.Open(filePath)
- if err != nil {
- log.Fatalf("failed to open")
- }
- scanner := bufio.NewScanner(file)
- for scanner.Scan() {
- line := scanner.Text()
- getBags(line, bags)
- }
- if err := scanner.Err(); err != nil {
- log.Println(err)
- }
- }
- func checkBag(phrase string, bagName string, bags map[string][]Bag) bool {
- for _, bag := range bags[bagName] {
- if bag.name == phrase {
- return true
- }
- if checkBag(phrase, bag.name, bags) {
- return true
- }
- }
- return false
- }
- func countBagsContaining(phrase string, bags map[string][]Bag) int {
- count := 0
- for name, _ := range bags {
- if name == phrase {
- continue
- }
- if checkBag(phrase, name, bags) {
- count++
- }
- }
- return count
- }
- func countBagsIn(bag string, bags map[string][]Bag) int64 {
- var count int64 = 0
- for _, value := range bags[bag] {
- count += value.count
- count += value.count * countBagsIn(value.name, bags)
- }
- return count
- }
- func main() {
- if len(os.Args) < 2 {
- log.Fatal("You need to specify a file!")
- }
- var bags = make(map[string][]Bag)
- readFile(os.Args[1], bags)
- fmt.Println("Part1:", countBagsContaining("shiny gold", bags))
- fmt.Println("Part2:", countBagsIn("shiny gold", bags))
- }
|