Module: Wheeler

Defined in:
lib/wheeler.rb,
lib/wheeler/version.rb

Constant Summary collapse

INDEX_PATH =
'.index'
VERSION =
'0.5.2'

Instance Method Summary collapse

Instance Method Details

#cascade_words(words, &block) ⇒ Object



36
37
38
39
40
41
42
# File 'lib/wheeler.rb', line 36

def cascade_words(words, &block)
  len = words.size
  len.times do |i|
    block.call words[0..i]
  end
  words.shift
end

#each_phrase(io, max_words = 4, &block) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/wheeler.rb', line 17

def each_phrase(io, max_words=4, &block)
  words = []
  each_word(io) do |word|
    words << word
    if word[-1] == '.'
      # remove period
      words[-1] = words[-1][0..-2]

      cascade_words(words, &block)

      # we can start a new phrase by resetting the words
      words.clear
    elsif words.length >= max_words
      cascade_words(words, &block)
    end
  end
  cascade_words(words, &block)
end

#each_word(io, &block) ⇒ Object



7
8
9
10
11
12
13
14
15
# File 'lib/wheeler.rb', line 7

def each_word(io, &block)
  # break on spaces instead of \n
  io.each_line(' ') do |line|
    # alphas with quote and period. We'll use the period as a hint for phrasing
    line.scan(/\b([[:word:]]+)\b/).each do |word, _|
      block.call word.upcase
    end
  end
end

#guess(puzzle) ⇒ Object

Parameters:

  • puzzle (String)

    Known letters in their position and ‘_` underscore the unknown letters



111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/wheeler.rb', line 111

def guess(puzzle)
  # split up into words and replace _ with dot
  words = puzzle.split(/\s+/).map{|w| w.gsub('_', '.').upcase}

  # Example: "_ ____ ____" should constuct `.index/1/4/4/phrases`
  phrase_path = "#{INDEX_PATH}/#{words.map(&:size) * '/'}/phrases"

  cmd = "grep --color=always -e '#{words * ' '}' #{phrase_path}"
  puts cmd
  puts `#{cmd}`
  if $?.exitstatus == 1
    puts "Phrases not found in #{phrase_path}"
  end
end

#map_phrases(io, max_words) ⇒ Object



56
57
58
59
60
61
62
63
64
65
# File 'lib/wheeler.rb', line 56

def map_phrases(io, max_words)
  each_phrase(io, max_words) do |words|
    row = [
        word_sizes(words),
        words * ' '
     ]

    puts row * '|'
  end
end

#reduce_fs(io) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/wheeler.rb', line 76

def reduce_fs(io)
  last_sizes = nil
  texts = []

  io.each_line do |line|

    sizes, text = *line.split('|')

    # write out when the size of the words changes
    if last_sizes and sizes != last_sizes
      write_sizes(last_sizes, texts)
      texts.clear
    end

    text = text[0..-2]                                 # strip new line
    throttle{$stderr.print "\e[0K#{sizes}|#{text}\r"}  # some debug output
    if texts.last != text
      texts << text           # text that matches the word size pattern
    end

    last_sizes = sizes
  end

  if texts.any?          # make sure we write out the remaining phrases
    write_sizes(last_sizes, texts)
  end
end

#remove_last_punctuation_if_needed(words) ⇒ Object



48
49
50
51
52
53
54
# File 'lib/wheeler.rb', line 48

def remove_last_punctuation_if_needed(words)
  last_char = words.last[-1]
  if last_char == ',' or last_char == ';'
    words[-1] = words[0..-2]
  end
  words
end

#throttle(duration = 0.1, &block) ⇒ Object

ensure the block is called at most once per duration



68
69
70
71
72
73
74
# File 'lib/wheeler.rb', line 68

def throttle(duration=0.1, &block)
  @last_time ||= Time.now
  if @last_time and (Time.now - duration) > @last_time
    block.call
    @last_time = Time.now
  end
end

#word_sizes(words) ⇒ Object



44
45
46
# File 'lib/wheeler.rb', line 44

def word_sizes(words)
  words.map{|m| m.size } * ' '
end

#write_sizes(sizes, texts) ⇒ Object



104
105
106
107
108
# File 'lib/wheeler.rb', line 104

def write_sizes(sizes, texts)
  idx_path = "#{INDEX_PATH}/#{sizes.gsub(' ', '/')}"
  FileUtils.mkdir_p idx_path
  File.open("#{idx_path}/phrases", 'w') { |f| f << texts.join("\n") }
end