comparison day3.rb @ 2:0f4991eca11a

Implement day 3
author IBBoard <dev@ibboard.co.uk>
date Sun, 03 Dec 2023 16:07:25 +0000
parents
children
comparison
equal deleted inserted replaced
1:49dd1ae93696 2:0f4991eca11a
1 #! /usr/bin/env ruby
2
3 if ARGV.length != 1
4 abort("Incorrect arguments - needs input file")
5 elsif not File.exist? (ARGV[0])
6 abort("File #{ARGV[0]} did not exist")
7 end
8
9 file = ARGV[0]
10
11 number_chars = *('0'..'9')
12 skip_chars = ['.']
13
14 numbers = Hash.new
15 symbols = Array.new
16 Position = Struct.new(:x, :y)
17 NumberValue = Struct.new(:value, :positions)
18 SymbolValue = Struct.new(:position)
19
20 def create_number_position(vals)
21 number = vals.reduce("") {|m, v| m + v[0]}.to_i
22 positions = vals.map {|v| Position.new(v[1], v[2])}
23 NumberValue.new(number, positions)
24 end
25
26 def adjacent(a, b)
27 (a.x - b.x).abs <= 1 and (a.y - b.y).abs <= 1
28 end
29
30 sum = 0
31 positions = File.open(file, "r").each_line(chomp: true).with_index.map do |line, index|
32 numbers = line.each_char.with_index.map {|c, i| if number_chars.include? c or !skip_chars.include? c then [c, index, i] end }\
33 .filter {|v| v != nil }\
34 .reduce([[], []]) do |memo, val|
35 if number_chars.include? val[0] then
36 if memo[1].last and memo[1].last[2] + 1 != val[2] then
37 memo[0] << create_number_position(memo[1])
38 memo[1] = []
39 end
40 memo[1] << val
41 else
42 if memo[1] != [] then
43 memo[0] << create_number_position(memo[1])
44 memo[1] = []
45 end
46 memo[0] << SymbolValue.new(Position.new(val[1], val[2]))
47 end
48 memo
49 end
50 if numbers[1] != [] then
51 numbers[0] << create_number_position(numbers[1])
52 end
53 numbers[0]
54 end.flatten.group_by {|elem| elem.class}
55
56 symbol_pos = positions[SymbolValue]
57 number_pos = positions[NumberValue]
58
59 puts number_pos.filter {|num| num.positions.any? {|num_pos| symbol_pos.any? { |sym_pos| adjacent(num_pos, sym_pos.position) } } }.sum {|v|v.value}