res = < good or match+N-a.compact.length < good } end def bf(a) return a if a.compact.length == N p = a.index(nil) || a.length (0..9).each { |i| a[p] = i next if test_fail(a) resp = bf(a) return resp if resp } a[p] = nil end # n = index of Tries we try to guess correct positions def solve(n=0, a=[]) if n == Tries.length p a return bf(a) end if Good[n] == 0 aa = solve(n+1, a) if not test_fail(a) return aa if aa else (0...N).each { |p1| if a[p1] next if a[p1] != Tries[n][p1] didp1 = false else didp1 = true a[p1] = Tries[n][p1] end if Good[n] == 1 aa = solve(n+1, a) if not test_fail(a) return aa if aa else (p1+1...N).each { |p2| puts "#{p1} #{p2}" if n == 0 if a[p2] next if a[p2] != Tries[n][p2] didp2 = false else didp2 = true a[p2] = Tries[n][p2] end if Good[n] == 2 aa = solve(n+1, a) if not test_fail(a) return aa if aa else (p2+1...N).each { |p3| if a[p3] next if a[p3] != Tries[n][p3] didp3 = false else didp3 = true a[p3] = Tries[n][p3] end aa = solve(n+1, a) if not test_fail(a) return aa if aa a[p3] = nil if didp3 } if not test_fail(a) end a[p2] = nil if didp2 } if not test_fail(a) end a[p1] = nil if didp1 } end nil end res = solve() || abort('no solution') puts Tries.zip(Good).map { |t, g| "#{t.join} ; #{g}" }, '', res.join, '' Tries.each { |t| N.times { |p| t[p] = '-' if t[p] != res[p] } } puts Tries.zip(Good).map { |t, g| "#{t.join} ; #{g}" }