diff --git a/11/main.go b/11/main.go new file mode 100644 index 0000000..360f1da --- /dev/null +++ b/11/main.go @@ -0,0 +1,201 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" + "time" +) + +func mustAtoi(line string) int { + i, _ := strconv.Atoi(line) + return i +} + +func main() { + start := time.Now() + partOne() + duration := time.Since(start) + partTwo() + duration2 := time.Since(start) + fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration) +} + +func makeScanner(test bool) *bufio.Scanner { + var f *os.File + if test { + f, _ = os.Open("inputs/testinput") + } else { + f, _ = os.Open("inputs/input") + } + reader := bufio.NewReader(f) + return bufio.NewScanner(reader) +} + +type monkey struct { + items []int + operation string // either "plus", "times", or "square" + value int // ignored for "square" + test int // "divisible by " + testpass int // monkey to throw to if test passes + testfail int // monkey to throw to if test fails + inspections int +} + +func partOne() { + scanner := makeScanner(false) + + currentMonkey := 0 + monkeys := []monkey{} + + // parse monkeys + for scanner.Scan() { + line := scanner.Text() + switch { + case strings.HasPrefix(line, "M"): + currentMonkey = mustAtoi(strings.Trim(line, "Monkey :")) + monkeys = append(monkeys, monkey{items: make([]int, 0)}) + case strings.HasPrefix(line, " S"): + _, after, _ := strings.Cut(line, ":") + items := strings.Split(after, ",") + for _, i := range items { + monkeys[currentMonkey].items = append(monkeys[currentMonkey].items, mustAtoi(strings.TrimSpace(i))) + } + case strings.HasPrefix(line, " O"): + if strings.Contains(line, "+") { + monkeys[currentMonkey].operation = "plus" + l := strings.Split(line, " ") + monkeys[currentMonkey].value = mustAtoi(l[len(l)-1]) + } else if strings.Contains(line, "old * old") { + monkeys[currentMonkey].operation = "square" + } else if strings.Contains(line, "*") { + monkeys[currentMonkey].operation = "times" + l := strings.Split(line, " ") + monkeys[currentMonkey].value = mustAtoi(l[len(l)-1]) + } + case strings.HasPrefix(line, " T"): + l := strings.Split(line, " ") + monkeys[currentMonkey].test = mustAtoi(l[len(l)-1]) + case strings.HasPrefix(line, " If t"): + l := strings.Split(line, " ") + monkeys[currentMonkey].testpass = mustAtoi(l[len(l)-1]) + case strings.HasPrefix(line, " If f"): + l := strings.Split(line, " ") + monkeys[currentMonkey].testfail = mustAtoi(l[len(l)-1]) + } + } + for i := 0; i < 20; i++ { + for m := range monkeys { + monkeys[m].inspections += len(monkeys[m].items) + for _, i := range monkeys[m].items { + if monkeys[m].operation == "plus" { + i = (i + monkeys[m].value) / 3 + } + if monkeys[m].operation == "times" { + i = (i * monkeys[m].value) / 3 + } + if monkeys[m].operation == "square" { + i = (i * i) / 3 + } + if i%monkeys[m].test == 0 { + monkeys[monkeys[m].testpass].items = append(monkeys[monkeys[m].testpass].items, i) + } else { + monkeys[monkeys[m].testfail].items = append(monkeys[monkeys[m].testfail].items, i) + } + } + monkeys[m].items = []int{} + } + } + one, two := 0, 0 + for _, m := range monkeys { + if m.inspections > one && m.inspections > two { + one, two = two, m.inspections + } else if m.inspections > one { + one = m.inspections + } + } + fmt.Println(one * two) +} + +func partTwo() { + scanner := makeScanner(false) + + currentMonkey := 0 + monkeys := []monkey{} + + // parse monkeys + for scanner.Scan() { + line := scanner.Text() + switch { + case strings.HasPrefix(line, "M"): + currentMonkey = mustAtoi(strings.Trim(line, "Monkey :")) + monkeys = append(monkeys, monkey{items: make([]int, 0)}) + case strings.HasPrefix(line, " S"): + _, after, _ := strings.Cut(line, ":") + items := strings.Split(after, ",") + for _, i := range items { + monkeys[currentMonkey].items = append( + monkeys[currentMonkey].items, mustAtoi(strings.TrimSpace(i)), + ) + } + case strings.HasPrefix(line, " O"): + if strings.Contains(line, "+") { + monkeys[currentMonkey].operation = "plus" + l := strings.Split(line, " ") + monkeys[currentMonkey].value = mustAtoi(l[len(l)-1]) + } else if strings.Contains(line, "old * old") { + monkeys[currentMonkey].operation = "square" + } else if strings.Contains(line, "*") { + monkeys[currentMonkey].operation = "times" + l := strings.Split(line, " ") + monkeys[currentMonkey].value = mustAtoi(l[len(l)-1]) + } + case strings.HasPrefix(line, " T"): + l := strings.Split(line, " ") + monkeys[currentMonkey].test = mustAtoi(l[len(l)-1]) + case strings.HasPrefix(line, " If t"): + l := strings.Split(line, " ") + monkeys[currentMonkey].testpass = mustAtoi(l[len(l)-1]) + case strings.HasPrefix(line, " If f"): + l := strings.Split(line, " ") + monkeys[currentMonkey].testfail = mustAtoi(l[len(l)-1]) + } + } + common := 1 + for i := range monkeys { + common = common * monkeys[i].test + } + for j := 0; j < 10000; j++ { + for m := range monkeys { + monkeys[m].inspections += len(monkeys[m].items) + for _, i := range monkeys[m].items { + if monkeys[m].operation == "plus" { + i = i + monkeys[m].value + } + if monkeys[m].operation == "times" { + i = i * monkeys[m].value + } + if monkeys[m].operation == "square" { + i = i * i + } + if i%monkeys[m].test == 0 { + monkeys[monkeys[m].testpass].items = append(monkeys[monkeys[m].testpass].items, i%common) + } else { + monkeys[monkeys[m].testfail].items = append(monkeys[monkeys[m].testfail].items, i%common) + } + } + monkeys[m].items = []int{} + } + } + one, two := 0, 0 + for _, m := range monkeys { + if m.inspections > one && m.inspections > two { + one, two = two, m.inspections + } else if m.inspections > one { + one = m.inspections + } + } + fmt.Println(one * two) +} diff --git a/11/main.rs b/11/main.rs new file mode 100644 index 0000000..a49eaf0 --- /dev/null +++ b/11/main.rs @@ -0,0 +1,38 @@ +#![allow(dead_code)] +use std::fs::File; +use std::io; +use std::io::BufRead; +use std::path::Path; +use std::time::Instant; + +fn main() { + let now = Instant::now(); + part_one(); + let part_one_duration = now.elapsed(); + part_two(); + let part_two_duration = now.elapsed(); + println!( + "p1: {}ms, p2: {}ms", + part_one_duration.as_millis(), + (part_two_duration - part_one_duration).as_millis() + ); +} + +fn read_lines

(filename: P) -> io::Result>> +where + P: AsRef, +{ + // note that this discards a final newline + let file = File::open(filename)?; + Ok(io::BufReader::new(file).lines()) +} + +fn part_one() { + if let Ok(lines) = read_lines("./inputs/input") { + for line in lines { + // do stuff + } + } +} + +fn part_two() {} diff --git a/main.go.tmpl b/main.go.tmpl new file mode 100644 index 0000000..0d3fbc3 --- /dev/null +++ b/main.go.tmpl @@ -0,0 +1,50 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "time" +) + +func mustAtoi(line string) int { + i, _ := strconv.Atoi(line) + return i +} + +func main() { + start := time.Now() + partOne() + duration := time.Since(start) + partTwo() + duration2 := time.Since(start) + fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration) +} + +func makeScanner(test bool) *bufio.Scanner { + var f *os.File + if test { + f, _ = os.Open("inputs/testinput") + } else { + f, _ = os.Open("inputs/input") + } + reader := bufio.NewReader(f) + return bufio.NewScanner(reader) +} + +func partOne() { + scanner := makeScanner(false) + + for scanner.Scan() { + // line := scanner.Text() + } +} + +func partTwo() { + scanner := makeScanner(false) + + for scanner.Scan() { + // line := scanner.Text() + } +} diff --git a/new.sh b/new.sh index 46a9900..aabd6bb 100755 --- a/new.sh +++ b/new.sh @@ -14,5 +14,8 @@ if [ "${1}" != "" ]; then if [ ! -f "${padded}/main.rs" ]; then cp -n main.rs.tmpl ${padded}/main.rs fi + if [ ! -f "${padded}/main.go" ]; then + cp -n main.go.tmpl ${padded}/main.go + fi echo "https://adventofcode.com/2022/day/${1}" fi