X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=riddle_creator.md;fp=riddle_creator.md;h=36b939ac7ec65a26c9628b47325467ccadf2a199;hb=ce34915246926441c163272e09f1343db3fd1955;hp=0000000000000000000000000000000000000000;hpb=ffbfb5b3117178a49a93946daed6c2689df3e1b8;p=riddle-generator.git diff --git a/riddle_creator.md b/riddle_creator.md new file mode 100644 index 0000000..36b939a --- /dev/null +++ b/riddle_creator.md @@ -0,0 +1,214 @@ +--- +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 + +```