X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;ds=sidebyside;f=riddle_solver.md;fp=riddle_solver.md;h=a9e3064dd36242c65fd1b04a11d203e3143ba3d9;hb=ce34915246926441c163272e09f1343db3fd1955;hp=0000000000000000000000000000000000000000;hpb=ffbfb5b3117178a49a93946daed6c2689df3e1b8;p=riddle-generator.git diff --git a/riddle_solver.md b/riddle_solver.md new file mode 100644 index 0000000..a9e3064 --- /dev/null +++ b/riddle_solver.md @@ -0,0 +1,160 @@ +--- +jupyter: + jupytext: + formats: ipynb,md + text_representation: + extension: .md + format_name: markdown + format_version: '1.3' + jupytext_version: 1.14.5 + kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +```python +from riddle_definitions import * + +import re +from typing import Dict, Tuple, List, Set +from enum import Enum, auto +``` + +```python +def tokenise(phrase: str) -> List[str]: + return [w.lower() for w in re.split(r'\W+', phrase) if w] +``` + +```python +tokenise("My first is in apple, but not in fish.") +``` + +```python +def parse_line(tokens: List[str]) -> Tuple[int, Tuple[RiddleClue, RiddleClue]]: + stripped_tokens = [t for t in tokens if t not in stop_words] + + position_word = [t for t in stripped_tokens if t in ordinals][0] + pos = from_ordinal(position_word) + + first_index, first_word = [(i, t) for i, t in enumerate(stripped_tokens) + if t not in ordinals + if t not in negative_words][0] + second_index, second_word = [(i, t) for i, t in enumerate(stripped_tokens) + if t not in ordinals + if t not in negative_words][1] + neg_indices = [i for i, t in enumerate(stripped_tokens) if t in negative_words] + + first_clue = None + second_clue = None + + if neg_indices: + if neg_indices[0] < first_index: + first_clue = RiddleClue(valence = RiddleValence.Exclude, + word = first_word) + if len(neg_indices) > 1: + second_clue = RiddleClue(valence = RiddleValence.Exclude, + word = second_word) + elif neg_indices[0] < second_index: + second_clue = RiddleClue(valence = RiddleValence.Exclude, + word = second_word) + + if first_clue is None: + first_clue = RiddleClue(valence = RiddleValence.Include, + word = first_word) + + if second_clue is None: + second_clue = RiddleClue(valence = RiddleValence.Include, + word = second_word) + + return (pos, (first_clue, second_clue)) +``` + +```python +e1 = parse_line(tokenise("My first is in apple, but not in pad.")) +e1 +``` + +```python +e2 = parse_line(tokenise("My second is in apple and also in banana.")) +e2 +``` + +```python +e3 = parse_line(tokenise('My seventh is neither in callus nor in calves')) +e3 +``` + +```python +sample_riddle_text = """My first is in shoat but not in oath +My second is in orate but not in ratter +My third is in preposition but not in osteoporosis +My fourth is in astern but not in taster +My fifth is in conscientiousness but not in suction +My sixth is in immorality but not in immorally""" + +sample_riddle_lines = {i: elem + for i, elem in + [parse_line(tokenise(l)) + for l in sample_riddle_text.split('\n')]} +sample_riddle_lines +``` + +```python +sample_riddle = collapse_riddle_clues(sample_riddle_lines) +sample_riddle +``` + +```python +def parse_riddle(riddle_text: str) -> Riddle: + riddle_lines = {i: elem + for i, elem in + [parse_line(tokenise(l)) for l in riddle_text.split('\n')]} + return collapse_riddle_clues(riddle_lines) +``` + +```python +solve_riddle(sample_riddle) +``` + +```python +def parse_and_solve_riddle(riddle_text: str) -> List[str]: + riddle = parse_riddle(riddle_text) + return solve_riddle(riddle) +``` + +```python +sample_riddles = open('sample-riddles.txt').read().split('\n\n') +sample_riddles +``` + +```python +[parse_and_solve_riddle(r) for r in sample_riddles] +``` + +```python +sample_riddles = open('generated-riddles.txt').read().split('\n\n') +sample_riddles = [riddle.split('\nTarget: ') for riddle in sample_riddles] +sample_riddles = [(r, s.strip()) for r, s in sample_riddles] +sample_riddles +``` + +```python +for r, s in sample_riddles: + found_solns = parse_and_solve_riddle(r) + correct = len(found_solns) == 1 and found_solns[0] == s + print(found_solns, s, correct) +``` + +```python +# [parse_line(tokenise(line)) for line in sample_riddles[4][0]] +[parse_line(tokenise(line)) for line in sample_riddles[4][0].split('\n')] +``` + +```python +parse_riddle(sample_riddles[4][0]) +``` + +```python + +```