### Solve a few more puzzles.

master
Danila Fedorin 8 months ago
parent
commit
8a7eab81e0
6 changed files with 176 additions and 17 deletions
1. 72
day10.cr
2. 42
day11.cr
3. 6
day7.cr
4. 19
day8.cr
5. 7
day9.cr
6. 47
intcode_fibers.cr

#### 72 day10.cr View File

 `@ -0,0 +1,72 @@` `require "advent"` ``` ``` `struct Tuple(*T)` ` def reduce_fraction` ` gcd = (self[0].gcd self[1]).abs` ` return self if gcd == 0` ` {self[0] // gcd, self[1]//gcd}` ` end` `end` ``` ``` `struct Tuple(*T)` ` def -(other)` ` {self[0]-other[0], self[1] - other[1]}` ` end` ``` ``` ` def dist` ` self[0] + self[1]` ` end` `end` ``` ``` `input = input(2019, 10)` `asteroids = Set({Int32, Int32}).new` `input.lines.each_with_index do |l, y|` ` l.chars.each_with_index do |c, x|` ` next unless c == '#'` ` asteroids << {x, y}` ` end` `end` ``` ``` `p1 = asteroids.max_of do |a|` ` angles = Set({Int32, Int32}).new` ` asteroids.each do |b|` ` next if a == b` ` angles << (b-a).reduce_fraction` ` end` ` angles.size` `end` ``` ``` `puts p1` ``` ``` `p2s = asteroids.max_by do |a|` ` angles = Set({Int32, Int32}).new` ` asteroids.each do |b|` ` next if a == b` ` angles << (b-a).reduce_fraction` ` end` ` angles.size` `end` ``` ``` `angle_groups = asteroids.group_by do |a|` ` (a - p2s).reduce_fraction` `end` `angle_groups.delete({0,0})` `angle_groups.each do |k, v|` ` v.sort! do |a|` ` (a - p2s).dist` ` end` `end` ``` ``` `angles = angle_groups.keys.sort_by do |k|` ` -Math.atan2(k[0].to_f32, k[1].to_f32)` `end` `i = 1` `angles.cycle do |angle|` ` next if angle_groups[angle].empty?` ` asteroid = angle_groups[angle].delete_at(0)` ` if i == 200` ` puts asteroid[0] * 100 + asteroid[1]` ` break` ` end` ` i += 1` `end`

#### 42 day11.cr View File

 `@ -0,0 +1,42 @@` `require "advent"` `require "./intcode_fibers.cr"` ``` ``` `painted_white = Set({Int64, Int64}).new` `color = {} of {Int64,Int64} => Int64` `color[{0_i64, 0_i64}] = 1_i64` `input, output = new_interpreter("", input(2019, 11).split(",").map &.to_i64)` `pos = {0_i64, 0_i64}` `facing = {0_i64, 1_i64}` ``` ``` `struct Tuple(*T)` ` def turn_left` ` {-self[1], self[0]}` ` end` ``` ``` ` def turn_right` ` turn_left.turn_left.turn_left` ` end` ``` ``` ` def add(other)` ` {self[0] + other[0], self[1] + other[1]}` ` end` `end` ``` ``` `loop do` ` c = color[pos]? || 0_i64` ` input.send c` ` break unless nc = output.receive` ` break unless turn = output.receive` ` color[pos] = nc` ` painted_white << pos if nc == 1` ` facing = (turn == 0 ? facing.turn_left : facing.turn_right)` ` pos = pos.add facing` `end` ``` ``` `6.times do |y|` ` y = - y` ` 45.times do |x|` ` print (color[{x.to_i64, y.to_i64}]? == 1 ? '#' : ' ')` ` end` ` puts` `end`

#### 6 day7.cr View File

 `@ -1,18 +1,18 @@` `require "./intcode.cr"` `require "./intcode_fibers.cr"` ``` ``` `prog = File.read("day7.txt").chomp.split(",").map(&.to_i32)` `prog = File.read("day7.txt").chomp.split(",").map(&.to_i64)` ``` ``` `def chain_amplifiers(prog, perm, loop = false)` ` chans = perm.map { |f| new_interpreter(f, prog) }` ` chans.zip perm do |amp, freq|` ` amp[0].send freq` ` amp[0].send freq.to_i64` ` end` ``` ``` ` chans[0][0].send 0` ``` ``` ` i = 0` ` history = Array(Int32).new(chans.size, 0)` ` history = Array(Int64).new(chans.size, 0)` ` loop do` ` j = (i+1) % chans.size` ` break unless received = chans[i][1].receive`

