Skip to content

Instantly share code, notes, and snippets.

@shawnz
Created April 17, 2025 14:21
Show Gist options
  • Save shawnz/7c2d6afb4f67b872f05c3153e590118a to your computer and use it in GitHub Desktop.
Save shawnz/7c2d6afb4f67b872f05c3153e590118a to your computer and use it in GitHub Desktop.
import itertools
colours = ["red", "orange", "yellow", "green", "blue", "purple"]
people = ["caleb", "arje", "freddie", "beny"]
shapes = [
"pumpkin",
"wagon",
"pond",
"banana",
"lizard",
"hydrant",
"broccoli",
"map",
"grape",
"mountain",
"hourglass",
"heart",
]
worksheets = [
([None, "red", None, None, None, "red", None, None, None, "red", "red", "red"], 2),
(
[
"orange",
"red",
"blue",
"yellow",
"green",
"red",
"green",
"blue",
"purple",
"yellow",
"orange",
"purple",
],
10,
),
(
[
"orange",
"red",
"blue",
"yellow",
"purple",
"red",
"green",
"yellow",
"purple",
"yellow",
"green",
"orange",
],
9,
),
(
[
"orange",
"red",
"blue",
"yellow",
"red",
"red",
"green",
"blue",
"purple",
"blue",
"purple",
"orange",
],
10,
),
]
def check_contradictions(assumed_answers, worksheets):
if len(worksheets) == 0:
if any(answer is None for answer in assumed_answers):
print(f"underspecified: {assumed_answers=}")
elif any(
sum(answer == colour for answer in assumed_answers) > 2
for colour in colours
):
print(f"violates two colour rule: {assumed_answers=}")
else:
print(f"no contradiction: {assumed_answers=}")
return
worksheet, *remaining_worksheets = worksheets
worksheet_answers, grade = worksheet
assumed_correct = 0
assumed_wrong = 0
indeterminate = []
for i, answer in enumerate(assumed_answers):
if answer is None and worksheet_answers[i] is None:
pass
elif answer is None and worksheet_answers[i] is not None:
indeterminate.append(i)
elif answer == worksheet_answers[i]:
assumed_correct += 1
else:
assumed_wrong += 1
if not (assumed_correct <= grade <= (12 - assumed_wrong)):
return
combinations = itertools.combinations(indeterminate, r=(grade - assumed_correct))
for combination in combinations:
candidate_answers = assumed_answers.copy()
for n in combination:
candidate_answers[n] = worksheet_answers[n]
check_contradictions(candidate_answers, remaining_worksheets)
return
check_contradictions([None] * 12, worksheets)
# Brute-force approach
# def get_permutations(colours, repeats, max_length, starting_with=[]):
# if len(starting_with) >= max_length:
# yield starting_with
# for colour in colours:
# if sum(val == colour for val in starting_with) >= repeats:
# continue
# for permutation in get_permutations(
# colours, repeats, max_length, starting_with + [colour]
# ):
# yield permutation
# permutations = get_permutations(colours, 2, 12)
# for permutation in permutations:
# valid_worksheets = 0
# for worksheet, grade in worksheets:
# computed_grade = 0
# for i, answer in enumerate(worksheet):
# if permutation[i] == answer:
# computed_grade += 1
# if computed_grade == grade:
# valid_worksheets += 1
# if valid_worksheets == len(worksheets):
# print(f"possible permutation: {permutation}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment