173 lines
3.5 KiB
Go
173 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
var gamma int64 = 0
|
|
var epsilon int64 = 0
|
|
var lines int = 0
|
|
var ones []int
|
|
var scannedLines []string
|
|
var e error
|
|
|
|
func checkErr(e error) {
|
|
if e != nil {
|
|
log.Fatal(e)
|
|
panic(e)
|
|
}
|
|
}
|
|
func main() {
|
|
ones = readTextFile()
|
|
gammaBinary, epsilonBinary := getMostAndLeast(ones, len(scannedLines), 1)
|
|
calcPower(gammaBinary, epsilonBinary)
|
|
|
|
oxygen := calcOxygen()
|
|
scrubber := calcCO2ScrubberRating()
|
|
|
|
rating := oxygen * scrubber
|
|
fmt.Print("Support Rating ")
|
|
fmt.Println(rating)
|
|
}
|
|
func calcCO2ScrubberRating() int64 {
|
|
scrub := findCO2Scrubber(scannedLines, 0)
|
|
scrubber, e := strconv.ParseInt(scrub, 2, 64)
|
|
checkErr(e)
|
|
return scrubber
|
|
}
|
|
func calcOxygen() int64 {
|
|
oxy := findOxgenRating(scannedLines, 0)
|
|
oxygen, e := strconv.ParseInt(oxy, 2, 64)
|
|
checkErr(e)
|
|
return oxygen
|
|
}
|
|
|
|
func findCO2Scrubber(lines []string, startingPoint int) string {
|
|
least := getLeastCommonAtPos(lines, startingPoint, 0)
|
|
resultLines := filterListByBitAtPos(lines, least, startingPoint)
|
|
if len(resultLines) == 1 {
|
|
return resultLines[0]
|
|
} else {
|
|
return findCO2Scrubber(resultLines, startingPoint+1)
|
|
}
|
|
}
|
|
|
|
func filterListByBitAtPos(lines []string, bit string, pos int) []string {
|
|
returnLines := make([]string, 0)
|
|
for _, val := range lines {
|
|
valueAtPos := val[pos : pos+1]
|
|
if valueAtPos == bit {
|
|
returnLines = append(returnLines, val)
|
|
}
|
|
}
|
|
|
|
return returnLines
|
|
}
|
|
func findOxgenRating(lines []string, startingPoint int) string {
|
|
most := getMostCommonAtPos(lines, startingPoint, 1)
|
|
resultLines := filterListByBitAtPos(lines, most, startingPoint)
|
|
if len(resultLines) == 1 {
|
|
return resultLines[0]
|
|
} else {
|
|
return findOxgenRating(resultLines, startingPoint+1)
|
|
}
|
|
}
|
|
func getLeastCommonAtPos(lines []string, pos int, onEqual int) string {
|
|
ones, zeroes := 0, 0
|
|
for _, val := range lines {
|
|
bit := val[pos : pos+1]
|
|
if bit == "1" {
|
|
ones++
|
|
} else {
|
|
zeroes++
|
|
}
|
|
}
|
|
if ones < zeroes {
|
|
return "1"
|
|
} else if ones > zeroes {
|
|
return "0"
|
|
} else {
|
|
return fmt.Sprint(onEqual)
|
|
}
|
|
}
|
|
func getMostCommonAtPos(lines []string, pos int, onEqual int) string {
|
|
ones, zeroes := 0, 0
|
|
for _, val := range lines {
|
|
bit := val[pos : pos+1]
|
|
if bit == "1" {
|
|
ones++
|
|
} else {
|
|
zeroes++
|
|
}
|
|
}
|
|
if ones > zeroes {
|
|
return "1"
|
|
} else if ones < zeroes {
|
|
return "0"
|
|
} else {
|
|
return fmt.Sprint(onEqual)
|
|
}
|
|
}
|
|
|
|
func calcPower(gammaBinary string, epsilonBinary string) {
|
|
gamma, e = strconv.ParseInt(gammaBinary, 2, 64)
|
|
checkErr(e)
|
|
epsilon, e = strconv.ParseInt(epsilonBinary, 2, 64)
|
|
checkErr(e)
|
|
fmt.Print("Power Level ")
|
|
fmt.Println(gamma * epsilon)
|
|
}
|
|
|
|
func getMostAndLeast(ones []int, lineNumber int, onEqual int) (string, string) {
|
|
most := ""
|
|
for _, value := range ones {
|
|
if value > lineNumber/2 {
|
|
most += "1"
|
|
} else if value < lineNumber/2 {
|
|
most += "0"
|
|
} else {
|
|
most += fmt.Sprint(onEqual)
|
|
}
|
|
}
|
|
least := ""
|
|
for _, value := range most {
|
|
if value == '0' {
|
|
least += "1"
|
|
}
|
|
if value == '1' {
|
|
least += "0"
|
|
}
|
|
}
|
|
return most, least
|
|
}
|
|
func readTextFile() []int {
|
|
var onelist []int
|
|
f, err := os.Open("input")
|
|
checkErr(err)
|
|
defer f.Close()
|
|
scanner := bufio.NewScanner(f)
|
|
for scanner.Scan() {
|
|
scannedText := scanner.Text()
|
|
scannedLines = append(scannedLines, scannedText)
|
|
lines++
|
|
}
|
|
onelist = getOnesList(scannedLines)
|
|
return onelist
|
|
}
|
|
func getOnesList(text []string) []int {
|
|
onelist := make([]int, len(text[0]))
|
|
for _, scannedText := range text {
|
|
|
|
for pos, char := range scannedText {
|
|
if char == '1' {
|
|
onelist[pos] = onelist[pos] + 1
|
|
}
|
|
}
|
|
}
|
|
return onelist
|
|
}
|