Removed neighbour generation out of the core library
[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 parse_line(tokenise("My fourth is in both apple and banana."))
86 ```
87
88 ```python
89 e3 = parse_line(tokenise('My seventh is neither in callus nor in calves'))
90 e3
91 ```
92
93 ```python
94 sample_riddle_text = """My first is in shoat but not in oath
95 My second is in orate but not in ratter
96 My third is in preposition but not in osteoporosis
97 My fourth is in astern but not in taster
98 My fifth is in conscientiousness but not in suction
99 My sixth is in immorality but not in immorally"""
100
101 sample_riddle_lines = {i: elem
102 for i, elem in
103 [parse_line(tokenise(l))
104 for l in sample_riddle_text.split('\n')]}
105 sample_riddle_lines
106 ```
107
108 ```python
109 sample_riddle = collapse_riddle_clues(sample_riddle_lines)
110 sample_riddle
111 ```
112
113 ```python
114 def parse_riddle(riddle_text: str) -> Riddle:
115 return {i: elem
116 for i, elem in
117 [parse_line(tokenise(l))
118 for l in riddle_text.split('\n')]}
119 ```
120
121 ```python
122 solve_riddle(sample_riddle)
123 ```
124
125 ```python
126 def parse_and_solve_riddle(riddle_text: str) -> List[str]:
127 riddle = parse_riddle(riddle_text)
128 elems = collapse_riddle_clues(riddle)
129 return solve_riddle(elems)
130 ```
131
132 ```python
133 sample_riddles = open('sample-riddles.txt').read().split('\n\n')
134 sample_riddles
135 ```
136
137 ```python
138 [parse_and_solve_riddle(r) for r in sample_riddles]
139 ```
140
141 ```python
142 sample_riddles = open('generated-riddles.txt').read().split('\n\n')
143 sample_riddles = [riddle.split('\nTarget: ') for riddle in sample_riddles]
144 sample_riddles = [(r, s.strip()) for r, s in sample_riddles]
145 sample_riddles
146 ```
147
148 ```python
149 for r, s in sample_riddles:
150 found_solns = parse_and_solve_riddle(r)
151 correct = len(found_solns) == 1 and found_solns[0] == s
152 print(found_solns, s, correct)
153 ```
154
155 ```python
156 # [parse_line(tokenise(line)) for line in sample_riddles[4][0]]
157 [parse_line(tokenise(line)) for line in sample_riddles[4][0].split('\n')]
158 ```
159
160 ```python
161 parse_riddle(sample_riddles[4][0])
162 ```
163
164 ```python
165
166 ```