"""Enumerate feedback-compatible partitions; no game requests or answer key.""" from itertools import combinations from pathlib import Path import json WORDS = tuple('ABCDEFGH') GUESSES = (set('ABCD'), set('ABCE')) def partitions(): # Name the first group by its containing A; complementary duplicates vanish. for rest in combinations(WORDS[1:], 3): group = {'A', *rest} yield group, set(WORDS) - group def near_miss(partition, guess): return max(len(group & guess) for group in partition) == 3 def main(): original = list(partitions()) first = [p for p in original if near_miss(p, GUESSES[0])] second = [p for p in first if near_miss(p, GUESSES[1])] assert (len(original), len(first), len(second)) == (35, 16, 6) # Independent representation: all 70 labelled four-bit subsets. The two # intersection cardinalities must each be either one or three. masks = [m for m in range(256) if m.bit_count() == 4] valid_masks = [m for m in masks if (m & 0b00001111).bit_count() in (1, 3) and (m & 0b00010111).bit_count() in (1, 3)] assert len(valid_masks) == 12 canonical = {min(m, m ^ 255) for m in valid_masks} groups_as_masks = {min(sum(1 << WORDS.index(w) for w in p[0]), sum(1 << WORDS.index(w) for w in p[1])) for p in second} assert canonical == groups_as_masks pair_results = [] for pair in combinations(WORDS, 2): together = [p for p in second if any(set(pair) <= g for g in p)] split = next((p for p in second if not any(set(pair) <= g for g in p)), None) pair_results.append({'pair': list(pair), 'together_count': len(together), 'counterexample': [sorted(g) for g in split] if split else None}) assert [r['pair'] for r in pair_results if r['together_count'] == 6] == [['D', 'E']] assert all(0 < r['together_count'] <= 6 for r in pair_results) result = {'assumptions': 'Eight distinct tokens, partitioned into two groups of four; each given guess has exactly three members of one group.', 'guesses': [sorted(g) for g in GUESSES], 'partition_counts': [35, 16, 6], 'partitions': [[sorted(g) for g in p] for p in second], 'pairs': pair_results, 'verification': {'set_and_bitmask_enumerations_agree': True, 'pairs_checked': len(pair_results), 'unique_guaranteed_pair': ['D', 'E'], 'enumeration_requires_actual_game_answer': False}} path = Path(__file__).with_name('verification.json') path.write_text(json.dumps(result, indent=2) + '\n') print(json.dumps({k: result[k] for k in ('partition_counts', 'verification')}, indent=2)) if __name__ == '__main__': main()