Skip to content

Instantly share code, notes, and snippets.

@mchail
Created April 2, 2018 23:01
Show Gist options
  • Save mchail/1c990fd3da6efb6347e7e59cafc298e6 to your computer and use it in GitHub Desktop.
Save mchail/1c990fd3da6efb6347e7e59cafc298e6 to your computer and use it in GitHub Desktop.
Make words out of airport codes
# https://twitter.com/xor/status/978793975590150144
require 'open-uri'
require 'csv'
class PrefixTreeSearch
attr_reader :codes, :words, :root
attr_accessor :found
MAX_LENGTH = 12
def initialize
@codes = CSV.parse(
open('http://ourairports.com/data/airports.csv'),
headers: true,
).map do |row|
case row['type']
when 'large_airport', 'medium_airport'
row['iata_code']
else
nil
end
end.uniq.compact.sort.select do |row|
row =~ /^[A-Z]+$/
end
@words = open('/usr/share/dict/words').readlines.map(&:chomp).map(&:upcase)
build_tree
@found = []
end
def build_tree
@root = Node.new(nil)
words.each do |word|
letters = word.split('')
cursor = root
letters.each do |letter|
child = cursor.find_child(letter)
if child.nil?
child = Node.new(letter)
cursor.children << child
end
cursor = child
end
cursor.terminal = true
end
end
def is_word?(word)
root.is_terminal_path?(word.split(''))
end
def is_partial_word?(word)
root.is_path?(word.split(''))
end
def search(word = '')
if is_word?(word)
puts word
found << word
end
return if word.size >= MAX_LENGTH || !is_partial_word?(word)
codes.each do |code|
search(word + code)
end
end
class Node
attr_reader :children, :value
attr_accessor :terminal
def initialize(value)
@children = []
@value = value
@terminal = false
end
def find_child(value)
children.find do |child|
child.value == value
end
end
def is_path?(values)
cursor = self
values.each do |value|
cursor = cursor.find_child(value)
return false if cursor.nil?
end
true
end
def is_terminal_path?(values)
cursor = self
values.each do |value|
cursor = cursor.find_child(value)
return false if cursor.nil?
end
return cursor.terminal
end
end
end
PrefixTreeSearch.search
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment