d09.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package main
  2. import "strconv"
  3. import "strings"
  4. import "bufio"
  5. import "fmt"
  6. import "io"
  7. import "os"
  8. var (
  9. ex1 = true
  10. )
  11. type Compressed struct {
  12. BSize int
  13. Count int
  14. }
  15. func ReadCompressed(line string) *Compressed {
  16. if (line[len(line) -1] != ')') {
  17. return nil
  18. }
  19. line = line[0:len(line)-1]
  20. parts := strings.Split(line, "x")
  21. if (len(parts) != 2) {
  22. return nil
  23. }
  24. this := new(Compressed)
  25. var err error
  26. this.BSize, err = strconv.Atoi(parts[0])
  27. if (err != nil) {
  28. return nil
  29. }
  30. this.Count, err = strconv.Atoi(parts[1])
  31. if (err != nil) {
  32. return nil
  33. }
  34. return this
  35. }
  36. func readString(reader io.Reader, sep byte) (string, error) {
  37. buf := ""
  38. for {
  39. byteBuffer := make([]byte, 1)
  40. n, err := reader.Read(byteBuffer)
  41. buf += string(byteBuffer[:n])
  42. if (byteBuffer[0] == sep || err != nil) {
  43. return buf, err
  44. }
  45. }
  46. return "", nil
  47. }
  48. func doRead(reader io.Reader) int {
  49. length := 0
  50. for {
  51. line, err := readString(reader, '(')
  52. if (len(line) > 0 && line[len(line) -1] == '(') {
  53. length += len(line) -1
  54. line, err = readString(reader, ')')
  55. compressed := ReadCompressed(line)
  56. if (compressed == nil) {
  57. length += len(line)
  58. } else {
  59. var num int
  60. var buf string
  61. read := 0
  62. for ; compressed.BSize > read; {
  63. bytes := make([]byte, compressed.BSize - read)
  64. num, err = reader.Read(bytes)
  65. read += num
  66. if (!ex1) {
  67. buf += string(bytes[:num])
  68. }
  69. }
  70. if (ex1) {
  71. length += read * compressed.Count
  72. } else {
  73. length += doRead(strings.NewReader(buf)) * compressed.Count
  74. }
  75. }
  76. } else {
  77. length += len(line)
  78. }
  79. if err != nil {
  80. break
  81. }
  82. }
  83. return length
  84. }
  85. func main() {
  86. reader := bufio.NewReader(os.Stdin)
  87. length := doRead(reader)
  88. fmt.Println(length -1)
  89. }