Tidying and documentation
[riddle-generator.git] / riddle_solver.md
1 ---
2 jupyter:
3 jupytext:
4 formats: ipynb,md
5 text_representation:
6 extension: .md
7 format_name: markdown
8 format_version: '1.3'
9 jupytext_version: 1.14.5
10 kernelspec:
11 display_name: Python 3 (ipykernel)
12 language: python
13 name: python3
14 ---
15
16 ```python
17 from riddle_definitions import *
18
19 import re
20 from typing import Dict, Tuple, List, Set
21 from enum import Enum, auto
22 ```
23
24 ```python
25 def tokenise(phrase: str) -> List[str]:
26 return [w.lower() for w in re.split(r'\W+', phrase) if w]
27 ```
28
29 ```python
30 tokenise("My first is in apple, but not in fish.")
31 ```
32
33 ```python
34 def parse_line(tokens: List[str]) -> Tuple[int, Tuple[RiddleClue, RiddleClue]]:
35 stripped_tokens = [t for t in tokens if t not in stop_words]
36
37 position_word = [t for t in stripped_tokens if t in ordinals][0]
38 pos = from_ordinal(position_word)
39
40 indexed_words = [(i, t) for i, t in enumerate(stripped_tokens)
41 if t not in ordinals
42 if t not in negative_words]
43
44 first_index, first_word = indexed_words[0]
45 second_index, second_word = indexed_words[1]
46
47 neg_indices = [i for i, t in enumerate(stripped_tokens) if t in negative_words]
48
49 first_clue = None
50 second_clue = None
51
52 if neg_indices:
53 if neg_indices[0] < first_index:
54 first_clue = RiddleClue(valence = RiddleValence.Exclude,
55 word = first_word)
56 if len(neg_indices) > 1:
57 second_clue = RiddleClue(valence = RiddleValence.Exclude,
58 word = second_word)
59 elif neg_indices[0] < second_index:
60 second_clue = RiddleClue(valence = RiddleValence.Exclude,
61 word = second_word)
62
63 if first_clue is None:
64 first_clue = RiddleClue(valence = RiddleValence.Include,
65 word = first_word)
66
67 if second_clue is None:
68 second_clue = RiddleClue(valence = RiddleValence.Include,
69 word = second_word)
70
71 return (pos, (first_clue, second_clue))
72 ```
73
74 ```python
75 e1 = parse_line(tokenise("My first is in apple, but not in pad."))
76 e1
77 ```
78
79 ```python
80 e2 = parse_line(tokenise("My second is in apple and also in banana."))
81 e2
82 ```
83
84 ```python
85 e3 = parse_line(tokenise('My seventh is neither in callus nor in calves'))
86 e3
87 ```
88
89 ```python
90 sample_riddle_text = """My first is in shoat but not in oath
91 My second is in orate but not in ratter
92 My third is in preposition but not in osteoporosis
93 My fourth is in astern but not in taster
94 My fifth is in conscientiousness but not in suction
95 My sixth is in immorality but not in immorally"""
96
97 sample_riddle_lines = {i: elem
98 for i, elem in
99 [parse_line(tokenise(l))
100 for l in sample_riddle_text.split('\n')]}
101 sample_riddle_lines
102 ```
103
104 ```python
105 sample_riddle = collapse_riddle_clues(sample_riddle_lines)
106 sample_riddle
107 ```
108
109 ```python
110 def parse_riddle(riddle_text: str) -> Riddle:
111 return {i: elem
112 for i, elem in
113 [parse_line(tokenise(l))
114 for l in riddle_text.split('\n')]}
115 ```
116
117 ```python
118 solve_riddle(sample_riddle)
119 ```
120
121 ```python
122 def parse_and_solve_riddle(riddle_text: str) -> List[str]:
123 riddle = parse_riddle(riddle_text)
124 elems = collapse_riddle_clues(riddle)
125 return solve_riddle(elems)
126 ```
127
128 ```python
129 sample_riddles = open('sample-riddles.txt').read().split('\n\n')
130 sample_riddles
131 ```
132
133 ```python
134 [parse_and_solve_riddle(r) for r in sample_riddles]
135 ```
136
137 ```python
138 sample_riddles = open('generated-riddles.txt').read().split('\n\n')
139 sample_riddles = [riddle.split('\nTarget: ') for riddle in sample_riddles]
140 sample_riddles = [(r, s.strip()) for r, s in sample_riddles]
141 sample_riddles
142 ```
143
144 ```python
145 for r, s in sample_riddles:
146 found_solns = parse_and_solve_riddle(r)
147 correct = len(found_solns) == 1 and found_solns[0] == s
148 print(found_solns, s, correct)
149 ```
150
151 ```python
152 # [parse_line(tokenise(line)) for line in sample_riddles[4][0]]
153 [parse_line(tokenise(line)) for line in sample_riddles[4][0].split('\n')]
154 ```
155
156 ```python
157 parse_riddle(sample_riddles[4][0])
158 ```
159
160 ```python
161
162 ```