pastebin light

pastebin is a collaborative debugging tool allowing you to share and modify code snippets while chatting on IRC, IM or a message board.

pastebin light //misacek

Posted by sqr.rb on Fri 18 Nov 2011 17:33:30 CET
download | new post

  1. #!/usr/bin/env ruby
  2.  
  3. =begin
  4. $desired_pattern = [1, 2, 3,
  5.   8, 0, 4,
  6.   7, 6, 5]
  7. =end
  8. $desired_pattern = [1, 2, 3,
  9. 4, 5, 6,
  10. 7, 8, 0]
  11.  
  12. if [0,9].include?(ARGV.size) then
  13. else
  14. print "Bad usage. Examples:\n <app>\n <app> 1 2 3 4 5 6 7 8 0\n"
  15. exit
  16. end
  17.  
  18. class Array
  19. def where(number)
  20. 0.upto(self.size-1) do|i|
  21. return i if self[i] == number
  22. end
  23. return nil
  24. end
  25. end
  26.  
  27. class VariantList
  28.  
  29. @@list = []
  30.  
  31. def self.add(t)
  32. @@list[t.fnc()] = [] if @@list[t.fnc()] == nil
  33. @@list[t.fnc()] << t
  34. end
  35.  
  36. def self.include?(t)
  37. @@list.each do|i|
  38. next if i == nil
  39. i.each do|j|
  40. return true if j == t
  41. end
  42. end
  43. return false
  44. end
  45.  
  46. def self.list
  47. @@list
  48. end
  49.  
  50. def self.info
  51. print "[\n"
  52. @@list.each do|i|
  53. if i == nil then
  54. print "\tnil,"
  55. else
  56. i.each do|j|
  57. print "\t"
  58. j.info_line
  59. print j.checked?, ','
  60. end
  61. end
  62. print "\n"
  63. end
  64. print "]\n"
  65. end
  66.  
  67. end
  68.  
  69. class Tile
  70.  
  71. attr_accessor :set
  72. attr_accessor :checked
  73. @@count = 0
  74.  
  75. def initialize(*args)
  76. @set = []
  77. @checked = false
  78. if args.size == 1 && args[0].kind_of?(Array) && args[0].size == 9 then
  79. 0.upto(8)do|i|
  80. if not (args[0].include?(i.to_s) || args[0].include?(i)) then
  81. puts "Invalid argument content."
  82. exit
  83. end
  84. end
  85. args[0].each do|a| begin
  86. @set[@set.size] = Integer(a)
  87. rescue ArgumentError
  88. puts "Invalid argument type."
  89. exit
  90. end end
  91. else
  92. @set = [0, 1, 2, 3, 4, 5, 6, 7, 8].sort_by { rand }
  93. end
  94.  
  95. return nil if VariantList.include?(@set)
  96.  
  97. if is_finished() then
  98. puts 'Finished!'
  99. info()
  100. exit
  101. end
  102.  
  103. VariantList.add(self)
  104. @@count += 1
  105. # print '[', @@count, '] New variant (value ', hamming(), '):', "\n"
  106. # self.info
  107. end
  108.  
  109. def set()
  110. return @set
  111. end
  112.  
  113. def info()
  114. 0.upto(8){|i|
  115. print @set[i] != 0 ? @set[i] : ' '
  116. if [2,5,8].include?(i) then print "\n" else print ' ' end
  117. }
  118. puts
  119. end
  120.  
  121. def info_line()
  122. print '[ '
  123. 0.upto(8){|i|
  124. print @set[i]
  125. }
  126. print ' ]'
  127. end
  128.  
  129. def checked?()
  130. @checked
  131. end
  132.  
  133. def check!()
  134. @checked = true
  135. end
  136.  
  137. def is_finished()
  138. # 1 2 3
  139. # 8 4
  140. # 7 6 5
  141. @set == $desired_pattern
  142. end
  143.  
  144. def ==(state)
  145. return matches(state)
  146. end
  147.  
  148. def [](at)
  149. @set[at]
  150. end
  151.  
  152. def []=(at, value)
  153. @set[at] = value
  154. end
  155.  
  156. def matches(state)
  157. 0.upto(8) do|i|
  158. return false if @set[i] != state[i]
  159. end
  160. true
  161. end
  162.  
  163. def steps_between(i,j)
  164. return 0 if i == j
  165. return ((i/3)-(j/3)).abs + ((i%3)-(j%3)).abs
  166. end
  167.  
  168. def where(number)
  169. 0.upto(8) do|i|
  170. if @set[i] == number then return i end
  171. end
  172. print 'Invalid number search: ', number, "\n"
  173. exit
  174. end
  175.  
  176. def swapped(i,j)
  177. ret = @set.dup
  178. ret[i] += ret[j]
  179. ret[j] = ret[i] - ret[j]
  180. ret[i] -= ret[j]
  181. return ret
  182. end
  183.  
  184. def hamming() # returns number of wrong placed elements
  185. count = 0
  186. 0.upto(8) do|i|
  187. count +=1 if $desired_pattern[i] != @set[i]
  188. end
  189. return count
  190. end
  191.  
  192. def manhattan()
  193. sum = 0
  194. 0.upto(8) do|i|
  195. sum += steps_between(where(i), $desired_pattern.where(i))
  196. end
  197. return sum
  198. end
  199.  
  200. def fnc
  201. return hamming
  202. end
  203.  
  204. def negotiate_next()
  205. i = where(0)
  206. Tile.new(swapped(i, i-1)) if not [0, 3, 6].include?(i)
  207. Tile.new(swapped(i, i+1)) if not [2, 5, 8].include?(i)
  208. Tile.new(swapped(i, i-3)) if not [0, 1, 2].include?(i)
  209. Tile.new(swapped(i, i+3)) if not [6, 7, 8].include?(i)
  210. end
  211.  
  212. end
  213.  
  214. Tile.new(ARGV)
  215. i = 1
  216. catch(:bigloop) do while true do
  217. # VariantList::info
  218. catch(:loop) do VariantList::list.each do|i|
  219. next if i == nil || i.size == 0
  220. i.each do|j|
  221. if not j.checked? then
  222. j.check!
  223. j.negotiate_next()
  224. # puts 'Press Enter to continue.'
  225. # STDIN.gets
  226. throw :loop
  227. end
  228. end
  229. throw :bigloop if i.object_id == VariantList::list[VariantList::list.size].object_id
  230. end end
  231. end end
  232.  

Syntax highlighting: