Skip to content

Instantly share code, notes, and snippets.

@skunkworker
Last active January 6, 2019 06:35
Show Gist options
  • Save skunkworker/b481dfada5e5b152334b8d188f3854c5 to your computer and use it in GitHub Desktop.
Save skunkworker/b481dfada5e5b152334b8d188f3854c5 to your computer and use it in GitHub Desktop.
New York Times SET puzzle solver
# Brute force NYT set Solver.
# from https://www.nytimes.com/puzzles/set - Accessed Jan 6
require 'set'
class Item
include Comparable
attr_accessor :color, :shape, :pattern, :item_count
def initialize(color:, shape:, pattern:, item_count:)
self.color = color
self.shape = shape
self.pattern = pattern
self.item_count = item_count
end
def inspect
"#{color} #{shape} #{pattern} #{item_count}"
end
end
class ItemSet
attr_accessor :items
def initialize(params)
@name = params[:name]
@items = []
@solutions = []
end
def add_item(item_color, item_shape, item_pattern, item_count)
items << Item.new(color: item_color, shape: item_shape, pattern: item_pattern, item_count: item_count)
end
def solve!
# find unique sets.
# look_for_same_color
puts "\nSolving #{@name}"
permutations = items.permutation(3).to_a
puts "#{permutations.count} permutations"
permutations.each do |perm|
@solutions << Set[*perm] if valid_set?(Set[*perm])
end
@solutions.uniq.each do |s|
puts s.inspect
end
end
private
# This is a card-matching game. Cards have 4 features, each with 3 variations:
# A SET is 3 cards for which each feature is either common across all 3 cards or is different on each card.
def valid_set?(items = Set[])
return false if items.count != 3
_color_count = items.map{|i| i.color}.uniq.count
_shape_count = items.map{|i| i.shape}.uniq.count
_pattern_count = items.map{|i| i.pattern}.uniq.count
_count_count = items.map{|i| i.item_count}.uniq.count
_color = (_color_count == 1 || _color_count == 3)
_shape = (_shape_count == 1 || _shape_count == 3)
_pattern = (_pattern_count == 1 || _pattern_count == 3)
_count = (_count_count == 1 || _count_count == 3)
return [_color,_shape,_pattern,_count].count(true) == 4
end
end
item_set = ItemSet.new(name: "Basic 1")
item_set.add_item(:green, :diamond, :striped, 1)
item_set.add_item(:green, :diamond, :solid, 1)
item_set.add_item(:purple, :diamond, :striped, 2)
item_set.add_item(:green, :diamond, :striped, 3)
item_set.add_item(:green, :diamond, :bordered, 2)
item_set.add_item(:purple, :diamond, :bordered, 3)
item_set.add_item(:purple, :diamond, :solid, 1)
item_set.add_item(:red, :diamond, :striped, 2)
item_set.add_item(:red, :diamond, :striped, 1)
item_set.solve!
# Advanced 1
item_set = ItemSet.new(name: "Advanced 1")
item_set.add_item(:red, :squiggly, :bordered, 2)
item_set.add_item(:red, :squiggly, :striped, 2)
item_set.add_item(:red, :squiggly, :striped, 1)
item_set.add_item(:purple, :oval, :bordered, 2)
item_set.add_item(:purple, :diamond, :bordered, 2)
item_set.add_item(:green, :oval, :solid, 3)
item_set.add_item(:red, :squiggly, :solid, 2)
item_set.add_item(:purple, :squiggly, :solid, 3)
item_set.add_item(:purple, :diamond, :striped, 1)
item_set.add_item(:purple, :oval, :striped, 2)
item_set.add_item(:green, :diamond, :striped, 2)
item_set.add_item(:red, :oval, :solid, 2)
item_set.solve!
# Advanced 2
item_set = ItemSet.new(name: "Advanced 2")
item_set.add_item(:purple, :squiggly, :solid, 1)
item_set.add_item(:purple, :diamond, :striped, 3)
item_set.add_item(:green, :oval, :solid, 2)
item_set.add_item(:purple, :diamond, :solid, 2)
item_set.add_item(:red, :oval, :bordered, 3)
item_set.add_item(:purple, :oval, :striped, 1)
item_set.add_item(:green, :diamond, :bordered, 3)
item_set.add_item(:green, :squiggly, :striped, 1)
item_set.add_item(:red, :squiggly, :solid, 3)
item_set.add_item(:green, :oval, :bordered, 3)
item_set.add_item(:red, :diamond, :striped, 1)
item_set.add_item(:red, :squiggly, :bordered, 2)
item_set.solve!
@skunkworker
Copy link
Author

Output is

Solving Basic 1
504 permutations
#<Set: {green diamond solid 1, green diamond striped 3, green diamond bordered 2}>
#<Set: {green diamond solid 1, purple diamond bordered 3, red diamond striped 2}>
#<Set: {purple diamond striped 2, green diamond striped 3, red diamond striped 1}>
#<Set: {purple diamond striped 2, purple diamond bordered 3, purple diamond solid 1}>

Solving Advanced 1
1320 permutations
#<Set: {red squiggly bordered 2, red squiggly striped 2, red squiggly solid 2}>
#<Set: {red squiggly bordered 2, green oval solid 3, purple diamond striped 1}>
#<Set: {red squiggly striped 2, purple oval striped 2, green diamond striped 2}>
#<Set: {red squiggly striped 1, purple diamond bordered 2, green oval solid 3}>
#<Set: {purple oval bordered 2, red squiggly solid 2, green diamond striped 2}>
#<Set: {purple oval bordered 2, purple squiggly solid 3, purple diamond striped 1}>

Solving Advanced 2
1320 permutations
#<Set: {purple diamond striped 3, red squiggly solid 3, green oval bordered 3}>
#<Set: {green oval solid 2, red oval bordered 3, purple oval striped 1}>
#<Set: {green oval solid 2, green diamond bordered 3, green squiggly striped 1}>
#<Set: {purple diamond solid 2, red oval bordered 3, green squiggly striped 1}>
#<Set: {purple diamond solid 2, green diamond bordered 3, red diamond striped 1}>
#<Set: {purple oval striped 1, green squiggly striped 1, red diamond striped 1}>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment