Removed neighbour generation out of the core library
[riddle-generator.git] / riddle_creator_filtered_dict.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 from typing import Dict, Tuple, List, Set
20 from enum import Enum, auto
21 import random
22 import gzip
23 ```
24
25 ```python
26 dictionary_neighbours = {}
27
28 for line in gzip.open('dictionary_neighbours.txt.gz', 'rt').readlines():
29 words = line.strip().split(',')
30 dictionary_neighbours[words[0]] = words[1:]
31
32 possible_riddle_solutions = list(dictionary_neighbours.keys())
33 ```
34
35 ```python
36 len(dictionary_neighbours['sonnet'])
37 ```
38
39 ```python
40 def include_exclude_clue(letter: str, limit: int = 3) -> (RiddleClue, RiddleClue):
41 finished = False
42 while not finished:
43 with_letter = random.choice([w for w in dictionary_neighbours if letter in w])
44 without_letter = [w for w in dictionary_neighbours[with_letter]
45 if letter not in w
46 if edit_distance(with_letter, w) <= limit]
47 if without_letter:
48 other = random.choice(without_letter)
49 finished = True
50
51 return (RiddleClue(word=with_letter, valence=RiddleValence.Include),
52 RiddleClue(word=other, valence=RiddleValence.Exclude))
53
54 a, b = include_exclude_clue('s')
55 a, b, set(a.word) - set(b.word), edit_distance(a.word, b.word)
56 ```
57
58 ```python
59 def include_include_clue(letter: str, limit: int = 3) -> (RiddleClue, RiddleClue):
60 finished = False
61 while not finished:
62 with_letter = random.choice([w for w in dictionary_neighbours if letter in w])
63 others = [w for w in dictionary_neighbours[with_letter]
64 if letter in w
65 if edit_distance(with_letter, w) <= limit]
66 if others:
67 other = random.choice(others)
68 finished = True
69 return (RiddleClue(word=with_letter, valence=RiddleValence.Include),
70 RiddleClue(word=other, valence=RiddleValence.Include))
71
72 a, b = include_include_clue('s')
73 a, b, set(a.word) | set(b.word), edit_distance(a.word, b.word)
74 ```
75
76 ```python
77 def exclude_exclude_clue(letter: str, limit: int = 3) -> (RiddleClue, RiddleClue):
78 finished = False
79 while not finished:
80 without_letter = random.choice([w for w in dictionary_neighbours if letter not in w])
81 others = [w for w in dictionary_neighbours[without_letter]
82 if letter not in w
83 if edit_distance(without_letter, w) <= limit]
84 if others:
85 other = random.choice(others)
86 finished = True
87
88 return (RiddleClue(word=without_letter, valence=RiddleValence.Exclude),
89 RiddleClue(word=other, valence=RiddleValence.Exclude))
90
91 a, b = exclude_exclude_clue('s')
92 a, b, set(a.word) | set(b.word), edit_distance(a.word, b.word)
93 ```
94
95 ```python
96 def random_clue( letter: str
97 , ie_limit: int = 3
98 , ii_limit: int = 2
99 , ee_limit: int = 2) -> (RiddleClue, RiddleClue):
100 clue_type = random.choices(['include_exclude', 'include_include', 'exclude_exclude'],
101 weights=[7, 2, 1],
102 k=1)[0]
103 if clue_type == 'include_exclude':
104 return include_exclude_clue(letter, limit=ie_limit)
105 elif clue_type =='include_include':
106 return include_include_clue(letter, limit=ii_limit)
107 else:
108 return exclude_exclude_clue(letter, limit=ee_limit)
109 ```
110
111 ```python
112 def random_riddle( word: str
113 , ie_limit: int = 3
114 , ii_limit: int = 2
115 , ee_limit: int = 2
116 ) -> Riddle:
117 return {i+1 :
118 random_clue(l,
119 ie_limit=ie_limit, ii_limit=ii_limit, ee_limit=ee_limit)
120 for i, l in enumerate(word)}
121 ```
122
123 ```python
124 sample_riddle = random_riddle('teacup')
125 sample_riddle
126 ```
127
128 ```python
129 solve_riddle(collapse_riddle_clues(sample_riddle))
130 ```
131
132 ```python
133 # write_riddle(sample_riddle)
134 ```
135
136 ```python
137 # sample_riddle = random_riddle('sonnet', limit=4)
138 # sample_riddle
139 ```
140
141 ```python
142 sample_riddle
143 ```
144
145 ```python
146 collapse_riddle_clues(sample_riddle)
147 ```
148
149 ```python
150 solve_riddle(collapse_riddle_clues(sample_riddle))
151 ```
152
153 ```python
154 def valid_random_riddle(word: str) -> Riddle:
155 finished = False
156 while not finished:
157 riddle = random_riddle(word)
158 solns = solve_riddle(collapse_riddle_clues(riddle))
159 finished = (len(solns) == 1)
160 return riddle
161 ```
162
163 ```python
164 import time
165 import csv
166 reports = []
167 for _ in range(1000):
168 gencount = 0
169 w1, c1 = time.perf_counter(), time.process_time()
170 r = valid_random_riddle(random.choice(dictionary))
171 w2, c2 = time.perf_counter(), time.process_time()
172 linecount = len(r)
173 reports.append({'wall_time': w2 - w1,
174 'cpu_time': c2 - c1,
175 'generated_lines': gencount,
176 'riddle_lines': linecount})
177 glcounts.append((gencount, linecount))
178 w_times.append(w2 - w1)
179 c_times.append(c2 - c1)
180
181 with open('metrics_related.csv', 'w', newline='') as csvfile:
182 fieldnames = list(reports[0].keys())
183 writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
184
185 writer.writeheader()
186 for r in reports:
187 writer.writerow(r)
188 ```
189
190 ```python
191 def write_include_exclude_line(clue_a: RiddleClue, clue_b: RiddleClue) -> str:
192 line = f"is in {clue_a.word} but not in {clue_b.word}"
193 return line
194 ```
195
196 ```python
197 def write_include_include_line(clue_a: RiddleClue, clue_b: RiddleClue) -> str:
198 if random.randrange(2) == 0:
199 line = f"is in {clue_a.word} and also in {clue_b.word}"
200 else:
201 line = f"is in both {clue_a.word} and {clue_b.word}"
202 return line
203 ```
204
205 ```python
206 def write_exclude_exclude_line(clue_a: RiddleClue, clue_b: RiddleClue) -> str:
207 line = f"is neither in {clue_a.word} nor in {clue_b.word}"
208 return line
209 ```
210
211 ```python
212 def write_line(a: RiddleClue, b: RiddleClue) -> str:
213 if a.valence == RiddleValence.Include and b.valence == RiddleValence.Include:
214 return write_include_include_line(a, b)
215 elif a.valence == RiddleValence.Include and b.valence == RiddleValence.Exclude:
216 return write_include_exclude_line(a, b)
217 elif a.valence == RiddleValence.Exclude and b.valence == RiddleValence.Exclude:
218 return write_exclude_exclude_line(a, b)
219 else:
220 return "illegal line"
221 ```
222
223 ```python
224 def write_riddle(riddle: Riddle) -> List[str]:
225 output = []
226 for i, (clue_a, clue_b) in sorted(riddle.items()):
227 pos = reverse_ordinals[i]
228 if i == len(riddle) and random.random() <= 0.3:
229 pos = reverse_ordinals[-1]
230 line = write_line(clue_a, clue_b)
231 full_line = f"My {pos} {line}"
232 output.append(full_line)
233 return output
234 ```
235
236 ```python
237
238 ```
239
240 ```python
241 sample_riddle = valid_random_riddle("elephant")
242 sample_riddle
243 ```
244
245 ```python
246 write_riddle(sample_riddle)
247 ```
248
249 ```python
250 solve_riddle(collapse_riddle_clues(sample_riddle))
251 ```
252
253 ```python
254 with open("generated-riddles.txt", 'w') as file:
255 between = False
256 for _ in range(10):
257 if between:
258 file.write('\n')
259 between = True
260 target = random.choice(dictionary)
261 riddle = valid_random_riddle(target)
262 lines = write_riddle(riddle)
263 file.writelines(l + '\n' for l in lines)
264 file.write(f'Target: {target}\n')
265 ```
266
267 ```python
268
269 ```