fork download
  1.  
  2. F=
  3. ->input{
  4.  
  5. rows = input.split'
  6. '
  7. node = Struct.new :incoming_connection_count, :next_node
  8.  
  9. nodes = Hash.new{|h,k|h[k] = node.new 0}
  10.  
  11. rows.size.times{|y|
  12. x=0
  13. rows[y].chars{|c|
  14. case c
  15. when ?>
  16. from = [y,x-4]
  17. to = [y,x+2]
  18. when ?<
  19. from = [y,x+4]
  20. to = [y,x-2]
  21. when ?^
  22. from = [y+3,x]
  23. to = [y-1,x]
  24. when ?v
  25. from = [y-3,x]
  26. to = [y+1,x]
  27. end
  28.  
  29. if from
  30. nodes[from].next_node = nodes[to]
  31. nodes[to].incoming_connection_count += 1
  32. end
  33.  
  34. x+=1
  35. }
  36. }
  37.  
  38. current = nodes.values.find{|n|n.incoming_connection_count < 1}
  39. loop_start = nodes.values.find{|n|n.incoming_connection_count > 1}
  40.  
  41. unless loop_start
  42. # no loop; adjust the total node count
  43. [nodes.size-1, 0]
  44. else
  45. # there's a loop; measure length of the tail
  46. tail = 0
  47. (tail+=1;current = current.next_node) while current!=loop_start
  48. [tail, nodes.size-tail]
  49. end
  50.  
  51. }
  52.  
  53. require 'minitest/autorun'
  54.  
  55. describe F do
  56.  
  57. def test_simple_case
  58. assert_equal [2, 6], F[<<-DOC]
  59. # --> # --> # --> #
  60. ^ ^ |
  61. | | |
  62. | | v
  63. # # <-- # <-- #
  64. DOC
  65. end
  66.  
  67. def test_harder_case
  68. assert_equal [3, 10], F[<<-DOC]
  69. # --> # --> #
  70. ^ |
  71. | |
  72. | v
  73. # --> # <-- # # --> #
  74. ^ ^ |
  75. | | |
  76. | | v
  77. # --> # # <-- # <-- #
  78. DOC
  79. end
  80.  
  81. def test_no_loop
  82. assert_equal [6, 0], F[<<-DOC]
  83. # --> # --> # --> #
  84. |
  85. |
  86. v
  87. <-- # <-- #
  88. DOC
  89. end
  90.  
  91. end
Success #stdin #stdout 0.08s 10728KB
stdin
Standard input is empty
stdout
Run options: --seed 23398

# Running tests:

...

Finished tests in 0.001623s, 1848.1089 tests/s, 1848.1089 assertions/s.

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