refactor(go/day3-2): simpler reading func.
authorsgf <sgf.dma@gmail.com>
Mon, 20 Dec 2021 19:59:33 +0000 (22:59 +0300)
committersgf <sgf.dma@gmail.com>
Mon, 20 Dec 2021 20:35:01 +0000 (23:35 +0300)
day3/main.go
main.go

index 90fce4d..f0b688d 100644 (file)
@@ -13,19 +13,17 @@ type BitCount struct {
     zero, one int
 }
 
-func parseDiag(r io.Reader) ([]BitCount, []uint32, error) {
+func parseDiag(r io.Reader) ([]BitCount, error) {
     s := bufio.NewScanner(r)
 
-    if ok := s.Scan(); !ok { return nil, nil, nil }
+    if ok := s.Scan(); !ok { return nil, nil }
 
     line := s.Text()
     n := len(line)
     bc := make([]BitCount, n)
-    nums := make([]uint32, 0, 1)
 
     for {
         //fmt.Printf("%v\n", line)
-        var x uint32 = 0
         for i, c := range line {
             k := n - 1 -i
             switch c {
@@ -33,18 +31,15 @@ func parseDiag(r io.Reader) ([]BitCount, []uint32, error) {
                     bc[k].zero++
                 case '1':
                     bc[k].one++
-                    x |= 1<<k
                 default:
-                    return nil, nil, fmt.Errorf("Wrong input")
+                    return nil, fmt.Errorf("Wrong input")
             }
         }
-        //fmt.Printf("%d, %0b\n", x, x)
         //fmt.Printf("%v\n", bc)
-        nums = append(nums, x)
         if ok := s.Scan(); !ok { break }
         line = s.Text()
     }
-    return bc, nums, nil
+    return bc, nil
 }
 
 func f1(bc []BitCount) (gamma uint32, epsilon uint32) {
@@ -67,12 +62,12 @@ func RunF1(input string) {
     if err != nil { return }
     defer h0.Close()
 
-    bc, _, err := parseDiag(h0)
+    bc, err := parseDiag(h0)
     if err != nil {
         fmt.Printf("Error: %v\n", err)
         return
     }
-    fmt.Printf("bc=%v\n", bc)
+    //fmt.Printf("bc=%v\n", bc)
     gamma, epsilon := f1(bc)
     //findSimilar(gamma, nums)
     //fmt.Printf("%0b\n", (^t<<27)>>27)
@@ -80,6 +75,37 @@ func RunF1(input string) {
     fmt.Printf("Answer1: %d (%d(%0b), %d(%0b))\n", gamma * epsilon, gamma, gamma, epsilon, epsilon)
 }
 
+func readDiag(r io.Reader) (nums []uint32, maxBit uint32, err error) {
+    s := bufio.NewScanner(r)
+
+    if ok := s.Scan(); !ok { return }
+
+    line := s.Text()
+    maxBit = uint32(len(line))
+    nums = make([]uint32, 0, 1)
+
+    for {
+        //fmt.Printf("%v\n", line)
+        var x uint32 = 0
+        for i, c := range line {
+            k := int(maxBit) - 1 - i
+            switch c {
+                case '0': continue
+                case '1': x |= 1<<k
+                default:
+                    err = fmt.Errorf("Wrong input")
+                    return
+            }
+        }
+        //fmt.Printf("%d, %0b\n", x, x)
+        //fmt.Printf("%v\n", bc)
+        nums = append(nums, x)
+        if ok := s.Scan(); !ok { break }
+        line = s.Text()
+    }
+    return
+}
+
 type BitGroup struct {
     bit uint32
     ones []uint32
@@ -103,10 +129,10 @@ func groupByBit (bit uint32, nums []uint32) (bc BitGroup) {
     return
 }
 
-func findNumber (maxBit int, nums []uint32, choose func(BitGroup) []uint32) uint32 {
+func findNumber (maxBit uint32, nums []uint32, choose func(BitGroup) []uint32) uint32 {
     for i := maxBit - 1; i >= 0 && len(nums) > 1; i-- {
         //fmt.Printf("Grouping numbers %0b\n", nums)
-        bg := groupByBit(uint32(i), nums)
+        bg := groupByBit(i, nums)
         nums = choose(bg)
         //fmt.Printf("Groups by bit 2^%d are 1=%0b(%d) and 0=%0b(%d)\n", i, bg.ones, len(bg.ones), bg.zeros, len(bg.zeros))
     }
@@ -118,7 +144,7 @@ func findNumber (maxBit int, nums []uint32, choose func(BitGroup) []uint32) uint
     panic("Impossible, more than one number left.")
 }
 
-func f2 (maxBit int, nums []uint32) (oxygen uint32, co2 uint32) {
+func f2 (nums []uint32, maxBit uint32) (oxygen uint32, co2 uint32) {
     mostCommon := func (gr BitGroup) []uint32 {
         if len(gr.ones) >= len(gr.zeros) {
             return gr.ones
@@ -143,13 +169,14 @@ func RunF2(input string) {
     if err != nil { return }
     defer h0.Close()
 
-    bc, nums, err := parseDiag(h0)
+    nums, maxBit, err := readDiag(h0)
     if err != nil {
         fmt.Printf("Error: %v\n", err)
         return
     }
     //fmt.Printf("bc=%v, nums=%v (%d)\n", bc, nums, len(nums))
-    oxygen, co2 := f2(len(bc), nums)
+    oxygen, co2 := f2(nums, maxBit)
     fmt.Printf("Answer2: %d (%d, %d)\n", oxygen * co2, oxygen, co2)
 
 }
+
diff --git a/main.go b/main.go
index b123a77..ea4d932 100644 (file)
--- a/main.go
+++ b/main.go
@@ -11,7 +11,7 @@ func main() {
     //day1.RunF1("day1/input.txt")
     //day1.RunF2("day1/input.txt")
 
-    day3.RunF1("day3/in.txt")
+    day3.RunF1("day3/input.txt")
     day3.RunF2("day3/input.txt")
     //day3.RunF2("day2/input.txt")
 }