DAY 16 - Advent of Code 2020 w/ GoLang
Tags: go, adventofcode
Published: 2020-12-16 20:38:17

---
title: DAY 16 - Advent of Code 2020 w/ GoLang
published: true
description: AoC 2020 Day16 solutions in GoLang
tags: golang, AdventOfCode
series: Advent of Code 2020
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/gb6jnhz1didpnth3pbsw.jpeg
---
**DAY16:**
![dont like it](https://media.giphy.com/media/67SXeoc8RLwvqCwn2F/giphy.gif)

I just did not like the code I wrote for this one. Part one was fine and took about 5 lines of code (other than the input parsing). Part two had me flipping and filtering my matrix of fields and values in a lot of messy ways. Granted I could have done it cleaner but I did not revisit the code I should clean up. If I had some of the mapping and reducing functionality of JS, this would've been simpler. Not complaining that Go doesn't have those, but it is worth mentioning.

Oh.. also, my code will either return the correct answer or just hang.. 

```golang
package days

import (
	"fmt"
	"strings"

	inputs "../inputs"
)

// https://adventofcode.com/2020/day/16
// Sixteen : advent of code, day sixteen part1 and 2
func Sixteen() {

	/*
		This struct is being used for input

		type Tickets struct {
			Fields        map[string][]int
			Ticket        []int
			NearbyTickets [][]int
		}
	*/
	input := inputs.Day16

	fmt.Print("(Part 1) - Sum of all bad field values: ")
	fmt.Println(sumAllInvalidValuesOnNearbyTickets(input))

	fmt.Println("(Part 2) - : ")

	withValidTicketsOnly := tossBadTickets(input)
	matchingFieldNames := getFieldNames(withValidTicketsOnly)

	departureTotal := 1

	for i, fieldName := range matchingFieldNames {
		if strings.Contains(fieldName, "departure") {
			departureTotal *= withValidTicketsOnly.Ticket[i]
		}
	}

	fmt.Println(departureTotal)
}

func sumAllInvalidValuesOnNearbyTickets(tickets inputs.Tickets) int {
	badSum := 0

	for _, ticket := range tickets.NearbyTickets {
		for _, fieldValue := range ticket {
			if !validForAnyField(fieldValue, tickets) {
				badSum = badSum + fieldValue
			}
		}
	}

	return badSum
}

func validForAnyField(fieldValue int, tickets inputs.Tickets) bool {
	isIt := false

	for _, ranges := range tickets.Fields {
		if (fieldValue >= ranges[0] && fieldValue <= ranges[1]) || (fieldValue >= ranges[2] && fieldValue <= ranges[3]) {
			isIt = true
			break
		} else {
			isIt = false
		}
	}

	return isIt
}

func tossBadTickets(tickets inputs.Tickets) inputs.Tickets {
	toReturn := inputs.Tickets{}
	toReturn.Fields = tickets.Fields
	toReturn.Ticket = tickets.Ticket
	toReturn.NearbyTickets = [][]int{}

	for _, ticket := range tickets.NearbyTickets {
		fullTicketMatch := true
		for _, fieldValue := range ticket {
			if !validForAnyField(fieldValue, tickets) {
				fullTicketMatch = false
				break
			}
		}
		if fullTicketMatch {
			toReturn.NearbyTickets = append(toReturn.NearbyTickets, ticket)
		}
	}

	return toReturn
}

func getFieldName(column []int, fields map[string][]int) []string {
	allMatchingFieldNames := []string{}

	for fieldName, ranges := range fields {
		fullMatch := true
		for _, val := range column {
			if !((val >= ranges[0] && val <= ranges[1]) || (val >= ranges[2] && val <= ranges[3])) {
				fullMatch = false
				break
			}
		}

		if fullMatch {
			allMatchingFieldNames = append(allMatchingFieldNames, fieldName)
		}
	}

	return allMatchingFieldNames
}

func getFieldNames(tickets inputs.Tickets) []string {
	columns := [][]int{}
	column := []int{}

	for col := 0; col < len(tickets.NearbyTickets[0]); col++ {
		column = []int{}
		for row := 0; row < len(tickets.NearbyTickets); row++ {
			column = append(column, tickets.NearbyTickets[row][col])
		}
		columns = append(columns, column)
	}

	matchingFieldNames := [][]string{}

	for _, col := range columns {
		matchingFieldNames = append(matchingFieldNames, getFieldName(col, tickets.Fields))
	}

	return filterFieldNames(matchingFieldNames)
}

func filterFieldNames(allMatchingFieldNames [][]string) []string {
	filtered := []string{}

	for !allSizeOne(allMatchingFieldNames) {
		for i, rows := range allMatchingFieldNames {
			for j, col := range rows {

				anotherOfMe := false

				for k, rowsInner := range allMatchingFieldNames {
					for y, colInner := range rowsInner {
						if y != j && k != y {
							if col == colInner {
								anotherOfMe = true
							}
						}
					}
				}

				if !anotherOfMe {
					allMatchingFieldNames[i] = []string{col}
				}
			}
		}
	}

	for _, fieldNameAsSlice := range allMatchingFieldNames {
		filtered = append(filtered, fieldNameAsSlice[0])
	}

	return filtered
}

func allSizeOne(doubleSlice [][]string) bool {
	res := true

	for _, v := range doubleSlice {
		if len(v) > 1 {
			res = false
			break
		}
	}

	return res
}

```

[Link to Github source file](https://github.com/dizveloper/AdventOfCode/blob/main/2020/days/day16.go)