Created
December 2, 2019 17:35
-
-
Save AaronC81/ecd2347ac70f92b694279d3cd488cec2 to your computer and use it in GitHub Desktop.
Work out the longest YMCA-able word
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Object | |
# Deeply clones this object, if it can be marshalled. | |
def deep_clone | |
Marshal.load(Marshal.dump(self)) | |
end | |
end | |
class String | |
# Determines whether this string contains only characters from one permutation | |
# of a given set of choices (excluding any "core" characters). | |
# | |
# @param [<String>] core The core characters. These are always allowed to | |
# appear. | |
# @param [<<String>>] choices An array of sets of characters. From each set of | |
# characters, only one element is allowed to appear in the string. No two | |
# choices should contain the same character, nor should any character in a | |
# choice appear in the core characters. | |
# @return [Boolean] | |
def contains_only_one_permutation?(core, choices) | |
chosen_from_choices = [] | |
remaining_choices = choices.deep_clone | |
self.chars.all? do |char| | |
# Are we obviously allowed to use this character? | |
# (i.e, is it a core character, or was it chosen from a choice) | |
next true if core.include?(char) || chosen_from_choices.include?(char) | |
# If not, search the choices for it | |
success = false | |
remaining_choices.each do |choice| | |
if choice.include?(char) | |
# We found a choice we can use for this character | |
remaining_choices.delete(choice) | |
chosen_from_choices << char | |
success = true | |
break | |
end | |
end | |
# Return whether or not this search succeeded for this iteration | |
success | |
end | |
end | |
end | |
# Load all words in uppercase, filter to alphabetic only, and sort by descending length | |
words = File | |
.read('/usr/share/dict/words') | |
.split("\n") | |
.select { |x| /[A-Za-z]/ === x } | |
.map(&:upcase) | |
.sort_by(&:length) | |
.reverse | |
# Find the first word matching our rules | |
words.each do |word| | |
if word.contains_only_one_permutation?( | |
[ | |
'A', # arms stretched upwards (pointier than O) | |
'B', # arms to the side, curving into torso | |
'C', # obvious | |
# D conflicts with P | |
# not enough limbs for E | |
'F', # arms straight out to the side, | |
# G is too complicated | |
# H would need legs | |
'I', # arms straight up | |
# J would need legs | |
'K', # obvious | |
'L', # one arm up, one arm out to side | |
'M', # arms diagonally down | |
# N would need legs | |
'O', # arms up in an arc | |
# P conflicts with D | |
# Q is too hard | |
# R would need legs | |
# S could be one arm arcing up, one arcing the other way down, but that's a bit of a stretch | |
'T', # T-pose | |
'U', # arms arcing out from the side upwards | |
# V conflicts with Y and W | |
# W conflicts with Y and V | |
# X would need legs | |
# Y conflicts with V and W | |
# Z is too hard | |
], | |
[ | |
# Arms joining in an arc at the side | |
["D", "P"], | |
# Arms up in a V shape | |
["V", "W", "Y"] | |
] | |
) | |
puts word | |
break | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment