--- /dev/null
+---
+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
+
+```