-
Notifications
You must be signed in to change notification settings - Fork 0
/
solution_checker.rb
63 lines (60 loc) · 1.81 KB
/
solution_checker.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class SolutionChecker
def self.run(chromosome)
length, genes = chromosome.length, chromosome.genes
puts "Checking solution..."
# Prepare empty array.
occupied = genes.map { Array.new length, false }
err = 0
bound = length - 1
range = 0..bound
genes.each_with_index do |y, x|
err += 1 if occupied[x][y]
# Mark whole line as occupied
range.each do |i|
if occupied[i][y]
puts " (#{x},#{y})[+row]: already occupied at (#{i},#{y})."
err += 1
end
if occupied[x][i]
puts " (#{x},#{y})[+col]: already occupied at (#{i},#{y})."
err += 1
end
end
# Check top-right diagonal.
ty = y; ((x + 1)..bound).each do |tx|
break if (ty += 1) > bound
if tx != x && ty != y && occupied[tx][ty]
puts " (#{x},#{y})[dtr]: already taken at (#{tx},#{ty})."
err += 1
end
end
# Check top-left diagonal.
ty = y; (x - 1).downto(0).each do |tx|
break if (ty += 1) > bound
if tx != x && ty != y && occupied[tx][ty]
puts " (#{x},#{y})[dtl]: already taken at (#{tx},#{ty})."
err += 1
end
end
# Check bottom-right diagonal.
ty = y; ((x + 1)..bound).each do |tx|
break if (ty -= 1) < 0
if tx != x && ty != y && occupied[tx][ty]
puts " (#{x},#{y})[dbr]: already taken at (#{tx},#{ty})."
err += 1
end
end
# Check bottom-left diagonal.
ty = y; (x - 1).downto(0).each do |tx|
break if (ty -= 1) < 0
if tx != x && ty != y && occupied[tx][ty]
puts " (#{x},#{y})[dbl]: already taken at (#{tx},#{ty})."
err += 1
end
end
# Mark this position as occupied.
occupied[x][y] = true
end
err
end
end