main.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package main
  2. import (
  3. "bufio"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "log"
  8. "os"
  9. )
  10. const MAX_LOOP = 1_000_000
  11. func main() {
  12. blocks := make([]int, 0, 8192)
  13. r := bufio.NewReader(os.Stdin)
  14. // Read input
  15. for i := 0; i < MAX_LOOP; i++ {
  16. b, err := r.ReadByte()
  17. if errors.Is(err, io.EOF) {
  18. break
  19. }
  20. if err != nil {
  21. log.Fatalf("While reading input: %v", err)
  22. }
  23. switch {
  24. case b == '\n':
  25. break
  26. case '0' <= b || b <= '9':
  27. size := int(b - 48)
  28. fid := -1
  29. if i%2 == 0 { // If file block
  30. fid = int(i / 2)
  31. }
  32. for j := 0; j < size; j++ {
  33. blocks = append(blocks, fid)
  34. }
  35. default:
  36. log.Fatalf("unexpected input block '%q' encountered at column %d", b, i+1)
  37. }
  38. }
  39. // Compact
  40. free := 0
  41. for i := len(blocks) - 1; free+1 < i; i-- {
  42. if blocks[i] == -1 {
  43. continue
  44. }
  45. for blocks[free] != -1 {
  46. free++
  47. }
  48. blocks[free] = blocks[i]
  49. blocks[i] = -1
  50. }
  51. printBlocks(blocks)
  52. // Calculate checksum
  53. sum := 0
  54. for i, b := range blocks {
  55. if b == -1 {
  56. continue
  57. }
  58. sum += i * b
  59. }
  60. fmt.Printf("%d\n", sum)
  61. }
  62. func printBlocks(blocks []int) {
  63. for _, b := range blocks {
  64. if b == -1 {
  65. fmt.Printf(".")
  66. continue
  67. }
  68. fmt.Printf("%d", b)
  69. }
  70. fmt.Println()
  71. }