13 "golang.org/x/exp/constraints"
16 func PanicOnErr(err error) {
22 const MaxInt = int(^uint(0) >> 1)
23 const MinInt = ^MaxInt
25 func Max[T constraints.Ordered](a, b T) T {
32 func Min[T constraints.Ordered](a, b T) T {
39 func SliceMinMax[T constraints.Ordered](slice []T) (*T, *T) {
45 for i, v := range slice {
56 func MustAtoi(s string) int {
57 v, err := strconv.Atoi(s)
62 // Returns key from map[T]int which has the max value
63 func MapFindMax(m interface{}) interface{} {
64 var maxK interface{} = nil
66 iter := reflect.ValueOf(m).MapRange()
69 v := int(iter.Value().Int())
78 // Returns key from map[T]int which has the min value
79 func MapFindMin(m interface{}) interface{} {
80 var minK interface{} = nil
82 iter := reflect.ValueOf(m).MapRange()
85 v := int(iter.Value().Int())
94 func Readfile(day int) string {
95 filename := fmt.Sprintf("day%02d/input.txt", day)
96 file, err := os.Open(filename)
100 reader := bufio.NewReader(file)
101 contents, err := io.ReadAll(reader)
104 return strings.TrimSuffix(string(contents), "\n")
107 func ParseToStruct(re *regexp.Regexp, input string, target interface{}) bool {
108 m := re.FindStringSubmatch(input)
115 for i, name := range re.SubexpNames() {
119 var field reflect.Value
124 } else if !useOffset {
125 panic("can't mix named and unnamed subexpressions")
127 field = reflect.ValueOf(target).Elem().Field(i - 1)
132 } else if useOffset {
133 panic("can't mix named and unnamed subexpressions")
135 field = reflect.ValueOf(target).Elem().FieldByName(name)
137 if field.Kind() == reflect.String {
138 field.SetString(m[i])
139 } else if field.Kind() == reflect.Int {
140 v, err := strconv.Atoi(m[i])
142 field.SetInt(int64(v))
143 } else if field.Kind() == reflect.Uint8 {
145 panic(fmt.Sprintf("expecting 1 char, got: %s", m[i]))
147 field.SetUint(uint64(m[i][0]))
149 panic(fmt.Sprintf("unknown kind: %s", field.Kind()))
155 func MustParseToStruct(re *regexp.Regexp, input string, target interface{}) {
156 if !ParseToStruct(re, input, target) {
157 panic(fmt.Errorf("failed to parse: %s", input))
161 func CharToLower(c byte) byte {
162 return strings.ToLower(string(c))[0]
165 func CharToUpper(c byte) byte {
166 return strings.ToUpper(string(c))[0]
169 func Contains(haystack []string, needle string) bool {
170 for _, s := range haystack {
178 func Abs[T constraints.Signed](x T) T {
185 func Gcd(x, y int) int {
186 if x <= 0 || y <= 0 {
187 panic(fmt.Errorf("invalid input: %d, %d", x, y))
199 func Sign[T constraints.Signed](x T) int {