--- /dev/null
+---
+jupyter:
+ jupytext:
+ formats: ipynb,md,py:percent
+ 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 *
+
+from typing import Dict, Tuple, List, Set
+from enum import Enum, auto
+import random
+```
+
+```python
+def include_exclude_clue(letter: str, limit: int = 3) -> (RiddleClue, RiddleClue):
+ with_letter = [w for w in dictionary if letter in w]
+ without_letter = [w for w in dictionary if letter not in w]
+
+ finished = False
+ while not finished:
+ a = random.choice(with_letter)
+ b = random.choice(without_letter)
+ finished = ((edit_distance(a, b) <= limit) and
+ not set(a) <= set(b) and
+ not set(a) >= set(b))
+ return (RiddleClue(word=a, valence=RiddleValence.Include),
+ RiddleClue(word=b, valence=RiddleValence.Exclude))
+
+a, b = include_exclude_clue('s')
+a, b, set(a.word) - set(b.word), edit_distance(a.word, b.word)
+```
+
+```python
+def include_include_clue(letter: str, limit: int = 3) -> (RiddleClue, RiddleClue):
+ with_letter = [w for w in dictionary if letter in w]
+
+ finished = False
+ while not finished:
+ a = random.choice(with_letter)
+ b = random.choice(with_letter)
+ finished = ((a != b) and
+ (edit_distance(a, b) <= limit) and
+ not set(a) <= set(b) and
+ not set(a) >= set(b))
+ return (RiddleClue(word=a, valence=RiddleValence.Include),
+ RiddleClue(word=b, valence=RiddleValence.Include))
+
+a, b = include_include_clue('s')
+a, b, set(a.word) | set(b.word), edit_distance(a.word, b.word)
+```
+
+```python
+def exclude_exclude_clue(letter: str, limit: int = 3) -> (RiddleClue, RiddleClue):
+ without_letter = [w for w in dictionary if letter not in w]
+
+ finished = False
+ while not finished:
+ a = random.choice(without_letter)
+ b = random.choice(without_letter)
+ finished = ((a != b) and
+ (edit_distance(a, b) <= limit) and
+ not set(a) <= set(b) and
+ not set(a) >= set(b))
+ return (RiddleClue(word=a, valence=RiddleValence.Exclude),
+ RiddleClue(word=b, valence=RiddleValence.Exclude))
+
+a, b = exclude_exclude_clue('s')
+a, b, set(a.word) | set(b.word), edit_distance(a.word, b.word)
+```
+
+```python
+def random_clue( letter: str
+ , ie_limit: int = 3
+ , ii_limit: int = 2
+ , ee_limit: int = 2) -> (RiddleClue, RiddleClue):
+ r = random.random()
+ if r <= 0.7:
+ return include_exclude_clue(letter, limit=ie_limit)
+ elif r <= 0.9:
+ return include_include_clue(letter, limit=ii_limit)
+ else:
+ return exclude_exclude_clue(letter, limit=ee_limit)
+```
+
+```python
+def random_riddle(word: str, limit: int = 3) -> Riddle:
+ return {i+1 : random_clue(l, ie_limit=limit)
+ for i, l in enumerate(word)}
+```
+
+```python
+sample_riddle = random_riddle('sonnet')
+sample_riddle
+```
+
+```python
+
+```
+
+```python
+sample_riddle = random_riddle('sonnet', limit=4)
+sample_riddle
+```
+
+```python
+sample_riddle
+```
+
+```python
+collapse_riddle_clues(sample_riddle)
+```
+
+```python
+solve_riddle(collapse_riddle_clues(sample_riddle))
+```
+
+```python
+def valid_random_riddle(word: str) -> Riddle:
+ finished = False
+ while not finished:
+ riddle = random_riddle(word)
+ solns = solve_riddle(collapse_riddle_clues(riddle))
+ finished = (len(solns) == 1)
+ return riddle
+```
+
+```python
+def write_include_exclude_line(clue_a: RiddleClue, clue_b: RiddleClue) -> str:
+ line = f"is in {clue_a.word} but not in {clue_b.word}"
+ return line
+```
+
+```python
+def write_include_include_line(clue_a: RiddleClue, clue_b: RiddleClue) -> str:
+ line = f"is in {clue_a.word} and also in {clue_b.word}"
+ return line
+```
+
+```python
+def write_exclude_exclude_line(clue_a: RiddleClue, clue_b: RiddleClue) -> str:
+ line = f"is neither in {clue_a.word} nor in {clue_b.word}"
+ return line
+```
+
+```python
+def write_line(a: RiddleClue, b: RiddleClue) -> str:
+ if a.valence == RiddleValence.Include and b.valence == RiddleValence.Include:
+ return write_include_include_line(a, b)
+ elif a.valence == RiddleValence.Include and b.valence == RiddleValence.Exclude:
+ return write_include_exclude_line(a, b)
+ elif a.valence == RiddleValence.Exclude and b.valence == RiddleValence.Exclude:
+ return write_exclude_exclude_line(a, b)
+ else:
+ return "illegal line"
+```
+
+```python
+def write_riddle(riddle: Riddle) -> List[str]:
+ output = []
+ for i, (clue_a, clue_b) in sorted(riddle.items()):
+ pos = reverse_ordinals[i]
+ if i == len(riddle) and random.random() <= 0.3:
+ pos = reverse_ordinals[-1]
+ line = write_line(clue_a, clue_b)
+ full_line = f"My {pos} {line}"
+ output.append(full_line)
+ return output
+```
+
+```python
+
+```
+
+```python
+sample_riddle = valid_random_riddle("elephant")
+sample_riddle
+```
+
+```python
+write_riddle(sample_riddle)
+```
+
+```python
+solve_riddle(collapse_riddle_clues(sample_riddle))
+```
+
+```python
+with open("generated-riddles.txt", 'w') as file:
+ between = False
+ for _ in range(10):
+ if between:
+ file.write('\n')
+ between = True
+ target = random.choice(dictionary)
+ riddle = valid_random_riddle(target)
+ lines = write_riddle(riddle)
+ file.writelines(l + '\n' for l in lines)
+ file.write(f'Target: {target}\n')
+
+```
+
+```python
+
+```