Mercurial > repos > other > adventofcode2023
view day14b.rb @ 34:59620bbc4084
Implement day 24 - 2D intersection
Needs an offset because the numbers are big enough to overflow
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Fri, 05 Jan 2024 11:42:13 +0000 |
parents | 19481b061461 |
children |
line wrap: on
line source
#! /usr/bin/env ruby require 'set' if ARGV.length != 1 abort("Incorrect arguments - needs input file") elsif not File.exist? (ARGV[0]) abort("File #{ARGV[0]} did not exist") end file = ARGV[0] platform = File.open(file, "r").each_line(chomp: true).map {|row| row.each_char.to_a}.to_a.transpose() COL_SIZE = platform[0].length puts "Column size: #{COL_SIZE}" def cycle(platform) [:north, :west, :south, :east].reduce(platform) do |platform, iter| # puts "Push #{iter}" result = platform.map {|col| col.chunk_while {|i, j| i != "#"}.to_a}.map do |col| col.flat_map do |chunk| num_movable_objects = chunk.count("O") new_chunk = Array.new(num_movable_objects, "O") new_chunk.concat(Array.new(chunk.length - num_movable_objects, ".")) new_chunk[-1] = "#" if chunk[-1] == "#" new_chunk end end case iter when :north # Pushed it North, now we need to go West # puts "#{result.transpose.map{|col| col.join('')}.join("\n")}\n\n" result.transpose when :west # Pushed it West, now we need to go South # puts "#{result.map{|col| col.join('')}.join("\n")}\n\n" result.transpose.map(&:reverse) when :south # Pushed it South, now we need to go East # puts "#{result.map(&:reverse).transpose.map{|col| col.join('')}.join("\n")}\n\n" result.transpose.map(&:reverse) when :east # Pushed it East, now we need to get back to North alignment # puts "#{result.map(&:reverse).transpose.map(&:reverse).transpose.map{|col| col.join('')}.join("\n")}\n\n" result.map(&:reverse).transpose.map(&:reverse) end end end previous_states = [] max_cycle_length = 1000000000 cycle_start = nil cycle_length = max_cycle_length (1..max_cycle_length).each do |iter| # puts "Cycle #{iter}" platform = cycle(platform) if iter % 1000 == 0 puts iter end cycle_start = previous_states.index platform if !cycle_start.nil? cycle_start += 1 # Compensate for zero-indexing in array cycle_length = iter - cycle_start # puts "#{iter} - #{cycle_start} + 1 = #{cycle_length}" break end previous_states << platform puts "\n\n" end # Already did the first cycle of the loop, so skip it #puts "#{(max_cycle_length - cycle_start)} % #{cycle_length} = #{((max_cycle_length - cycle_start) % cycle_length)} extras" ((max_cycle_length - cycle_start) % cycle_length).times {|n| platform = cycle(platform)} total_load = platform.reduce(0) do |weight, col| col_weight = col.each_with_index.reduce(0) do |accum, cell| cell_contents, cell_pos = cell accum + (cell_contents == "O" ? (COL_SIZE - cell_pos) : 0) end # puts "#{col} = #{col_weight}" weight + col_weight end puts total_load