Skip to content

Instantly share code, notes, and snippets.

@AaronC81
Created December 2, 2019 17:35
Show Gist options
  • Save AaronC81/ecd2347ac70f92b694279d3cd488cec2 to your computer and use it in GitHub Desktop.
Save AaronC81/ecd2347ac70f92b694279d3cd488cec2 to your computer and use it in GitHub Desktop.
Work out the longest YMCA-able word
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