1. # http://c...content-available-to-author-only...e.com/questions/47229/water-held-in-a-hexagonal-rod-scuplture
2. require 'minitest/autorun'
3. require 'pp'
4.
5. Rod = Struct.new :x,:y,:height,:water_height,:neighbors do
6. def to_s
7. "(#{x},#{y})->#{height}"
8. end
9.
10. def total_height
11. height + water_height
12. end
13. end
14.
15. f=->input{
16.
17. #parse input
18. list = []
19. l = input.lines.to_a
20. (0...l.size).map do |y|
21. x=-1
22. list += l[y].scan(/../).map{|v| Rod.new x=x+1, y, v.to_i, v.to_i<1?0:99}
23. end
24.
25. empty_rod = Rod.new(0,0,0,0)
26. find_rod_by_coords=->x,y{list.find{ |r| r.x==x && r.y==y } || empty_rod}
27.
28. # populate the neighbors of each rod
29. list.each do |rod|
30. neighbor_coord_offsets = [[-1,-1],[1,-1],[-2,0],[2,0],[1,-1],[1,1]]
31. rod.neighbors = neighbor_coord_offsets.map{|w,z| find_rod_by_coords[rod.x+w,rod.y+z]}
32. end
33.
34. # let the water leak...
35. changed = 1
36.
38. m = rod.neighbors.map(&:total_height).min
39. if rod.total_height > m && rod.water_height > 0
40. rod.water_height = [0,m-rod.height].max
41. changed = 1
42. end
43. }
44.
45. (changed=!0
47. )while changed
48.
49. # ...and return the result
50. list.map(&:water_height).reduce :+
51. }
52.
53.
54. describe '#f' do
55.
56. it 'passes test case #1' do
57. input = <<-EOS
58. 04 04
59. 04 01 03
60. 04 04
61. EOS
62.
63. assert_equal 2, f[input]
64. end
65.
66. it 'passes test case #2' do
67. input = <<-EOS
68. 55 34 45 66
69. 33 21 27
70. 23 12 01 77
71. 36 31 74
72. EOS
73.
74. assert_equal 35, f[input]
75. end
76.
77.
78. it 'passes test case #3' do
79. input = <<-EOS
80. 35 36 77 22 23 32 54 24
81. 33 07 02 04 21 54 07 07 07 76
82. 20 04 07 07 01 20 54 11 81 81 07 76
83. 20 67 67 22 07 01 78 54 07 81 07 81 09 76
84. 20 67 07 67 22 22 07 44 55 54 07 81 07 07 61 07 20
85. 67 57 50 50 07 07 14 03 02 15 81 99 91 07 81 04
86. 67 07 50 50 87 39 45 41 34 81 07 07 89 07 81 79
87. 67 07 50 50 07 07 07 27 07 27 81 07 07 79 81 78
88. 20 67 67 07 07 07 07 99 33 46 02 81 07 07 81 01 20
89. 33 07 07 01 05 01 92 20 02 81 07 81 15 32
90. 22 07 20 20 07 20 63 02 80 81 15 32
91. 45 20 01 20 39 20 15 07 15 32
92. 23 20 20 29 43 21 18 41 20 66 66 43 21
93. 90 99 47 07 20
94. 50 20 02 48
95. 70 56 20
96. 90
97. EOS
98.
99. assert_equal 1432, f[input]
100. end
101. end
102.
Success #stdin #stdout 0.32s 8808KB
stdin
Standard input is empty
stdout
Run options: --seed 54380

# Running tests:

...

Finished tests in 0.259400s, 11.5652 tests/s, 11.5652 assertions/s.

3 tests, 3 assertions, 0 failures, 0 errors, 0 skips