Skip to content

Instantly share code, notes, and snippets.

@takehiko
Created October 30, 2011 20:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takehiko/1326411 to your computer and use it in GitHub Desktop.
Save takehiko/1326411 to your computer and use it in GitHub Desktop.
Four fives: Method C
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
class Rot90c
def initialize
@field_s = (<<EOS).gsub(/\n/, "")
**
**
******
******
**
**
EOS
reset_field
@width = @height = 6
@field_size = @width * @height
setup_coord
@pos_1 = @width * (@height / 2 - 1) + @width / 2 - 1
end
def start
print_field
@qstar = count_star / 4
@stack = [] # array of position
@num_answer = 0
search
end
def setup_coord
@coord1 = {} # {0, 1, ..., @width-1} => {-@width/2, ..., -1, 1, ..., @width/2}
@coord2 = {} # inverse mapping of @coord1
half = @width / 2
@width.times do |i|
j = i - half
j += 1 if i >= half
@coord1[i] = j
@coord2[j] = i
end
end
def search(pos_start = 0)
pos_start.upto(@field_size - 1) do |i|
if @field[i, 1] == "*"
@stack << i
if @stack.length == @qstar
if @stack.index(@pos_1) && examine_field
@num_answer += 1
puts "Answer No.#{@num_answer}"
print_field
end
reset_field
else
search(i + 1)
end
@stack.pop
end
end
end
def examine_field
reset_field
@stack.each do |pos|
@field[pos, 1] = "1"
end
rotate_superpose("1", "2")
rotate_superpose("2", "3")
rotate_superpose("3", "4")
# If there is no "*" in the field, then that is a solution!
count_star == 0
end
def reset_field
@field = @field_s.dup
end
def count_star
@field.scan(/\*/).length
end
def print_field
@height.times do |i|
puts @field[@height * i, @width]
end
end
def xy_rot90(x_from, y_from)
x1 = @coord1[x_from]
y1 = @coord1[y_from]
x2 = y1
y2 = -x1
x_to = @coord2[x2]
y_to = @coord2[y2]
[x_to, y_to]
end
def rotate_superpose(c_from, c_to)
@field_size.times do |pos|
if @field[pos, 1] == c_from
y, x = pos.divmod(@width)
x_to, y_to = xy_rot90(x, y)
@field[@width * y_to + x_to] = c_to
end
end
end
end
if __FILE__ == $0
Rot90c.new.start
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment