Poimintoja suomen kielen sanalistalta

Johdanto

Tällä sivulla on lueteltu kiinnostavia suomenkielisiä sanoja. Olen etsinyt sanat Kotimaisten kielten keskuksen (Kotus) nykysuomen sanalistalta, jossa on 104 336 sanaa. Kunkin sanalistan yhteydessä on Python-ohjelma, jolla sanat on löydetty. Ohjelmat vaativat tekstitiedostot sivulta Muunnelmiani Kotuksen sanalistasta.

Sanojen pituus

Vähintään 28 kirjainta:

Kaksi kirjainta: AD, ah, ai, au, bi, CD, CV, DJ, ei, EU, ex, EY, ha, he, hi, hm, hä, id, in, IT, ja, jo, ma, me, mi, mä, ne, no, oh, oi, OK, oy, PC, pH, PR, ry, sa, se, so, sä, te, tv, tä, UV, WC, YT, yö, äh, ÄO

Yksi kirjain: S2

Ohjelma:

with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letterCnt = sum(1 for c in word if c.isalpha())
        if letterCnt <= 2 or letterCnt >= 28:
            print(letterCnt, word)

Sanojen pituus – ei yhdyssanoja

Vähintään 20 kirjainta:

Ohjelma:

with open("singles,finals.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letterCnt = sum(1 for c in word if c.isalpha())
        if letterCnt >= 20:
            print(letterCnt, word)

Moniosaiset yhdyssanat

Vähintään viisi osaa:

Ohjelma:

with open("compounds.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        parts = word.rstrip("\n").split("_")
        if len(parts) >= 5:
            print(len(parts), "".join(parts))

Yhdyssanojen yleisimmät osat

Ei-yhdyssanat, jotka esiintyvät vähintään 300 yhdyssanan osana. Taivutetut muodot on huomioitu perusmuodossa (esim. maa sanasta maantiede).

Ohjelma:

from collections import Counter
INFLECTED_TO_LEMMA = {
    "aikaan": "aika", "aineen": "aine", "ajan": "aika", "auton": "auto",
    "ilmaan": "ilma",
    "kasvin": "kasvi", "kaupan": "kauppa", "kielen": "kieli",
    "kirjan": "kirja", "kiven": "kivi", "kodin": "koti", "koneen": "kone",
    "kotiin": "koti", "koulun": "koulu", "kunnan": "kunta", "kuvan": "kuva",
    "lehden": "lehti", "lennon": "lento", "liikenteen": "liikenne",
    "liikkeelle": "liike", "liikkeen": "liike", "luvun": "luku",
    "maahan": "maa", "maan": "maa", "maasta": "maa", "matkan": "matka",
    "meren": "meri", "merkin": "merkki", "miehen": "mies", "miesten": "mies",
    "oikeuden": "oikeus",
    "paikan": "paikka", "päivän": "päivä", "päähän": "pää", "päällä": "pää",
    "pään": "pää", "puoleensa": "puoli", "puolen": "puoli", "puun": "puu",
    "sodan": "sota", "sähkön": "sähkö",
    "talouden": "talous", "tien": "tie", "tilan": "tila", "työhön": "työ",
    "työn": "työ",
    "valon": "valo", "veden": "vesi", "värin": "väri",
    "ylen": "yli",
    "öljyn": "öljy",
}
partCounts = Counter()
with open("compounds.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for compound in handle:
        parts = compound.rstrip("\n").split("_")
        parts = [p.rstrip("- ") for p in parts]
        parts = [INFLECTED_TO_LEMMA.get(p, p) for p in parts]
        partCounts.update(parts)
for part in partCounts:
    if partCounts[part] >= 300:
        print(partCounts[part], part)

Kirjainten yleisyydet

Kirjaimet yleisimmästä harvinaisimpaan sen mukaan, monessako sanassa ne esiintyvät:

i, a, t, s, e, k, u, l, n, o, r, m, p, v, ä, h, y, j, d, ö, g, f, b, c, w, š, z, x, q, é, ž, è, à, õ, û, á, â, å, ê, î, ñ, ô

Ohjelma:

from collections import Counter
counts = Counter()
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        counts.update({c for c in word.lower() if c.isalpha()})
ordered = sorted(counts)
ordered.sort(key=lambda l: counts[l], reverse=True)
print(", ".join(ordered))

Kirjainyhdistelmien yleisyydet

Kahden kirjaimen yhdistelmät, jotka esiintyvät vähintään 10 000 sanassa, yleisimmästä harvinaisimpaan:

in, is, ta, en, ka, st, ti, us, li, ne, al, tt, ai, tu, it, la, el, to, si, aa, te, ri

Kolmen kirjaimen yhdistelmät, jotka esiintyvät vähintään 3000 sanassa, yleisimmästä harvinaisimpaan:

ine, nen, ist, sti, ain, tus, lli, uus, kka, tel, tti, ikk, nta, ast

Neljän kirjaimen yhdistelmät, jotka esiintyvät vähintään 1200 sanassa, yleisimmästä harvinaisimpaan:

inen, aine, isuu, suus, esti, line, llis, ises, sest, ttaa, alli, ikka, isti

Ohjelma:

from collections import Counter
for (groupLen, minCount) in ((2, 10000), (3, 3000), (4, 1200)):
    letterGroupCounts = Counter()
    with open("stripped.txt", "rt", encoding="utf8") as handle:
        handle.seek(0)
        for word in handle:
            word = word.lower()
            charGroups = set(
                word[i:i+groupLen] for i in range(0, len(word) - groupLen + 1)
            )
            letterGroupCounts.update(p for p in charGroups if p.isalpha())
    letterGroups = [
        p for p in letterGroupCounts if letterGroupCounts[p] >= minCount
    ]
    letterGroups.sort()
    letterGroups.sort(key=lambda p: letterGroupCounts[p], reverse=True)
    print(", ".join(letterGroups))

Sanat, joissa kaikki yleisimmät kirjaimet

Lyhimmät sanat, jotka sisältävät kaikki yleisimmät kirjaimet (katso ”Kirjainten yleisyydet” edellä):

Ohjelma:

LETTERS_BY_FREQ = "iatsekulnormpvähyjdögfbcwšzxqéžèàõûáâåêîñô"
def get_words_by_letters():
    # group words by set of lowercase letters; e.g. "aet" -> "tae", "taeta"
    wordsByLetters = {}
    with open("stripped.txt", "rt") as handle:
        handle.seek(0)
        for word in handle:
            word = word.rstrip("\n")
            letters = frozenset(c for c in word.lower() if c.isalpha())
            wordsByLetters.setdefault(letters, set()).add(word)
    return wordsByLetters
def count_letters(word):
    return sum(1 for c in word if c.isalpha())
def main():
    wordsByLetters = get_words_by_letters()
    # get number of letters in shortest word for each set of letters;
    # e.g. frozenset("aet"): 3
    minLengthsByLetters = dict(
        (l, min(count_letters(w) for w in wordsByLetters[l]))
        for l in wordsByLetters
    )
    # how many of the most common letters must the words contain
    for commonCnt in range(2, len(LETTERS_BY_FREQ) + 1):
        # which letters
        lettersToFind = set(LETTERS_BY_FREQ[:commonCnt])
        # exit if no words
        if not any(l.issuperset(lettersToFind) for l in wordsByLetters):
            break
        # smallest number of letters in those words
        minLength = min(
            minLengthsByLetters[l]
            for l in minLengthsByLetters if l.issuperset(lettersToFind)
        )
        # find and print those words
        words = set()
        for letters in wordsByLetters:
            if (
                letters.issuperset(lettersToFind)
                and minLengthsByLetters[letters] == minLength
            ):
                words.update(
                    w for w in wordsByLetters[letters]
                    if count_letters(w) == minLength
                )
        print(
            ",".join(LETTERS_BY_FREQ[:commonCnt]) + ": "
            + ",".join(sorted(words))
        )
main()

Harvinaiset merkit

Sanat, joissa on muu merkki kuin kirjain, väliviiva tai välilyönti:

Sanat, joissa on muu kirjain kuin A–Z, Ä tai Ö (isona tai pienenä):

Ohjelma:

from itertools import chain
from string import ascii_lowercase
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    words = [w.rstrip("\n") for w in handle]
allChars = set(chain.from_iterable(w.lower() for w in words))
interestingChars = [
    c for c in allChars
    if not c.isalpha() and c not in "- "
    or c.isalpha() and c not in ascii_lowercase + "äö"
]
for char in sorted(interestingChars):
    print(f'"{char}":', ", ".join(w for w in words if char in w))

Toistuvat kirjainjonot

Kahden kirjaimen jono neljästi:

Vähintään kahden kirjaimen jono kolmesti peräkkäin, pisin jono ensin:

Kolmen kirjaimen jono kolmesti:

Vähintään viiden kirjaimen jono kahdesti peräkkäin, pisin jono ensin:

Vähintään kuuden kirjaimen jono kahdesti, pisin jono ensin:

Ohjelma:

import re
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letters = "".join(c for c in word.lower() if c.isalpha())
        # no gaps
        if re.search(r"([a-zäö]{3})\1\1", letters) is not None:
            print("count 3, no gaps, length 3:", word)
        elif re.search(r"([a-zäö]{2})\1\1", letters) is not None:
            print("count 3, no gaps, length 2:", word)
        if re.search(r"([a-zäö]{6})\1", letters) is not None:
            print("count 2, no gaps, length 6:", word)
        elif re.search(r"([a-zäö]{5})\1", letters) is not None:
            print("count 2, no gaps, length 5:", word)
        # gaps
        if re.search(r"([a-zäö]{2})(.*\1){3}", letters) is not None:
            print("count 4, gaps, length 2:", word)
        if re.search(r"([a-zäö]{3})(.*\1){2}", letters) is not None:
            print("count 3, gaps, length 3:", word)
        if re.search(r"([a-zäö]{7}).*\1", letters) is not None:
            print("count 2, gaps, length 7:", word)
        elif re.search(r"([a-zäö]{6}).*\1", letters) is not None:
            print("count 2, gaps, length 6:", word)

Kaksoiskirjaimet

Kuusi kaksoiskirjainta:

Viisi kaksoiskirjainta:

aatteellisuus, ennakkoluulottomuus, hullaannuttaa, hurraaisänmaallisuus, huumaannuttaa, hyökkäämättömyyssopimus, jälleenvakuuttaa, kiireellisyysluokka, kulttuuri-identiteetti, kunnallishallinnollinen, kylläännyttää, laajennussuunnitelma, liikenneonnettomuus, liikennesuunnittelu, lukkiinnuttaa, maahanmuuttopolitiikka, maallikkosaarnaaja, paikannussatelliitti, periaatteettomuus, persoonallisuustyyppi, piilo-opetussuunnitelma, piittaamattomuus, puolueettomuuspolitiikka, puutteellisuus, riitaannuttaa, riittämättömyydentunne, suunnilleenkaan, suunnittelemattomuus, suurtaajuustekniikka, tietoliikennesatelliitti, uudenseelanninpinaatti, vaatetussuunnittelija, valuutta-automaatti, viitteellisyys, villiinnyttää, äänentallennustekniikka

Neljä kaksoiskirjainta peräkkäin:

aatteellinen, aatteellisesti, aatteellisuus, hakkuuttaa, hellyyttää, hyppyyttää, lappeellaan, lappeelleen, leikkuuttaa, liikkeelle, liikkeellelähtö, liikkeellelasku, liikkeellepaneva, liikkeellä, liikkeelläolo, liikkeessä, liikkeessäolo, lääkkeellinen, nuoremmuuttaan, omistusliitteellinen, paikkuuttaa, periaatteellinen, periaatteettomuus, puutteellinen, puutteellisesti, puutteellisuus, päätteellinen, saappaannuolija, tarkkuuttaa, toppuuttaa, vanhemmuuttaan, viitteellinen, viitteellisesti, viitteellisyys

Vähintään neljä kaksoiskonsonanttia:

Neljä kaksoisvokaalia:

Kaksi kaksoisvokaalia peräkkäin:

Ohjelma:

import re
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letters = "".join(c for c in word.lower() if c.isalpha())
        if re.search(r"(([a-zäö])\2.*){6}", letters) is not None:
            print("letters with gaps, 6", word)
        elif re.search(r"(([a-zäö])\2.*){5}", letters) is not None:
            print("letters with gaps, 5", word)
        if re.search(r"(([a-zäö])\2){4}", letters) is not None:
            print("letters without gaps, 4", word)
        if re.search(r"(([aeiouyäö])\2.*){4}", letters) is not None:
            print("vowels with gaps, 4", word)
        if re.search(r"(([aeiouyäö])\2){2}", letters) is not None:
            print("vowels without gaps, 2", word)
        if re.search(r"(([b-df-hj-np-tv-xz])\2.*){5}", letters) is not None:
            print("consonants with gaps, 5", word)
        elif re.search(r"(([b-df-hj-np-tv-xz])\2.*){4}", letters) is not None:
            print("consonants with gaps, 4", word)

Palindromit ja anadromit – koko sanat

Palindromit (sama etuperin ja takaperin; vähintään neljä kirjainta):

Anadromit (sama kuin toinen sana takaperin; vähintään neljä kirjainta):

Ohjelma:

# group words by lowercase letters
wordsByLetters = {}
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letters = "".join(c for c in word.lower() if c.isalpha())
        wordsByLetters.setdefault(letters, set()).add(word)
for letters in wordsByLetters:
    backwards = letters[::-1]
    if backwards == letters and len(letters) >= 4:
        print("palindrome", str(len(letters)), "/".join(
            sorted(wordsByLetters[letters])
        ))
    elif (
        backwards in wordsByLetters and letters < backwards
        and len(letters) >= 4
    ):
        print("anadrome", str(len(letters)), "/".join(
            sorted(wordsByLetters[letters] | wordsByLetters[backwards])
        ))

Palindromit – sanan osat

Yhdeksänkirjaiminen sanan osa, joka on palindromi (sama etuperin ja takaperin):

Ohjelma:

# group words by lowercase letters
wordsByLetters = {}
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letters = "".join(c for c in word.lower() if c.isalpha())
        wordsByLetters.setdefault(letters, set()).add(word)
for letterList in wordsByLetters:
    for length in range(9, len(letterList)):
        for pos in range(len(letterList) - length + 1):
            substr = letterList[pos:pos+length]
            if substr == substr[::-1]:
                print(
                    length,
                    "/".join(sorted(w for w in wordsByLetters[letterList]))
                )

Anagrammit

Sanat ovat toistensa anagrammeja, jos niissä on sama määrä samoja kirjaimia eri järjestyksessä.

Seitsemän sanan joukot:

Kuuden sanan joukot:

Viiden sanan joukot:

Neljän sanan joukot:

Vähintään 13-kirjaimisten sanojen joukot (joukon sisällä ei yli nelikirjaimisia yhteisiä sanan osia); suluissa kirjainten määrä:

Ohjelma:

from itertools import combinations
def word_to_lowercase_letters(word):
    # "Foo Bar" -> "foobar"
    return "".join(c for c in word.lower() if c.isalpha())
def have_common_substrs(str1, str2, minLen):
    # do the strings have any common substrings of minLen letters?
    substrs1 = set(str1[i:i+minLen] for i in range(len(str1) - minLen + 1))
    return any(s in str2 for s in substrs1)
def main():
    # group words by sorted lowercase letters
    wordsByLetters = {}
    with open("stripped.txt", "rt", encoding="utf8") as handle:
        handle.seek(0)
        for word in handle:
            word = word.rstrip("\n")
            letters = "".join(sorted(word_to_lowercase_letters(word)))
            wordsByLetters.setdefault(letters, set()).add(word)
    for letters in wordsByLetters:
        words = set(
            word_to_lowercase_letters(w) for w in wordsByLetters[letters]
        )
        if (
            len(words) >= 4
            or len(letters) >= 13 and len(words) >= 2 and not all(
                have_common_substrs(w1, w2, 5)
                for (w1, w2) in combinations(words, 2)
            )
        ):
            print(
                len(words), len(letters),
                ", ".join(sorted(wordsByLetters[letters]))
            )
main()

Puolianagrammit

(Termi on omakeksimäni.) Kuin anagrammit, mutta kirjainten määrillä ei ole väliä, kunhan niitä on vähintään yksi. Esimerkiksi sanat kaataa ja takka ovat toistensa ”puolianagrammeja”, koska molemmat sisältävät kirjaimia a, k ja t vähintään yhden kutakin ja ei muita kirjaimia.

Eniten puolianagrammeja (75) saa kirjaimista a, i, k, l, s, t, u: aikataulutus, aktuaalistaa, aktuaalistua, aktuaalisuus, altistusaika, illalliskutsu, iltakausi, iltakutsut, iltakuusi, kalisuttaa, kalkitus, kallistua, kallistus, kaltaisuus, kasuaalisti, kilkatus, kituliaasti, kituliaisuus, kitulias, kultaisuus, kultakausi, kultalusikka, kultasakaali, kuusilauta, laikutus, laiskistua, laitataklaus, lasikuisti, lasikuitu, lasikuitusuksi, laskusilta, laskutikku, laskutila, laukaista, laukaisualusta, liikakalastus, liikakulutus, liiskautua, liitukausi, liukastaa, liukastua, liukastus, liukastuttaa, liukkaasti, liukualusta, liukutaklaus, luiskata, luiskauttaa, lukaista, lukuisasti, lukulasit, siilikaktus, siilitukka, sisalkuitu, sisuskalut, sukulaistua, sukutila, sulkulista, takalukitus, tilausaika, tilauskausi, tilauslasku, tilikausi, tukalasti, tukialus, tukikaulus, tukkiallas, tukkilaiskisat, tulitikkuaski, tullitaksa, tuskailla, tuskailu, tuskallisuus, tuskatila, uskaliaasti.

Kuuden kirjaimen joukko, josta saa eniten puolianagrammeja (74), on a, i, k, s, t, u: aikaistua, aikaistus, aikakatkaisu, aikautus, aikuistaa, aikuistua, aistikkuus, akustiikka, akuutisti, asiakastuki, aukaista, ikuistaa, iskuttaa, istukas, istukka, istuksia, istutusaika, kaikutausta, kassakuitti, kasuistiikka, katkaisu, kikatus, kiksauttaa, kitsaus, kittaus, kiukustua, kiukustuttaa, kiusata, kuiskata, kuiskuttaa, kuittaus, kukistaa, kukistua, kukkaistutus, kusaista, kutista, kutistaa, kutistua, kuusiaita, kuusisataa, saikuttaa, satikuti, sisukkaasti, sisustustakka, sisustustikkaat, suikata, sukaatti, sukaista, sukittaa, sukkaatti, suutuksissa, taikaisku, taikuus, takaisku, takkuisuus, taksikuski, taktisuus, taustatuki, tikkaus, tiskaus, tiukassa, tiukasti, tiuskaista, tiuskia, tuikkaus, tuiskia, tuiskuta, tuiskuttaa, tukistaa, tukisukka, tuskaisa, tuskaisasti, tuskaisuus, uutiskatsaus.

Viiden kirjaimen joukko, josta saa eniten puolianagrammeja (38), on a, i, r, s, t: arasti, aristaa, artisti, irstaasti, irstas, itarasti, itsari, raaistaa, raatsia, raa’asti, raitis, raitistaa, raittiisti, rasisti, rasittaa, rasti, rastia, rastittaa, ratista, ratsia, riista, riista-aita, riita-asia, riitaisa, ristiriita, ristiritari, ritsa, sairaasti, sairastaa, satiiri, sitar, sitra, startti, strassi, tirsat, trassaatti, tsaari, tsaaritar.

Neljän kirjaimen joukko, josta saa eniten puolianagrammeja (37), on a, s, t, u: astua, astuttaa, astutus, asustaa, asuttaa, asutus, auts, autuas, autuus, saastua, saastuttaa, saastutus, satsaus, sattua, satu, satuttaa, status, sutata, suttautua, suuttua, suututtaa, tasaus, tasauttaa, tasautua, tasautus, tassu, tassuttaa, taus, tausta, taustaa, tussata, tussaus, tutustaa, tutustua, tutustuttaa, tuuttaus, usuttaa.

Kolmen kirjaimen joukko, josta saa eniten puolianagrammeja (12), on a, k, t: atk, kaakattaa, kaataa, kakata, kakattaa, kat, katka, kattaa, taakka, taka, takaa, takka.

Ohjelma:

# group words by sorted distinct lowercase letters
wordsByLetters = {}
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letters = "".join(sorted(set(c for c in word.lower() if c.isalpha())))
        wordsByLetters.setdefault(letters, set()).add(word)
for letters in wordsByLetters:
    wordCount = len(wordsByLetters[letters])
    if (
        wordCount >= 75
        or len(letters) == 6 and wordCount >= 74
        or len(letters) == 5 and wordCount >= 38
        or len(letters) == 4 and wordCount >= 37
        or len(letters) == 3 and wordCount >= 12
    ):
        print(
            len(letters), wordCount, ",".join(letters),
            ",".join(sorted(wordsByLetters[letters]))
        )

Paljon eri kirjaimia

Vähintään 16 eri kirjainta:

Vähintään 13 eri kirjainta, ei mitään kahdesti:

Kahdeksan eri vokaalia, ei mitään kahdesti:

Kymmenen eri konsonanttia:

Yhdeksän eri konsonanttia, ei mitään kahdesti:

Ohjelma:

VOWELS = "aàáâäåeèéêiîoôõöuûy"
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letters    = [c for c in word.lower() if c.isalpha()]
        vowels     = [c for c in letters      if c in VOWELS]
        consonants = [c for c in letters      if c not in VOWELS]
        if len(set(letters)) == len(letters) >= 13:
            print("letters, all distinct", len(letters), word)
        elif len(set(letters)) >= 16:
            print("letters, many distinct", len(set(letters)), word)
        if len(set(vowels)) == len(vowels) >= 8:
            print("vowels, all distinct", len(vowels), word)
        elif len(set(vowels)) >= 8:
            print("vowels, many distinct", len(set(vowels)), word)
        if len(set(consonants)) == len(consonants) >= 9:
            print("consonants, all distinct", len(consonants), word)
        elif len(set(consonants)) >= 10:
            print("consonants, many distinct", len(set(consonants)), word)

Vähän eri kirjaimia – koko sanat

Vain kahta eri kirjainta (vähintään kuusi kirjainta yhteensä):

Vain kolmea eri kirjainta (vähintään yhdeksän kirjainta yhteensä):

Sama vokaali kahdeksasti:

Sama vokaali seitsemästi, ei muita vokaaleja:

Ei vokaaleja: CD, CV, DJ, DVD, hm, hmh, hmm, LSD, PC, pH, PMS, PR, S2, tv, WC, www

Sama konsonantti seitsemästi:

Sama konsonantti viidesti, ei muita konsonantteja:

Ei konsonantteja: ai, aie, au, ei, eioo, EU, EY, oi, oy, yö, ÄO

Ohjelma:

from collections import Counter
VOWELS = "aàáâäåeèéêiîoôõöuûy"
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letters    = [c for c in word.lower() if c.isalpha()]
        vowels     = [c for c in letters      if c in VOWELS]
        consonants = [c for c in letters      if c not in VOWELS]
        maxVowelCnt = max(Counter(vowels).values())     if vowels     else 0
        maxConsCnt  = max(Counter(consonants).values()) if consonants else 0
        #
        if (
            len(set(letters))    == 2 and len(letters) >= 6
            or len(set(letters)) == 3 and len(letters) >= 9
        ):
            print("letters", len(set(letters)), len(letters), word)
        #
        if not vowels:
            print("vowels, none", word)
        elif len(set(vowels)) == 1 and len(vowels) >= 7:
            print("vowels, one distinct", len(vowels), word)
        elif maxVowelCnt >= 8:
            print("vowels, most common", maxVowelCnt, word)
        #
        if not consonants:
            print("consonants, none", word)
        elif len(set(consonants)) == 1 and len(consonants) >= 5:
            print("consonants, one distinct", len(consonants), word)
        elif maxConsCnt >= 7:
            print("consonants, most common", maxConsCnt, word)

Vähän eri kirjaimia – sanan osat

Vähintään kahdeksankirjaimiset sanan osat, joissa on vain kahta eri kirjainta:

Kymmenkirjaimiset sanan osat, joissa on vain kolmea eri kirjainta:

Ohjelma:

# group words by lowercase letters
wordsByLetters = {}
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letters = "".join(c for c in word.lower() if c.isalpha())
        wordsByLetters.setdefault(letters, set()).add(word)
for letterList in wordsByLetters:
    for length in range(8, len(letterList)):
        for pos in range(len(letterList) - length + 1):
            substr = letterList[pos:pos+length]
            if (
                len(set(substr)) <= 2 or len(set(substr)) == 3 and length >= 10
            ):
                print(
                    len(set(substr)), length,
                    "/".join(sorted(w for w in wordsByLetters[letterList]))
                )

Peräkkäiset vokaalit ja konsonantit

Sanoja, joissa on neljä vokaalia peräkkäin, on paljon; tässä vain kahdeksankirjaimiset ja lyhemmät: asia-aine, au-äiti, buuaus, eioo, EU-oikeus, hääyö, jaa-ääni, jääaika, kauaa, koeaika, kuuauto, layout, liioin, maa-aines, maaäiti, matka-aie, meioosi, niiaus, peeaa, puuaine, puuaines, pääaine, pääaines, pääuoma, riiailla, riiuu, suoaukea, suuaukko, työaika, yöaika

Viisi konsonanttia peräkkäin:

Ei kahta vokaalia tai kahta konsonanttia peräkkäin, vähintään 14 kirjainta:

Ei kahta vokaalia peräkkäin, vähintään 25 kirjainta:

Ei kahta konsonanttia peräkkäin, vähintään 20 kirjainta:

Ohjelma:

from re import search
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letters = "".join(c for c in word.lower() if c.isalpha())
        if search(r"[aeiouyäö]{4}", letters) is not None and len(letters) <= 8:
            print("vowels, 4 adjacent", word)
        if search(r"[aeiouyäö]{2}", letters) is None and len(letters) >= 25:
            print("vowels, no 2 adjacent", len(word), word)
        if search(r"[^aáeiouyåäö]{5}", letters) is not None:
            print("consonants, 5 adjacent", word)
        if search(r"[^aeiouyäö]{2}", letters) is None and len(letters) >= 20:
            print("consonants, no 2 adjacent", len(word), word)
        if search(
            r"^[aeiouyäö]?([^aeiouyäö][aeiouyäö])*[^aeiouyäö]?$", letters
        ) is not None and len(letters) >= 14:
            print("alternating vowels and consonants", len(word), word)

Kirjaimet aakkosjärjestyksessä – koko sanat

Vähintään kuusi kirjainta aakkosjärjestyksessä:

Ohjelma:

with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letters = [c for c in word.lower() if c.isalpha()]
        if letters == sorted(letters) and len(word) >= 6:
            print(len(letters), word)

Kirjaimet aakkosjärjestyksessä – sanan osat

Vähintään kahdeksan kirjainta aakkosjärjestyksessä:

Ohjelma:

with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for word in handle:
        word = word.rstrip("\n")
        letters = [c for c in word.lower() if c.isalpha()]
        for substrLen in range(len(letters), 8 - 1, -1):
            if any(
                letters[p:p+substrLen] == sorted(letters[p:p+substrLen])
                for p in range(len(letters) - substrLen + 1)
            ):
                print(substrLen, word)
                break

Kirjaimet aakkosjärjestyksessä – siellä täällä

Sanat, joiden kirjaimista voidaan poimia monta aakkosjärjestyksessä olevaa, kun sana käydään läpi alusta loppuun.

Vähintään 12 kirjainta aakkosjärjestyksessä:

Sanoja, joista saa yhdeksän eri kirjainta aakkosjärjestyksessä, on paljon; tässä vain 15-kirjaimiset ja lyhemmät:

Ohjelma:

def generate_rising_sequences(rest, found=""):
    # generate sequences of rising non-adjacent items from rest;
    # e.g. "bocud" -> "bou", "bcu", "bcd" and many shorter substrings
    yield found
    for pos in range(0, len(rest)):
        if not found or found[-1] <= rest[pos]:
            yield from generate_rising_sequences(
                rest[pos+1:], found + rest[pos]
            )
def main():
    with open("stripped.txt", "rt", encoding="utf8") as handle:
        handle.seek(0)
        for line in handle:
            word = line.rstrip("\n")
            letters = "".join(c for c in word.lower() if c.isalpha())
            # non-strictly rising sequences (with repeating letters)
            sequences = set(generate_rising_sequences(letters))
            maxLen = max(len(s) for s in sequences)
            if maxLen >= 12:
                sequence = sorted(s for s in sequences if len(s) == maxLen)[0]
                print("N", maxLen, word, ",".join(sequence))
            # strictly rising sequences (without repeating letters)
            sequences = set(s for s in sequences if len(s) == len(set(s)))
            maxLen = max(len(s) for s in sequences)
            if maxLen >= 10 or maxLen >= 9 and len(letters) <= 15:
                sequence = sorted(s for s in sequences if len(s) == maxLen)[0]
                print("S", maxLen, word, ",".join(sequence))
main()

Kirjaimet, jotka ovat aakkosissa peräkkäin

16 kirjainta aakkosissa peräkkäin:

Vähintään yhdeksän eri kirjainta aakkosissa peräkkäin:

Viisi kirjainta aakkosissa ja sanassa peräkkäin, enintään 12 kirjainta yhteensä:

Neljä eri kirjainta aakkosissa ja sanassa peräkkäin, enintään kahdeksan kirjainta yhteensä:

Ohjelma:

# note: delete leading and trailing extra letters from the results manually
def get_score(word):
    # get length of longest substring in which letters increase by 0 or 1;
    # e.g. "cbbbcda" -> 5 because of "bbbcd"; word must be lowercase
    bestScore = 0
    for startPos in range(len(word)):
        prevOrd = -1
        endPos = len(word)
        for pos in range(startPos, len(word)):
            ord_ = ord(word[pos])
            if not (prevOrd == -1 or prevOrd <= ord_ <= prevOrd + 1):
                endPos = pos
                break
            prevOrd = ord_
        bestScore = max(bestScore, endPos - startPos)
    return bestScore
def remove_repeats(word):
    # remove repeating characters from word; e.g. "cbbba" -> "cba"
    return word[0] + "".join(
        b if b != a else "" for (a, b) in zip(word, word[1:])
    )
def main():
    with open("stripped.txt", "rt", encoding="utf8") as handle:
        handle.seek(0)
        for line in handle:
            word = line.rstrip("\n")
            letters = "".join(c for c in word.lower() if c.isalpha())
            letters2 = "".join(sorted(letters))
            score = get_score(letters2)
            if score >= 16:
                print("A1", score, word, ",".join(letters2))
            letters2 = "".join(sorted(set(letters)))
            score = get_score(letters2)
            if score >= 9:
                print("A2", score, word, ",".join(letters2))
            score = get_score(letters)
            if score >= 6 or score == 5 and len(letters) <= 12:
                print("B1", score, word)
            score = get_score(remove_repeats(letters))
            if score >= 5 or score == 4 and len(letters) <= 8:
                print("B2", score, word)
main()

Sanat, jotka sisältävät muita sanoja

Sanat, jotka sisältävät vähintään 21 muuta sanaa (vähintään kaksikirjaimista):

Yhdeksän kaksikirjaimista sanaa:

Seitsemän kolmikirjaimista sanaa:

Seitsemän nelikirjaimista sanaa:

Ohjelma:

from itertools import chain
MIN_SUBSTR_CNT = 21
MIN_SUBSTR_LEN = 2
MAX_SUBSTR_LEN = 99
# get words grouped by lowercase letters
wordsByLetters = {}
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for line in handle:
        word = line.rstrip("\n")
        letters = "".join(c for c in word.lower() if c.isalpha())
        wordsByLetters.setdefault(letters, set()).add(word)
allSubstrings = frozenset(
    w for w in wordsByLetters if MIN_SUBSTR_LEN <= len(w) <= MAX_SUBSTR_LEN
)
for word in sorted(wordsByLetters):
    # get substrings that are words too
    substrings = set(chain.from_iterable(
        (word[p:p+l] for p in range(len(word) - l + 1))
        for l in range(MIN_SUBSTR_LEN, min(len(word), MAX_SUBSTR_LEN) + 1)
    ))
    substrings.intersection_update(allSubstrings)
    substrings.discard(word)
    if len(substrings) >= MIN_SUBSTR_CNT:
        substrings = sorted(substrings)
        substrings.sort(key=lambda s: word.index(s))
        print(
            len(substrings),
            ",".join(sorted(wordsByLetters[word])),
            ",".join(
                chain.from_iterable(sorted(wordsByLetters[s])
                for s in substrings
            )
        ))

Toisiaan muistuttavat sanat I

Sanat, joista saa muodostettua vähintään 23 muuta sanaa poistamalla, vaihtamalla tai lisäämällä yhden kirjaimen:

Sanat, joista saadaan neljä muuta sanaa poistamalla yksi kirjain:

Sana, josta saadaan 20 muuta sanaa korvaamalla yksi kirjain:

Sana, josta saadaan 11 muuta sanaa lisäämällä yksi kirjain:

Ohjelma (sallii kaikki operaatiot):

from itertools import chain
# get words grouped by lowercase letters
wordsByLetters = {}
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for line in handle:
        word = line.rstrip("\n")
        letters = "".join(c for c in word.lower() if c.isalpha())
        wordsByLetters.setdefault(letters, set()).add(word)
distinctLetters = set(chain.from_iterable(wordsByLetters))
allWords = set(wordsByLetters)  # for speed
for word in wordsByLetters:
    similarWords = set()
    for pos in range(len(word)):  # deletion, replacement
        similarWords.add(word[:pos] + word[pos+1:])
        similarWords.update(
            word[:pos] + l + word[pos+1:] for l in distinctLetters
        )
    for pos in range(len(word) + 1):  # insertion
        similarWords.update(
            word[:pos] + l + word[pos:] for l in distinctLetters
        )
    similarWords.intersection_update(allWords)
    similarWords.remove(word)
    if len(similarWords) >= 23:
        print(
            len(similarWords),
            ",".join(sorted(wordsByLetters[word])),
            ",".join(sorted(
                "/".join(sorted(wordsByLetters[w])) for w in similarWords
            ))
        )

Toisiaan muistuttavat sanat II

Vähintään yhdeksän sanan joukot, joissa kaikki sanat voidaan muuttaa toisikseen poistamalla, vaihtamalla tai lisäämällä yksi kirjain:

Ohjelma:

from itertools import chain
# group words by letters in lower case
wordsByLetters = {}
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for line in handle:
        word = line.rstrip("\n")
        letters = "".join(c for c in word.lower() if c.isalpha())
        wordsByLetters.setdefault(letters, set()).add(word)
# for each word length and position to delete a letter from, group words by
# what remains
for length in range(2, max(len(w) for w in wordsByLetters) + 1):
    wordsOfThisLen = {w for w in wordsByLetters if len(w) == length}
    wordsOfThisLenMinusOne = {
        w for w in wordsByLetters if len(w) == length - 1
    }
    for pos in range(length):
        # e.g. {"ili": {"kili", "tili"}, ...}
        # or   {"evä": {"evä", "levä"}, ...}
        wordsByCommonPart = {w: {w} for w in wordsOfThisLenMinusOne}
        for word in wordsOfThisLen:
            wordsByCommonPart.setdefault(
                word[:pos] + word[pos+1:], set()
            ).add(word)
        #
        for commonPart in wordsByCommonPart:
            if len(wordsByCommonPart[commonPart]) >= 9:
                print(len(wordsByCommonPart[commonPart]), ",".join(
                    chain.from_iterable(
                        sorted(wordsByLetters[w])
                        for w in sorted(wordsByCommonPart[commonPart])
                    )
                ))

Sanaketjut I

Vähintään kahdeksan sanan ketjut, joiden sanat muodostetaan poistamalla edellisestä sanasta yksi kirjain mistä tahansa:

Ohjelma:

from itertools import chain
# group words by letters in lower case
wordsByLetters = dict()
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for line in handle:
        word = line.rstrip("\n")
        letters = "".join(c for c in word.lower() if c.isalpha())
        if len(letters) >= 2:
            wordsByLetters.setdefault(letters, set()).add(word)
# for each word, get "shorts" (words that are one deleted character away)
wordSet = set(wordsByLetters)  # for speed
shortsByWord = dict()
for word in wordsByLetters:
    shorts = set(
        word[:pos] + word[pos+1:] for pos in range(len(word))
    ) & wordSet
    if shorts:
        shortsByWord[word] = shorts
del wordSet
# for each word, get score (maximum number of shorter words in chain)
scores = dict()
for length in range(max(len(w) for w in shortsByWord) + 1):
    for word in (w for w in shortsByWord if len(w) == length):
        scores[word] = max(
            scores.get(short, 0) for short in shortsByWord[word]
        ) + 1
# process words that start a long chain and are not part of a longer chain
for word in (
    w for w
    in set(shortsByWord) - set(chain.from_iterable(shortsByWord.values()))
    if scores[w] >= 8 - 1
):
    # reconstruct chain (on each round, add shorts of all words from previous
    # round if they have the maximum score);
    # e.g. [{"aine"}, {"aie", "ane"}, {"ai", "ne"}]
    wordChain = [frozenset((word,))]
    for score in range(scores[word] - 1, -1, -1):
        wordChain.append(frozenset(
            s for s in chain.from_iterable(
                shortsByWord[w] for w in wordChain[-1]
            )
            if scores.get(s, 0) == score
        ))
    print(len(wordChain), ", ".join(
        "/".join(sorted(chain.from_iterable(wordsByLetters[w] for w in words)))
        for words in wordChain
    ))

Sanaketjut II

Kukin ketjun sana muodostetaan poistamalla edellisestä sanasta yksi tai useampi kirjain, aina alusta tai aina lopusta.

Seitsemän sanan ketjut, joissa kirjaimet poistetaan sanan lopusta:

Viiden sanan ketjut, joissa kirjaimet poistetaan sanan alusta; aloitussanassa enintään kahdeksan kirjainta:

Ohjelma:

with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    words = frozenset(l.rstrip("\n") for l in handle)
for word in words:
    prefixes = [word[:i] for i in range(1, len(word)) if word[:i] in words]
    suffixes = [word[i:] for i in range(1, len(word)) if word[i:] in words]
    if len(prefixes) >= 7 - 1:
        print("P", len(prefixes) + 1, ",".join([word] + prefixes[::-1]))
    if len(suffixes) >= 6 - 1 or len(suffixes) >= 5 - 1 and len(word) <= 8:
        print("S", len(suffixes) + 1, ",".join([word] + suffixes))

Kirjainten muodot

Vain aukollisia kirjaimia (esim. O, A):

Vain aukottomia kirjaimia:

Vain kaarellisia kirjaimia (esim. C, D):

Vain kaarettomia kirjaimia:

Vain kaarettomia aukottomia kirjaimia:

Vain kulmallisia kirjaimia (esim. L, D):

Vain kulmallisia kaarettomia kirjaimia:

Vain kulmattomia kirjaimia:

Vain risteyksellisiä kirjaimia (esim. K, T, Y, X):

Vain risteyksellisiä kaarettomia kirjaimia:

Vain risteyksettömiä kirjaimia:

Vain symmetrisiä kirjaimia, joiden vasen ja oikea puoli peilikuvia toisistaan (esim. U, I):

Vain symmetrisiä kirjaimia, joiden ylä- ja alapuoli peilikuvia toisistaan (esim. C, I):

Ohjelma:

# key = description; value = (minimum length for words with these letters only,
# minimum length for words with none of these letters, letters);
# only the letters ABCDEÉFGHIJKLMNOPQRSŠTUVWXYZŽÅÄÖ are considered here
LETTER_SETS = {
    "angle": (11, 13, frozenset("ABDEÉFGLMNPRŠVWZŽÅÄÖ")),
    "crossing": (11, 13, frozenset("ABEÉFHKPQRTXYÅÄ")),
    "curve": (8, 17, frozenset("BCDGJOPQRSŠUÅÖ")),
    "hole": (7, 20, frozenset("ABDOPQRÅÄÖ")),
    "symmetryLr": (12, 99, frozenset("AHIMOTUVWXYÅÄÖ")),  # left vs. right
    "symmetryTb": (7, 99, frozenset("BCDEHIKOX")),  # top vs. bottom
    #
    "angle,no-curve": (9, 99, frozenset("AEÉFLMNVWZŽÄ")),
    "crossing,no-curve": (10, 99, frozenset("AEÉFHKTXYÄ")),
    "no-curve,no-hole": (14, 99, frozenset("EÉFHIKLMNTVWXYZŽ")),
}
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for line in handle:
        word = line.rstrip("\n").upper()
        letterCnt = sum(1 for c in word if c.isalpha())
        letters   = set(c for c in word if c.isalpha())
        for descr in LETTER_SETS:
            (minLenAll, minLenNone, letterSet) = LETTER_SETS[descr]
            if letters.issubset(letterSet) and letterCnt >= minLenAll:
                print(descr, "all", letterCnt, word)
            elif letters.isdisjoint(letterSet) and letterCnt >= minLenNone:
                print(descr, "none", letterCnt, word)

Morseaakkosina

20 pistettä peräkkäin:

21 viivaa peräkkäin:

17 pistettä, ei viivoja:

12 viivaa, ei pisteitä:

Ohjelma:

import re
# https://fi.wikipedia.org/wiki/Sähkötys
MORSE = {
    "a": ".-", "b": "-...", "c": "-.-.", "d": "-..", "e": ".", "f": "..-.",
    "g": "--.", "h": "....", "i": "..", "j": ".---", "k": "-.-", "l": ".-..",
    "m": "--", "n": "-.", "o": "---", "p": ".--.", "q": "--.-", "r": ".-.",
    "s": "...", "t": "-", "u": "..-", "v": "...-", "w": ".--", "x": "-..-",
    "y": "-.--", "z": "--..", "å": ".--.-", "ä": ".-.-", "ö": "---.",
}
REGEXES = (
    ("dot, not only, 20",  r"\.{20}"),
    ("dot, not only, 21",  r"\.{21}"),     # shouldn't find any
    ("dash, not only, 21", r"-{21}"),
    ("dash, not only, 22", r"-{22}"),      # shouldn't find any
    ("dot, only, 17",      r"^\.{17,}$"),
    ("dot, only, 18",      r"^\.{18,}$"),  # shouldn't find any
    ("dash, only, 12",     r"^-{12,}$"),
    ("dash, only, 13",     r"^-{13,}$"),   # shouldn't find any
)
with open("stripped.txt", "rt", encoding="utf8") as handle:
    handle.seek(0)
    for line in handle:
        word = line.rstrip("\n")
        lowerCase = word.lower()
        if set(lowerCase).issubset(set(MORSE)):
            morse = "".join(MORSE[c] for c in lowerCase)
            for (descr, regex) in REGEXES:
                if re.search(regex, morse) is not None:
                    print(
                        descr, word,
                        "(" + " ".join(MORSE[c] for c in word) + ")"
                    )

Pistekirjoituksena

Pistekirjoitus (braille) on kohokirjoitusjärjestelmä näkörajoitteisille.

Sanan jokaisessa kirjaimessa enintään kaksi pistettä

abi, ai, aie, aika, akka, baba, bebee, beibi, ei, eka, iikka, iki, ikiaika, kaakki, kai, kaikaa, kaikki, kaki, kakka, kakkia, kebab, keikka, kii, kikka

Samat sanat pistekirjoitusmerkkien kanssa (ohita):

Sanan jokaisessa kirjaimessa vähintään neljä pistettä

nynny, nyppy, nyt, pyry, pytty, pyy, rynttyyt, ryppy, ryyppy, tv, tyyny, tyyt, yty

Samat sanat pistekirjoitusmerkkien kanssa (ohita):

Sanan jokin pisterivi täynnä

nynny, nyppy, pyy

Samat sanat pistekirjoitusmerkkien kanssa (ohita):

Sanan jokin pisterivi tyhjä

aamu, abi, ah, ahaa, ahde, ai, aie, aihe, aijai, ajaa, ajaja, akka, akku, ammu, ammua, ammuu, auma, baba, bebee, beibi, beige, bidee, caddie, chic, dia, ehei, ei, faija, fiba, giga, ha, haa, hah, hai, haja, haje, he, hede, heh, hei, hi, hie, hifi, hiha, hihhei, idea, ja, jaa, jaaha, jade, jae, jaha, jiddi, kaakku, kakka, kakku, kama, kamu, kaukaa, kuka, kukka, kukkamaa, kukku, kukkua, kukkuu, kumma, kumu, kuu, kuuma, kuumua, ma, maa, maku, makuu, mamma, mau, maukua, muka, mukaa, mukauma, mummu, muu, uuma

Samat sanat pistekirjoitusmerkkien kanssa (ohita):

Ohjelma

# https://fi.wikipedia.org/wiki/Pistekirjoitus
# codepoints: U+2800–U+283F or 0x2800 + 0bABCDEF; bits:
#   F C
#   E B
#   D A
BRAILLE = {
    "a": "⠁", "b": "⠃", "c": "⠉", "d": "⠙", "e": "⠑", "f": "⠋", "g": "⠛",
    "h": "⠓", "i": "⠊", "j": "⠚", "k": "⠅", "l": "⠇", "m": "⠍", "n": "⠝",
    "o": "⠕", "p": "⠏", "q": "⠟", "r": "⠗", "s": "⠎", "t": "⠞", "u": "⠥",
    "v": "⠧", "w": "⠺", "x": "⠭", "y": "⠽", "z": "⠵", "å": "⠡", "ä": "⠜",
    "ö": "⠪",
}
def to_braille(word):
    return "".join(BRAILLE[l] for l in word)
def main():
    with open("stripped.txt", "rt", encoding="utf8") as handle:
        handle.seek(0)
        for line in handle:
            word = line.rstrip("\n")
            if set(word).issubset(BRAILLE):
                codepoints = [ord(BRAILLE[l]) for l in word]
                dotCounts = [int.bit_count(c % 64) for c in codepoints]
                if max(dotCounts) <= 2:
                    print(
                        "max dotcount", max(dotCounts), word, to_braille(word)
                    )
                elif min(dotCounts) >= 4:
                    print(
                        "min dotcount", min(dotCounts), word, to_braille(word)
                    )
                if (
                    all(c & 0b1001   == 0b1001   for c in codepoints) or
                    all(c & 0b10010  == 0b10010  for c in codepoints) or
                    all(c & 0b100100 == 0b100100 for c in codepoints)
                ):
                    print(
                        "all dots on a row", word, to_braille(word)
                    )
                if (
                    all(c & 0b1001   == 0 for c in codepoints) or
                    all(c & 0b10010  == 0 for c in codepoints) or
                    all(c & 0b100100 == 0 for c in codepoints)
                ):
                    print(
                        "no dots on a row", word, to_braille(word)
                    )
main()

Alkuaineiden kemiallisina merkkeinä

Ei yksikirjaimisia kemiallisia merkkejä ja vähintään viisi kaksikirjaimista:

Yksi yksikirjaiminen kemiallinen merkki ja vähintään kuusi kaksikirjaimista:

Kaksi yksikirjaimista kemiallista merkkiä ja (vähintään) seitsemän kaksikirjaimista:

Ohjelma:

# https://fi.wikipedia.org/wiki/Luettelo_alkuaineista
# key = symbol in lower case, value = Finnish name
ELEMENTS = {
    "ac": "aktinium", "ag": "hopea", "al": "alumiini", "am": "amerikium",
    "ar": "argon", "as": "arseeni", "at": "astatiini", "au": "kulta",
    "b": "boori", "ba": "barium", "be": "beryllium", "bh": "bohrium",
    "bi": "vismutti", "bk": "berkelium", "br": "bromi", "c": "hiili",
    "ca": "kalsium", "cd": "kadmium", "ce": "cerium", "cf": "kalifornium",
    "cl": "kloori", "cm": "curium", "cn": "kopernikium", "co": "koboltti",
    "cr": "kromi", "cs": "cesium", "cu": "kupari", "db": "dubnium",
    "ds": "darmstadtium", "dy": "dysprosium", "er": "erbium",
    "es": "einsteinium", "eu": "europium", "f": "fluori", "fe": "rauta",
    "fl": "flerovium", "fm": "fermium", "fr": "frankium", "ga": "gallium",
    "gd": "gadolinium", "ge": "germanium", "h": "vety", "he": "helium",
    "hf": "hafnium", "hg": "elohopea", "ho": "holmium", "hs": "hassium",
    "i": "jodi", "in": "indium", "ir": "iridium", "k": "kalium",
    "kr": "krypton", "la": "lantaani", "li": "litium", "lr": "lawrencium",
    "lu": "lutetium", "lv": "livermorium", "mc": "moskovium",
    "md": "mendelevium", "mg": "magnesium", "mn": "mangaani",
    "mo": "molybdeeni", "mt": "meitnerium", "n": "typpi", "na": "natrium",
    "nb": "niobium", "nd": "neodyymi", "ne": "neon", "nh": "nihonium",
    "ni": "nikkeli", "no": "nobelium", "np": "neptunium", "o": "happi",
    "og": "oganesson", "os": "osmium", "p": "fosfori", "pa": "protaktinium",
    "pb": "lyijy", "pd": "palladium", "pm": "prometium", "po": "polonium",
    "pr": "praseodyymi", "pt": "platina", "pu": "plutonium", "ra": "radium",
    "rb": "rubidium", "re": "renium", "rf": "rutherfordium",
    "rg": "röntgenium", "rh": "rodium", "rn": "radon", "ru": "rutenium",
    "s": "rikki", "sb": "antimoni", "sc": "skandium", "se": "seleeni",
    "sg": "seaborgium", "si": "pii", "sm": "samarium", "sn": "tina",
    "sr": "strontium", "ta": "tantaali", "tb": "terbium", "tc": "teknetium",
    "te": "telluuri", "th": "torium", "ti": "titaani", "tl": "tallium",
    "tm": "tulium", "ts": "tennessiini", "u": "uraani", "v": "vanadiini",
    "w": "volframi", "xe": "ksenon", "y": "yttrium", "yb": "ytterbium",
    "zn": "sinkki", "zr": "zirkonium",
}
def word_to_letter_pairs(word):
    # length must be even
    return [word[p:p+2] for p in range(0, len(word), 2)]
def print_word(descr, symbols):
    print(
        descr,
        sum(len(s) for s in symbols),
        "".join(s.title() for s in symbols),
        "(" + ",".join(ELEMENTS[s] for s in symbols) + ")"
    )
def get_alphabetic_words():
    with open("stripped.txt", "rt", encoding="utf8") as handle:
        handle.seek(0)
        for line in handle:
            word = line.rstrip("\n")
            if word.isalpha():
                yield word.lower()
def main():
    for word in get_alphabetic_words():
        if len(word) % 2 == 0 and len(word) >= 10:
            # no 1-letter symbols
            symbols = word_to_letter_pairs(word)
            if set(symbols).issubset(ELEMENTS):
                print_word(0, symbols)
            if len(word) >= 16:
                # two 2-letter symbols
                # positions of 1-letter symbols
                for pos1 in range(0, len(word), 2):
                    for pos2 in range(pos1 + 1, len(word), 2):
                        symbols = (
                            word_to_letter_pairs(word[:pos1])
                            + [word[pos1]]
                            + word_to_letter_pairs(word[pos1+1:pos2])
                            + [word[pos2]]
                            + word_to_letter_pairs(word[pos2+1:])
                        )
                        if set(symbols).issubset(ELEMENTS):
                            print_word(2, symbols)
        elif len(word) >= 13:
            # one 1-letter symbol
            # position of 1-letter symbol
            for pos in range(0, len(word), 2):
                symbols = (
                    word_to_letter_pairs(word[:pos])
                    + [word[pos]]
                    + word_to_letter_pairs(word[pos+1:])
                )
                if set(symbols).issubset(ELEMENTS):
                    print_word(1, symbols)
main()