package main import ( "bufio" "errors" "fmt" "io" "log" "os" ) const MAX_LOOP = 1_000_000 func main() { blocks := make([]int, 0, 8192) r := bufio.NewReader(os.Stdin) // Read input for i := 0; i < MAX_LOOP; i++ { b, err := r.ReadByte() if errors.Is(err, io.EOF) { break } if err != nil { log.Fatalf("While reading input: %v", err) } switch { case b == '\n': break case '0' <= b || b <= '9': size := int(b - 48) fid := -1 if i%2 == 0 { // If file block fid = int(i / 2) } for j := 0; j < size; j++ { blocks = append(blocks, fid) } default: log.Fatalf("unexpected input block '%q' encountered at column %d", b, i+1) } } // Compact free := 0 for i := len(blocks) - 1; free+1 < i; i-- { if blocks[i] == -1 { continue } for blocks[free] != -1 { free++ } blocks[free] = blocks[i] blocks[i] = -1 } printBlocks(blocks) // Calculate checksum sum := 0 for i, b := range blocks { if b == -1 { continue } sum += i * b } fmt.Printf("%d\n", sum) } func printBlocks(blocks []int) { for _, b := range blocks { if b == -1 { fmt.Printf(".") continue } fmt.Printf("%d", b) } fmt.Println() }