a9e3064dd36242c65fd1b04a11d203e3143ba3d9
[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 first_index, first_word = [(i, t) for i, t in enumerate(stripped_tokens)
41 if t not in ordinals
42 if t not in negative_words][0]
43 second_index, second_word = [(i, t) for i, t in enumerate(stripped_tokens)
44 if t not in ordinals
45 if t not in negative_words][1]
46 neg_indices = [i for i, t in enumerate(stripped_tokens) if t in negative_words]
47
48 first_clue = None
49 second_clue = None
50
51 if neg_indices:
52 if neg_indices[0] < first_index:
53 first_clue = RiddleClue(valence = RiddleValence.Exclude,
54 word = first_word)
55 if len(neg_indices) > 1:
56 second_clue = RiddleClue(valence = RiddleValence.Exclude,
57 word = second_word)
58 elif neg_indices[0] < second_index:
59 second_clue = RiddleClue(valence = RiddleValence.Exclude,
60 word = second_word)
61
62 if first_clue is None:
63 first_clue = RiddleClue(valence = RiddleValence.Include,
64 word = first_word)
65
66 if second_clue is None:
67 second_clue = RiddleClue(valence = RiddleValence.Include,
68 word = second_word)
69
70 return (pos, (first_clue, second_clue))
71 ```
72
73 ```python
74 e1 = parse_line(tokenise("My first is in apple, but not in pad."))
75 e1
76 ```
77
78 ```python
79 e2 = parse_line(tokenise("My second is in apple and also in banana."))
80 e2
81 ```
82
83 ```python
84 e3 = parse_line(tokenise('My seventh is neither in callus nor in calves'))
85 e3
86 ```
87
88 ```python
89 sample_riddle_text = """My first is in shoat but not in oath
90 My second is in orate but not in ratter
91 My third is in preposition but not in osteoporosis
92 My fourth is in astern but not in taster
93 My fifth is in conscientiousness but not in suction
94 My sixth is in immorality but not in immorally"""
95
96 sample_riddle_lines = {i: elem
97 for i, elem in
98 [parse_line(tokenise(l))
99 for l in sample_riddle_text.split('\n')]}
100 sample_riddle_lines
101 ```
102
103 ```python
104 sample_riddle = collapse_riddle_clues(sample_riddle_lines)
105 sample_riddle
106 ```
107
108 ```python
109 def parse_riddle(riddle_text: str) -> Riddle:
110 riddle_lines = {i: elem
111 for i, elem in
112 [parse_line(tokenise(l)) for l in riddle_text.split('\n')]}
113 return collapse_riddle_clues(riddle_lines)
114 ```
115
116 ```python
117 solve_riddle(sample_riddle)
118 ```
119
120 ```python
121 def parse_and_solve_riddle(riddle_text: str) -> List[str]:
122 riddle = parse_riddle(riddle_text)
123 return solve_riddle(riddle)
124 ```
125
126 ```python
127 sample_riddles = open('sample-riddles.txt').read().split('\n\n')
128 sample_riddles
129 ```
130
131 ```python
132 [parse_and_solve_riddle(r) for r in sample_riddles]
133 ```
134
135 ```python
136 sample_riddles = open('generated-riddles.txt').read().split('\n\n')
137 sample_riddles = [riddle.split('\nTarget: ') for riddle in sample_riddles]
138 sample_riddles = [(r, s.strip()) for r, s in sample_riddles]
139 sample_riddles
140 ```
141
142 ```python
143 for r, s in sample_riddles:
144 found_solns = parse_and_solve_riddle(r)
145 correct = len(found_solns) == 1 and found_solns[0] == s
146 print(found_solns, s, correct)
147 ```
148
149 ```python
150 # [parse_line(tokenise(line)) for line in sample_riddles[4][0]]
151 [parse_line(tokenise(line)) for line in sample_riddles[4][0].split('\n')]
152 ```
153
154 ```python
155 parse_riddle(sample_riddles[4][0])
156 ```
157
158 ```python
159
160 ```