In [8]:
given = """
C C C D D A A
E E E C C C E
D E D D E D E
E A E E D B A
A A A E A C A
C A E C A B A
D E D B C B D
C B C C B C B
C C D D E A C
C C D D A E C
B D B B D B D
D A E C A D C
B D B A D B B
D C D D C D C
C B A B D A B
E C E E A E B
E A E E A E A
B D D E C C D
A B A A B A B
A A C A C C C
D D A D D D A
"""
answer_to_idx = {answer: i for i, answer in enumerate('ABCDE')}
idx_to_answer = {v: k for k, v in answer_to_idx.items()}
expected_scores = [
5, 6, 5, 9, 8, 5, 10,
]
In [3]:
people = [[], [], [], [], [], [], []]
for line in given.strip('\n').split('\n'):
guesses = line.split('\t')
for person, guess in zip(people, guesses):
person.append(guess)
In [57]:
import Numberjack
grid = Numberjack.Matrix(22, 5, 0, 1, 'answers')
model = Numberjack.Model()
# One correct solution per row.
for question in range(0, 21):
model.add(
sum([grid[question][i] for i in range(0, 5)]) == 1
)
for person_idx, expected_score in enumerate(expected_scores):
person_guessed_correct = []
for question in range(0, 21):
person_guessed_correct.append(
grid[question][answer_to_idx[people[person_idx][question]]])
model.add(
sum(person_guessed_correct) == expected_score
)
solver = model.load('Mistral')
print('Solution is...')
solver.solve()
for row in range(0, 21):
print(grid[row])
print('Nodes:', solver.getNodes(), ' Time:', solver.getTime())
In [4]:
finished = [
[0, 0, 0, 0, 1],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 1],
[0, 0, 1, 0, 0],
[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 1, 0, 0],
[1, 0, 0, 0, 0],
[0, 0, 0, 1, 0],
[0, 1, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 1, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[1, 0, 0, 0, 0],
]
In [5]:
n_to_letter = []
for row in finished:
print(int(''.join(map(str, row)), 2))
In [37]:
import Numberjack
questions = Numberjack.VarArray(21, 5, 'answers')
model = Numberjack.Model()
for person_idx, expected_score in enumerate(expected_scores):
person_guessed_correct = []
for question in range(0, 21):
person_guessed_correct.append(
questions[question] == answer_to_idx[people[person_idx][question]])
model.add(
sum(person_guessed_correct) == expected_score
)
correct = """
A
E
D
B
A
C
D
B
E
D
D
E
A
D
A
E
A
C
B
C
A
"""
# Attempt to constrain != correct solution.
correct = """
A
E
D
B
A
C
D
B
E
D
D
E
A
D
A
E
A
C
B
"""
for question, answer in enumerate(correct.strip('\n').split('\n')):
print('#%s != %s' % (question, answer))
model.add(
questions[question] != answer_to_idx[answer]
)
solver = model.load('Mistral')
print('Solution is...')
solver.solve()
possibilities = [set() for _ in range(21)]
for row in range(0, 21):
print(idx_to_answer[questions[row].get_value()])
print('Nodes:', solver.getNodes(), ' Time:', solver.getTime())
n_solutions = 1
while solver.getNextSolution() and n_solutions < 1000:
n_solutions += 1
for row in range(0, 21):
# print(idx_to_answer[questions[row].get_value()])
possibilities[row].add(idx_to_answer[questions[row].get_value()])
print('Nodes:', solver.getNodes(), ' Time:', solver.getTime())
print(n_solutions)
print(possibilities)
In [20]:
possibilities
Out[20]:
In [ ]: