Created
May 2, 2015 09:47
-
-
Save gabrii/ecf6107e150496408f6e to your computer and use it in GitHub Desktop.
Algorithm to encode any text in the optimal chemical symbols representation. Full article at http://gabgav.com/writing-with-elements/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# import elements database | |
from periodic import elements | |
# Exclude last 6 new elements, which have 3 letters provisional names | |
# And parse everything into a tuples array | |
elements = [(element.symbol, element.name) for element in elements[:-6]] | |
def print_elements(elements_array): | |
"""Prints an array of elements with brackets, and prints fake elements as normal text""" | |
print ''.join( | |
[ | |
'[' + element[0] + ']' if element[1] != 'fake' else element[0] | |
for element in elements_array | |
] | |
) | |
def encode_one(left): | |
""" | |
Internal recursive function. Algorithm: | |
encode(string): | |
list options | |
for element in (elements + fake element made of first letter): | |
if string starts with element: | |
if element isn't fake or options is empty: | |
if string equals to element: | |
append element to options | |
else: | |
for option in encode(string - element): | |
append [element] + option to options | |
return options | |
""" | |
options = [] | |
for element in elements + [(left[:1], 'fake')]: | |
if left.startswith(element[0].lower()): | |
if element[1] != 'fake' or options == []: | |
if len(left) == len(element[0]): | |
options.append([element]) | |
else: | |
for option in encode_one(left[len(element[0]):]): | |
options.append([element] + option) | |
return options | |
def score(option): | |
"""Calculates score of an option""" | |
fakes = 0 | |
shorts = 0 | |
longs = 0 | |
for pos in option: | |
if pos[1] == 'fake': | |
fakes += len(pos[0]) | |
elif len(pos[0]) == 2: | |
longs += 1 | |
else: | |
shorts += 1 | |
return shorts**2 + longs**2.5 - fakes**3 | |
def sort_options(options): | |
"""Sorts the options based on the score function""" | |
options = [(score(option), option) for option in options] | |
options.sort() | |
return [option[1] for option in options] | |
def encode(string): | |
"""Returns all the valid options""" | |
return sort_options(encode_one(string.lower())) | |
def print_options(string): | |
for option in encode(string): | |
print_elements(option) | |
print_options('Hello world!') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment