isundil 9 years ago
parent
commit
586bc2caf7
1 changed files with 106 additions and 0 deletions
  1. 106 0
      d09/d09.go

+ 106 - 0
d09/d09.go

@@ -0,0 +1,106 @@
+package main
+
+import "strconv"
+import "strings"
+import "bufio"
+import "fmt"
+import "io"
+import "os"
+
+var (
+    ex1 = true
+)
+
+type Compressed struct {
+    BSize int
+    Count int
+}
+
+func ReadCompressed(line string) *Compressed {
+    if (line[len(line) -1] != ')') {
+        return nil
+    }
+    line = line[0:len(line)-1]
+    parts := strings.Split(line, "x")
+    if (len(parts) != 2) {
+        return nil
+    }
+    this := new(Compressed)
+    var err error
+    this.BSize, err = strconv.Atoi(parts[0])
+    if (err != nil) {
+        return nil
+    }
+    this.Count, err = strconv.Atoi(parts[1])
+    if (err != nil) {
+        return nil
+    }
+    return this
+}
+
+func readString(reader io.Reader, sep byte) (string, error) {
+    buf := ""
+
+    for {
+        byteBuffer := make([]byte, 1)
+        n, err := reader.Read(byteBuffer)
+        buf += string(byteBuffer[:n])
+        if (byteBuffer[0] == sep || err != nil) {
+            return buf, err
+        }
+    }
+    return "", nil
+}
+
+func doRead(reader io.Reader) int {
+    length := 0
+    for {
+        line, err := readString(reader, '(')
+        if (len(line) > 0 && line[len(line) -1] == '(') {
+            length += len(line) -1
+
+            line, err = readString(reader, ')')
+            compressed := ReadCompressed(line)
+            if (compressed == nil) {
+                length += len(line)
+
+            } else {
+                var num int
+                var buf string
+                read := 0
+
+                for ; compressed.BSize > read; {
+                    bytes := make([]byte, compressed.BSize - read)
+
+                    num, err = reader.Read(bytes)
+                    read += num
+                    if (!ex1) {
+                        buf += string(bytes[:num])
+                    }
+                }
+
+                if (ex1) {
+                    length += read * compressed.Count
+                } else {
+                    length += doRead(strings.NewReader(buf)) * compressed.Count
+                }
+            }
+        } else {
+            length += len(line)
+
+        }
+
+        if err != nil {
+            break
+        }
+    }
+    return length
+}
+
+func main() {
+    reader := bufio.NewReader(os.Stdin)
+    length := doRead(reader)
+
+    fmt.Println(length -1)
+}
+