@@ -2,21 +2,25 @@ class Day09
22 attr_accessor :input , :disk , :checksum
33
44 def part_one ( input )
5+ return 0
56 # Parse input
67 parse_input ( input )
78
89 # Defrag
910 defrag!
10- @disk . compact!
1111
1212 checksum!
13-
14- # Calc checksum
1513 @checksum
1614 end
1715
1816 def part_two ( input )
19- 0
17+ parse_input ( input )
18+
19+ # Defrag
20+ defrag2!
21+
22+ checksum!
23+ @checksum
2024 end
2125
2226 def parse_input ( input )
@@ -48,8 +52,43 @@ def defrag!
4852 end
4953 end
5054
55+ def defrag2!
56+ # @files is now an array of tuples: [id, start, length]
57+ chunkers = @disk . map { |e | e || '.' } . chunk { |y | y }
58+ _ , @files = chunkers . each_with_object ( [ 0 , [ ] ] ) do |( k , chunk ) , memo |
59+ memo [ 1 ] << [ k , memo [ 0 ] , chunk . size ]
60+ memo [ 0 ] += chunk . length
61+ end
62+
63+ @inputs = @files . dup . select { |b | b [ 0 ] != '.' } . reverse
64+ @inputs . each do |filler |
65+ gap_needed = filler [ 2 ]
66+
67+ block = @files . find { |b | b [ 0 ] == '.' && b [ 2 ] >= gap_needed }
68+
69+ next if block . nil? || block [ 1 ] >= filler [ 1 ]
70+
71+ base = block [ 1 ]
72+
73+ # Copy data on @disk
74+ 0 . upto ( filler [ 2 ] - 1 ) do |i |
75+ @disk [ base + i ] = @disk [ filler [ 1 ] + i ]
76+ @disk [ filler [ 1 ] + i ] = nil
77+ end
78+
79+ # Update @files
80+ block_idx = @files . index ( block )
81+ @files . delete_at ( block_idx )
82+ @files . insert ( block_idx , [ '.' , block [ 1 ] + filler [ 2 ] , block [ 2 ] - filler [ 2 ] ] )
83+ @files . delete ( filler )
84+ end
85+ end
86+
87+ def place_file! ( idx , space )
88+ end
89+
5190 def checksum!
5291 @checksum = 0
53- @disk . each_with_index { |id , idx | @checksum += idx * id }
92+ @disk . each_with_index { |id , idx | @checksum += idx * id unless id . nil? }
5493 end
5594end
0 commit comments