diff --git a/08-slovniky/k-gramy.py b/08-slovniky/k-gramy.py
new file mode 100755
index 0000000000000000000000000000000000000000..c0dd493068e9d8328893e03aab46faa975334457
--- /dev/null
+++ b/08-slovniky/k-gramy.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+# Spočítá frekvence k-gramů v souboru soubor.txt
+# (v každém řádku zvlášť).
+
+from collections import defaultdict
+
+k=3
+kgramy=defaultdict(int)
+
+for radek in open('soubor.txt'):
+    # Rozdělíme na k-gramy
+    # (ignorujeme znak konce řádku na poslední pozici)
+    for i in range(len(radek)-k):
+        kgramy[radek[i:i+k]] += 1
+
+# Vytvoříme seznam dvojic (frekvence, k-gram), vypíšeme seřazeně
+vystup = [ (f, g) for g, f in kgramy.items() ]
+for f, g in reversed(sorted(vystup)):
+    print(f, g)
diff --git a/08-slovniky/k-gramy2.py b/08-slovniky/k-gramy2.py
new file mode 100755
index 0000000000000000000000000000000000000000..0a0c552f71728b4e609aaeb16d1bb70bd67e7f1d
--- /dev/null
+++ b/08-slovniky/k-gramy2.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+# Spočítá frekvence k-gramů v souboru soubor.txt
+# (uvažujeme i k-gramy jdoucí přes hranice řádků).
+
+from collections import defaultdict
+
+k=3
+
+text = ""
+for radek in open('soubor.txt'):
+    text += radek[:-1] + ' '
+
+kgramy=defaultdict(int)
+for i in range(len(text)-k):
+    kgramy[text[i:i+k]] += 1
+
+# Vytvoříme seznam dvojic (frekvence, k-gram), vypíšeme seřazeně
+vystup = [ (f, g) for g, f in kgramy.items() ]
+for f, g in reversed(sorted(vystup)):
+    print(f, g)
diff --git a/08-slovniky/k-gramy3.py b/08-slovniky/k-gramy3.py
new file mode 100755
index 0000000000000000000000000000000000000000..af68c137c0d76e7b61dcc88d5a2b33ded122c9ef
--- /dev/null
+++ b/08-slovniky/k-gramy3.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+# Vygeneruje náhodný text na motivy zadaného
+# podle k-gramové statistiky.
+
+from collections import defaultdict
+import random
+
+k=3
+
+text = ""
+for radek in open('soubor.txt'):
+    text += radek[:-1] + ' '
+
+pokrac=defaultdict(list)
+for i in range(len(text)-k-1):
+    pokrac[text[i:i+k]] += text[i+k]
+
+gen = random.choice(list(pokrac))
+while len(gen) < 1000:
+    p = pokrac[gen[-k:]]
+    if p:
+        gen += random.choice(p)
+    else:
+        gen += '/' + random.choice(list(pokrac))
+
+print(gen)
diff --git a/08-slovniky/porovnavani.py b/08-slovniky/porovnavani.py
new file mode 100644
index 0000000000000000000000000000000000000000..16923f8275144dff2aa8da9a113f95b2b23fb1ab
--- /dev/null
+++ b/08-slovniky/porovnavani.py
@@ -0,0 +1,25 @@
+# Obsahují dva seznamy tytéž prvky (až na pořadí)?
+# Verze pro seznamy, které mají všechny prvky různé.
+def porovnej(x, y):
+    return set(x) == set(y)
+
+# Pokud se prvky mohou opakovat, můžeme seznamy setřídit
+# a pak je porovnat. To ovšem trvá řádově n*log n kroků.
+def porovnej2(x, y):
+    return sorted(x) == sorted(y)
+
+# Nebo můžeme použít slovník, abychom spočítali četnosti
+# prvků v obou seznamech. To trvá řádově n kroků.
+
+def pocitej(x):
+    cetnosti = defaultdict(int)
+    for a in x:
+        cetnosti[a] += 1
+    return cetnosti
+
+def porovnej3(x, y):
+    return pocitej(x) == pocitej(y)
+
+# Jsou všechny prvky seznamu navzájem různé?
+def ruzne_prvky(x):
+    return len(x) == len(set(x))