aboutsummaryrefslogtreecommitdiff
path: root/mendeleev.py
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2022-08-28 15:40:21 +0200
committerIgor Pashev <pashev.igor@gmail.com>2022-09-25 20:23:05 +0200
commitf0881305402f3dff56f99fcc4cbc8b615581b780 (patch)
tree5d475e2e95138f63ad249f4d44a453999c1c14f6 /mendeleev.py
downloadmendeleev-f0881305402f3dff56f99fcc4cbc8b615581b780.tar.gz
C, Haskell, Python, Fortran
Diffstat (limited to 'mendeleev.py')
-rw-r--r--mendeleev.py102
1 files changed, 102 insertions, 0 deletions
diff --git a/mendeleev.py b/mendeleev.py
new file mode 100644
index 0000000..b026ab1
--- /dev/null
+++ b/mendeleev.py
@@ -0,0 +1,102 @@
+import sys
+
+
+# fmt: off
+ELEMENTS = [
+ "Ac", "Ag", "Al", "Am", "Ar", "As", "At", "Au", "B", "Ba", "Be", "Bh",
+ "Bi", "Bk", "Br", "C", "Ca", "Cd", "Ce", "Cf", "Cl", "Cm", "Cn", "Co",
+ "Cr", "Cs", "Cu", "Db", "Ds", "Dy", "Er", "Es", "Eu", "F", "Fe", "Fl",
+ "Fm", "Fr", "Ga", "Gd", "Ge", "H", "He", "Hf", "Hg", "Ho", "Hs", "I",
+ "In", "Ir", "K", "Kr", "La", "Li", "Lr", "Lu", "Lv", "Mc", "Md", "Mg",
+ "Mn", "Mo", "Mt", "N", "Na", "Nb", "Nd", "Ne", "Nh", "Ni", "No", "Np",
+ "O", "Og", "Os", "P", "Pa", "Pb", "Pd", "Pm", "Po", "Pr", "Pt", "Pu",
+ "Ra", "Rb", "Re", "Rf", "Rg", "Rh", "Rn", "Ru", "S", "Sb", "Sc", "Se",
+ "Sg", "Si", "Sm", "Sn", "Sr", "Ta", "Tb", "Tc", "Te", "Th", "Ti", "Tl",
+ "Tm", "Ts", "U", "V", "W", "Xe", "Y", "Yb", "Zn", "Zr"
+]
+# fmt: on
+
+elements = [el.lower() for el in ELEMENTS]
+
+
+def search(start, length, shift, char):
+ upper = start + length
+ lower = start
+ while lower < upper:
+ mid = int((lower + upper) / 2)
+ if elements[mid][shift] < char:
+ lower = mid + 1
+ else:
+ upper = mid
+
+ if lower == start + length:
+ return (0, 0)
+
+ if elements[lower][shift] != char:
+ return (0, 0)
+
+ upper = start + length
+ start = lower
+ while lower < upper:
+ mid = int((lower + upper) / 2)
+ if char < elements[mid][shift]:
+ upper = mid
+ else:
+ lower = mid + 1
+
+ length = upper - start
+
+ return (start, length)
+
+
+def divide(tail):
+ result = []
+
+ start = 0
+ length = len(ELEMENTS)
+ shift = 0
+
+ while shift < len(tail):
+ start, length = search(start, length, shift, tail[shift])
+ if length == 0:
+ break
+
+ shift += 1
+ if len(ELEMENTS[start]) == shift:
+ result.append((ELEMENTS[start], tail[shift:]))
+ start += 1
+ length -= 1
+
+ return result or [("?", tail[1:])]
+
+
+def advance(els, tail):
+ return [(els + [e], t) for (e, t) in divide(tail)]
+
+
+def explode(word):
+ result = [([], word.lower())]
+ while True:
+ new = []
+ tail = None
+ for res in result:
+ if res[1]:
+ adv = advance(*res)
+ new.extend(adv)
+ if not tail:
+ tail = adv[0][1]
+ else:
+ new.append(res)
+
+ result = new
+
+ if not tail:
+ break
+
+ return [els for els, _ in result]
+
+
+for w in sys.argv[1:]:
+ print(w + ":")
+ for f in filter(None, explode(w)):
+ print(" " + " ".join(f))