Skip to content

Instantly share code, notes, and snippets.

@mattsan
Last active October 7, 2017 09:44
Show Gist options
  • Save mattsan/310e3c9614a33cbd39b37920671eddff to your computer and use it in GitHub Desktop.
Save mattsan/310e3c9614a33cbd39b37920671eddff to your computer and use it in GitHub Desktop.
# solver.rb の Range を Array に置き換えて早くした版
# 実行する時はファイル名を solver.rb にしてください
module Solver
def parse_triangle(src)
/(\d+),(\d+)(\w)(\d+)/.match(src) {|m|
x = m[1].to_i
y = m[2].to_i
direction = m[3]
height = m[4].to_i
height_1 = height - 1
case direction
when 'R'
top = y - height_1
left = x - height_1
right = left
(height * 2 - 1).times.with_object({}) {|i, acc|
acc[top + i] = [left, right]
delta = (i < height_1) ? 1 : -1
right += delta
}
when 'L'
top = y - height_1
right = x + height_1
left = right
(height * 2 - 1).times.with_object({}) {|i, acc|
acc[top + i] = [left, right]
delta = (i < height_1) ? -1 : 1
left += delta
}
when 'T'
height.times.with_object({}) {|i, acc|
acc[y + i] = [x - i, x + i]
}
when 'B'
height.times.with_object({}) {|i, acc|
acc[y - i] = [x - i, x + i]
}
end
}
end
def parse(input)
input.split('/').map {|t| parse_triangle(t) }
end
def solve(input)
t1, t2 = parse(input)
y_min = [t1.keys.min, t2.keys.min].max
y_max = [t1.keys.max, t2.keys.max].min
(y_min..y_max).each.map {|y|
if t1[y] && t2[y]
l = [t1[y][0], t2[y][0]].max
r = [t1[y][1], t2[y][1]].min
(l <= r) ? (r - l + 1) : 0
else
0
end
}.reduce(&:+).to_s
end
end
module Solver
def parse_triangle(src)
/(\d+),(\d+)(\w)(\d+)/.match(src) {|m|
x = m[1].to_i
y = m[2].to_i
direction = m[3]
height = m[4].to_i
height_1 = height - 1
case direction
when 'R'
top = y - height_1
left = x - height_1
right = left
(height * 2 - 1).times.with_object({}) {|i, acc|
acc[top + i] = (left..right)
delta = (i < height_1) ? 1 : -1
right += delta
}
when 'L'
top = y - height_1
right = x + height_1
left = right
(height * 2 - 1).times.with_object({}) {|i, acc|
acc[top + i] = (left..right)
delta = (i < height_1) ? -1 : 1
left += delta
}
when 'T'
height.times.with_object({}) {|i, acc|
acc[y + i] = (x - i .. x + i)
}
when 'B'
height.times.with_object({}) {|i, acc|
acc[y - i] = (x - i .. x + i)
}
end
}
end
def parse(input)
input.split('/').map {|t| parse_triangle(t) }
end
def solve(input)
t1, t2 = parse(input)
y_min = [t1.keys.min, t2.keys.min].max
y_max = [t1.keys.max, t2.keys.max].min
(y_min..y_max).each.map {|y|
if t1[y] && t2[y]
(t1[y].to_a & t2[y].to_a).size
else
0
end
}.reduce(&:+).to_s
end
end
#!/usr/bin/env ruby
require './doukaku/test_runner'
require './solver'
class TestRunner
extend Doukaku::TestRunner
extend Solver
test('7,0R6/3,1B5', '15')
test('1,6L4/4,9R9', '4')
test('0,2R4/1,3B4', '3')
test('1,2L4/1,2L5', '16')
test('3,2L5/5,6B4', '8')
test('4,1B3/6,3B4', '4')
test('4,4R7/4,3R5', '20')
test('4,5R9/0,7T3', '7')
test('4,7T9/1,6T3', '1')
test('4,8B7/3,7L4', '10')
test('5,3L3/9,8L4', '0')
test('5,6B4/4,4R2', '3')
test('5,6B4/8,5R4', '8')
test('5,8B9/5,2L2', '4')
test('6,1L5/7,1T2', '3')
test('7,2B4/7,2T4', '1')
test('7,3T9/9,6L6', '11')
test('8,0R6/8,1R7', '30')
test('0,4R7/4,6R10', '36')
test('10,4L4/9,1T6', '9')
test('2,2T7/6,7T10', '4')
test('2,7R4/1,6L8', '2')
test('3,0R10/1,2T7', '7')
test('3,5T2/3,6B10', '2')
test('4,7R10/8,2T8', '6')
test('6,8B10/4,5B6', '36')
test('9,2B7/1,1B10', '6')
test('9,3R14/2,4R1', '1')
test('3,0R10/0,6B10', '54')
test('4,10T8/4,10T8', '64')
test('1,5T10/1,20B10', '56')
test('15,16L4/5,12L12', '4')
test('12,11T18/7,18R18', '34')
test('15,16T14/5,12L15', '44')
test('5,10L40/22,22B10', '100')
test('46,34T34/34,29T14', '30')
test('52,75L12/88,69T54', '0')
test('67,83B70/99,48T14', '52')
test('291,11T120/258,54B130', '424')
test('62,170L139/133,172R21', '441')
test('98,189B116/183,127R27', '240')
test('646,684B96/435,690R772', '0')
test('113,668L866/581,859L852', '158404')
test('309,321B162/137,420B423', '15750')
test('5474,6459R9089/8177,150R5120', '376996')
test('2399,1640B2451/1718,2100L1623', '221334')
test('5621,8460T7612/2715,5697L8851', '861192')
end
class Doukaku
module TestRunner
def self.extended(obj)
obj.instance_variable_set(:@n, 1)
end
def test(input, expected)
actual = solve(input)
print "#{format('%2d', @n)}: "
if actual == expected
puts "\x1b[32mpassed\x1b[0m"
else
puts "\x1b[31mfailed input: #{input}, expected: #{expected}, actual: #{actual}\x1b[0m"
end
@n += 1
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment