Distress signal

2022 advent day 13

package problems

import (
	"encoding/json"
	"fmt"
	"sort"

	"github.com/xxxx/advent/internal"
)

type day13 struct {
	lines []string
}

func Day13(part int, file string) int {

	in := day13{
		lines: internal.Read(file),
	}

	switch part {
	case 1:
		return in.part_one()
	case 2:
		return in.part_two()
	default:
		return 0
	}

}

type OrderedResult int

const (
	Unordered OrderedResult = iota
	Equal
	Ordered
)

func is_ordered(left []interface{}, right []interface{}) OrderedResult {

	for i := 0; i < len(left); i++ {
		if i > len(right)-1 {
			return Unordered
		}

		left_int, is_left_int := left[i].(float64)
		right_int, is_right_int := right[i].(float64)

		left_list, _ := left[i].([]interface{})
		right_list, _ := right[i].([]interface{})

		if is_left_int && is_right_int {
			if left_int != right_int {
				if left_int < right_int {
					return Ordered
				}
				if left_int > right_int {
					return Unordered
				}
			}
		} else if is_left_int {
			is_order := is_ordered([]interface{}{left_int}, right_list)
			if is_order == Equal {
				continue
			} else {
				return is_order
			}
		} else if is_right_int {
			is_order := is_ordered(left_list, []interface{}{right_int})
			if is_order == Equal {
				continue
			} else {
				return is_order
			}
		} else {
			is_order := is_ordered(left_list, right_list)
			if is_order == Equal {
				continue
			} else {
				return is_order
			}
		}
	}

	if len(left) == len(right) {
		return Equal
	}
	return Ordered
}

func (input day13) part_one() int {
	total_count := 0
	for i := 0; i <= len(input.lines)/3; i++ {
		left := []interface{}{}
		right := []interface{}{}
		json.Unmarshal([]byte(input.lines[i*3]), &left)
		json.Unmarshal([]byte(input.lines[i*3+1]), &right)
		order := is_ordered(left, right)
		if order == Equal || order == Ordered {
			total_count = total_count + i + 1
		}
	}
	return total_count
}

func (input day13) part_two() int {

	all_rows := [][]interface{}{
		{[]interface{}{float64(2)}},
		{[]interface{}{float64(6)}},
	}

	for i := 0; i <= len(input.lines)/3; i++ {
		left := []interface{}{}
		right := []interface{}{}
		json.Unmarshal([]byte(input.lines[i*3]), &left)
		json.Unmarshal([]byte(input.lines[i*3+1]), &right)
		all_rows = append(all_rows, left, right)
	}

	// https://www.geeksforgeeks.org/how-to-sort-a-slice-in-golang/
	sort.Slice(all_rows, func(i, j int) bool {
		left, right := all_rows[i], all_rows[j]
		order := is_ordered(left, right)
		if order == Equal || order == Ordered {
			return true
		}
		return false
	})

	total := 1
	for i, packet := range all_rows {
		if fmt.Sprint(packet) == "[[2]]" || fmt.Sprint(packet) == "[[6]]" {
			total = total * (i + 1)
		}
	}

	return total
}