Skip to content

Instantly share code, notes, and snippets.

@apua
Last active February 27, 2023 14:20
Show Gist options
  • Save apua/38115c3d30ec9c403c8b5298324bc7fb to your computer and use it in GitHub Desktop.
Save apua/38115c3d30ec9c403c8b5298324bc7fb to your computer and use it in GitHub Desktop.
r"""
>>> cases = [
... ('', ''), (' ', ''),
... ('11 111 010 000 0', 'MORSE'),
... ('11111 01111 00111 00011 00001', '01234'),
... ('00000 10000 11000 11100 11110', '56789'),
... ]
...
>>> for stream, result in cases:
... assert ''.join(decode_stream(stream)) == result
...
>>> for string, result in cases:
... assert decode(string) == result
"""
from itertools import chain
def decode_char(code, table='..ETIANMSURWDKGOHVF.L.PJBXCYZQ..54.3...2.......16.......7...8.90'):
return c if (c := table[code]) != '.' else None
def map_char(code):
yield from [c] if (c := decode_char(code)) else []
def decode_stream(stream, code=1):
if not stream:
yield from map_char(code)
elif (c := stream[0]) in '01':
yield from decode_stream(stream[1:], code << 1 | int(c))
else:
yield from chain(map_char(code), decode_stream(stream[1:], 1))
def decode(string):
return ''.join(decode_char(eval(f'0b1{code}')) for code in string.strip().split())
@apua
Copy link
Author

apua commented Feb 27, 2023

Below are equivalent:

eval(f'0b1{code}')
eval('0b1' + code)
int('1' + code, 2)
1 << len(code) | int(code, 2)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment