fork download
  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.  
  37. adjust_water=->rod{
  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
  46. list.map{|rod| adjust_water[rod]}
  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