1
0
Fork 0

Morse app: optimize letter lookup and constants

The dictionary of strings was taking a lot of space, and is now replaced
by a binary tree flattened into a string plus a small loookup function.

Signed-off-by: Francesco Gazzetta <fgaz@fgaz.me>
This commit is contained in:
Francesco Gazzetta 2021-09-15 16:20:10 +02:00 committed by Daniel Thompson
parent c0065190b5
commit 0854adb630

View file

@ -32,50 +32,17 @@ _MAXINPUT = const(16)
_FONTH = const(24) _FONTH = const(24)
_FONT = fonts.sans24 _FONT = fonts.sans24
_LINEH = int(_FONTH * 1.25) # Precomputed for efficiency
_MAXLINES = floor(_HEIGHT / _LINEH) - 1 # the "-1" is the input line _LINEH = const(30) # int(_FONTH * 1.25)
_MAXLINES = const(7) # floor(_HEIGHT / _LINEH) - 1 # the "-1" is the input line
_code = { # The morse lookup table, represented as a flattened binary tree.
"" : " ", # The head is the value of the node, the tail are the subtrees:
# left half of the tail = the next symbol is a dot
".-" : "A", # right half of the tail = the next symbol is a line
"-..." : "B", _CODE = " EISH54V?3UF????2ARL?????WP??J?1TNDB6?X??KC??Y??MGZ7?Q??O?8??90"
"-.-." : "C", # Or, letters only:
"-.." : "D", #_CODE = " EISHVUF?ARL?WPJTNDBXKCYMGZQO??"
"." : "E",
"..-." : "F",
"--." : "G",
"...." : "H",
".." : "I",
".---" : "J",
"-.-" : "K",
".-.." : "L",
"--" : "M",
"-." : "N",
"---" : "O",
".--." : "P",
"--.-" : "Q",
".-." : "R",
"..." : "S",
"-" : "T",
"..-" : "U",
"...-" : "V",
".--" : "W",
"-..-" : "X",
"-.--" : "Y",
"--.." : "Z",
".----": "1",
"..---": "2",
"...--": "3",
"....-": "4",
".....": "5",
"-....": "6",
"--...": "7",
"---..": "8",
"----.": "9",
"-----": "0",
}
class MorseApp(): class MorseApp():
NAME = 'Morse' NAME = 'Morse'
@ -110,7 +77,7 @@ class MorseApp():
self._update() self._update()
def touch(self, event): def touch(self, event):
addition = _code[self.letter] if self.letter in _code else "/{}/".format(self.letter) addition = self._lookup(self.letter)
self.letter = "" self.letter = ""
merged = self.text[-1] + addition merged = self.text[-1] + addition
# Check if the new text overflows the screen and add a new line if that's the case # Check if the new text overflows the screen and add a new line if that's the case
@ -143,6 +110,27 @@ class MorseApp():
The full text area is updated in _draw() instead.""" The full text area is updated in _draw() instead."""
draw = wasp.watch.drawable draw = wasp.watch.drawable
draw.string(self.text[-1], 0, _LINEH*(len(self.text)-1)) draw.string(self.text[-1], 0, _LINEH*(len(self.text)-1))
guess = _code[self.letter] if self.letter in _code else "?" guess = self._lookup(self.letter)
draw.string("{} {}".format(self.letter, guess), 0, _HEIGHT - _FONTH, width=_WIDTH) draw.string("{} {}".format(self.letter, guess), 0, _HEIGHT - _FONTH, width=_WIDTH)
def _lookup(self, s):
i = 0 # start of the subtree (current node)
l = len(_CODE) # length of the subtree
for c in s:
# first discard the head, which represent the previous guess
i += 1
l -= 1
# Check if we can no longer bisect while there are still dots/lines
if l <= 0: return "?"
# Update the bounds to the appropriate subtree
# (left or right of the tail).
# The length will always be half:
l //= 2
# The index will be either at the beginning of the tail,
# or at its half, in which case we subtract the current length,
# which is half of the old length:
if c == "-": i += l
return _CODE[i]