#### 19 day8.cr View File

 `@ -0,0 +1,19 @@` `require "advent"` ``` ``` `input = input(2019, 8).chomp` `layers = input.chars.each_slice(25*6).to_a` `layer = layers.min_by(&.count('0'))` `puts(layer.count('2') * layer.count('1'))` ``` ``` `message = layers.reduce do |l1, l2|` ` l1.zip_with(l2) do |a1, a2|` ` next (a1 == '2') ? a2 : a1` ` end` `end` ``` ``` `6.times do |i|` ` 25.times do |j|` ` print(message[25*i+j] == '1' ? '#' : ' ')` ` end` ` puts` `end`

#### 7 day9.cr View File

 `@ -0,0 +1,7 @@` `require "advent"` `require "./intcode_fibers.cr"` ``` ``` `input = input(2019, 9).split(",").map &.to_i64` `input, output = new_interpreter("", input)` `input.send 2_i64` `puts output.receive`

#### 47 intcode_fibers.cr View File

 `@ -1,40 +1,59 @@` `def new_interpreter(f, prog)` ` prog = prog.clone` ` input = Channel(Int32).new` ` output = Channel(Int32?).new` `def new_interpreter(f, p)` ` prog = {} of Int64 => Int64` ` p.each_with_index do |v, i|` ` prog[i.to_i64] = v.to_i64` ` end` ``` ``` ` input = Channel(Int64).new` ` output = Channel(Int64?).new` ` spawn do` ` op = ""` ` pc = 0` ` arg = ->(i : Int32) { op[-(3+i)] == '0' ? prog[prog[pc+1+i]] : prog[pc+1+i] }` ` pc = 0_i64` ` base = 0_i64` ` index = ->(i : Int32) {` ` case op[-(3+i)]` ` when '0'` ` prog[pc+1+i]` ` when '1'` ` pc+1+i` ` else` ` prog[pc+1+i] + base` ` end` ` }` ` get = ->(i : Int32) { prog[index.call(i)]? || 0_i64 }` ` set = ->(i : Int32, v : Int64) { prog[index.call(i)] = v }` ` loop do` ` op = "0000" + prog[pc].to_s` ` case op` ` when .ends_with? "1"` ` prog[prog[pc+3]] = arg.call(0) + arg.call(1)` ` set.call(2, get.call(0) + get.call(1))` ` pc += 4` ` when .ends_with? "2"` ` prog[prog[pc+3]] = arg.call(0) * arg.call(1)` ` set.call(2, get.call(0) * get.call(1))` ` pc += 4` ` when .ends_with? "3"` ` prog[prog[pc+1]] = input.receive` ` set.call(0, input.receive)` ` pc += 2` ` when .ends_with? "4"` ` output.send(arg.call(0))` ` output.send(get.call(0))` ` pc += 2` ` when .ends_with? "5"` ` pc = arg.call(0) != 0 ? arg.call(1) : pc + 3` ` pc = get.call(0) != 0 ? get.call(1) : pc + 3` ` when .ends_with? "6"` ` pc = arg.call(0) == 0 ? arg.call(1) : pc + 3` ` pc = get.call(0) == 0 ? get.call(1) : pc + 3` ` when .ends_with? "7"` ` prog[prog[pc+3]] = arg.call(0) < arg.call(1) ? 1 : 0` ` set.call(2, get.call(0) < get.call(1) ? 1_i64 : 0_i64)` ` pc += 4` ` when .ends_with? "8"` ` prog[prog[pc+3]] = arg.call(0) == arg.call(1) ? 1 : 0` ` set.call(2, get.call(0) == get.call(1) ? 1_i64 : 0_i64)` ` pc += 4` ` when .ends_with? "99"` ` input.receive` ` output.send(nil)` ` break` ` when .ends_with? "9"` ` base += get.call(0)` ` pc += 2` ` end` ` end` ` end`