github.com/cycloss/advent-of-code@v0.0.0-20221210145555-15039b95faa6/2021/day3/day3.go (about) 1 package main 2 3 import ( 4 "bufio" 5 "fmt" 6 "math" 7 "os" 8 "strconv" 9 ) 10 11 const binLen = 40 12 13 func main() { 14 file, err := os.Open("day3/bigboyDay3.txt") 15 if err != nil { 16 fmt.Println(err) 17 return 18 } 19 defer file.Close() 20 var nums = convertFileToInts(file) 21 fmt.Printf("Part 1 Solution: %d\n", solvePart1(nums)) 22 fmt.Printf("Part 2 Solution: %d\n", solvePart2(nums)) 23 } 24 25 func convertFileToInts(file *os.File) []int { 26 var buff = bufio.NewScanner(file) 27 var nums = []int{} 28 for buff.Scan() { 29 var line = buff.Text() 30 var num, _ = strconv.ParseInt(line, 2, 64) 31 nums = append(nums, int(num)) 32 } 33 return nums 34 } 35 36 func solvePart1(nums []int) int { 37 var maskBit = 1 38 var gamma = 0 39 for i := 0; i < binLen; i++ { 40 gamma |= extractMostCommonBit(nums, maskBit) 41 maskBit <<= 1 42 } 43 var epsilon = ^gamma & int(math.Pow(2, binLen)-1) 44 45 return gamma * epsilon 46 } 47 48 func extractMostCommonBit(nums []int, maskBit int) int { 49 var count = 0 50 for _, v := range nums { 51 var bit = v & maskBit 52 if bit > 0 { 53 count++ 54 } else { 55 count-- 56 } 57 } 58 if count > 0 { 59 return maskBit 60 } else if count < 0 { 61 return 0 62 } else { 63 return -1 64 } 65 } 66 67 func solvePart2(nums []int) int { 68 var oxygenRating = reduceNumbers(nums, 1<<(binLen-1), oxygenFilter) 69 var scrubberRating = reduceNumbers(nums, 1<<(binLen-1), scrubberFilter) 70 return oxygenRating * scrubberRating 71 } 72 73 /// returns true if the filter is passed 74 type filterFunc func(int, int, int) bool 75 76 func reduceNumbers(nums []int, mask int, filter filterFunc) int { 77 if len(nums) == 1 { 78 return nums[0] 79 } 80 var commonBit = extractMostCommonBit(nums, mask) 81 var nums2 = []int{} 82 for _, v := range nums { 83 if filter(v, commonBit, mask) { 84 nums2 = append(nums2, v) 85 } 86 } 87 return reduceNumbers(nums2, mask>>1, filter) 88 } 89 90 func oxygenFilter(num int, commonBit int, mask int) bool { 91 if commonBit > 0 { 92 return (mask & num) != 0 93 } else if commonBit == 0 { 94 return (mask & num) == 0 95 } else { 96 return (mask & num) != 0 97 } 98 } 99 100 func scrubberFilter(num int, commonBit int, mask int) bool { 101 if commonBit > 0 { 102 return (mask & num) == 0 103 } else if commonBit == 0 { 104 return (mask & num) != 0 105 } else { 106 return (mask & num) == 0 107 } 108 }