advent2022

Advent of Code 2022 Solutions
git clone git://bsandro.tech/advent2022
Log | Files | Refs | README | LICENSE

main.go (2492B)


      1 package main
      2 
      3 import (
      4 	"encoding/json"
      5 	"fmt"
      6 	"log"
      7 	"os"
      8 	"sort"
      9 	"strings"
     10 )
     11 
     12 type Packets []any
     13 
     14 func (p Packets) Len() int { return len(p) }
     15 func (p Packets) Swap(i, j int) {
     16 	p[i], p[j] = p[j], p[i]
     17 }
     18 func (p Packets) Less(i, j int) bool {
     19 	cmp, _ := Compare(p[i], p[j])
     20 	return cmp
     21 }
     22 
     23 func main() {
     24 	if len(os.Args) > 1 {
     25 		day13(os.Args[1])
     26 	} else if len(os.Args) == 1 {
     27 		fmt.Printf("usage: %s inputfile.txt\n", os.Args[0])
     28 	} else {
     29 		fmt.Println("No input data")
     30 	}
     31 }
     32 
     33 func day13(input_file string) {
     34 	fmt.Printf("day 13 input filename: %s\n", input_file)
     35 	input, err := os.ReadFile(input_file)
     36 	if err != nil {
     37 		log.Fatal(err)
     38 	}
     39 	pairs := strings.Split(string(input), "\n\n")
     40 	sum := 0
     41 	var packets Packets
     42 	for i, p := range pairs {
     43 		pair := strings.Split(p, "\n")
     44 		if len(pair) < 2 {
     45 			log.Fatal("Invalid pair", pair)
     46 		}
     47 		var p1, p2 any
     48 		if err = json.Unmarshal([]byte(pair[0]), &p1); err != nil {
     49 			log.Fatal(err)
     50 		}
     51 		if err = json.Unmarshal([]byte(pair[1]), &p2); err != nil {
     52 			log.Fatal(err)
     53 		}
     54 		res, _ := Compare(p1, p2)
     55 		if res {
     56 			sum += i + 1
     57 		}
     58 		packets = append(packets, p1, p2)
     59 	}
     60 	m1, m2 := "[[2]]", "[[6]]"
     61 	var marker1, marker2 any
     62 	json.Unmarshal([]byte(m1), &marker1)
     63 	json.Unmarshal([]byte(m2), &marker2)
     64 	packets = append(packets, marker1, marker2)
     65 
     66 	sort.Sort(packets)
     67 
     68 	v1, v2 := 0, 0
     69 	for i, p := range packets {
     70 		j, err := json.Marshal(p)
     71 		if err != nil {
     72 			log.Fatal(err)
     73 		}
     74 		if string(j) == m1 {
     75 			v1 = i + 1
     76 		}
     77 		if string(j) == m2 {
     78 			v2 = i + 1
     79 		}
     80 	}
     81 
     82 	fmt.Println("Part 1:", sum)
     83 	fmt.Println("Part 2:", v1*v2)
     84 }
     85 
     86 // returns (result, continue)
     87 func Compare(p1, p2 any) (bool, bool) {
     88 	p1ar, p2ar := IsArray(p1), IsArray(p2)
     89 	if !p1ar && !p2ar {
     90 		p1n, p2n := int(p1.(float64)), int(p2.(float64))
     91 		return p1n < p2n, p1n == p2n
     92 	} else if p1ar && p2ar {
     93 		return CompareArrays(p1.([]any), p2.([]any))
     94 	} else if p1ar {
     95 		return CompareArrays(p1.([]any), []any{p2})
     96 	} else if p2ar {
     97 		return CompareArrays([]any{p1}, p2.([]any))
     98 	}
     99 	log.Fatal("Invalid something")
    100 	return false, false
    101 }
    102 
    103 func CompareArrays(p1, p2 []any) (bool, bool) {
    104 	for i := 0; i < len(p1); i++ {
    105 		if i >= len(p2) {
    106 			return false, false
    107 		}
    108 		res, cont := Compare(p1[i], p2[i])
    109 		if !cont {
    110 			return res, false
    111 		}
    112 	}
    113 	return len(p1) < len(p2), len(p1) >= len(p2)
    114 }
    115 
    116 func IsArray(v any) bool {
    117 	switch v.(type) {
    118 	case float64:
    119 		return false
    120 	case []any:
    121 		return true
    122 	default:
    123 		log.Fatal("unknown value", v)
    124 		//return true
    125 	}
    126 	return false
    127 }