Advertisement
Guest User

Untitled

a guest
Aug 25th, 2016
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.47 KB | None | 0 0
  1. #!/usr/bin/env ruby
  2.  
  3. class WordPuz
  4. def initialize
  5. @puzzle = []
  6. @words = []
  7. end
  8.  
  9. def process_puz_row line
  10. @puzzle << line.gsub(/\s/, '').downcase.chars
  11. end
  12.  
  13. def process_words line
  14. @words += line.gsub(/\s/, '').downcase.split(',')
  15. end
  16.  
  17. DIRS = [
  18. [-1, -1], [-1, 0], [-1, 1],
  19. [0, -1], [0, 1],
  20. [1, -1], [1, 0], [1, 1]
  21. ]
  22.  
  23. def sanity_check
  24. # Allow only rectangular puzzles for now.
  25. @puzzle.each_with_index { |row, i|
  26. raise "Row #{i + 1} length of #{row.size} is not #{@row_len}!" if row.size != @row_len
  27. }
  28.  
  29. max_word_size = [@row_len, @row_count].max
  30. @words.each { |word|
  31. raise "Length of word #{word} is longer than max possible #{max_word_size} characters!" if word.size > max_word_size
  32. }
  33. end
  34.  
  35. def check_word word, startpos, dir
  36. pos = [startpos[0], startpos[1]]
  37. word.each_char { |c|
  38. return false if pos[0] < 0 || pos[0] >= @row_count
  39. return false if pos[1] < 0 || pos[1] >= @row_len
  40. return false if @puzzle[pos[0]][pos[1]] != c
  41. pos[0] += dir[0]
  42. pos[1] += dir[1]
  43. }
  44. true
  45. end
  46.  
  47. def mark_word word, startpos, dir
  48. puts "Found word #{word} at position (#{startpos[0]}, #{startpos[1]}) in direction (#{dir[0]}, #{dir[1]})"
  49.  
  50. pos = [startpos[0], startpos[1]]
  51. word.size.times {
  52. @used[pos[0]][pos[1]] = true
  53. pos[0] += dir[0]
  54. pos[1] += dir[1]
  55. }
  56. end
  57.  
  58. def solve
  59. @row_len = @puzzle.first.size
  60. @row_count = @puzzle.size
  61.  
  62. sanity_check
  63.  
  64. words_by_first_char = Hash.new { |h, k| h[k] = [] }
  65. @words.each { |word| words_by_first_char[word[0]] << word }
  66.  
  67. @used = ([nil] * @row_count).map { [false] * @row_len }
  68.  
  69. 0.upto(@row_count - 1) { |i|
  70. 0.upto(@row_len - 1) { |j|
  71. startpos = [i, j]
  72. words_by_first_char[@puzzle[i][j]].each { |word|
  73. DIRS.each { |dir|
  74. mark_word(word, startpos, dir) if check_word(word, startpos, dir)
  75. }
  76. }
  77. }
  78. }
  79.  
  80. unused = ''
  81. 0.upto(@row_count - 1) { |i|
  82. 0.upto(@row_len - 1) { |j|
  83. unused << @puzzle[i][j] unless @used[i][j]
  84. }
  85. }
  86.  
  87. puts "Unused characters: #{unused}"
  88. end
  89. end
  90.  
  91. def parse_input
  92. wordpuz = WordPuz.new
  93.  
  94. mode = :puzzle
  95. ARGF.each_line { |line|
  96. line.strip!
  97. next if line.empty?
  98.  
  99. if line == '---'
  100. mode = :words
  101. next
  102. end
  103.  
  104. if mode == :puzzle
  105. wordpuz.process_puz_row line
  106. else
  107. wordpuz.process_words line
  108. end
  109. }
  110.  
  111. wordpuz
  112. end
  113.  
  114. wordpuz = parse_input
  115. wordpuz.solve
  116.  
  117. __END__
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement