Skip to content

Instantly share code, notes, and snippets.

@samwho
Created September 18, 2022 18:01
Show Gist options
  • Select an option

  • Save samwho/df9460db8feab62f7610bc4f75cbc7c8 to your computer and use it in GitHub Desktop.

Select an option

Save samwho/df9460db8feab62f7610bc4f75cbc7c8 to your computer and use it in GitHub Desktop.
require 'set'
class Node
attr_accessor :value, :parent
def initialize(value = nil, parent = nil)
@is_word = false
@parent = parent
@value = value
@children = {}
end
def word
s = ""
node = self
while node.value
s += node.value
node = node.parent
end
s.reverse
end
def is_word?
@is_word
end
def mark_word
@is_word = true
end
def child(char)
if not @children.has_key?(char)
@children[char] = Node.new(char, self)
end
@children[char]
end
def to_s indent = 0
s = ""
if @value
s += ((" " * indent) + @value)
end
if @is_word
s += " (word)"
end
@children.each do |key, value|
s += "\n" + value.to_s(indent + 1)
end
s
end
end
def build_trie(words)
root = Node.new
words.each do |word|
node = root
word.each_char { |char| node = node.child(char) }
node.mark_word
end
root
end
def build_trie_from_file(file)
root = Node.new
File.open(file).each_line do |line|
node = root
line.strip.downcase.each_char { |char| node = node.child(char) }
node.mark_word
end
root
end
def substrings(string, dictionary)
root = build_trie(dictionary)
nodes = []
words = Set.new
result = Hash.new { |h, k| h[k] = 0 }
string.downcase.each_char do |char|
if char == ' '
words.each { |word| result[word] += 1 }
words.clear
next
end
nodes << root
nodes.each_with_index do |node, i|
nodes[i] = nodes[i].child(char)
if nodes[i].is_word?
words << nodes[i].word
end
end
end
words.each { |word| result[word] += 1 }
result
end
dictionary = ["below","down","go","going","horn","how","howdy","it","i","low","own","part","partner","sit"]
puts substrings("below", dictionary)
puts substrings("Howdy partner, sit down! How's it going?", dictionary)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment