main.go (1728B)
1 package main 2 3 import ( 4 "bufio" 5 "fmt" 6 "log" 7 "os" 8 ) 9 10 func main() { 11 if len(os.Args) > 1 { 12 day03(os.Args[1]) 13 } else if len(os.Args) == 1 { 14 fmt.Printf("usage: %s inputfile.txt\n", os.Args[0]) 15 } else { 16 fmt.Println("No input data") 17 } 18 } 19 20 func day03(input_file string) { 21 fmt.Printf("day 03 input filename: %s\n", input_file) 22 input, err := os.Open(input_file) 23 if err != nil { 24 log.Fatal(err) 25 } 26 defer input.Close() 27 scanner := bufio.NewScanner(input) 28 var sum1 int32 = 0 29 var sum2 int32 = 0 30 var group []string 31 for scanner.Scan() { 32 rucksack := scanner.Text() 33 item1 := compareCompartments(rucksack) 34 sum1 += getItemScore(item1) 35 group = append(group, rucksack) 36 if len(group) == 3 { 37 item2 := compareRucksacks(group) 38 sum2 += getItemScore(item2) 39 group = nil 40 } 41 } 42 if err = scanner.Err(); err != nil { 43 log.Fatal(err) 44 } 45 46 fmt.Println("Part 1:", sum1) 47 fmt.Println("Part 2:", sum2) 48 } 49 50 func getItemScore(item int32) int32 { 51 // unicode rune to fantasy scoring 52 if item >= 97 { // lowercase 53 return item - 96 54 } else if item >= 65 { // uppercase 55 return item - 38 56 } 57 return 0 58 } 59 60 func compareCompartments(in string) int32 { 61 strLen := len(in) 62 if strLen%2 != 0 { 63 log.Fatal("invalid input string") 64 } 65 66 comp1 := in[0 : strLen/2] 67 comp2 := in[strLen/2:] 68 69 // only 1 misplaced item per rucksack 70 for _, rune1 := range comp1 { 71 for _, rune2 := range comp2 { 72 if rune1 == rune2 { 73 return rune1 74 } 75 } 76 } 77 78 return 0 79 } 80 81 func compareRucksacks(group []string) int32 { 82 if len(group) != 3 { 83 log.Fatal("Group size has to be 3") 84 } 85 for _, r1 := range group[0] { 86 for _, r2 := range group[1] { 87 for _, r3 := range group[2] { 88 if r1 == r2 && r2 == r3 { 89 return r1 90 } 91 } 92 } 93 } 94 return 0 95 }