|
|
@ -3,19 +3,70 @@ disk_map = DATA.read.chars.each_slice(2)
|
|
|
|
[ Array.new(a.to_i, i), Array.new(b.to_i, nil) ]
|
|
|
|
[ Array.new(a.to_i, i), Array.new(b.to_i, nil) ]
|
|
|
|
}.reject(&:empty?)
|
|
|
|
}.reject(&:empty?)
|
|
|
|
|
|
|
|
|
|
|
|
while (prev, free = disk_map.each_cons(2).find { _2.include?(nil) })
|
|
|
|
# while (prev, free = disk_map.each_cons(2).find { _2.include?(nil) })
|
|
|
|
tail = disk_map.last
|
|
|
|
# tail = disk_map.last
|
|
|
|
until free.empty? || tail.empty?
|
|
|
|
# until free.empty? || tail.empty?
|
|
|
|
prev << tail.shift
|
|
|
|
# prev << tail.shift
|
|
|
|
free.pop
|
|
|
|
# free.pop
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# while disk_map.last.all?(&:nil?)
|
|
|
|
|
|
|
|
# disk_map.pop
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# pp disk_map.flatten.compact.each.with_index.sum { _1 * _2 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Block = Struct.new(:id, :size, :prev, :next) do
|
|
|
|
|
|
|
|
def each
|
|
|
|
|
|
|
|
return enum_for(__method__) unless block_given?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cur = self
|
|
|
|
|
|
|
|
while cur
|
|
|
|
|
|
|
|
yield cur
|
|
|
|
|
|
|
|
cur = cur.next
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def inspect
|
|
|
|
|
|
|
|
"<Block id=#{id} size=#{size} prev=#{prev&.id} next=#{self.next&.id}>"
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def to_s
|
|
|
|
|
|
|
|
(id || ?.).to_s * size
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
blocks = disk_map.map { Block.new(_1[0], _1.size) }
|
|
|
|
|
|
|
|
.each_cons(2) { _1.next = _2; _2.prev = _1 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
head = blocks.first
|
|
|
|
|
|
|
|
tail = blocks.last
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
until tail == head
|
|
|
|
|
|
|
|
unless tail.id.nil?
|
|
|
|
|
|
|
|
find_free = head
|
|
|
|
|
|
|
|
until (find_free.id.nil? && find_free.size >= tail.size) || (find_free == tail)
|
|
|
|
|
|
|
|
find_free = find_free.next
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
if find_free != tail
|
|
|
|
|
|
|
|
a = find_free
|
|
|
|
|
|
|
|
b = tail
|
|
|
|
|
|
|
|
a.id, b.id = b.id, a.id
|
|
|
|
|
|
|
|
|
|
|
|
while disk_map.last.all?(&:nil?)
|
|
|
|
if a.size > b.size
|
|
|
|
disk_map.pop
|
|
|
|
c = Block.new(nil, a.size - b.size, a, a.next)
|
|
|
|
|
|
|
|
a.size = b.size
|
|
|
|
|
|
|
|
a.next = c
|
|
|
|
|
|
|
|
c.next.prev = c
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
pp disk_map.flatten.each.with_index.sum { _1 * _2 }
|
|
|
|
tail = tail.prev
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pp head.each.flat_map { Array.new(_1.size, _1.id) }.each.with_index.sum { _1.to_i * _2 }
|
|
|
|
|
|
|
|
|
|
|
|
__END__
|
|
|
|
__END__
|
|
|
|
2333133121414131402
|
|
|
|
2333133121414131402
|
|
|
|