feat: add main code
This commit is contained in:
122
2021/day03/main.go
Normal file
122
2021/day03/main.go
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseInput(file string) []string {
|
||||||
|
content, err := os.ReadFile(file)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to read input file: %v", err)
|
||||||
|
}
|
||||||
|
return strings.Split(strings.TrimSpace(string(content)), "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func PartOne(data []string) int {
|
||||||
|
bitlen := len(data[0])
|
||||||
|
ones := make([]int, bitlen)
|
||||||
|
|
||||||
|
for _, line := range data {
|
||||||
|
for i := range bitlen {
|
||||||
|
if line[i] == '1' {
|
||||||
|
ones[i]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var gamma int
|
||||||
|
total := len(data)
|
||||||
|
for idx := range bitlen {
|
||||||
|
gamma <<= 1
|
||||||
|
if ones[idx] > total-ones[idx] {
|
||||||
|
gamma |= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mask := (1 << bitlen) - 1
|
||||||
|
epsilon := mask ^ gamma
|
||||||
|
return gamma * epsilon
|
||||||
|
}
|
||||||
|
|
||||||
|
func PartTwo(data []string) int {
|
||||||
|
bitlen := len(data[0])
|
||||||
|
|
||||||
|
oxygenIndices := make([]int, len(data))
|
||||||
|
for idx := range oxygenIndices {
|
||||||
|
oxygenIndices[idx] = idx
|
||||||
|
}
|
||||||
|
|
||||||
|
co2Indices := make([]int, len(data))
|
||||||
|
for idx := range co2Indices {
|
||||||
|
co2Indices[idx] = idx
|
||||||
|
}
|
||||||
|
|
||||||
|
for indice := 0; indice < bitlen && len(oxygenIndices) > 1; indice++ {
|
||||||
|
ones := 0
|
||||||
|
for _, idx := range oxygenIndices {
|
||||||
|
if data[idx][indice] == '1' {
|
||||||
|
ones++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target := byte('1')
|
||||||
|
if ones*2 < len(oxygenIndices) {
|
||||||
|
target = '0'
|
||||||
|
}
|
||||||
|
writeIdx := 0
|
||||||
|
for readIdx := 0; readIdx < len(oxygenIndices); readIdx++ {
|
||||||
|
if data[oxygenIndices[readIdx]][indice] == target {
|
||||||
|
oxygenIndices[writeIdx] = oxygenIndices[readIdx]
|
||||||
|
writeIdx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oxygenIndices = oxygenIndices[:writeIdx]
|
||||||
|
}
|
||||||
|
|
||||||
|
for idx := 0; idx < bitlen && len(co2Indices) > 1; idx++ {
|
||||||
|
ones := 0
|
||||||
|
for _, indice := range co2Indices {
|
||||||
|
if data[indice][idx] == '1' {
|
||||||
|
ones++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target := byte('0')
|
||||||
|
if ones*2 < len(co2Indices) {
|
||||||
|
target = '1'
|
||||||
|
}
|
||||||
|
writeIdx := 0
|
||||||
|
for readIdx := 0; readIdx < len(co2Indices); readIdx++ {
|
||||||
|
if data[co2Indices[readIdx]][idx] == target {
|
||||||
|
co2Indices[writeIdx] = co2Indices[readIdx]
|
||||||
|
writeIdx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
co2Indices = co2Indices[:writeIdx]
|
||||||
|
}
|
||||||
|
|
||||||
|
oxygenRating := 0
|
||||||
|
for _, char := range data[oxygenIndices[0]] {
|
||||||
|
oxygenRating <<= 1
|
||||||
|
if char == '1' {
|
||||||
|
oxygenRating |= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
co2Rating := 0
|
||||||
|
for _, char := range data[co2Indices[0]] {
|
||||||
|
co2Rating <<= 1
|
||||||
|
if char == '1' {
|
||||||
|
co2Rating |= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return oxygenRating * co2Rating
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
data := parseInput("input.txt")
|
||||||
|
fmt.Println("Part 1:", PartOne(data))
|
||||||
|
fmt.Println("Part 2:", PartTwo(data))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user