Skip to content

Instantly share code, notes, and snippets.

@kenaniah
Last active August 5, 2017 23:28
Show Gist options
  • Save kenaniah/4616613995b221b5e6f0205e8875e200 to your computer and use it in GitHub Desktop.
Save kenaniah/4616613995b221b5e6f0205e8875e200 to your computer and use it in GitHub Desktop.
Capitals Word Finder
#!/usr/bin/env ruby
require 'colorize'
require 'sequel'
DB = Sequel.connect "postgres:///ospd"
# Helper method
class String
def counts
self
.downcase
.strip
.split("")
.group_by{ |v| v }
.map{ |k, v| [k.to_sym, v.count] }
.sort
.to_h
end
end
# Table schema
DB << <<~SQL
CREATE TABLE IF NOT EXISTS words (
id SERIAL PRIMARY KEY,
word TEXT,
a INTEGER NOT NULL DEFAULT 0,
b INTEGER NOT NULL DEFAULT 0,
c INTEGER NOT NULL DEFAULT 0,
d INTEGER NOT NULL DEFAULT 0,
e INTEGER NOT NULL DEFAULT 0,
f INTEGER NOT NULL DEFAULT 0,
g INTEGER NOT NULL DEFAULT 0,
h INTEGER NOT NULL DEFAULT 0,
i INTEGER NOT NULL DEFAULT 0,
j INTEGER NOT NULL DEFAULT 0,
k INTEGER NOT NULL DEFAULT 0,
l INTEGER NOT NULL DEFAULT 0,
m INTEGER NOT NULL DEFAULT 0,
n INTEGER NOT NULL DEFAULT 0,
o INTEGER NOT NULL DEFAULT 0,
p INTEGER NOT NULL DEFAULT 0,
q INTEGER NOT NULL DEFAULT 0,
r INTEGER NOT NULL DEFAULT 0,
s INTEGER NOT NULL DEFAULT 0,
t INTEGER NOT NULL DEFAULT 0,
u INTEGER NOT NULL DEFAULT 0,
v INTEGER NOT NULL DEFAULT 0,
w INTEGER NOT NULL DEFAULT 0,
x INTEGER NOT NULL DEFAULT 0,
y INTEGER NOT NULL DEFAULT 0,
z INTEGER NOT NULL DEFAULT 0,
"-" INTEGER NOT NULL DEFAULT 0
);
SQL
# Table data
unless DB[:words].count > 0
require 'open-uri'
open("https://github.com/dwyl/english-words/raw/master/words_alpha.txt").each do |word|
# Add to the database
row = { word: word.strip }.merge word.counts
DB[:words].insert row
end
end
# Parse inputs
available = (ARGV[0] || "").counts
required = (ARGV[1] || "").counts
puts "----".white
puts "Available letters: ".white + available.map{ |k, v| "#{k.upcase} => #{v}" }.join(", ")
puts "Required letters: ".white + required.map{ |k, v| "#{k.upcase} => #{v}" }.join(", ")
puts "----".white
# Determine query ranges
query = DB[:words]
(:a..:z).each do |char|
min = required[char] || 0
max = available[char] || 0
query = query.where Sequel.lit("#{char} BETWEEN #{min} AND #{max}")
end
query = query.order Sequel.lit("LENGTH(word) DESC")
# Run the query
puts "#{query.count} words found...".blue.bold
query.limit(20).each do |result|
puts result[:word].green
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment