package main import ( "flag" "fmt" "log" "os" "runtime/pprof" "strconv" "strings" "time" "parnic.com/aoc2019/days" "parnic.com/aoc2019/utilities" ) type day interface { Parse() Num() int Part1() string Part2() string } const ( part1Header = utilities.ColorGreen + "Part1:" + utilities.TextReset part2Header = utilities.ColorGreen + "Part2:" + utilities.TextReset ) var ( flagPart1 = flag.Bool("part1", false, "whether to run part1 or not; if no flags are present, all parts are run") flagPart2 = flag.Bool("part2", false, "whether to run part2 or not; if no flags are present, all parts are run") flagCpuProfile = flag.String("cpuprofile", "", "write cpu profile to file") flagMemProfile = flag.String("memprofile", "", "write memory profile to file") ) var dayMap = []day{ &days.Day01{}, &days.Day02{}, &days.Day03{}, &days.Day04{}, &days.Day05{}, &days.Day06{}, &days.Day07{}, &days.Day08{}, &days.Day09{}, &days.Day10{}, &days.Day11{}, &days.Day12{}, &days.Day13{}, &days.Day14{}, &days.Day15{}, &days.Day16{}, &days.Day17{}, &days.Day18{}, &days.Day19{}, &days.Day20{}, &days.Day21{}, } func main() { flag.Parse() if *flagCpuProfile != "" { f, err := os.Create(*flagCpuProfile) if err != nil { log.Fatal(err) } defer f.Close() pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } arg := strconv.Itoa(len(dayMap)) flagArgs := flag.Args() if len(flagArgs) > 0 && len(flagArgs[0]) > 0 { arg = flagArgs[0] } if strings.ToLower(arg) == "all" { startTime := time.Now() for _, v := range dayMap { solve(v) } fmt.Printf("%sAll days completed in %v%s\n", utilities.ColorBrightBlack, time.Since(startTime), utilities.TextReset) } else { iArg, err := strconv.Atoi(arg) if err != nil { log.Fatalf("Invalid day " + utilities.ColorCyan + arg + utilities.TextReset) } if iArg < 0 || iArg > len(dayMap) { log.Fatalf("Unknown day " + utilities.ColorCyan + arg + utilities.TextReset) } solve(dayMap[iArg-1]) } if *flagMemProfile != "" { f, err := os.Create(*flagMemProfile) if err != nil { log.Fatal(err) } pprof.WriteHeapProfile(f) f.Close() } } func solve(d day) { fmt.Printf("%sDay %d%s\n", utilities.ColorCyan, d.Num(), utilities.TextReset) fmt.Printf("----%s\n", strings.Repeat("-", len(strconv.Itoa(d.Num())))) runPart1 := (!*flagPart1 && !*flagPart2) || *flagPart1 runPart2 := (!*flagPart1 && !*flagPart2) || *flagPart2 parseStart := time.Now() d.Parse() parseTime := time.Since(parseStart) part1Start := time.Now() var part1Text string if runPart1 { part1Text = d.Part1() } part1Time := time.Since(part1Start) if runPart1 { fmt.Println(part1Header) fmt.Println(">", part1Text) fmt.Println() } part2Start := time.Now() var part2Text string if runPart2 { part2Text = d.Part2() } part2Time := time.Since(part2Start) if runPart2 { fmt.Println(part2Header) fmt.Println(">", part2Text) fmt.Println() } fmt.Print(utilities.ColorBrightBlack) fmt.Println("Parsed in", parseTime) if runPart1 { fmt.Println("Part01 in", part1Time) } if runPart2 { fmt.Println("Part02 in", part2Time) } fmt.Println(utilities.TextReset) }