diff --git a/2020/day05/main.go b/2020/day05/main.go old mode 100644 new mode 100755 diff --git a/2020/day06/input b/2020/day06/input old mode 100644 new mode 100755 diff --git a/2020/day12/input b/2020/day12/input old mode 100644 new mode 100755 diff --git a/2020/day13/input b/2020/day13/input new file mode 100755 index 0000000..d2a3669 --- /dev/null +++ b/2020/day13/input @@ -0,0 +1,2 @@ +1006605 +19,x,x,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,883,x,x,x,x,x,x,x,23,x,x,x,x,13,x,x,x,17,x,x,x,x,x,x,x,x,x,x,x,x,x,797,x,x,x,x,x,x,x,x,x,41,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,29 \ No newline at end of file diff --git a/2020/day13/main.go b/2020/day13/main.go new file mode 100755 index 0000000..a373ccc --- /dev/null +++ b/2020/day13/main.go @@ -0,0 +1,131 @@ +package main + +import ( + "fmt" + "sort" + "strings" + + h "git.bullercodeworks.com/brian/adventofcode/helpers" +) + +func main() { + fmt.Println("# Day 13") + inp := h.StdinToStringSlice() + if len(inp) != 2 { + fmt.Println("Invalid input") + return + } + part1(inp) + part2Rework(inp) +} + +func part1(inp []string) { + me := h.Atoi(inp[0]) + pts := strings.Split(inp[1], ",") + earliest := h.MAX_INT + var earliestBus int + for k := range pts { + if pts[k] == "x" { + continue + } + bus := h.Atoi(pts[k]) + div := me / bus + wait := (bus * (div + 1)) - me + if earliest > wait { + earliest = wait + earliestBus = bus + } + } + fmt.Println("## Part 1") + fmt.Printf("Answer %d\n\n", earliest*earliestBus) +} + +// This may not work with all inputs... +func part2Rework(inp []string) { + pts := strings.Split(inp[1], ",") + buses := make(map[int]int) + var keys []int + for k, v := range pts { + if v == "x" { + continue + } + keys = append(keys, k) + buses[k] = h.Atoi(v) + } + for _, v := range buses { + if !h.IsPrime(v) { + fmt.Println("Not all buses are prime numbers... This solution _may not work_. Or it may still.", h.SHRUG) + break + } + } + res := 0 + mins := buses[keys[0]] + for k := 1; k < len(keys); k++ { + wrk := keys[k] + bus := buses[wrk] + for (res+wrk)%bus != 0 { + res = res + mins + } + mins = mins * bus + } + fmt.Println("## Part 2") + fmt.Printf("Answer: %d\n", res) +} + +/* + 7 13 59 31 19 +1068781 D . . . . +1068782 . D . . . +1068783 . . . . . +1068784 . . . . . +1068785 . . D . . +1068786 . . . . . +1068787 . . . D . +1068788 D . . . D + +7 = 0 +13 = 1 +59 = 4 +31 = 6 +19 = 7 + +*/ + +// I think this will get there... Eventually... Maybe... +func part2(inp []string) { + pts := strings.Split(inp[1], ",") + wrk := make(map[int]int) + var keys []int + var vals []int + var highK, highV int + for k := range pts { + if pts[k] == "x" { + continue + } + keys = append(keys, k) + vals = append(vals, wrk[k]) + wrk[k] = h.Atoi(pts[k]) + if wrk[k] > highV { + highK = k + highV = wrk[k] + } + } + sort.Sort(sort.Reverse(sort.IntSlice(keys))) + sort.Sort(sort.Reverse(sort.IntSlice(keys))) + target := highV - highK + for !checkMap(target, keys, wrk) { + target = target + highV + } + + fmt.Println("## Part 2") + fmt.Printf("Answer: %d\n", target) +} + +func checkMap(target int, keys []int, all map[int]int) bool { + for _, k := range keys { + if (target+k)%all[k] != 0 { + return false + } + } + return true +} diff --git a/2020/day13/testinput b/2020/day13/testinput new file mode 100755 index 0000000..e473080 --- /dev/null +++ b/2020/day13/testinput @@ -0,0 +1,2 @@ +939 +7,13,x,x,59,x,31,19 \ No newline at end of file diff --git a/2020/day13/testinput2 b/2020/day13/testinput2 new file mode 100755 index 0000000..b5b6d6c --- /dev/null +++ b/2020/day13/testinput2 @@ -0,0 +1,2 @@ +1 +1789,37,47,1889 \ No newline at end of file diff --git a/go.mod b/go.mod index f907069..355a45b 100644 --- a/go.mod +++ b/go.mod @@ -3,20 +3,13 @@ module git.bullercodeworks.com/brian/adventofcode go 1.13 require ( - github.com/BurntSushi/toml v0.3.1 // indirect github.com/br0xen/termbox-screen v0.0.0-20190712162752-c91f70ac38c6 github.com/br0xen/termbox-util v0.0.0-20190325151025-c168c0df31ca - github.com/br0xen/user-config v0.0.0-20170914134719-16e743ec93a2 // indirect - github.com/casimir/xdg-go v0.0.0-20160329195404-372ccc2180da // indirect github.com/fatih/color v1.7.0 github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 github.com/go-gl/glfw v0.0.0-20191125211704-12ad95a8df72 - github.com/google/uuid v1.1.1 // indirect - github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 // indirect github.com/mattn/go-colorable v0.1.4 // indirect github.com/mattn/go-isatty v0.0.10 // indirect github.com/mattn/go-runewidth v0.0.7 // indirect - github.com/nanobox-io/golang-scribble v0.0.0-20190309225732-aa3e7c118975 // indirect - github.com/nlopes/slack v0.6.0 // indirect github.com/nsf/termbox-go v0.0.0-20190817171036-93860e161317 ) diff --git a/helpers/helpers.go b/helpers/helpers.go index a4e793e..aa73db1 100644 --- a/helpers/helpers.go +++ b/helpers/helpers.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "log" + "math" "os" "strconv" "strings" @@ -25,9 +26,11 @@ const ( MAX_INT = int(^uint(0) >> 1) MIN_INT = -MAX_INT - 1 + + SHRUG = "¯\\_(ツ)_/¯" ) -// Find the greatest common denominator +// Gcd Finds the greatest common denominator func Gcd(x, y int) int { for y != 0 { x, y = y, x%y @@ -35,7 +38,7 @@ func Gcd(x, y int) int { return x } -// Find the least common multiple, using gcd +// Lcm finds the least common multiple, using gcd func Lcm(a, b int, integers ...int) int { result := a * b / Gcd(a, b) for i := 0; i < len(integers); i++ { @@ -44,6 +47,7 @@ func Lcm(a, b int, integers ...int) int { return result } +// AbsInt returns the absolute value of i func AbsInt(i int) int { if i < 0 { return i * -1 @@ -51,6 +55,7 @@ func AbsInt(i int) int { return i } +// ArgIsSet return true if an argument with the asked for key is present func ArgIsSet(a string) bool { for i := range os.Args { if os.Args[i] == a || strings.HasPrefix(os.Args[i], a+"=") { @@ -60,6 +65,7 @@ func ArgIsSet(a string) bool { return false } +// GetArgValue returns the argument with the asked for key or "" func GetArgValue(a string) string { for i := range os.Args { if strings.HasPrefix(os.Args[i], a+"=") { @@ -69,6 +75,7 @@ func GetArgValue(a string) string { return "" } +// GetArgNumber returns the asked for argument position or "" func GetArgNumber(i int) string { if len(os.Args) > i { return os.Args[i] @@ -76,6 +83,7 @@ func GetArgNumber(i int) string { return "" } +// OptArgNumber returns either the asked for argument position or the passed default func OptArgNumber(i int, def string) string { if len(os.Args) > i { return os.Args[i] @@ -83,6 +91,7 @@ func OptArgNumber(i int, def string) string { return def } +// StdinToIntSlice reads from stdin and returns it as an int slice func StdinToIntSlice() []int { var ret []int st := StdinToStringSlice() @@ -92,6 +101,7 @@ func StdinToIntSlice() []int { return ret } +// StdinToStringSlice reads from stdin and returns it as a string slice func StdinToStringSlice() []string { var input []string scanner := bufio.NewScanner(os.Stdin) @@ -101,10 +111,12 @@ func StdinToStringSlice() []string { return input } +// StdinToCoordMap reads stdin and returns it as a CoordByteMap func StdinToCoordMap() CoordByteMap { return StringSliceToCoordByteMap(StdinToStringSlice()) } +// Atoi is basically redundant func Atoi(i string) int { var ret int var err error @@ -114,10 +126,12 @@ func Atoi(i string) int { return ret } +// Itoa is basically redundant func Itoa(i int) string { return strconv.Itoa(i) } +// StdinToString reads from stdin and returns a string func StdinToString() string { var input string scanner := bufio.NewScanner(os.Stdin) @@ -127,14 +141,17 @@ func StdinToString() string { return input } +// FileToStringSlice takes a file and returns it as a slice of strings func FileToStringSlice(fn string) []string { return strings.Split(string(FileToBytes(fn)), "\n") } +// FileToString reads a file and returns it as a string func FileToString(fn string) string { return string(FileToBytes(fn)) } +// FileToBytes reads a file and returns it as a slice of bytes func FileToBytes(fn string) []byte { var c []byte var err error @@ -146,6 +163,7 @@ func FileToBytes(fn string) []byte { return c } +// PrintProgress is for outputting a progress bar func PrintProgress(curr, total int) { pct := int(float64(curr)/float64(total)) * 100 for i := 0; i < 100; i += 10 { @@ -155,6 +173,7 @@ func PrintProgress(curr, total int) { } } +// StringPermutations takes a string and returns all permutations of it func StringPermutations(str string) []string { perms := stringPermHelper(str, 0) var wrk []string @@ -186,6 +205,7 @@ func stringPermHelper(str string, i int) []string { return ret } +// IntPermutations takes a slice of ints and returns all permutations of it func IntPermutations(inp []int) [][]int { perms := intPermHelper(inp, 0) var wrk [][]int @@ -219,6 +239,7 @@ func intPermHelper(inp []int, i int) [][]int { return ret } +// IntSlicesAreEqual takes two int slices and returns if they are equal func IntSlicesAreEqual(s1 []int, s2 []int) bool { if len(s1) != len(s2) { return false @@ -231,6 +252,8 @@ func IntSlicesAreEqual(s1 []int, s2 []int) bool { return true } +// StringSliceContains takes a string slice and a string and return true +// if the string is in the slice func StringSliceContains(h []string, n string) bool { for _, v := range h { if v == n { @@ -239,3 +262,13 @@ func StringSliceContains(h []string, n string) bool { } return false } + +// IsPrime takes a number and return true if that number is prime +func IsPrime(value int) bool { + for i := 2; i <= int(math.Floor(float64(value)/2)); i++ { + if value%i == 0 { + return false + } + } + return value > 1 +}