This commit is contained in:
Adam Blažek 2021-06-05 13:36:20 +02:00
commit ec97950a9d
39 changed files with 1001 additions and 99 deletions

46
c/grupy.html Normal file
View File

@ -0,0 +1,46 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><link rel="stylesheet" href="/styles/mathsessions.css"><link rel="stylesheet" href="/styles/katex.min.css"><script defer src="/scripts/katex.min.js" onload="renderMathInElement(document.body)"></script><title>Grupy</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><p class="notice">Tento článek je zkopírován ze stránky <a href="http://mathsessions.klusik.cz/">Matematická setkání</a>.</p><div class="entry-content"><h1 class="entry-title">Grupy</h1>
<p>Tento článek je pokračováním k <a href="http://mathsessions.klusik.cz/2021/01/02/semigrupy/">článku o semigrupách</a>.</p>
<h2>Definice</h2>
<p>Už jsme si vysvětlili, co jsou to grupoidy, semigrupy a monoidy. Nyní povýšíme ještě o jednu úroveň a definujeme <em>grupu</em>.</p>
<p class="has-light-blue-background-color has-background">Monoid \((G; \cdot)\) nazveme <em>grupou</em>, pokud v něm funguje <em>inverze</em>. To znamená, že ke každému prvku \(x \in G\) existuje nějaký inverzní prvek \(x^{-1} \in G\) (ne nutně různý od \(x\)), pro který platí \(x \cdot x^{-1} = x^{-1} \cdot x = e\) (kde \(e\) je prvek identity, který máme již zahrnutý v definici monoidu).</p>
<h2>Příklady</h2>
<p>Pojďme zjistit, zda náš oblíbený grupoid \((\mathbb Z; +)\) je grupa. Již jsme si dokázali, že jde o monoid, kde prvkem identity je \(0\), takže nyní nám stačí dokázat, že v něm všechny prvky mají inverzi.</p>
<p>Vezměme si například \(x = 6\). Chceme-li najít inverzní prvek, řešíme rovnici \(6 + x^{-1} = x^{-1} + 6 = 0\). Řešením této rovnice je \(x^{-1} = -6\), a to je tedy inverzním prvkem ke zvolenému \(x\). Zároveň zřejmě podobným způsobem najdeme inverzi ke každému prvku \(x\), a sice \(-x\). Z toho plyne, že \((\mathbb Z; +)\) je grupa.</p>
<p>Povšimněme si, že inverzí \(0\) je opět \(0\). To platí pro prvek identity v každé grupě, neboť řešením rovnice \(e \cdot e^{-1} = e\) je právě \(e^{-1} = e\).</p>
<p>Jako druhý příklad zjistěme, zda \((\mathbb Z; \cdot)\) je grupa (kde \(\cdot\) tentokrát skutečně značí násobení). Dá se celkem snadno dokázat, že jde o monoid s identitou \(1\), takže nás opět zajímá hlavně inverze. Pokud si vybereme například \(x = -1\) a budeme k němu hledat inverzi, dostaneme se na rovnici \((-1) \cdot x^{-1} = 1\), která má řešení \(x^{-1} = -1\). Inverzi však musí mít všechny prvky, a pokud vybereme třeba \(x = -7\), rovnice \((-7) \cdot x^{-1} = 1\) už řešení v oboru celých čísel mít nebude. \((\mathbb Z; \cdot)\) tedy sice je monoid, ale grupa už ne.</p>
<p>Pokračujme nyní s příklady S2 a S4 z článku o semigrupách. (O grupoidu v příkladu S3 jsme zjistili, že není monoid, tudíž nemůže být ani grupa.)</p>
<h5>S2</h5>
<p>Máme množinu tří funkcí \(F = \{f(x),g(x),h(x)\}\) definovaných takto:</p>
<p>\[f(x) = x, \\ g(x) = 1-\frac{1}{x}, \\ h(x) = \frac {1}{1-x}. \\ D(f) = \mathbb{R} \{0,1\}, \\ D(g) = \mathbb{R}-\{0\}, \\ D(h) = \mathbb{R}-\{1\}.\]</p>
<p>Již jsme dokázali, že \((F, \circ)\), kde \(\circ\) značí skládání funkcí, tvoří monoid s identitou \(f\). Také jsme si sestavili přehlednou tabulku:</p>
<p>\[\begin {array} {c|ccc} \circ &amp; f(x) &amp; g(x) &amp; h(x) \\ \hline f(x) &amp; f(x) &amp; g(x) &amp; h(x) \\ g(x) &amp; g(x) &amp; h(x) &amp; f(x) \\ h(x) &amp; h(x) &amp; f(x) &amp; g(x) \\ \end {array}\]</p>
<p>Máme-li takovouto tabulku, potom je velmi snadné určit, zda se jedná o grupu. Chceme, aby každý prvek měl inverzi, což neznamená nic jiného, než že v příslušném řádku najdeme prvek identity. Inverzní prvek poté nalezneme v záhlaví odpovídajícího sloupce. Musíme si však dát pozor na to, že při obrácení pořadí prvků musí také vyjít identita (grupa obecně nemusí být komutativní) — to již snadno v tabulce dohledáme.</p>
<p>V tomto konkrétním případě tedy zjistíme, že \(f^{-1} = f\), \(g^{-1} = h\) a \(h^{-1} = g\). Dokázali jsme, že \((F; \circ)\) je grupa.</p>
<h5>S4</h5>
<p>Zde máme algebraickou strukturu \(( (-c; c); \oplus)\) s nějakou konstantou \(c \in \mathbb R^+\) (v praxi jde o rychlost světla), kde operace \(\oplus\) je definována následovně:</p>
<p>\[u \oplus v = \frac{u+v}{1+{\frac{uv}{c^2}}}\]</p>
<p>Tu nejtěžší část máme již za sebou — dokázali jsme, že je to grupoid, semigrupa i monoid (s identitou \(0\)). Nyní máme daný nějaký prvek \(u\) a chceme k němu najít inverzi. To znamená, že řešíme rovnici:</p>
<p>\[\frac{u+u^{-1}}{1+{\displaystyle\frac{uu^{-1}}{c^2}}} = 0\]</p>
<p>Řešení je velmi jednoduché: obě strany rovnice vynásobíme jmenovatelem velkého zlomku. Ten nemůže být \(0\), protože jsme si již dokázali, že výraz je vždy definovaný. Dostaneme se tím na tvar \(u + u^{-1} = 0 \Longrightarrow u^{-1} = -u\). Tato inverze bude jistě ležet v nosné množině, neboť ta obsahuje vzájemně si odpovídající kladná a záporná čísla. Máme tedy dokázáno, že \(( (-c; c); \oplus)\) je grupa.</p>
<h2>Věty</h2>
<p>Nyní si dokažme pár zajímavých vět o grupách:</p>
<p class="has-yellow-background-color has-background">Věta: Každý prvek grupy má právě jednu inverzi.</p>
<p>Důkaz: Předpokládejme, že by jeden prvek \(x\) měl dvě různé inverze \(x^{-1}_1\) a \(x^{-1}_2\). Podle definice inverze můžeme psát:</p>
<p>\[xx^{-1}_1 = e = xx^{-1}_2\]</p>
<p>(Operaci grupy zde značíme jako násobení bez tečky.) Vynásobíme obě strany rovnice zleva \(x^{-1}_1\):</p>
<p>\[x^{-1}_1(xx^{-1}_1) = x^{-1}_1(xx^{-1}_2)\]</p>
<p>V grupě platí asociativita, takže můžeme přehodit závorky:</p>
<p>\[(x^{-1}_1x)x^{-1}_1 = (x^{-1}_1x)x^{-1}_2\]</p>
<p>Nyní můžeme opět uplatnit definici inverze:</p>
<p>\[ex^{-1}_1 = ex^{-1}_2\]</p>
<p>A nakonec použijeme definici identity:</p>
<p>\[x^{-1}_1 = x^{-1}_2\]</p>
<p>Tím jsme se dostali do sporu s předpokladem, že jsme vybrali dvě různé inverze. Věta tedy musí platit.</p>
<p class="has-yellow-background-color has-background">Věta: Každá grupa je kvazigrupa, tedy funguje v ní krácení a dělení. (Více informací o kvazigrupách najdete v našem článku o nich.)</p>
<p class="has-light-blue-background-color has-background">Definice krácení: Pokud pro nějaká \(x, y, z \in G\) platí \(xz = yz\) nebo \(zx = zy\), potom \(x = y\).</p>
<p>Důkaz krácení: Začněme rovností \(xz = yz\). Obě strany vynásobíme zprava \(z^{-1}\) a máme \(xzz^{-1} = yzz^{-1}\). (Díky asociativitě není nutné zde psát závorky.) Poté podle identity máme \(x = y\). Podobně můžeme dokázat i druhou část, stačí násobit zleva místo zprava.</p>
<p class="has-light-blue-background-color has-background">Definice dělení: Pro každé dva prvky \(x, y \in G\) existují dva prvky \(a, b \in G\) (ne nutně různé) takové, že \(ax = y = xb\).</p>
<p>Důkaz dělení: Zvolíme \(a = yx^{-1}\) a \(b = x^{-1}y\). Poté máme \(ax = yx^{-1}x = y\) a \(xb = xx^{-1}y = y\). Tím je důkaz hotov.</p>
<p>Tím zároveň víme, že každá grupa je lupa, neboť lupa je definována jako kvazigrupa s identitou a grupa samozřejmě má identitu.</p>
<!-- .author-info -->
</div></body></html>

52
c/grupy.jade Normal file
View File

@ -0,0 +1,52 @@
extends ../templates/mathsessions.jade
block title
| Grupy
block article
<div class="entry-content"><h1 class="entry-title">Grupy</h1>
<p>Tento článek je pokračováním k <a href="http://mathsessions.klusik.cz/2021/01/02/semigrupy/">článku o semigrupách</a>.</p>
<h2>Definice</h2>
<p>Už jsme si vysvětlili, co jsou to grupoidy, semigrupy a monoidy. Nyní povýšíme ještě o jednu úroveň a definujeme <em>grupu</em>.</p>
<p class="has-light-blue-background-color has-background">Monoid \((G; \cdot)\) nazveme <em>grupou</em>, pokud v něm funguje <em>inverze</em>. To znamená, že ke každému prvku \(x \in G\) existuje nějaký inverzní prvek \(x^{-1} \in G\) (ne nutně různý od \(x\)), pro který platí \(x \cdot x^{-1} = x^{-1} \cdot x = e\) (kde \(e\) je prvek identity, který máme již zahrnutý v definici monoidu).</p>
<h2>Příklady</h2>
<p>Pojďme zjistit, zda náš oblíbený grupoid \((\mathbb Z; +)\) je grupa. Již jsme si dokázali, že jde o monoid, kde prvkem identity je \(0\), takže nyní nám stačí dokázat, že v něm všechny prvky mají inverzi.</p>
<p>Vezměme si například \(x = 6\). Chceme-li najít inverzní prvek, řešíme rovnici \(6 + x^{-1} = x^{-1} + 6 = 0\). Řešením této rovnice je \(x^{-1} = -6\), a to je tedy inverzním prvkem ke zvolenému \(x\). Zároveň zřejmě podobným způsobem najdeme inverzi ke každému prvku \(x\), a sice \(-x\). Z toho plyne, že \((\mathbb Z; +)\) je grupa.</p>
<p>Povšimněme si, že inverzí \(0\) je opět \(0\). To platí pro prvek identity v každé grupě, neboť řešením rovnice \(e \cdot e^{-1} = e\) je právě \(e^{-1} = e\).</p>
<p>Jako druhý příklad zjistěme, zda \((\mathbb Z; \cdot)\) je grupa (kde \(\cdot\) tentokrát skutečně značí násobení). Dá se celkem snadno dokázat, že jde o monoid s identitou \(1\), takže nás opět zajímá hlavně inverze. Pokud si vybereme například \(x = -1\) a budeme k němu hledat inverzi, dostaneme se na rovnici \((-1) \cdot x^{-1} = 1\), která má řešení \(x^{-1} = -1\). Inverzi však musí mít všechny prvky, a pokud vybereme třeba \(x = -7\), rovnice \((-7) \cdot x^{-1} = 1\) už řešení v oboru celých čísel mít nebude. \((\mathbb Z; \cdot)\) tedy sice je monoid, ale grupa už ne.</p>
<p>Pokračujme nyní s příklady S2 a S4 z článku o semigrupách. (O grupoidu v příkladu S3 jsme zjistili, že není monoid, tudíž nemůže být ani grupa.)</p>
<h5>S2</h5>
<p>Máme množinu tří funkcí \(F = \{f(x),g(x),h(x)\}\) definovaných takto:</p>
<p>\[f(x) = x, \\ g(x) = 1-\frac{1}{x}, \\ h(x) = \frac {1}{1-x}. \\ D(f) = \mathbb{R} \{0,1\}, \\ D(g) = \mathbb{R}-\{0\}, \\ D(h) = \mathbb{R}-\{1\}.\]</p>
<p>Již jsme dokázali, že \((F, \circ)\), kde \(\circ\) značí skládání funkcí, tvoří monoid s identitou \(f\). Také jsme si sestavili přehlednou tabulku:</p>
<p>\[\begin {array} {c|ccc} \circ &amp; f(x) &amp; g(x) &amp; h(x) \\ \hline f(x) &amp; f(x) &amp; g(x) &amp; h(x) \\ g(x) &amp; g(x) &amp; h(x) &amp; f(x) \\ h(x) &amp; h(x) &amp; f(x) &amp; g(x) \\ \end {array}\]</p>
<p>Máme-li takovouto tabulku, potom je velmi snadné určit, zda se jedná o grupu. Chceme, aby každý prvek měl inverzi, což neznamená nic jiného, než že v příslušném řádku najdeme prvek identity. Inverzní prvek poté nalezneme v záhlaví odpovídajícího sloupce. Musíme si však dát pozor na to, že při obrácení pořadí prvků musí také vyjít identita (grupa obecně nemusí být komutativní) — to již snadno v tabulce dohledáme.</p>
<p>V tomto konkrétním případě tedy zjistíme, že \(f^{-1} = f\), \(g^{-1} = h\) a \(h^{-1} = g\). Dokázali jsme, že \((F; \circ)\) je grupa.</p>
<h5>S4</h5>
<p>Zde máme algebraickou strukturu \(( (-c; c); \oplus)\) s nějakou konstantou \(c \in \mathbb R^+\) (v praxi jde o rychlost světla), kde operace \(\oplus\) je definována následovně:</p>
<p>\[u \oplus v = \frac{u+v}{1+{\frac{uv}{c^2}}}\]</p>
<p>Tu nejtěžší část máme již za sebou — dokázali jsme, že je to grupoid, semigrupa i monoid (s identitou \(0\)). Nyní máme daný nějaký prvek \(u\) a chceme k němu najít inverzi. To znamená, že řešíme rovnici:</p>
<p>\[\frac{u+u^{-1}}{1+{\displaystyle\frac{uu^{-1}}{c^2}}} = 0\]</p>
<p>Řešení je velmi jednoduché: obě strany rovnice vynásobíme jmenovatelem velkého zlomku. Ten nemůže být \(0\), protože jsme si již dokázali, že výraz je vždy definovaný. Dostaneme se tím na tvar \(u + u^{-1} = 0 \Longrightarrow u^{-1} = -u\). Tato inverze bude jistě ležet v nosné množině, neboť ta obsahuje vzájemně si odpovídající kladná a záporná čísla. Máme tedy dokázáno, že \(( (-c; c); \oplus)\) je grupa.</p>
<h2>Věty</h2>
<p>Nyní si dokažme pár zajímavých vět o grupách:</p>
<p class="has-yellow-background-color has-background">Věta: Každý prvek grupy má právě jednu inverzi.</p>
<p>Důkaz: Předpokládejme, že by jeden prvek \(x\) měl dvě různé inverze \(x^{-1}_1\) a \(x^{-1}_2\). Podle definice inverze můžeme psát:</p>
<p>\[xx^{-1}_1 = e = xx^{-1}_2\]</p>
<p>(Operaci grupy zde značíme jako násobení bez tečky.) Vynásobíme obě strany rovnice zleva \(x^{-1}_1\):</p>
<p>\[x^{-1}_1(xx^{-1}_1) = x^{-1}_1(xx^{-1}_2)\]</p>
<p>V grupě platí asociativita, takže můžeme přehodit závorky:</p>
<p>\[(x^{-1}_1x)x^{-1}_1 = (x^{-1}_1x)x^{-1}_2\]</p>
<p>Nyní můžeme opět uplatnit definici inverze:</p>
<p>\[ex^{-1}_1 = ex^{-1}_2\]</p>
<p>A nakonec použijeme definici identity:</p>
<p>\[x^{-1}_1 = x^{-1}_2\]</p>
<p>Tím jsme se dostali do sporu s předpokladem, že jsme vybrali dvě různé inverze. Věta tedy musí platit.</p>
<p class="has-yellow-background-color has-background">Věta: Každá grupa je kvazigrupa, tedy funguje v ní krácení a dělení. (Více informací o kvazigrupách najdete v našem článku o nich.)</p>
<p class="has-light-blue-background-color has-background">Definice krácení: Pokud pro nějaká \(x, y, z \in G\) platí \(xz = yz\) nebo \(zx = zy\), potom \(x = y\).</p>
<p>Důkaz krácení: Začněme rovností \(xz = yz\). Obě strany vynásobíme zprava \(z^{-1}\) a máme \(xzz^{-1} = yzz^{-1}\). (Díky asociativitě není nutné zde psát závorky.) Poté podle identity máme \(x = y\). Podobně můžeme dokázat i druhou část, stačí násobit zleva místo zprava.</p>
<p class="has-light-blue-background-color has-background">Definice dělení: Pro každé dva prvky \(x, y \in G\) existují dva prvky \(a, b \in G\) (ne nutně různé) takové, že \(ax = y = xb\).</p>
<p>Důkaz dělení: Zvolíme \(a = yx^{-1}\) a \(b = x^{-1}y\). Poté máme \(ax = yx^{-1}x = y\) a \(xb = xx^{-1}y = y\). Tím je důkaz hotov.</p>
<p>Tím zároveň víme, že každá grupa je lupa, neboť lupa je definována jako kvazigrupa s identitou a grupa samozřejmě má identitu.</p>
<!-- .author-info -->
</div>

2
c/index.html Normal file
View File

@ -0,0 +1,2 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><link rel="stylesheet" href="/styles/katex.min.css"><script defer src="/scripts/katex.min.js" onload="renderMathInElement(document.body)"></script><title>xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><p class="warning">This website is a work in progress.</p><p>
Ahoj! Jsem <em class="xigoi">xigoi</em>. Mám rád programování a dalši záležitosti s počítači, matematiku, lingvistiku a chůzi. Ovládám češtinu, angličtinu, <a href="https://tokipona.org/">Toki Ponu</a> a trochu němčiny. Jsem velký nadšenec do open-source — používám <a href="https://www.linux.com/news/what-is-gnu-linux/">GNU/Linux</a>, <a href="https://www.vim.org/">Vim</a>, <a href="https://www.latex-project.org/">\(\text{\LaTeX}\)</a>, <a href="https://f-droid.org/">F-Droid</a>, <a href="https://disroot.org/en">Disroot</a> a další. Na této stránce a její <a href="/">anglickě verzi</a> můžete najít různé věci mnou napsané a jinak vytvořené. Šťastné prohlížení!</p><h2>Matematika</h2><ul class="index"><li><a href="grupy.html">Grupy</a></li><li><a href="permutace-a-symetricke-grupy.html">Permutace a symetrické grupy</a></li><li><a href="latex.html">\(\mathrm\LaTeX\)</a></li><li><a href="vytvareni-dokumentu-v-systemu-latex.html">Vytváťení dokumentů v systému \(\mathrm\LaTeX\)</a></li></ul><h2>Kontaktujte mě</h2><ul class="index"><li>E-mail: <a href="mailto:xigoi@disroot.org">xigoi@disroot.org</a></li><li>Ruqqus: <a href="https://ruqqus.com/@xigoi">@xigoi</a></li><li>Reddit: <a href="https://www.reddit.com/user/xigoi">u/xigoi</a></li><li>Discord: xigoi#1759</li></ul></body></html>

44
c/index.jade Normal file
View File

@ -0,0 +1,44 @@
extends ../templates/main.jade
block head
include ../templates/katex.jade
block content
p.warning This website is a work in progress.
p
| Ahoj! Jsem
em.xigoi xigoi
| . Mám rád programování a dalši záležitosti s počítači, matematiku, lingvistiku a chůzi. Ovládám češtinu, angličtinu,
a(href="https://tokipona.org/") Toki Ponu
| a trochu němčiny. Jsem velký nadšenec do open-source — používám
a(href="https://www.linux.com/news/what-is-gnu-linux/") GNU/Linux
| ,
a(href="https://www.vim.org/") Vim
| ,
a(href="https://www.latex-project.org/") \(\text{\LaTeX}\)
| ,
a(href="https://f-droid.org/") F-Droid
| ,
a(href="https://disroot.org/en") Disroot
| a další. Na této stránce a její
a(href="/") anglickě verzi
| můžete najít různé věci mnou napsané a jinak vytvořené. Šťastné prohlížení!
h2 Matematika
ul.index
li
a(href="grupy.html") Grupy
li
a(href="permutace-a-symetricke-grupy.html") Permutace a symetrické grupy
li
a(href="latex.html") \(\mathrm\LaTeX\)
li
a(href="vytvareni-dokumentu-v-systemu-latex.html") Vytváťení dokumentů v systému \(\mathrm\LaTeX\)
h2 Kontaktujte mě
ul.index
li E-mail:
a(href="mailto:xigoi@disroot.org") xigoi@disroot.org
li Ruqqus:
a(href="https://ruqqus.com/@xigoi") @xigoi
li Reddit:
a(href="https://www.reddit.com/user/xigoi") u/xigoi
li Discord: xigoi#1759

26
c/latex.html Normal file
View File

@ -0,0 +1,26 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><link rel="stylesheet" href="/styles/mathsessions.css"><link rel="stylesheet" href="/styles/katex.min.css"><script defer src="/scripts/katex.min.js" onload="renderMathInElement(document.body)"></script><title>LaTeX</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><p class="notice">Tento článek je zkopírován ze stránky <a href="http://mathsessions.klusik.cz/">Matematická setkání</a>.</p><div class="entry-content"><h1 class="entry-title">\(\mathrm\LaTeX\)</h1>
<h2>Historie</h2>
<p>Psaní matematických vzorců na klávesnici nikdy nebylo jednoduché. Do vzniku Unicode většinou chyběly základní symboly jako × nabo √ a na jakékoli zápisy, které vyžadovaly zmenšování písma nebo vertikální umisťování textu, jako například zlomky či exponenty, byly zapotřebí různé podivné triky.</p>
<span id="more-2603" />
<p>Potíže měl i známý americký informatik a matematik <em>Donald Knuth</em>, a proto se rozhodl, že s tím něco udělá. Jelikož uměl programovat, rozhodl se, že si vytvoří vlastní sazební systém zvaný \(\mathrm\TeX\) (čteno „tech“). Vstupem do tohoto systému je jakýsi kód, který se dá bez problému napsat na klávesnici, a výstupem je nádherně stylizovaný zápis. Přestože byl primárně určen pro matematickou notaci, umí \(\mathrm\TeX\) sázet celé dokumenty, a to často lépe než běžně používané editory dokumentů jako Microsoft Word. I samotný název ukazuje, že v systému \(\mathrm\TeX\) není žádný problém vertikálně hýbat s písmeny.</p>
<p>O něco později americký informatik <em>Leslie Lamport</em> vylepšil systém \(\mathrm\TeX\), aby se s ním běžnému člověku lépe pracovalo, a tím vznikl \(\mathrm\LaTeX\) (čteno „latech“). Ten je dodnes nejpoužívanější variantou systému \(\mathrm\TeX\). Na této stránce (a na spoustě dalších, včetně Wikipedie) je používán k sazbě veškeré matematické notace.</p>
<h2>Základy</h2>
<p>Kód pro systém \(\mathrm\LaTeX\) je obyčejný text, ve kterém se vyskytují <em>příkazy</em>. Příkaz se skládá ze zpětného lomítka a jednoho slova (nebo více slov bez mezery). Příkaz má často nějaké argumenty, které se většinou zapisují hned za něj do složených závorek. Než si ale ukážeme konkrétní příkazy, musíme si vysvětlit režimy.</p>
<h3>Režimy</h3>
<p>\(\mathrm\LaTeX\) rozlišuje dva <em>režimy</em>: <em>textový</em> režim a <em>matematický</em> režim. Mnoho příkazů funguje pouze v jednom z těchto režimů a i s běžným textem je v matematickém režimu zacházeno jinak. Tělo dokumentu je normálně v textovém režimu a do matematického režimu jde přepínat několika způsoby:</p>
<ul> <li>Chcete-li matematický zápis vložit přímo do odstavce, ohraničte ho buď dolary, nebo zpětnými lomítky a závorkami. Např. kód <code data-enlighter-language="latex" class="EnlighterJSRAW">$1 + 2$</code> nebo <code data-enlighter-language="latex" class="EnlighterJSRAW">\(1 + 2\)</code> povede k zápisu \(1 + 2\).</li> <li>Chcete-li pro matematický zápis vytvořit samostatný vycentrovaný odstavec, ohraničte ho dvojitými dolary či zpětnými lomítky s hranatými závorkami. Např. kód <code data-enlighter-language="latex" class="EnlighterJSRAW">$$1 + 2 = 3$$</code> nebo <code data-enlighter-language="latex" class="EnlighterJSRAW">\[1 + 2 = 3\]</code> povede k následujícímu zápisu:</li></ul>
<p>\[1 + 2 = 3\]</p>
<p>V matematickém režimu nezáleží na tom, jestli mezi operátory a čísly/proměnnými píšete mezery. Pro přehlednost je však dobrým zvykem je psát.</p>
<h3>Příkazy</h3>
<p>Nyní si již můžeme ukázat pár konkrétních příkazů:</p>
<div class="wp-block-columns">
<div style="flex-basis:100%" class="wp-block-column">
<div class="wp-block-group"> <div class="wp-block-group__inner-container">
<figure class="wp-block-table is-style-regular"> <table> <tbody> <tr> <td> <strong>Režim</strong> </td> <td> <strong>Příkaz</strong> </td> <td> <strong>Výsledek</strong> </td> </tr> <tr> <td>text</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\textbf{Ahoj}</code> </td> <td> <strong>Ahoj</strong> </td> </tr> <tr> <td>text</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\textit{Ahoj}</code> </td> <td> <em>Ahoj</em> </td> </tr> <tr> <td>text</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\LaTeX{}</code> </td> <td>\(\mathrm\LaTeX\)</td> </tr> <tr> <td>mat</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">x \cdot y</code> </td> <td>\(x \cdot y\)</td> </tr> <tr> <td>mat</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\frac{x}{y}</code> </td> <td>\(\frac{x}{y}\)</td> </tr> <tr> <td>mat</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\sqrt{x}</code> </td> <td>\(\sqrt{x}\)</td> </tr> <tr> <td>mat</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\sqrt[n]{x}</code> </td> <td>\(\sqrt[n]{x}\)</td> </tr> <tr> <td>mat</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\LaTeX{}</code> </td> <td>\(\LaTeX\)</td> </tr> </tbody> </table> <figcaption>Tabulka několika vybraných příkazů systému \(\mathrm\LaTeX\). „text“ = textový režim, „mat“ = matematický režim.</figcaption> </figure>
</div></div>
</div>
</div>
<p>Odsud vidíme, že některé příkazy fungují v obou režimech, za příkazy bez argumentů se občas píší prázdné složené závorky a některé příkazy také mohou přijmout argumenty navíc, které se poté uzavřou do hranatých závorek.</p>
<p>Nyní máme jakousi představu o tom, jak vypadá kód systému \(\mathrm\LaTeX\), a v <a href="http://mathsessions.klusik.cz/2021/01/04/vytvareni-dokumentu-v-systemu-latex/">dalším článku</a> si ukážeme, jak takový dokument vlastně vytvořit.</p>
<!-- .author-info -->
</div></body></html>

32
c/latex.jade Normal file
View File

@ -0,0 +1,32 @@
extends ../templates/mathsessions.jade
block title
| LaTeX
block article
<div class="entry-content"><h1 class="entry-title">\(\mathrm\LaTeX\)</h1>
<h2>Historie</h2>
<p>Psaní matematických vzorců na klávesnici nikdy nebylo jednoduché. Do vzniku Unicode většinou chyběly základní symboly jako × nabo √ a na jakékoli zápisy, které vyžadovaly zmenšování písma nebo vertikální umisťování textu, jako například zlomky či exponenty, byly zapotřebí různé podivné triky.</p>
<span id="more-2603" />
<p>Potíže měl i známý americký informatik a matematik <em>Donald Knuth</em>, a proto se rozhodl, že s tím něco udělá. Jelikož uměl programovat, rozhodl se, že si vytvoří vlastní sazební systém zvaný \(\mathrm\TeX\) (čteno „tech“). Vstupem do tohoto systému je jakýsi kód, který se dá bez problému napsat na klávesnici, a výstupem je nádherně stylizovaný zápis. Přestože byl primárně určen pro matematickou notaci, umí \(\mathrm\TeX\) sázet celé dokumenty, a to často lépe než běžně používané editory dokumentů jako Microsoft Word. I samotný název ukazuje, že v systému \(\mathrm\TeX\) není žádný problém vertikálně hýbat s písmeny.</p>
<p>O něco později americký informatik <em>Leslie Lamport</em> vylepšil systém \(\mathrm\TeX\), aby se s ním běžnému člověku lépe pracovalo, a tím vznikl \(\mathrm\LaTeX\) (čteno „latech“). Ten je dodnes nejpoužívanější variantou systému \(\mathrm\TeX\). Na této stránce (a na spoustě dalších, včetně Wikipedie) je používán k sazbě veškeré matematické notace.</p>
<h2>Základy</h2>
<p>Kód pro systém \(\mathrm\LaTeX\) je obyčejný text, ve kterém se vyskytují <em>příkazy</em>. Příkaz se skládá ze zpětného lomítka a jednoho slova (nebo více slov bez mezery). Příkaz má často nějaké argumenty, které se většinou zapisují hned za něj do složených závorek. Než si ale ukážeme konkrétní příkazy, musíme si vysvětlit režimy.</p>
<h3>Režimy</h3>
<p>\(\mathrm\LaTeX\) rozlišuje dva <em>režimy</em>: <em>textový</em> režim a <em>matematický</em> režim. Mnoho příkazů funguje pouze v jednom z těchto režimů a i s běžným textem je v matematickém režimu zacházeno jinak. Tělo dokumentu je normálně v textovém režimu a do matematického režimu jde přepínat několika způsoby:</p>
<ul> <li>Chcete-li matematický zápis vložit přímo do odstavce, ohraničte ho buď dolary, nebo zpětnými lomítky a závorkami. Např. kód <code data-enlighter-language="latex" class="EnlighterJSRAW">$1 + 2$</code> nebo <code data-enlighter-language="latex" class="EnlighterJSRAW">\(1 + 2\)</code> povede k zápisu \(1 + 2\).</li> <li>Chcete-li pro matematický zápis vytvořit samostatný vycentrovaný odstavec, ohraničte ho dvojitými dolary či zpětnými lomítky s hranatými závorkami. Např. kód <code data-enlighter-language="latex" class="EnlighterJSRAW">$$1 + 2 = 3$$</code> nebo <code data-enlighter-language="latex" class="EnlighterJSRAW">\[1 + 2 = 3\]</code> povede k následujícímu zápisu:</li></ul>
<p>\[1 + 2 = 3\]</p>
<p>V matematickém režimu nezáleží na tom, jestli mezi operátory a čísly/proměnnými píšete mezery. Pro přehlednost je však dobrým zvykem je psát.</p>
<h3>Příkazy</h3>
<p>Nyní si již můžeme ukázat pár konkrétních příkazů:</p>
<div class="wp-block-columns">
<div style="flex-basis:100%" class="wp-block-column">
<div class="wp-block-group"> <div class="wp-block-group__inner-container">
<figure class="wp-block-table is-style-regular"> <table> <tbody> <tr> <td> <strong>Režim</strong> </td> <td> <strong>Příkaz</strong> </td> <td> <strong>Výsledek</strong> </td> </tr> <tr> <td>text</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\textbf{Ahoj}</code> </td> <td> <strong>Ahoj</strong> </td> </tr> <tr> <td>text</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\textit{Ahoj}</code> </td> <td> <em>Ahoj</em> </td> </tr> <tr> <td>text</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\LaTeX{}</code> </td> <td>\(\mathrm\LaTeX\)</td> </tr> <tr> <td>mat</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">x \cdot y</code> </td> <td>\(x \cdot y\)</td> </tr> <tr> <td>mat</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\frac{x}{y}</code> </td> <td>\(\frac{x}{y}\)</td> </tr> <tr> <td>mat</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\sqrt{x}</code> </td> <td>\(\sqrt{x}\)</td> </tr> <tr> <td>mat</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\sqrt[n]{x}</code> </td> <td>\(\sqrt[n]{x}\)</td> </tr> <tr> <td>mat</td> <td> <code data-enlighter-language="latex" class="EnlighterJSRAW">\LaTeX{}</code> </td> <td>\(\LaTeX\)</td> </tr> </tbody> </table> <figcaption>Tabulka několika vybraných příkazů systému \(\mathrm\LaTeX\). „text“ = textový režim, „mat“ = matematický režim.</figcaption> </figure>
</div></div>
</div>
</div>
<p>Odsud vidíme, že některé příkazy fungují v obou režimech, za příkazy bez argumentů se občas píší prázdné složené závorky a některé příkazy také mohou přijmout argumenty navíc, které se poté uzavřou do hranatých závorek.</p>
<p>Nyní máme jakousi představu o tom, jak vypadá kód systému \(\mathrm\LaTeX\), a v <a href="http://mathsessions.klusik.cz/2021/01/04/vytvareni-dokumentu-v-systemu-latex/">dalším článku</a> si ukážeme, jak takový dokument vlastně vytvořit.</p>
<!-- .author-info -->
</div>

View File

@ -0,0 +1,68 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><link rel="stylesheet" href="/styles/mathsessions.css"><link rel="stylesheet" href="/styles/katex.min.css"><script defer src="/scripts/katex.min.js" onload="renderMathInElement(document.body)"></script><title>Permutace a symetrické grupy</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><p class="notice">Tento článek je zkopírován ze stránky <a href="http://mathsessions.klusik.cz/">Matematická setkání</a>.</p><div class="entry-content"><h1 class="entry-title">Permutace a symetrické grupy</h1>
<p>V <a href="grupy.html">minulém článku</a> jsme si vysvětlili, co jsou to <em>grupy</em>. Nyní se přesuneme do zdánlivě nesouvisející oblasti, kterou je teorie permutací, a následně si ukážeme, že tvoří jeden z nejzákladnějších druhů grup.</p>
<h2>Základy permutací</h2>
<p>Slovo <em>permutace</em> možná znáte ve významu přeházení pořadí nějakých věcí. A to není daleko od formální definice.</p>
<span id="more-2859" />
<h3>Definice</h3>
<p class="has-light-blue-background-color has-background">Máme-li <strong>konečně velkou</strong> množinu \(M\), potom <em>permutace</em> této množiny je jakákoli <strong>bijektivní</strong> funkce \(\pi: M \to M\). <em>Bijektivní</em> znamená, že každému prvku z první množiny je přiřazen právě jeden „další“ prvek z druhě množiny (v tomto případě té samé) a naopak každý prvek z druhé množiny je přiřazen právě jednomu „předchozímu“ prvku z první množiny. Jako množina \(M\) se často bere prvních několik kladných celých čísel.</p>
<h3>Zápisy</h3>
<p>Uveďme si jako příklad permutaci \(\pi\) na množině \(M = \{1,2,3,4,5,6\}\) definovanou následujícím předpisem:</p>
<p>\[\pi(1)=4\\\pi(2)=6\\\pi(3)=2\\\pi(4)=1\\\pi(5)=5\\\pi(6)=3\]</p>
<p>Tento zápis je poněkud zdlouhavý, proto existují hned tři různé jednodušší zápisy:</p>
<ol> <li> <em>Dvouřádkový zápis</em>. Do jednoho řádku se zapíšou prvky \(M\) a do druhého prvky, které jsou jim přiřazeny. V našem případě \(\pi = \begin{pmatrix}1&amp;2&amp;3&amp;4&amp;5&amp;6\\4&amp;6&amp;2&amp;1&amp;5&amp;3\end{pmatrix}\).</li> <li> <em>Jednořádkový zápis</em>. Pokud jde o uspořádanou množinu, první řádek dvouřádkového zápisu zapsaný ve správném pořadí je možné vynechat. V našem případě \(\pi = \begin{pmatrix}4&amp;6&amp;2&amp;1&amp;5&amp;3\end{pmatrix}\).</li> <li> <em>Cyklický zápis</em>. Ten se vytvoří tak, že začneme od libovolého prvku \(x\) množiny \(M\) a budeme postupně zapisovat \(x, \pi(x), \pi(\pi(x)), \ldots\). Jakmile se dostaname k počátečnímu prvku, tento seznam uzavřeme do závorek. Pokud jsou v množině nějaké prvky, které jsme ještě nezapsali, jeden z nich si vybereme a provedeme opět to samé. Opakujeme, až žádný prvek nezbyde. V našem případě \(\pi = (1,4)(2,6,3)(5)\). Části obsahující pouze jedno číslo (pro nějž platí \(\pi(x) = x\)) je možné vynechat, tedy \(\pi = (1,4)(2,6,3)\).</li></ol>
<h3>Cykly a transpozice</h3>
<p class="has-light-blue-background-color has-background">Permutace, která má v cyklickém zápisu pouze jednu část ohraničenou závorkami (vynecháme-li jednoprvkové části), se nazývá <em>cyklus</em>.</p>
<p>Platí pro ni, že pokud vybereme nějaký prvek \(x\), pro který \(\pi(x) \neq x\), potom opakovanou aplikací \(\pi\) postupně projdeme všechny takové prvky. <em>Délka</em> cyklu je počet takovýchto prvků.</p>
<p>Příkladem cyklu je permutace \(\pi = (6,2,3) = \begin{pmatrix}1&amp;2&amp;3&amp;4&amp;5&amp;6\\1&amp;3&amp;6&amp;4&amp;5&amp;2\end{pmatrix}\). Platí \(\pi(6) = 2, \pi(2) = 3, \pi(3) = 6\) a pro ostatní \(x\) je \(\pi(x) = x\).</p>
<p class="has-light-blue-background-color has-background">Cyklus délky \(2\) se označuje jako <em>transpozice</em>.</p>
<p>Jde o permutaci, která přehodí dva prvky a všechny ostatní ponechá. Např. u množiny \(M\) z předchozího příkladu by \(\pi = (3,5) = \begin{pmatrix}1&amp;2&amp;3&amp;4&amp;5&amp;6\\1&amp;2&amp;5&amp;4&amp;3&amp;6\end{pmatrix}\) byla transpozice.</p>
<p class="has-light-blue-background-color has-background">Dva cykly jsou <em>nezávislé</em>, pokud nemají žádný společný prvek. Např. \((2,4,5)\) a \((1,6)\) je dvojice nezávislých cyklů.</p>
<h3>Skládání permutací</h3>
<p>Jelikož permutace je určitý druh funkce, skládání permutací funguje stejně jako skládání funkcí. To máme vysvětleno ve <a href="http://mathsessions.klusik.cz/2021/01/02/kratke-povidani-o-funkcich-a-jejich-skladani/">vlastním článku</a>, společně s důkazem, že jde o asociativní operaci.</p>
<p>Ukážeme si konkrétní příklad. Mějme \(\pi = \begin{pmatrix}1&amp;2&amp;3&amp;4\\1&amp;4&amp;2&amp;3\end{pmatrix}\) a \(\sigma = \begin{pmatrix}1&amp;2&amp;3&amp;4\\2&amp;4&amp;3&amp;1\end{pmatrix}\). Pokud si vybereme např. prvek \(1\) a chceme zjistit \((\pi \circ \sigma)(1)\), musíme nejprve zjistit \(\sigma(1)\), což je \(2\). Výsledkem je pak \(\pi(2)\), což je \(4\). Určeme nyní, co dělá složená permutace se všemi prvky:</p>
<p>\[(\pi \circ \sigma)(1) = \pi(\sigma(1)) = \pi(2) = 4 \\(\pi \circ \sigma)(2) = \pi(\sigma(2)) = \pi(4) = 3 \\(\pi \circ \sigma)(3) = \pi(\sigma(3)) = \pi(3) = 2 \\(\pi \circ \sigma)(4) = \pi(\sigma(4)) = \pi(1) = 1 \\\pi \circ \sigma = \begin{pmatrix}1&amp;2&amp;3&amp;4\\4&amp;3&amp;2&amp;1\end{pmatrix} \\\]</p>
<p>Všimněme si, že složením permutací vznikla opět permutace. Pojďme si ukázat, že to tak platí vždy.</p>
<p class="has-yellow-background-color has-background">Věta: Jsou-li \(\pi\) a \(\sigma\) permutace na množině \(M\), potom \(\pi \circ \sigma\) je také permutace.</p>
<p class="has-bright-red-background-color has-background">Důkaz: Vezměme si nějaký prvek \(x \in M\). Podle definice permutace je \(\sigma(x) \in M\) a tedy také \((\pi \circ \sigma)(x) = \pi(\sigma(x)) \in M\). Tím je dokázáno, že skládáním vznikne skutečně funkce \(M \to M\) a nyní zbývá ještě dokázat, že je bijektivní. Vezměme dva různé prvky \(x,y \in M\). Podle definice permutace jsou \(\sigma(x)\) a \(\sigma(y)\) také dva různé prvky \(M\), a tedy i \(\pi(\sigma(x))\) a \(\pi(\sigma(y))\). Z toho plyne, že každý prvek \(M\) je funkcí \(\pi \circ \sigma\) přiřazen nejvýše jednomu prvku \(M\). Kdyby však nějaký nebyl přiřazen žádnému, potom by podle holubníkového principu musel néjaký jiný být přiřazen alespoň dvěma. Funkce \(\pi \circ \sigma\) je tedy bijektivní a jde o permutaci.</p>
<h4>Permutace identity</h4>
<p class="has-light-blue-background-color has-background"><em>Permutace identity </em>\(\mathbb{I}\) je permutace, která každému prvku přiřadí stejný prvek, tedy \(\mathbb{I} = \begin{pmatrix} a_1 &amp; a_2 &amp; \ldots &amp; a_n \\ a_1 &amp; a_2 &amp; \ldots &amp; a_n \end{pmatrix}\).</p>
<p>Každá permutace, která má v cyklickém zápisu pouze cykly délky \(1\), je identita, neboť tyto cykly prvky nijak nepřehazují. Pro každou permutaci \(\pi\) platí, že \(\pi \circ \mathbb{I} = \mathbb{I} \circ \pi\), neboť \(\pi(\mathbb{I}(x)) = \pi(x)\) a \(\mathbb{I}(\pi(x)) = \pi(x)\).</p>
<p>Konkrétním příkladem identity je \(\begin{pmatrix}1&amp;2&amp;3&amp;4&amp;5&amp;6\\1&amp;2&amp;3&amp;4&amp;5&amp;6\end{pmatrix}\).</p>
<h4>Inverzní permutace</h4>
<p class="has-light-blue-background-color has-background">Máme-li permutaci \(\pi = \begin{pmatrix} a_1 &amp; a_2 &amp; \ldots &amp; a_n \\ b_1 &amp; b_2 &amp; \ldots &amp; b_n \end{pmatrix}\), definujme její <em>inverzní permutaci</em> jako \(\pi^{-1} = \begin{pmatrix} b_1 &amp; b_2 &amp; \ldots &amp; b_n \\ a_1 &amp; a_2 &amp; \ldots &amp; a_n \end{pmatrix}\).</p>
<p>Pro tuto permutaci platí \(\pi^{-1} \circ \pi = \pi \circ \pi^{-1} = \mathbb{I}\), což je možné vidět ze skutečnosti, že každému \(a\) je permutací \(\pi\) přiřazeno nějaké \(b\), kterému následně \(\pi^{-1}\) přiřadí opět \(a\) — a naopak.</p>
<p>Jaká by byla inverze k permutaci \(\begin{pmatrix}1&amp;2&amp;3&amp;4\\2&amp;4&amp;3&amp;1\end{pmatrix}\)? Stačí přehodit řádky, tedy \(\begin{pmatrix}2&amp;4&amp;3&amp;1\\1&amp;2&amp;3&amp;4\end{pmatrix}\). Pro přehlednost můžeme následně seřadit sloupce: \(\begin{pmatrix}1&amp;2&amp;3&amp;4\\4&amp;1&amp;3&amp;2\end{pmatrix}\).</p>
<p>Stejně snadné je nalezení inverze, pokud máme cyklický zápis. Stačí jednoduše obrátit pořadí prvků ve všech cyklech. Např. inverze k \((4.2.6.7)(3,5,1)\) by byla \((7,6,2,4)(1,5,3)\).</p>
<h2>Symetrické grupy</h2>
<p>Zopakujme si, co už jsme si dokázali o skládání permutací: jde o asociativní operaci, která má prvek identity, množina permutací je na ní uzavřena a každá permutace má inverzi. Čtenáři, který si přečetl <a href="http://mathsessions.klusik.cz/2021/01/02/grupy/">náš článek o grupách</a>, je v tuto chvíli jistě zřejmé, že toto přesně odpovídá definici grupy. Máme-li konečnou množinu \(M\) o \(n\) prvcích, potom algebraickou strukturu tvořenou permutacemi na této množině a jejich skládáním nazýváme<em> symetrická grupa stupně \(n\)</em> a značíme \(\mathbb S_n\). Občas se pod tímto pojmem rozumí i grupy definované bijektivními funkcemi na nekonečných množinách, ale ty v tomto článku zanedbáme a budeme se soustředit na konečné symetrické grupy.</p>
<p>Povšimněme si, že symetrické grupy obecně nejsou komutativní. Pokud vezmeme např. \(\pi = \begin{pmatrix} 1&amp;2&amp;3 \\ 2&amp;1&amp;3\end{pmatrix}\) a \(\sigma = \begin{pmatrix} 1&amp;2&amp;3 \\ 1&amp;3&amp;2\end{pmatrix}\), potom \(\pi \circ \sigma = \begin{pmatrix} 1&amp;2&amp;3 \\ 2&amp;3&amp;1\end{pmatrix}\), ale \(\sigma \circ \pi = \begin{pmatrix} 1&amp;2&amp;3 \\ 3&amp;1&amp;2\end{pmatrix}\). Tím jsme tedy dokázali, že \(\mathbb S_3\) není komutativní. (Dokonce jde o nejmenší nekomutativní grupu, ovšem to tady dokazovat nebudeme.)</p>
<h2>Rozklad na cykly a transpozice</h2>
<p>Již jsme si ukázali tzv. cyklický zápis permutace, např. \((1,3)(2,5,4)\). Všimněme si, že vypadá, jako by šlo o jakýsi součin dvou cyklů. Ovšem toto není jen záležitost zápisu — ono totiž o součin dvou cyklů skutečně jde (přičemž součinem se rozumí grupová operace, což v případě permutací je skládání). </p>
<p>Obecně platí, že každá permutace se dá rozložit na součin několika nezávislých cyklů, a to přesně způbem, který byl již uveden při představení cyklického zápisu. Jelikož každý cyklus přemisťuje jiné prvky, nijak se vzájemně neovlivňují, což vysvětluje nejen to, proč jejich součinem vznikne původní permutace, ale také skutečnost, že skládání nezávislých cyklů je komutativní (na rozdíl od skládání obecně). Proto také můžeme cykly v cyklickém žapisu zapsat v libovolném pořadí.</p>
<p>S rozkládáním ovšem můžeme jít ješté dál. Dokažme si nyní, že každý cyklus, a tím pádem i každou permutaci, je možné rozložit na součin několika transpozic.<span class="footnote_referrer"><a href="#footnote_plugin_reference_2859_2_1"><sup class="footnote_plugin_tooltip_text" id="footnote_plugin_tooltip_2859_2_1">[1]</sup></a></span></p>
<p class="has-yellow-background-color has-background">Věta: Pro cykly platí \(\pi = (x_1, x_2, x_3, \ldots, x_n) = (x_1, x_n) \circ \cdots \circ (x_1, x_3) \circ (x_1, x_2)\).</p>
<div class="has-bright-red-background-color has-background"><p>Důkaz indukcí: Pro cyklus délky \(2\) (transpozici) věta triviálně platí. Předpokládejme nyní, že platí pro cyklus délky \(n-1\), tedy \(\sigma = (x_1, x_2, x_3, \ldots, x_{n-1}) = (x_1, x_{n-1}) \circ \cdots \circ (x_1, x_3) \circ (x_1, x_2)\). Nyní dokážeme, že přidáme-li do cyklu další prvek \(x_n\), čímž dostaneme permutaci \(\pi\), bude platit \(\pi = \tau \circ \sigma\), kde \(\tau = (x_1,x_n)\). Méjme nějaké \(x \in M\) a rozeberme čtyři případy:</p>
<ol> <li>Je-li \(x = x_{n-1}\), potom \(\tau(\sigma(x)) = \tau(x_1) = x_n = \pi(x)\).</li> <li>Je-li \(x = x_n\), potom \(\tau(\sigma(x)) = \tau(x_n) = x_1 = \pi(x)\).</li> <li>Je-li \(x = x_k\) pro \(k \in \{1, 2, \ldots, n-2\}\), potom \(\tau(\sigma(x)) = \tau(x_{k+1}) = x_{k+1} = \pi(x)\).</li> <li>Není-li \(x = x_k\) pro žádné \(k\), potom \(\tau(\sigma(x)) = \tau(x) = x = \pi(x)\).</li></ol>
<p>Tím je hotov indukční krok a tím pádem i celý důkaz. Jelikož každou permutaci lze rozložit na cykly, každý cyklus lze rozložit na transpozice a skládání permutací je asociativní, lze každou permutaci rozložit na transpozice.</p></div>
<p>Konkrétně např. permutace \((7,3,4,1,6)\) by se dala rozložit jako \((7,6)(7,1)(7,4)(7,3)\)</p>
<p>Doplňme, že tento součin transpozic na rozdíl od součinu nezávislých cyklů není komutativní.</p>
<h2>Inverze, parita a znaménko permutace</h2>
<p class="has-light-blue-background-color has-background"><em>Inverz</em>e v permutaci \(\pi\) na uspořádané množině \(M\) je dvojice prvků \(x,y \in M\), pro které je \(x &lt; y\), ale \(\pi(x) &gt; \pi(y)\). Jinak řečeno, jde o dva prvky, jejichž vzájemné pořadí se po uplatnění permutace změní.</p>
<p>Pozor! Inverze v permutaci nijak nesouvisí s inverzní permutací. Podobnost výrazů je čistě náhodná.</p>
<p>Pojďme spočítat, kolik inverzí má permutace \( \begin{pmatrix}1&amp;2&amp;3&amp;4&amp;5&amp;6&amp;7\\1&amp;2&amp;3&amp;6&amp;5&amp;4&amp;7\end{pmatrix}\). Vidíme, že \(6\) je před \(5\), \(5\) je před \(4\) a \(6\) je před \(4\). Jinak je vše ve „správném“ pořadí, celkově tedy máme tři inverze.</p>
<p class="has-light-blue-background-color has-background">Permutace, která má sudý počet inverzí, se označuje jako <em>sudá</em>. Permutace, kterš má lichý počet inverzí, se označuje jako <em>lichá</em>.</p>
<p>Permutace v předchozím příkladu měla tři inverze, jde tedy o lichou permutaci.</p>
<p class="has-light-blue-background-color has-background">Definujme <em>znaménko permutace</em> \(\operatorname{sgn}(\pi)\) takto: znaménko sudé permutace je \(+1\) a znaménko liché permutace je \(-1\).</p>
<p>Všimněme si analogie s celými čísly, kde funkce \(n \mapsto (-1)^n\) vrací \(+1\) pro sudé \(n\) a \(-1\) pro liché \(n\).</p>
<p>Je zřejmé, že každá permutace je buď sudá, nebo lichá, ale ne obojí zároveň. Nyní si dokážeme důležitou větu o paritě permutací.</p>
<p class="has-yellow-background-color has-background">Věta: Součinem sudého počtu transpozic vznikne sudá permutace. Součinem lichého počtu transpozic vznikne lichá permutace.</p>
<p class="has-bright-red-background-color has-background">Důkaz indukcí: Součin \(0\) transpozic je permutace identity, která nemá žádnou inverzi a je tedy sudá. Dokažme nyní, že pokud permutaci vynásobíme zleva transpozicí, změní se tím její parita. Pokud si permutaci představíme jako nějaké pořadí prvků, transpozice v tomto pořadí přehodí dva prvky \(x\) a \(y\). Tím se změní jejich pořadí. Pokud byly ve „správném“ pořadí, potom tímto vznikne jedna inverze, v opačném případě zanikne jedna inverze — ale každopádně se tím parita počtu inverzí změní. Mezi \(x\) a \(y\) však může být ještě dalších \(k\) prvků. Pro každý z těchto prvků se zméní jeho pořadí jak s \(x\), tak s \(y\), takže stejným způsobem dojde ke dvěma vznikům nebo zánikům inverze. To však paritu počtu inverzí neovlivní, jelikož se tyto výměny dají právě takto rozdělit do dvojic. Celkově se tedy parita musí změnit, což je přesně to, co jsme chtěli dokázat.</p>
<p>Permutace \(\begin{pmatrix}1&amp;2&amp;3&amp;4&amp;5&amp;6&amp;7\\1&amp;2&amp;3&amp;6&amp;5&amp;4&amp;7\end{pmatrix} = (6,4)\) se skládá z jedné transpozice, čímž se znovu potvrzuje, že je lichá.</p>
<p>Nyní si již uvažováním o rozkladu na transpozice lze snadno rozmyslet, že skládání permutací funguje co do parity stejně jako sčítání celých čísel: dvě sudé nebo dvě liché dají sudou, zatímco sudá s lichou nebo lichá se sudou dají lichou. To se dá jednoduše formulovat pomocí znamének: \(\operatorname{sgn}(\pi \circ \sigma) = \operatorname{sgn}(\pi) \cdot \operatorname{sgn}(\sigma)\).</p>
<p class="has-yellow-background-color has-background">Věta: Pro každé \(n \geq 2\) je v grupě \(\mathbb S_n\) stejný počet sudých a lichých permutací.</p>
<p>Důkaz: Vezměme libovolnou transpozici \(\tau\). Jelikož jde jen o přehození dvou prvků, které je po opětovném provedení vrátí do původního stavu, platí \(\tau = \tau^{-1}\). Definujme funkci \(f(\pi) = \tau \circ \pi\). Tato funkce je také inverzí sama sebe, jelikož \(f(f(\pi)) = \tau \circ \tau \circ \pi = \tau^{-1} \circ \tau \circ \pi = \pi\). Jelikož \(\tau\) je lichá permutace, funkce \(f\) změní znaménko permutace, kterou do ní vložíme. Z těchto dvou skutečností však plyne, že \(f\) je bijekce mezi množinou sudých a lichých permutací, a tyto množiny tedy musí mít stejnou velikost.</p>
<p>Zajímavostí na závěr je, že ve známé hře <a href="https://cs.wikipedia.org/wiki/Patn%C3%A1ctka">Patnáctka</a> nelze polovinu pozic vyřešit — a to právě proto, že libovolná posloupnost tahů, po které zůstane volné stejné pole jako před ní, nemůže změnit paritu permutace čísel na desce. Jeden vychytralý člověk na to kdysi vyhlásil tučnou peněžní odměnu, čímž vyvolal naprostou mánii a mnoho lidí trávilo čas marnými pokusy o nalezení posloupnosti tahů, která by vedla k přehození dvou čísel. Matematika samozřejmě stála při jeho zádech a nikomu se to nepodařilo.</p>
<div class="speaker-mute footnotes_reference_container"> <div class="footnote_container_prepare"> <p> <hr /> <span style="display: none;" role="button" class="footnote_reference_container_collapse_button" onclick="footnote_expand_collapse_reference_container_2859_2();" tabindex="0">[ <a id="footnote_reference_container_collapse_button_2859_2">+</a>]</span> </p></div> <div style="" id="footnote_references_container_2859_2"><table class="footnotes_table footnote-reference-container"> <tbody>
<tr class="footnotes_plugin_reference_row"> <th class="footnote_plugin_index_combi pointer" onclick="footnote_moveToAnchor_2859_2('footnote_plugin_tooltip_2859_2_1');" scope="row"> <a href="#footnote_plugin_tooltip_2859_2_1" class="footnote_backlink" id="footnote_plugin_reference_2859_2_1"> <span class="footnote_index_arrow"></span>1</a></th> <td class="footnote_plugin_text">Dokonce platí i silnější tvrzení, že každá permutace se dá rozložit na součin transpozic sousedních dvou prvků. Konkrétní způsob, jak to provést, je tzv. <a href="https://cs.wikipedia.org/wiki/Bublinkov%C3%A9_%C5%99azen%C3%AD">bublinkové řazení</a>.</td></tr>
</tbody> </table> </div></div>
</div></body></html>

View File

@ -0,0 +1,74 @@
extends ../templates/mathsessions.jade
block title
| Permutace a symetrické grupy
block article
<div class="entry-content"><h1 class="entry-title">Permutace a symetrické grupy</h1>
<p>V <a href="grupy.html">minulém článku</a> jsme si vysvětlili, co jsou to <em>grupy</em>. Nyní se přesuneme do zdánlivě nesouvisející oblasti, kterou je teorie permutací, a následně si ukážeme, že tvoří jeden z nejzákladnějších druhů grup.</p>
<h2>Základy permutací</h2>
<p>Slovo <em>permutace</em> možná znáte ve významu přeházení pořadí nějakých věcí. A to není daleko od formální definice.</p>
<span id="more-2859" />
<h3>Definice</h3>
<p class="has-light-blue-background-color has-background">Máme-li <strong>konečně velkou</strong> množinu \(M\), potom <em>permutace</em> této množiny je jakákoli <strong>bijektivní</strong> funkce \(\pi: M \to M\). <em>Bijektivní</em> znamená, že každému prvku z první množiny je přiřazen právě jeden „další“ prvek z druhě množiny (v tomto případě té samé) a naopak každý prvek z druhé množiny je přiřazen právě jednomu „předchozímu“ prvku z první množiny. Jako množina \(M\) se často bere prvních několik kladných celých čísel.</p>
<h3>Zápisy</h3>
<p>Uveďme si jako příklad permutaci \(\pi\) na množině \(M = \{1,2,3,4,5,6\}\) definovanou následujícím předpisem:</p>
<p>\[\pi(1)=4\\\pi(2)=6\\\pi(3)=2\\\pi(4)=1\\\pi(5)=5\\\pi(6)=3\]</p>
<p>Tento zápis je poněkud zdlouhavý, proto existují hned tři různé jednodušší zápisy:</p>
<ol> <li> <em>Dvouřádkový zápis</em>. Do jednoho řádku se zapíšou prvky \(M\) a do druhého prvky, které jsou jim přiřazeny. V našem případě \(\pi = \begin{pmatrix}1&amp;2&amp;3&amp;4&amp;5&amp;6\\4&amp;6&amp;2&amp;1&amp;5&amp;3\end{pmatrix}\).</li> <li> <em>Jednořádkový zápis</em>. Pokud jde o uspořádanou množinu, první řádek dvouřádkového zápisu zapsaný ve správném pořadí je možné vynechat. V našem případě \(\pi = \begin{pmatrix}4&amp;6&amp;2&amp;1&amp;5&amp;3\end{pmatrix}\).</li> <li> <em>Cyklický zápis</em>. Ten se vytvoří tak, že začneme od libovolého prvku \(x\) množiny \(M\) a budeme postupně zapisovat \(x, \pi(x), \pi(\pi(x)), \ldots\). Jakmile se dostaname k počátečnímu prvku, tento seznam uzavřeme do závorek. Pokud jsou v množině nějaké prvky, které jsme ještě nezapsali, jeden z nich si vybereme a provedeme opět to samé. Opakujeme, až žádný prvek nezbyde. V našem případě \(\pi = (1,4)(2,6,3)(5)\). Části obsahující pouze jedno číslo (pro nějž platí \(\pi(x) = x\)) je možné vynechat, tedy \(\pi = (1,4)(2,6,3)\).</li></ol>
<h3>Cykly a transpozice</h3>
<p class="has-light-blue-background-color has-background">Permutace, která má v cyklickém zápisu pouze jednu část ohraničenou závorkami (vynecháme-li jednoprvkové části), se nazývá <em>cyklus</em>.</p>
<p>Platí pro ni, že pokud vybereme nějaký prvek \(x\), pro který \(\pi(x) \neq x\), potom opakovanou aplikací \(\pi\) postupně projdeme všechny takové prvky. <em>Délka</em> cyklu je počet takovýchto prvků.</p>
<p>Příkladem cyklu je permutace \(\pi = (6,2,3) = \begin{pmatrix}1&amp;2&amp;3&amp;4&amp;5&amp;6\\1&amp;3&amp;6&amp;4&amp;5&amp;2\end{pmatrix}\). Platí \(\pi(6) = 2, \pi(2) = 3, \pi(3) = 6\) a pro ostatní \(x\) je \(\pi(x) = x\).</p>
<p class="has-light-blue-background-color has-background">Cyklus délky \(2\) se označuje jako <em>transpozice</em>.</p>
<p>Jde o permutaci, která přehodí dva prvky a všechny ostatní ponechá. Např. u množiny \(M\) z předchozího příkladu by \(\pi = (3,5) = \begin{pmatrix}1&amp;2&amp;3&amp;4&amp;5&amp;6\\1&amp;2&amp;5&amp;4&amp;3&amp;6\end{pmatrix}\) byla transpozice.</p>
<p class="has-light-blue-background-color has-background">Dva cykly jsou <em>nezávislé</em>, pokud nemají žádný společný prvek. Např. \((2,4,5)\) a \((1,6)\) je dvojice nezávislých cyklů.</p>
<h3>Skládání permutací</h3>
<p>Jelikož permutace je určitý druh funkce, skládání permutací funguje stejně jako skládání funkcí. To máme vysvětleno ve <a href="http://mathsessions.klusik.cz/2021/01/02/kratke-povidani-o-funkcich-a-jejich-skladani/">vlastním článku</a>, společně s důkazem, že jde o asociativní operaci.</p>
<p>Ukážeme si konkrétní příklad. Mějme \(\pi = \begin{pmatrix}1&amp;2&amp;3&amp;4\\1&amp;4&amp;2&amp;3\end{pmatrix}\) a \(\sigma = \begin{pmatrix}1&amp;2&amp;3&amp;4\\2&amp;4&amp;3&amp;1\end{pmatrix}\). Pokud si vybereme např. prvek \(1\) a chceme zjistit \((\pi \circ \sigma)(1)\), musíme nejprve zjistit \(\sigma(1)\), což je \(2\). Výsledkem je pak \(\pi(2)\), což je \(4\). Určeme nyní, co dělá složená permutace se všemi prvky:</p>
<p>\[(\pi \circ \sigma)(1) = \pi(\sigma(1)) = \pi(2) = 4 \\(\pi \circ \sigma)(2) = \pi(\sigma(2)) = \pi(4) = 3 \\(\pi \circ \sigma)(3) = \pi(\sigma(3)) = \pi(3) = 2 \\(\pi \circ \sigma)(4) = \pi(\sigma(4)) = \pi(1) = 1 \\\pi \circ \sigma = \begin{pmatrix}1&amp;2&amp;3&amp;4\\4&amp;3&amp;2&amp;1\end{pmatrix} \\\]</p>
<p>Všimněme si, že složením permutací vznikla opět permutace. Pojďme si ukázat, že to tak platí vždy.</p>
<p class="has-yellow-background-color has-background">Věta: Jsou-li \(\pi\) a \(\sigma\) permutace na množině \(M\), potom \(\pi \circ \sigma\) je také permutace.</p>
<p class="has-bright-red-background-color has-background">Důkaz: Vezměme si nějaký prvek \(x \in M\). Podle definice permutace je \(\sigma(x) \in M\) a tedy také \((\pi \circ \sigma)(x) = \pi(\sigma(x)) \in M\). Tím je dokázáno, že skládáním vznikne skutečně funkce \(M \to M\) a nyní zbývá ještě dokázat, že je bijektivní. Vezměme dva různé prvky \(x,y \in M\). Podle definice permutace jsou \(\sigma(x)\) a \(\sigma(y)\) také dva různé prvky \(M\), a tedy i \(\pi(\sigma(x))\) a \(\pi(\sigma(y))\). Z toho plyne, že každý prvek \(M\) je funkcí \(\pi \circ \sigma\) přiřazen nejvýše jednomu prvku \(M\). Kdyby však nějaký nebyl přiřazen žádnému, potom by podle holubníkového principu musel néjaký jiný být přiřazen alespoň dvěma. Funkce \(\pi \circ \sigma\) je tedy bijektivní a jde o permutaci.</p>
<h4>Permutace identity</h4>
<p class="has-light-blue-background-color has-background"><em>Permutace identity </em>\(\mathbb{I}\) je permutace, která každému prvku přiřadí stejný prvek, tedy \(\mathbb{I} = \begin{pmatrix} a_1 &amp; a_2 &amp; \ldots &amp; a_n \\ a_1 &amp; a_2 &amp; \ldots &amp; a_n \end{pmatrix}\).</p>
<p>Každá permutace, která má v cyklickém zápisu pouze cykly délky \(1\), je identita, neboť tyto cykly prvky nijak nepřehazují. Pro každou permutaci \(\pi\) platí, že \(\pi \circ \mathbb{I} = \mathbb{I} \circ \pi\), neboť \(\pi(\mathbb{I}(x)) = \pi(x)\) a \(\mathbb{I}(\pi(x)) = \pi(x)\).</p>
<p>Konkrétním příkladem identity je \(\begin{pmatrix}1&amp;2&amp;3&amp;4&amp;5&amp;6\\1&amp;2&amp;3&amp;4&amp;5&amp;6\end{pmatrix}\).</p>
<h4>Inverzní permutace</h4>
<p class="has-light-blue-background-color has-background">Máme-li permutaci \(\pi = \begin{pmatrix} a_1 &amp; a_2 &amp; \ldots &amp; a_n \\ b_1 &amp; b_2 &amp; \ldots &amp; b_n \end{pmatrix}\), definujme její <em>inverzní permutaci</em> jako \(\pi^{-1} = \begin{pmatrix} b_1 &amp; b_2 &amp; \ldots &amp; b_n \\ a_1 &amp; a_2 &amp; \ldots &amp; a_n \end{pmatrix}\).</p>
<p>Pro tuto permutaci platí \(\pi^{-1} \circ \pi = \pi \circ \pi^{-1} = \mathbb{I}\), což je možné vidět ze skutečnosti, že každému \(a\) je permutací \(\pi\) přiřazeno nějaké \(b\), kterému následně \(\pi^{-1}\) přiřadí opět \(a\) — a naopak.</p>
<p>Jaká by byla inverze k permutaci \(\begin{pmatrix}1&amp;2&amp;3&amp;4\\2&amp;4&amp;3&amp;1\end{pmatrix}\)? Stačí přehodit řádky, tedy \(\begin{pmatrix}2&amp;4&amp;3&amp;1\\1&amp;2&amp;3&amp;4\end{pmatrix}\). Pro přehlednost můžeme následně seřadit sloupce: \(\begin{pmatrix}1&amp;2&amp;3&amp;4\\4&amp;1&amp;3&amp;2\end{pmatrix}\).</p>
<p>Stejně snadné je nalezení inverze, pokud máme cyklický zápis. Stačí jednoduše obrátit pořadí prvků ve všech cyklech. Např. inverze k \((4.2.6.7)(3,5,1)\) by byla \((7,6,2,4)(1,5,3)\).</p>
<h2>Symetrické grupy</h2>
<p>Zopakujme si, co už jsme si dokázali o skládání permutací: jde o asociativní operaci, která má prvek identity, množina permutací je na ní uzavřena a každá permutace má inverzi. Čtenáři, který si přečetl <a href="http://mathsessions.klusik.cz/2021/01/02/grupy/">náš článek o grupách</a>, je v tuto chvíli jistě zřejmé, že toto přesně odpovídá definici grupy. Máme-li konečnou množinu \(M\) o \(n\) prvcích, potom algebraickou strukturu tvořenou permutacemi na této množině a jejich skládáním nazýváme<em> symetrická grupa stupně \(n\)</em> a značíme \(\mathbb S_n\). Občas se pod tímto pojmem rozumí i grupy definované bijektivními funkcemi na nekonečných množinách, ale ty v tomto článku zanedbáme a budeme se soustředit na konečné symetrické grupy.</p>
<p>Povšimněme si, že symetrické grupy obecně nejsou komutativní. Pokud vezmeme např. \(\pi = \begin{pmatrix} 1&amp;2&amp;3 \\ 2&amp;1&amp;3\end{pmatrix}\) a \(\sigma = \begin{pmatrix} 1&amp;2&amp;3 \\ 1&amp;3&amp;2\end{pmatrix}\), potom \(\pi \circ \sigma = \begin{pmatrix} 1&amp;2&amp;3 \\ 2&amp;3&amp;1\end{pmatrix}\), ale \(\sigma \circ \pi = \begin{pmatrix} 1&amp;2&amp;3 \\ 3&amp;1&amp;2\end{pmatrix}\). Tím jsme tedy dokázali, že \(\mathbb S_3\) není komutativní. (Dokonce jde o nejmenší nekomutativní grupu, ovšem to tady dokazovat nebudeme.)</p>
<h2>Rozklad na cykly a transpozice</h2>
<p>Již jsme si ukázali tzv. cyklický zápis permutace, např. \((1,3)(2,5,4)\). Všimněme si, že vypadá, jako by šlo o jakýsi součin dvou cyklů. Ovšem toto není jen záležitost zápisu — ono totiž o součin dvou cyklů skutečně jde (přičemž součinem se rozumí grupová operace, což v případě permutací je skládání). </p>
<p>Obecně platí, že každá permutace se dá rozložit na součin několika nezávislých cyklů, a to přesně způbem, který byl již uveden při představení cyklického zápisu. Jelikož každý cyklus přemisťuje jiné prvky, nijak se vzájemně neovlivňují, což vysvětluje nejen to, proč jejich součinem vznikne původní permutace, ale také skutečnost, že skládání nezávislých cyklů je komutativní (na rozdíl od skládání obecně). Proto také můžeme cykly v cyklickém žapisu zapsat v libovolném pořadí.</p>
<p>S rozkládáním ovšem můžeme jít ješté dál. Dokažme si nyní, že každý cyklus, a tím pádem i každou permutaci, je možné rozložit na součin několika transpozic.<span class="footnote_referrer"><a href="#footnote_plugin_reference_2859_2_1"><sup class="footnote_plugin_tooltip_text" id="footnote_plugin_tooltip_2859_2_1">[1]</sup></a></span></p>
<p class="has-yellow-background-color has-background">Věta: Pro cykly platí \(\pi = (x_1, x_2, x_3, \ldots, x_n) = (x_1, x_n) \circ \cdots \circ (x_1, x_3) \circ (x_1, x_2)\).</p>
<div class="has-bright-red-background-color has-background"><p>Důkaz indukcí: Pro cyklus délky \(2\) (transpozici) věta triviálně platí. Předpokládejme nyní, že platí pro cyklus délky \(n-1\), tedy \(\sigma = (x_1, x_2, x_3, \ldots, x_{n-1}) = (x_1, x_{n-1}) \circ \cdots \circ (x_1, x_3) \circ (x_1, x_2)\). Nyní dokážeme, že přidáme-li do cyklu další prvek \(x_n\), čímž dostaneme permutaci \(\pi\), bude platit \(\pi = \tau \circ \sigma\), kde \(\tau = (x_1,x_n)\). Méjme nějaké \(x \in M\) a rozeberme čtyři případy:</p>
<ol> <li>Je-li \(x = x_{n-1}\), potom \(\tau(\sigma(x)) = \tau(x_1) = x_n = \pi(x)\).</li> <li>Je-li \(x = x_n\), potom \(\tau(\sigma(x)) = \tau(x_n) = x_1 = \pi(x)\).</li> <li>Je-li \(x = x_k\) pro \(k \in \{1, 2, \ldots, n-2\}\), potom \(\tau(\sigma(x)) = \tau(x_{k+1}) = x_{k+1} = \pi(x)\).</li> <li>Není-li \(x = x_k\) pro žádné \(k\), potom \(\tau(\sigma(x)) = \tau(x) = x = \pi(x)\).</li></ol>
<p>Tím je hotov indukční krok a tím pádem i celý důkaz. Jelikož každou permutaci lze rozložit na cykly, každý cyklus lze rozložit na transpozice a skládání permutací je asociativní, lze každou permutaci rozložit na transpozice.</p></div>
<p>Konkrétně např. permutace \((7,3,4,1,6)\) by se dala rozložit jako \((7,6)(7,1)(7,4)(7,3)\)</p>
<p>Doplňme, že tento součin transpozic na rozdíl od součinu nezávislých cyklů není komutativní.</p>
<h2>Inverze, parita a znaménko permutace</h2>
<p class="has-light-blue-background-color has-background"><em>Inverz</em>e v permutaci \(\pi\) na uspořádané množině \(M\) je dvojice prvků \(x,y \in M\), pro které je \(x &lt; y\), ale \(\pi(x) &gt; \pi(y)\). Jinak řečeno, jde o dva prvky, jejichž vzájemné pořadí se po uplatnění permutace změní.</p>
<p>Pozor! Inverze v permutaci nijak nesouvisí s inverzní permutací. Podobnost výrazů je čistě náhodná.</p>
<p>Pojďme spočítat, kolik inverzí má permutace \( \begin{pmatrix}1&amp;2&amp;3&amp;4&amp;5&amp;6&amp;7\\1&amp;2&amp;3&amp;6&amp;5&amp;4&amp;7\end{pmatrix}\). Vidíme, že \(6\) je před \(5\), \(5\) je před \(4\) a \(6\) je před \(4\). Jinak je vše ve „správném“ pořadí, celkově tedy máme tři inverze.</p>
<p class="has-light-blue-background-color has-background">Permutace, která má sudý počet inverzí, se označuje jako <em>sudá</em>. Permutace, kterš má lichý počet inverzí, se označuje jako <em>lichá</em>.</p>
<p>Permutace v předchozím příkladu měla tři inverze, jde tedy o lichou permutaci.</p>
<p class="has-light-blue-background-color has-background">Definujme <em>znaménko permutace</em> \(\operatorname{sgn}(\pi)\) takto: znaménko sudé permutace je \(+1\) a znaménko liché permutace je \(-1\).</p>
<p>Všimněme si analogie s celými čísly, kde funkce \(n \mapsto (-1)^n\) vrací \(+1\) pro sudé \(n\) a \(-1\) pro liché \(n\).</p>
<p>Je zřejmé, že každá permutace je buď sudá, nebo lichá, ale ne obojí zároveň. Nyní si dokážeme důležitou větu o paritě permutací.</p>
<p class="has-yellow-background-color has-background">Věta: Součinem sudého počtu transpozic vznikne sudá permutace. Součinem lichého počtu transpozic vznikne lichá permutace.</p>
<p class="has-bright-red-background-color has-background">Důkaz indukcí: Součin \(0\) transpozic je permutace identity, která nemá žádnou inverzi a je tedy sudá. Dokažme nyní, že pokud permutaci vynásobíme zleva transpozicí, změní se tím její parita. Pokud si permutaci představíme jako nějaké pořadí prvků, transpozice v tomto pořadí přehodí dva prvky \(x\) a \(y\). Tím se změní jejich pořadí. Pokud byly ve „správném“ pořadí, potom tímto vznikne jedna inverze, v opačném případě zanikne jedna inverze — ale každopádně se tím parita počtu inverzí změní. Mezi \(x\) a \(y\) však může být ještě dalších \(k\) prvků. Pro každý z těchto prvků se zméní jeho pořadí jak s \(x\), tak s \(y\), takže stejným způsobem dojde ke dvěma vznikům nebo zánikům inverze. To však paritu počtu inverzí neovlivní, jelikož se tyto výměny dají právě takto rozdělit do dvojic. Celkově se tedy parita musí změnit, což je přesně to, co jsme chtěli dokázat.</p>
<p>Permutace \(\begin{pmatrix}1&amp;2&amp;3&amp;4&amp;5&amp;6&amp;7\\1&amp;2&amp;3&amp;6&amp;5&amp;4&amp;7\end{pmatrix} = (6,4)\) se skládá z jedné transpozice, čímž se znovu potvrzuje, že je lichá.</p>
<p>Nyní si již uvažováním o rozkladu na transpozice lze snadno rozmyslet, že skládání permutací funguje co do parity stejně jako sčítání celých čísel: dvě sudé nebo dvě liché dají sudou, zatímco sudá s lichou nebo lichá se sudou dají lichou. To se dá jednoduše formulovat pomocí znamének: \(\operatorname{sgn}(\pi \circ \sigma) = \operatorname{sgn}(\pi) \cdot \operatorname{sgn}(\sigma)\).</p>
<p class="has-yellow-background-color has-background">Věta: Pro každé \(n \geq 2\) je v grupě \(\mathbb S_n\) stejný počet sudých a lichých permutací.</p>
<p>Důkaz: Vezměme libovolnou transpozici \(\tau\). Jelikož jde jen o přehození dvou prvků, které je po opětovném provedení vrátí do původního stavu, platí \(\tau = \tau^{-1}\). Definujme funkci \(f(\pi) = \tau \circ \pi\). Tato funkce je také inverzí sama sebe, jelikož \(f(f(\pi)) = \tau \circ \tau \circ \pi = \tau^{-1} \circ \tau \circ \pi = \pi\). Jelikož \(\tau\) je lichá permutace, funkce \(f\) změní znaménko permutace, kterou do ní vložíme. Z těchto dvou skutečností však plyne, že \(f\) je bijekce mezi množinou sudých a lichých permutací, a tyto množiny tedy musí mít stejnou velikost.</p>
<p>Zajímavostí na závěr je, že ve známé hře <a href="https://cs.wikipedia.org/wiki/Patn%C3%A1ctka">Patnáctka</a> nelze polovinu pozic vyřešit — a to právě proto, že libovolná posloupnost tahů, po které zůstane volné stejné pole jako před ní, nemůže změnit paritu permutace čísel na desce. Jeden vychytralý člověk na to kdysi vyhlásil tučnou peněžní odměnu, čímž vyvolal naprostou mánii a mnoho lidí trávilo čas marnými pokusy o nalezení posloupnosti tahů, která by vedla k přehození dvou čísel. Matematika samozřejmě stála při jeho zádech a nikomu se to nepodařilo.</p>
<div class="speaker-mute footnotes_reference_container"> <div class="footnote_container_prepare"> <p> <hr /> <span style="display: none;" role="button" class="footnote_reference_container_collapse_button" onclick="footnote_expand_collapse_reference_container_2859_2();" tabindex="0">[ <a id="footnote_reference_container_collapse_button_2859_2">+</a>]</span> </p></div> <div style="" id="footnote_references_container_2859_2"><table class="footnotes_table footnote-reference-container"> <tbody>
<tr class="footnotes_plugin_reference_row"> <th class="footnote_plugin_index_combi pointer" onclick="footnote_moveToAnchor_2859_2('footnote_plugin_tooltip_2859_2_1');" scope="row"> <a href="#footnote_plugin_tooltip_2859_2_1" class="footnote_backlink" id="footnote_plugin_reference_2859_2_1"> <span class="footnote_index_arrow">↑</span>1</a></th> <td class="footnote_plugin_text">Dokonce platí i silnější tvrzení, že každá permutace se dá rozložit na součin transpozic sousedních dvou prvků. Konkrétní způsob, jak to provést, je tzv. <a href="https://cs.wikipedia.org/wiki/Bublinkov%C3%A9_%C5%99azen%C3%AD">bublinkové řazení</a>.</td></tr>
</tbody> </table> </div></div>
</div>

View File

@ -0,0 +1,35 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><link rel="stylesheet" href="/styles/mathsessions.css"><link rel="stylesheet" href="/styles/katex.min.css"><script defer src="/scripts/katex.min.js" onload="renderMathInElement(document.body)"></script><title>Vytváření dokumentů v systému LaTeX</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><p class="notice">Tento článek je zkopírován ze stránky <a href="http://mathsessions.klusik.cz/">Matematická setkání</a>.</p><div class="entry-content"><h1 class="entry-title">Vytváření dokumentů v systému \(\mathrm\LaTeX\)</h1>
<p>V <a href="http://mathsessions.klusik.cz/2021/01/03/latex/">minulém článku</a> jsme si vysvětlili, že \(\mathrm\LaTeX\)ový kód se skládá z příkazů a jak tyto příkazy vypadají. Ale jak vlastně začít psát takový \(\mathrm\LaTeX\)ový dokument? V zásadě existují tři možnosti:</p>
<span id="more-2629" />
<ul> <li>Obyčejný textový editor — např. <a href="https://www.vim.org/">Vim</a>, <a href="https://notepad-plus-plus.org/">Notepad++</a> nebo i Windows Poznámkový blok. Pozor, nikoliv editor formátovaného textu jako je Microsoft Word! O formátování se ostatně \(\mathrm\LaTeX\) postará sám. Napsaný kód se poté musí zkompilovat nějakým kompilátorem \(\mathrm\LaTeX\)u, nejpoužívanější je <a href="https://www.tug.org/texlive/">TeXLive</a>.</li> <li>Integrované prostředí, které poskytuje funkcionalitu pro editaci i kompilování zároveň. Příkladem je webová stránka <a href="https://www.overleaf.com/">Overleaf</a>, kde je možné bez jakéhokoli stahování napsat dokument a vytvořit z něj PDF.</li> <li>Nějaký jiný systém, který má podporu \(\mathrm\LaTeX\)ových vzorců. Tyto systémy podporují většinou pouze matematický režim. Patří mezi ně například WordPress, ve kterém je napsán tento článek.</li></ul>
<h2>Základní kód</h2>
<p>Takže už máme nějaký prázdný soubor, co do něj teď napsat? Začneme tím, že nastavíme druh dokumentu společně s nějakými dalšími parametry a použijeme některé základní balíčky. (Balíčky jsou vylepšení, která do dokumentů přidávají různou funkcionalitu, například možnost vkládat obrázky.) Následuje příkaz <code data-enlighter-language="latex" class="EnlighterJSRAW">\begin{document}</code>, který ukazuje, že zde začíná tělo dokumentu. Poté již můžeme psát samotný obsah. Dokument nakonec uzavřeme příkazem <code data-enlighter-language="latex" class="EnlighterJSRAW">\end{document}</code>. Kód bude vypadat následovně:</p><pre data-enlighter-highlight="" data-enlighter-group="" data-enlighter-language="latex" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-theme="" class="EnlighterJSRAW">\documentclass[a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[czech]{babel}
\usepackage{geometry}
\begin{document}
Toto je tělo dokumentu psaného v systému \LaTeX{}. Můžu v něm psát \textbf{tučně}, \textit{kurzívou}, \large{velkým písmem} i \small{malým písmem}.
Zde máme další odstavec. Odstavce jsou oddělené prázdným řádkem.
\end{document}</pre></pre><p>Pokud tento kód zkompilujeme (přesný postup záleží na používaněm nástroji), vznikne tím PDF dokument s jedním listem velikosti A4 o dvou odstavcích.</p>
<h2>Komentáře</h2>
<p>Do kódu je možné přidávat <em>komentáře</em>. Komentář je část textu, která se při kompilaci zcela ignoruje a slouží k tomu, abychom si do kódu mohli psát vlastní poznámky, které se neobjeví ve výsledném dokumentu. Komentář začíná znakem <code data-enlighter-language="latex" class="EnlighterJSRAW">%</code> a pokračuje až do konce řádku. V dalších příkladech budou pomocí komentářů vysvětlovány nové příkazy.</p>
<h2>Titulek</h2>
<p>Nyní se naučíme do dokumentu přidat titulek. To funguje tak, že v záhlaví (před <code data-enlighter-language="latex" class="EnlighterJSRAW">\begin{document}</code>) uvedeme informace o názvu a autorovi, popřípadě datu, a následně v textu můžeme použít příkaz <code data-enlighter-language="latex" class="EnlighterJSRAW">\maketitle</code>, který automaticky vygeneruje titulek. Nyní již přejděme ke kódu:</p><pre data-enlighter-highlight="" data-enlighter-group="" data-enlighter-language="latex" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-theme="" class="EnlighterJSRAW">\documentclass[a4paper]{article} % Vybere článek jakožto nejzákladnější druh dokumentu.
\usepackage[utf8]{inputenc} % Zařídí, aby bylo možné psát háčky a čárky
\usepackage[czech]{babel} % Nastaví češtinu jako jazyk dokumentu
\usepackage{geometry} % Nastaví hezčí velikosti okrajů
\title{Můj první \LaTeX{} dokument} % Název dokumentu, uvnitř lze používat příkazy
\author{Zuzana Psálková} % Autor dokumentu, uvnitř lze používat příkazy
\date{4.\ ledna 2021} % Datum; pokud příkaz vynecháte, použije se aktuální
% Pokud datum vůbec nechcete uvádět, použijte \date{}
\begin{document}
\maketitle % Vytvoří nadpis
Tento dokument má nadpis!
A opět dva odstavce. Jak jsme se již naučili, můžu používat matematický režim: $\frac{\sqrt{8}}{\sqrt{2}} = 2$
\end{document}</pre><p>V příštím článku si ukážeme, jak do dokumentu přidat nadpisy a obsah.</p>
<!-- .author-info -->
</div></body></html>

View File

@ -0,0 +1,47 @@
extends ../templates/mathsessions.jade
block title
| Vytváření dokumentů v systému LaTeX
block article
<div class="entry-content"><h1 class="entry-title">Vytváření dokumentů v systému \(\mathrm\LaTeX\)</h1>
<p>V <a href="http://mathsessions.klusik.cz/2021/01/03/latex/">minulém článku</a> jsme si vysvětlili, že \(\mathrm\LaTeX\)ový kód se skládá z příkazů a jak tyto příkazy vypadají. Ale jak vlastně začít psát takový \(\mathrm\LaTeX\)ový dokument? V zásadě existují tři možnosti:</p>
<span id="more-2629" />
<ul> <li>Obyčejný textový editor — např. <a href="https://www.vim.org/">Vim</a>, <a href="https://notepad-plus-plus.org/">Notepad++</a> nebo i Windows Poznámkový blok. Pozor, nikoliv editor formátovaného textu jako je Microsoft Word! O formátování se ostatně \(\mathrm\LaTeX\) postará sám. Napsaný kód se poté musí zkompilovat nějakým kompilátorem \(\mathrm\LaTeX\)u, nejpoužívanější je <a href="https://www.tug.org/texlive/">TeXLive</a>.</li> <li>Integrované prostředí, které poskytuje funkcionalitu pro editaci i kompilování zároveň. Příkladem je webová stránka <a href="https://www.overleaf.com/">Overleaf</a>, kde je možné bez jakéhokoli stahování napsat dokument a vytvořit z něj PDF.</li> <li>Nějaký jiný systém, který má podporu \(\mathrm\LaTeX\)ových vzorců. Tyto systémy podporují většinou pouze matematický režim. Patří mezi ně například WordPress, ve kterém je napsán tento článek.</li></ul>
<h2>Základní kód</h2>
<p>Takže už máme nějaký prázdný soubor, co do něj teď napsat? Začneme tím, že nastavíme druh dokumentu společně s nějakými dalšími parametry a použijeme některé základní balíčky. (Balíčky jsou vylepšení, která do dokumentů přidávají různou funkcionalitu, například možnost vkládat obrázky.) Následuje příkaz <code data-enlighter-language="latex" class="EnlighterJSRAW">\begin{document}</code>, který ukazuje, že zde začíná tělo dokumentu. Poté již můžeme psát samotný obsah. Dokument nakonec uzavřeme příkazem <code data-enlighter-language="latex" class="EnlighterJSRAW">\end{document}</code>. Kód bude vypadat následovně:</p>
pre(data-enlighter-highlight="" data-enlighter-group="" data-enlighter-language="latex" class="EnlighterJSRAW" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-theme="").
\documentclass[a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[czech]{babel}
\usepackage{geometry}
\begin{document}
Toto je tělo dokumentu psaného v systému \LaTeX{}. Můžu v něm psát \textbf{tučně}, \textit{kurzívou}, \large{velkým písmem} i \small{malým písmem}.
Zde máme další odstavec. Odstavce jsou oddělené prázdným řádkem.
\end{document}</pre>
<p>Pokud tento kód zkompilujeme (přesný postup záleží na používaněm nástroji), vznikne tím PDF dokument s jedním listem velikosti A4 o dvou odstavcích.</p>
<h2>Komentáře</h2>
<p>Do kódu je možné přidávat <em>komentáře</em>. Komentář je část textu, která se při kompilaci zcela ignoruje a slouží k tomu, abychom si do kódu mohli psát vlastní poznámky, které se neobjeví ve výsledném dokumentu. Komentář začíná znakem <code data-enlighter-language="latex" class="EnlighterJSRAW">%</code> a pokračuje až do konce řádku. V dalších příkladech budou pomocí komentářů vysvětlovány nové příkazy.</p>
<h2>Titulek</h2>
<p>Nyní se naučíme do dokumentu přidat titulek. To funguje tak, že v záhlaví (před <code data-enlighter-language="latex" class="EnlighterJSRAW">\begin{document}</code>) uvedeme informace o názvu a autorovi, popřípadě datu, a následně v textu můžeme použít příkaz <code data-enlighter-language="latex" class="EnlighterJSRAW">\maketitle</code>, který automaticky vygeneruje titulek. Nyní již přejděme ke kódu:</p>
pre(data-enlighter-highlight="" data-enlighter-group="" data-enlighter-language="latex" class="EnlighterJSRAW" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-theme="").
\documentclass[a4paper]{article} % Vybere článek jakožto nejzákladnější druh dokumentu.
\usepackage[utf8]{inputenc} % Zařídí, aby bylo možné psát háčky a čárky
\usepackage[czech]{babel} % Nastaví češtinu jako jazyk dokumentu
\usepackage{geometry} % Nastaví hezčí velikosti okrajů
\title{Můj první \LaTeX{} dokument} % Název dokumentu, uvnitř lze používat příkazy
\author{Zuzana Psálková} % Autor dokumentu, uvnitř lze používat příkazy
\date{4.\ ledna 2021} % Datum; pokud příkaz vynecháte, použije se aktuální
% Pokud datum vůbec nechcete uvádět, použijte \date{}
\begin{document}
\maketitle % Vytvoří nadpis
Tento dokument má nadpis!
A opět dva odstavce. Jak jsme se již naučili, můžu používat matematický režim: $\frac{\sqrt{8}}{\sqrt{2}} = 2$
\end{document}
<p>V příštím článku si ukážeme, jak do dokumentu přidat nadpisy a obsah.</p>
<!-- .author-info -->
</div>

View File

@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><link rel="stylesheet" href="/styles/katex.min.css"><script defer src="/scripts/katex.min.js" onload="renderMathInElement(document.body)"></script><title>Equality | xigoi</title></head><body><a href="/"><header><svg id="xigoi-logo" width="20" height="20" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>Equality</h1><figure class="quote"><blockquote>In <a href="/wiki/Mathematics" title="Mathematics">mathematics</a>, an <dfn>equivalence relation</dfn> is a <a href="/wiki/Binary_relation" title="Binary relation">binary relation</a> that is <a href="/wiki/Reflexive_relation" title="Reflexive relation">reflexive</a>, <a href="/wiki/Symmetric_relation" title="Symmetric relation">symmetric</a> and <a href="/wiki/Transitive_relation" title="Transitive relation">transitive</a>.</blockquote><figcaption><a href="https://en.wikipedia.org/wiki/Equivalence_relation">Wikipedia</a></figcaption></figure><p>Who doesn't want equal rights? Gender equality, racial equality, you name it. However, there seems to be a general disagreement on what “equality” should look like. I'd like to present my viewpoint using the mathematical definition of an <dfn>equivalence relation</dfn>, which is basically a generalized idea of equality.</p><h2>Reflexivity</h2><p><dfn>Reflexivity</dfn> simply means that everything is equal to itself. This is not really relevant when discussing human rights, since the rights of a given group are equal to themselves by nature.</p><h2>Symmetry</h2><p><dfn>Symmetry</dfn> says that if \(x = y\), then \(y = x\). In other words, two equal things are interchangeable. Now this gets more interesting. My interpretation is that if switching the roles of two people/groups wouldn't change their situation regarding what they can do, only then can we say that they have equal rights. Surprisingly, this already seems to be a very controversial opinion. I'll get to concrete examples later.</p><h2>Transitivity</h2><p><dfn>Transitivity</dfn> says that if \(x = y\) and \(y = z\), then also \(x = z\). It's hard to imagine a scenario where this would come relevant in human rights. After all, it involves three variables, but discussions about human rights usually compare the rights of two groups. We'll see if this becomes useful later.</p></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><link rel="stylesheet" href="/styles/katex.min.css"><script defer src="/scripts/katex.min.js" onload="renderMathInElement(document.body)"></script><title>Equality | xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>Equality</h1><figure class="quote"><blockquote>In <a href="/wiki/Mathematics" title="Mathematics">mathematics</a>, an <dfn>equivalence relation</dfn> is a <a href="/wiki/Binary_relation" title="Binary relation">binary relation</a> that is <a href="/wiki/Reflexive_relation" title="Reflexive relation">reflexive</a>, <a href="/wiki/Symmetric_relation" title="Symmetric relation">symmetric</a> and <a href="/wiki/Transitive_relation" title="Transitive relation">transitive</a>.</blockquote><figcaption><a href="https://en.wikipedia.org/wiki/Equivalence_relation">Wikipedia</a></figcaption></figure><p>Who doesn't want equal rights? Gender equality, racial equality, you name it. However, there seems to be a general disagreement on what “equality” should look like. I'd like to present my viewpoint using the mathematical definition of an <dfn>equivalence relation</dfn>, which is basically a generalized idea of equality.</p><h2>Reflexivity</h2><p><dfn>Reflexivity</dfn> simply means that everything is equal to itself. This is not really relevant when discussing human rights, since the rights of a given group are equal to themselves by nature.</p><h2>Symmetry</h2><p><dfn>Symmetry</dfn> says that if \(x = y\), then \(y = x\). In other words, two equal things are interchangeable. Now this gets more interesting. My interpretation is that if switching the roles of two people/groups wouldn't change their situation regarding what they can do, only then can we say that they have equal rights. Surprisingly, this already seems to be a very controversial opinion. I'll get to concrete examples later.</p><h2>Transitivity</h2><p><dfn>Transitivity</dfn> says that if \(x = y\) and \(y = z\), then also \(x = z\). It's hard to imagine a scenario where this would come relevant in human rights. After all, it involves three variables, but discussions about human rights usually compare the rights of two groups. We'll see if this becomes useful later.</p></body></html>

View File

@ -1,2 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><link rel="stylesheet" href="/styles/katex.min.css"><script defer src="/scripts/katex.min.js" onload="renderMathInElement(document.body)"></script><title>xigoi</title></head><body><a href="/"><header><svg id="xigoi-logo" width="20" height="20" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><p class="warning">This website is a work in progress.</p><p>
Hi! I am <em class="xigoi">xigoi</em>. I like programming and other computer stuff, mathematics, linguistics and walking. I live in Czechia and can speak Czech, English, <a href="https://tokipona.org/">Toki Pona</a> and some German. I am a big open source enthusiast I use <a href="https://www.linux.com/news/what-is-gnu-linux/">GNU/Linux</a>, <a href="https://www.vim.org/">Vim</a>, <a href="https://www.latex-project.org/">\(\text{\LaTeX}\)</a>, <a href="https://f-droid.org/">F-Droid</a>, <a href="https://disroot.org/en">Disroot</a> and others. I have some strong and possibly controversial <a href="opinions.html">opinions</a> about various aspects of life. On this website, you can find some things written and otherwise created by me. Happy browsing!</p><h2>Rants</h2><ul><li class="wip"><a href="equality.html">Equality</a></li><li><a href="language-criticism/">Language Criticism</a></li></ul><h2>Contact me</h2><ul><li>E-mail: <a href="mailto:xigoi@disroot.org">xigoi@disroot.org</a></li><li>Ruqqus: <a href="https://ruqqus.com/@xigoi">@xigoi</a></li><li>Reddit: <a href="https://www.reddit.com/user/xigoi">u/xigoi</a></li><li>Discord: xigoi#1759</li></ul></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><link rel="stylesheet" href="/styles/katex.min.css"><script defer src="/scripts/katex.min.js" onload="renderMathInElement(document.body)"></script><title>xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><p class="warning">This website is a work in progress.</p><p>Hi! I am <em class="xigoi">xigoi</em>. I like programming and other computer stuff, mathematics, linguistics and walking. I live in Czechia and can speak Czech, English, <a href="https://tokipona.org/">Toki Pona</a> and some German. I am a big open source enthusiast I use <a href="https://www.linux.com/news/what-is-gnu-linux/">GNU/Linux</a>, <a href="https://www.vim.org/">Vim</a>, <a href="https://www.latex-project.org/">\(\text{\LaTeX}\)</a>, <a href="https://f-droid.org/">F-Droid</a>, <a href="https://disroot.org/en">Disroot</a> and others. I have some strong and possibly controversial <a href="opinions.html">opinions</a> about various aspects of life. On this website, you can find some things written and otherwise created by me. Happy browsing!</p><h2>Math</h2><ul class="index"><li class="wip"><a href="quantum-games.html">Quantum games</a></li></ul><h2>Rants</h2><ul class="index"><li><a href="opinions.html">Opinions</a></li><li class="wip"><a href="equality.html">Equality</a></li><li><a href="language-criticism/">Language Criticism</a></li></ul><h2>Fiction</h2><ul class="index"><li class="wip"><a href="susan-and-male-privilege.html">Susan and Male Privilege</a></li></ul><h2>About me and this site</h2><ul class="index"><li><a href="logo.html">xigoi logo</a></li><li><a href="styles/main.sass">Stylesheet (SASS)</a></li><li><a href="styles/main.css">Stylesheet (CSS)</a></li></ul><h2>Contact me</h2><ul class="index"><li>E-mail: <a href="mailto:xigoi@disroot.org">xigoi@disroot.org</a></li><li>Ruqqus: <a href="https://ruqqus.com/@xigoi">@xigoi</a></li><li>Reddit: <a href="https://www.reddit.com/user/xigoi">u/xigoi</a></li><li>Discord: xigoi#1759</li></ul></body></html>

View File

@ -5,32 +5,50 @@ block head
block content
p.warning This website is a work in progress.
p
p
| Hi! I am
em.xigoi xigoi
| . I like programming and other computer stuff, mathematics, linguistics and walking. I live in Czechia and can speak Czech, English,
a(href='https://tokipona.org/') Toki Pona
a(href="https://tokipona.org/") Toki Pona
| and some German. I am a big open source enthusiast I use
a(href='https://www.linux.com/news/what-is-gnu-linux/') GNU/Linux
a(href="https://www.linux.com/news/what-is-gnu-linux/") GNU/Linux
| ,
a(href='https://www.vim.org/') Vim
a(href="https://www.vim.org/") Vim
| ,
a(href='https://www.latex-project.org/') \(\text{\LaTeX}\)
a(href="https://www.latex-project.org/") \(\text{\LaTeX}\)
| ,
a(href='https://f-droid.org/') F-Droid
a(href="https://f-droid.org/") F-Droid
| ,
a(href='https://disroot.org/en') Disroot
a(href="https://disroot.org/en") Disroot
| and others. I have some strong and possibly controversial
a(href='opinions.html') opinions
a(href="opinions.html") opinions
| about various aspects of life. On this website, you can find some things written and otherwise created by me. Happy browsing!
h2 Math
ul.index
li.wip
a(href="quantum-games.html") Quantum games
h2 Rants
ul
ul.index
li
a(href="opinions.html") Opinions
li.wip
a(href="equality.html") Equality
li
a(href="language-criticism/") Language Criticism
h2 Fiction
ul.index
li.wip
a(href="susan-and-male-privilege.html") Susan and Male Privilege
h2 About me and this site
ul.index
li
a(href="logo.html") xigoi logo
li
a(href="styles/main.sass") Stylesheet (SASS)
li
a(href="styles/main.css") Stylesheet (CSS)
h2 Contact me
ul
ul.index
li E-mail:
a(href="mailto:xigoi@disroot.org") xigoi@disroot.org
li Ruqqus:

View File

@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>Braces &amp; Semicolons | Language Criticism | xigoi</title></head><body><a href="/"><header><svg id="xigoi-logo" width="20" height="20" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>Braces Criticism</h1><p>There are, in general, three common ways to delimit code blocks: braces, end-keywords and indentation. When we write pseudocode on paper, we tend to almost always use indentation — it provides an easy visual cue and takes the least effort to write. So why do so many programmers insist on using braces for this purpose, which make code much harder to visually parse? Here are some commonly given reasons with my responses:</p><ul class="qa"><li>Pasting code from the internet messes up the indentation and it's tedious to fix it.</li><li>Are you coding in Windows Notepad?</li><li>A changed indent can cause the code to behave differently.</li><li>When this happens, you'll clearly see it. On the other hand, a misplaced brace might go unnoticed and the indentation will give you a false sense of the code being correct.</li><li>I have auto-indent, so the indentation will always match the braces.</li><li>That's cool. You'll still get slowed down by having to visually process them.</li><li>I don't think invisible characters should change the meaning of code.</li><li>Firstly, indentation is followed by visible characters, which makes you able to clearly see it. Secondly, by this argument, you could also argue that <code>publicstaticvoidmain</code> should be equivalent to <code>public static void main</code> — we're just ignoring “invisible” characters, no?</li><li>Mixing spaces and tabs is going to create a mess.</li><li>See the answer to the first question.</li></ul><h1>Semicolons Criticism</h1><p>A very popular feature in programming languages, especially those derived from <a href="c.html">C</a>, is requiring a semicolon after every statement. Why is this necessary if you're already separating statements by newlines? It just adds one more character you need to type; and more importantly, a lot more characters that you have to visually process, but that don't contribute in any way to the logic of the code (the term for this is <dfn>syntactic noise</dfn>). There's a lot of languages that do completely fine without them: Python, Ruby, Lua, Nim, Go, Haskell, etc. And JavaScript shows that even in a language that uses semicolons, they can be inferred pretty well. Also note that Lua doesn't actually care about newlines, its syntax is made in a way that a statement always ends unambiguously.</p></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>Braces &amp; Semicolons | Language Criticism | xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>Braces Criticism</h1><p>There are, in general, three common ways to delimit code blocks: braces, end-keywords and indentation. When we write pseudocode on paper, we tend to almost always use indentation — it provides an easy visual cue and takes the least effort to write. So why do so many programmers insist on using braces for this purpose, which make code much harder to visually parse? Here are some commonly given reasons with my responses:</p><ul class="qa"><li>Pasting code from the internet messes up the indentation and it's tedious to fix it.</li><li>Are you coding in Windows Notepad?</li><li>A changed indent can cause the code to behave differently.</li><li>When this happens, you'll clearly see it. On the other hand, a misplaced brace might go unnoticed and the indentation will give you a false sense of the code being correct.</li><li>I have auto-indent, so the indentation will always match the braces.</li><li>That's cool. You'll still get slowed down by having to visually process them.</li><li>I don't think invisible characters should change the meaning of code.</li><li>Firstly, indentation is followed by visible characters, which makes you able to clearly see it. Secondly, by this argument, you could also argue that <code>publicstaticvoidmain</code> should be equivalent to <code>public static void main</code> — we're just ignoring “invisible” characters, no?</li><li>Mixing spaces and tabs is going to create a mess.</li><li>See the answer to the first question.</li></ul><h1>Semicolons Criticism</h1><p>A very popular feature in programming languages, especially those derived from <a href="c.html">C</a>, is requiring a semicolon after every statement. Why is this necessary if you're already separating statements by newlines? It just adds one more character you need to type; and more importantly, a lot more characters that you have to visually process, but that don't contribute in any way to the logic of the code (the term for this is <dfn>syntactic noise</dfn>). There's a lot of languages that do completely fine without them: Python, Ruby, Lua, Nim, Go, Haskell, etc. And JavaScript shows that even in a language that uses semicolons, they can be inferred pretty well. Also note that Lua doesn't actually care about newlines, its syntax is made in a way that a statement always ends unambiguously.</p></body></html>

View File

@ -1,6 +1,6 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>C | Language Criticism | xigoi</title></head><body><a href="/"><header><svg id="xigoi-logo" width="20" height="20" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>C Language Criticism</h1><p class="disclaimer">I know that C was designed a long time ago when there wasn't much knowledge about language design. I'm not trying to berate its original creators, I just think it's time to move on to more modern systems programming languages like Nim, Rust or Zig. That's why this criticism is from a modern perspective.</p><p class="notice">I found <a href="https://eev.ee/blog/2016/12/01/lets-stop-copying-c/">this article</a> which explains everything much better than I, so please check it out. I'm leaving my original rant here because why not.</p><h2>Preprocessor</h2><p>What's a better way of doing imports and macros than embedding another language with completely different syntax, which does naive text substitution, into your language? In order to avoid dangers which are not present in any sane import/macro systems, you have to do ugly hacks such as:</p><ul><li><p>Include guards</p><pre>#ifndef YOU_NEED_TO_MANUALLY_MAKE_SURE_THAT_YOUR_FILE_ISNT_INCLUDED_MULTIPLE_TIMES
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>C | Language Criticism | xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>C Language Criticism</h1><p class="disclaimer">I know that C was designed a long time ago when there wasn't much knowledge about language design. I'm not trying to berate its original creators, I just think it's time to move on to more modern systems programming languages like Nim, Rust or Zig. That's why this criticism is from a modern perspective.</p><p class="notice">I found <a href="https://eev.ee/blog/2016/12/01/lets-stop-copying-c/">this article</a> which explains many things much better than I, so please check it out. My article contains a few duplicates and some additional points.</p><h2>Preprocessor</h2><p>What's a better way of doing imports and macros than embedding another language with completely different syntax, which does naive text substitution, into your language? In order to avoid dangers which are not present in any sane import/macro systems, you have to do ugly hacks such as:</p><ul><li><p>Include guards</p><pre><code>#ifndef YOU_NEED_TO_MANUALLY_MAKE_SURE_THAT_YOUR_FILE_ISNT_INCLUDED_MULTIPLE_TIMES
#define YOU_NEED_TO_MANUALLY_MAKE_SURE_THAT_YOUR_FILE_ISNT_INCLUDED_MULTIPLE_TIMES
// your code here
#endif</pre></li><li><p>The <code>do { ... } while (0)</code> thing to make sure that a macro can be used as a normal function</p></li><li><p>Wrapping everything in parentheses to make a macro work like a normal function</p><pre>#define MAX(a, b) ((a) > (b) ? (a) : (b))</pre><p>If any parentheses are left out, it results in counter-intuitive behavior. Actually, even with them it doesn't work like a normal function: the arguments will be evaluated as many times as they're in the macro body!</p></li></ul><h2>Braces &amp; Semicolons</h2><p>See <a href="braces-semicolons.html">Braces &amp; Semicolons</a></p><h2>Syntax inconsistencies &amp; warts</h2><p>Since many other languages (Java, C#, JavaScript, ...) have mindlessly copied most syntax from C, these mistakes have a profound effect on a whole family of languages.</p><ul><li>All control structures that take a statement (if, while, for, switch) have the form of <code>KEYWORD (SOMETHING) STATEMENT</code>. Except for the do-while loop, which for some reason has the form <code>KEYWORD STATEMENT KEYWORD (SOMETHING);</code>. Totally different and including an extra semicolon.<ul class="qa"><li>But it visually indicates that the condition is first checked after the statement!</li><li>Then why is a for loop written as <code>for (INIT; CONDITION; STEP) STATEMENT</code> rather than <code>for (INIT; CONDITION) STATEMENT (STEP);</code>? By the same logic, we should visually indicate that the step (usually increment) is first executed after the statement.</li></ul></li><li>The choice to require an if/while condition to be wrapped in parentheses, rather than requiring the body to be wrapped in braces (as in Rust). Not only does this introduce syntactic noise, but it leads to subtle bugs if you mess up indentation:<pre>if (launch_button_pressed)
check(missile); // this was added in after we decided to make our missile system safer
launch(missile);</pre></li><li>The for loop is just another way to write a while loop, instead of something actually useful like Python's <code>for item in items:</code>.</li><li>The syntax for labels (including switch cases) is completely different from everything else. For consistency, it could be something like <code>label (NAME) STATEMENT</code> and <code>case (VALUE) STATEMENT</code>.</li></ul></body></html>
#endif</code></pre></li><li><p>The <code>do { ... } while (0)</code> thing to make sure that a macro can be used as a normal function</p></li><li><p>Wrapping everything in parentheses to make a macro work like a normal function</p><pre><code>#define MAX(a, b) ((a) > (b) ? (a) : (b))</code></pre><p>If any parentheses are left out, it results in counter-intuitive behavior. Actually, even with them it doesn't work like a normal function: the arguments will be evaluated as many times as they're in the macro body!</p></li></ul><h2>Braces &amp; Semicolons</h2><p>See <a href="braces-semicolons.html">Braces &amp; Semicolons</a></p><h2>Syntax inconsistencies &amp; warts</h2><p>Since many other languages (Java, C#, JavaScript, ...) have mindlessly copied most syntax from C, these mistakes have a profound effect on a whole family of languages.</p><ul><li>All control structures that take a statement (if, while, for, switch) have the form of <code>KEYWORD (SOMETHING) STATEMENT</code>. Except for the do-while loop, which for some reason has the form <code>KEYWORD STATEMENT KEYWORD (SOMETHING);</code>. Totally different and including an extra semicolon.<ul class="qa"><li>But it visually indicates that the condition is first checked after the statement!</li><li>Then why is a for loop written as <code>for (INIT; CONDITION; STEP) STATEMENT</code> rather than <code>for (INIT; CONDITION) STATEMENT (STEP);</code>? By the same logic, we should visually indicate that the step (usually increment) is first executed after the statement.</li></ul></li><li>The choice to require an if/while condition to be wrapped in parentheses, rather than requiring the body to be wrapped in braces (as in Rust). Not only does this introduce syntactic noise, but it leads to subtle bugs if you mess up indentation:<pre><code>if (launch_button_pressed)
check(missile); /* this was added in after we decided to make our missile system safer */
launch(missile);</code></pre></li><li>The for loop is just another way to write a while loop, instead of something actually useful like Python's <code>for item in items:</code>.</li><li>The syntax for labels (including switch cases) is completely different from everything else. For consistency, it could be something like <code>label (NAME) STATEMENT</code> and <code>case (VALUE) STATEMENT</code>.</li></ul><h2>Tooling</h2><ul><li>By default, the compilers don't have most warnings enabled. And it's very difficult to actually enable all warnings. <code>-Wall</code> enables only some warnings. What the fuck?</li><li>The defau;t name for the compiled executable is <code>a.out</code>, instead of being based on the source filename. So you need to do things like <code>gcc my_awesome_program.c -o my_awesome_program</code>.</li><li>You need to specify the libraries you're using in the compilation command, instead of just putting them in the source file.</li></ul></body></html>

View File

@ -5,68 +5,71 @@ block title
block content
h1 C Language Criticism
p.disclaimer
| I know that C was designed a long time ago when there wasn't much knowledge about language design. I'm not trying to berate its original creators, I just think it's time to move on to more modern systems programming languages like Nim, Rust or Zig. That's why this criticism is from a modern perspective.
p.notice
| I found
p.disclaimer I know that C was designed a long time ago when there wasn't much knowledge about language design. I'm not trying to berate its original creators, I just think it's time to move on to more modern systems programming languages like Nim, Rust or Zig. That's why this criticism is from a modern perspective.
p.notice I found
a(href="https://eev.ee/blog/2016/12/01/lets-stop-copying-c/") this article
| which explains everything much better than I, so please check it out. I'm leaving my original rant here because why not.
| which explains many things much better than I, so please check it out. My article contains a few duplicates and some additional points.
h2 Preprocessor
p What's a better way of doing imports and macros than embedding another language with completely different syntax, which does naive text substitution, into your language? In order to avoid dangers which are not present in any sane import/macro systems, you have to do ugly hacks such as:
ul
li
p Include guards
pre.
#ifndef YOU_NEED_TO_MANUALLY_MAKE_SURE_THAT_YOUR_FILE_ISNT_INCLUDED_MULTIPLE_TIMES
#define YOU_NEED_TO_MANUALLY_MAKE_SURE_THAT_YOUR_FILE_ISNT_INCLUDED_MULTIPLE_TIMES
// your code here
#endif
pre
code.
#ifndef YOU_NEED_TO_MANUALLY_MAKE_SURE_THAT_YOUR_FILE_ISNT_INCLUDED_MULTIPLE_TIMES
#define YOU_NEED_TO_MANUALLY_MAKE_SURE_THAT_YOUR_FILE_ISNT_INCLUDED_MULTIPLE_TIMES
// your code here
#endif
li
p
| The
p The
code do { ... } while (0)
| thing to make sure that a macro can be used as a normal function
li
p Wrapping everything in parentheses to make a macro work like a normal function
pre.
#define MAX(a, b) ((a) > (b) ? (a) : (b))
pre
code.
#define MAX(a, b) ((a) > (b) ? (a) : (b))
p If any parentheses are left out, it results in counter-intuitive behavior. Actually, even with them it doesn't work like a normal function: the arguments will be evaluated as many times as they're in the macro body!
h2 Braces &amp; Semicolons
p
| See
p See
a(href='braces-semicolons.html') Braces &amp; Semicolons
h2 Syntax inconsistencies &amp; warts
p Since many other languages (Java, C#, JavaScript, ...) have mindlessly copied most syntax from C, these mistakes have a profound effect on a whole family of languages.
ul
li
| All control structures that take a statement (if, while, for, switch) have the form of
li All control structures that take a statement (if, while, for, switch) have the form of
code KEYWORD (SOMETHING) STATEMENT
| . Except for the do-while loop, which for some reason has the form
code KEYWORD STATEMENT KEYWORD (SOMETHING);
| . Totally different and including an extra semicolon.
ul.qa
li
| But it visually indicates that the condition is first checked after the statement!
li
| Then why is a for loop written as
li But it visually indicates that the condition is first checked after the statement!
li Then why is a for loop written as
code for (INIT; CONDITION; STEP) STATEMENT
| rather than
code for (INIT; CONDITION) STATEMENT (STEP);
| ? By the same logic, we should visually indicate that the step (usually increment) is first executed after the statement.
li
| The choice to require an if/while condition to be wrapped in parentheses, rather than requiring the body to be wrapped in braces (as in Rust). Not only does this introduce syntactic noise, but it leads to subtle bugs if you mess up indentation:
pre.
if (launch_button_pressed)
check(missile); // this was added in after we decided to make our missile system safer
launch(missile);
li
| The for loop is just another way to write a while loop, instead of something actually useful like Python's
li The choice to require an if/while condition to be wrapped in parentheses, rather than requiring the body to be wrapped in braces (as in Rust). Not only does this introduce syntactic noise, but it leads to subtle bugs if you mess up indentation:
pre
code.
if (launch_button_pressed)
check(missile); /* this was added in after we decided to make our missile system safer */
launch(missile);
li The for loop is just another way to write a while loop, instead of something actually useful like Python's
code for item in items:
| .
li
| The syntax for labels (including switch cases) is completely different from everything else. For consistency, it could be something like
li The syntax for labels (including switch cases) is completely different from everything else. For consistency, it could be something like
code label (NAME) STATEMENT
| and
code case (VALUE) STATEMENT
| .
h2 Tooling
ul
li By default, the compilers don't have most warnings enabled. And it's very difficult to actually enable all warnings.
code -Wall
| enables only some warnings. What the fuck?
li The defau;t name for the compiled executable is
code a.out
| , instead of being based on the source filename. So you need to do things like
code gcc my_awesome_program.c -o my_awesome_program
| .
li You need to specify the libraries you're using in the compilation command, instead of just putting them in the source file.

View File

@ -1,4 +1,4 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>C++ | Language Criticism | xigoi</title></head><body><a href="/"><header><svg id="xigoi-logo" width="20" height="20" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>C++ Language Criticism</h1><p>Everything that applies to <a href="c.html">C</a> also applies to C++. This article contains only things that don't apply to C.</p><p>The <a href="http://yosefk.com/c++fqa/index.html">C++ FQA</a> has a lot of great points, so go read it too.</p><h2>Overall philosophy</h2><p>I believe that a programming language should be designed to make simple things simple and complex things as simple as possible. C++ is designed to make simple things complex and complex things even more complex. For example, a program to read space-separated numbers from STDIN, sort them and again output them space-separated:</p><div class="comparison"><div class="compared"><h6>Python 3</h6><pre><code>nums = [int(inp) for inp in input().split()]
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>C++ | Language Criticism | xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>C++ Language Criticism</h1><p>Everything that applies to <a href="c.html">C</a> also applies to C++. This article contains only things that don't apply to C.</p><p>The <a href="http://yosefk.com/c++fqa/index.html">C++ FQA</a> has a lot of great points, so go read it too.</p><h2>Overall philosophy</h2><p>I believe that a programming language should be designed to make simple things simple and complex things as simple as possible. C++ is designed to make simple things complex and complex things even more complex. For example, a program to read space-separated numbers from STDIN, sort them and again output them space-separated:</p><div class="comparison"><div class="compared"><h6>Python 3</h6><pre><code>nums = [int(inp) for inp in input().split()]
print(*sorted(nums))</code></pre><a href="https://tio.run/##K6gsycjPM/7/P680t1jBViE6M69EIzOvQFMhLb9IAcgAYhBVWqKhqVdckJMJpGO5CopAyrSK84tKUlM0QFo1Nf//NzY0UTA0VbBUMDJTMFUwNgUA">Try it online!</a></div><div class="compared"><h6>Nim</h6><pre><code>import std/[strutils, sequtils, algorithm]
let nums = stdin.readLine.splitWhitespace.mapIt(it.parseInt)
@ -27,5 +27,106 @@ int main() {
std::cout &lt;&lt; num;
}
std::cout &lt;&lt; std::endl;
}</code></pre><a href="https://tio.run/##ZY/NTsMwEITveYqRONSRAlIpQSINfRXkOE66wrEj24ED6rMH2/kBxM2e@WZ2V4zjfS/EPN@RFmpqJWoyzlvJh0v2o31I4Y39rXDVG0v@GrCMtMfASbMcXxngfFtVS6IO1gV6Gtx5M0I56R6kxyh9XklJsOT00ivScvkI0kWEChxwyJdipKYHOYyKC/nWcPHO1k5DLMB5Hjtv@yhjPUuRRvZxvWIt0C1b0MYYhY6s83iFt5OMYmcsWLwpwKhSZJtPHVjCNwF7uuPKpXhYADK8d2K5x0wedR2vWaHsnxcm/dl/09MnLK3O2W2eT8cnHEu84PEZJU7lNw">Try it online!</a></div></div><h2>Syntax</h2><p>C++ took the horrible syntax of C and somehow managed to make it even worse.</p><ul><li>The <a href="https://en.wikipedia.org/wiki/Most_vexing_parse">most vexing parse</a> (and similar rules). I can't fathom what could possibly cause someone to think this is a good idea.</li><li><a href="https://blog.reverberate.org/2013/08/parsing-c-is-literally-undecidable.html">Parsing C++ is literally undecidable.</a></li><li>Using less-than and greater-than signs as brackets, which hinders auto-pairing and complicates parsing while also looking ugly.</li><li>
Who decided that <code>::</code> is a good path separator?</li></ul></body></html>
}</code></pre><a href="https://tio.run/##ZY/NTsMwEITveYqRONSRAlIpQSINfRXkOE66wrEj24ED6rMH2/kBxM2e@WZ2V4zjfS/EPN@RFmpqJWoyzlvJh0v2o31I4Y39rXDVG0v@GrCMtMfASbMcXxngfFtVS6IO1gV6Gtx5M0I56R6kxyh9XklJsOT00ivScvkI0kWEChxwyJdipKYHOYyKC/nWcPHO1k5DLMB5Hjtv@yhjPUuRRvZxvWIt0C1b0MYYhY6s83iFt5OMYmcsWLwpwKhSZJtPHVjCNwF7uuPKpXhYADK8d2K5x0wedR2vWaHsnxcm/dl/09MnLK3O2W2eT8cnHEu84PEZJU7lNw">Try it online!</a></div></div><h2>Features</h2><ul><li>Despite being a very large language, C++ doesn't have basic features like sum types or pattern matching.</li><li>Many features duplicate other features, adding their own advantages and drawbacks (and more unnecessary syntactic rules to learn). Examples: initializer lists, <code>typedef</code>/<code>using</code>, <code>#define</code>/<code>constexpr</code>, <code>char[]</code>/<code>std::string</code>, <code>int[]</code>/<code>std::array&lt;int&gt;</code>, <code>printf</code>/<code>cout</code>, <code>struct</code>/<code>class</code></li></ul><h2>Syntax</h2><p>C++ took the horrible syntax of C and somehow managed to make it even worse.</p><ul><li>The <a href="https://en.wikipedia.org/wiki/Most_vexing_parse">most vexing parse</a> (and similar rules). I can't fathom what could possibly cause someone to think this is a good idea.</li><li><a href="https://blog.reverberate.org/2013/08/parsing-c-is-literally-undecidable.html">Parsing C++ is literally undecidable.</a></li><li>Using less-than and greater-than signs as brackets, which hinders auto-pairing and complicates parsing while also looking ugly.</li><li>The semicolon after a <code>struct</code>/<code>class</code> definition. Just why?</li><li>Keywords that have multiple meanings depending on where you use them: <code>static</code>, <code>using</code>, <code>typename</code>.</li><li>The keyword <code>const</code> is used to declare immutable variables (not constants, for which there is <code>constexpr</code>) and it can be placed in various positions inside a type, which completely changes its meaning.</li><li>Who decided that <code>::</code> is a good path separator?</li></ul><h2>Standard library</h2><ul><li>Despite being quite extensive, the standard library doesn't have basic things like<ul><li>basic functions for working with strings (split, join)</li><li>functional abstractions (map, filter, fold, …) [C++20 partially solves this with “range adaptors” (what a weird name), but the usage is unbearably cumbersome]</li><li>optional/result types</li></ul></li><li>Using the term “vector” for a resizable array, even though the word has a completely different meaning in mathematics.</li><li>There is no convenient way to pass a whole array/vector/list to a function, you have to do something like <code>std::sort(arr.begin(), arr.end())</code>.</li><li>Weird function names: from C crypticisms (<code>stoi</code>, <code>fscanf</code>) to unusual words (<code>emplace_back</code>).</li></ul><h2>Tooling</h2><ul><li>Error messages.<ul><li>If you try to search a “vector” (array) of a wrong type…<p>Credit goes to <a href="https://codegolf.stackexchange.com/a/10470/98955">this StackExchange answer</a>.</p><pre><code>#include &lt;vector&gt;
#include &lt;algorithm&gt;
int main() {
int a;
std::vector&lt;std::vector&lt;int&gt;&gt; v;
std::vector&lt;std::vector&lt;int&gt;&gt;::const_iterator it = std::find(v.begin(), v.end(), a);
}</code></pre><a href="https://tio.run/##jY1BDoIwEEX3PcUkbiBRDlCwVzF1OtZJoCVl7MZ49lJgoUv/6uXl/3yc54tHLOXEAceXIxgyocRk1NfY0cfE8pyMUhwEJsuhaeGtoGYTtt9xEaf1MR9@uVaMgfxHSWuMYZEbCyVbLbDA9Zg8OLgmd3fy2/kZckdVVLBtrz6lrA">Try it online!</a><p>The error message (compiled with GCC 10.2.0) has 148 lines with about 12 kB of content, starting with:</p><pre><samp>In file included from /usr/include/c++/10.2.0/bits/stl_algobase.h:71,
from /usr/include/c++/10.2.0/vector:60,
from error.cpp:1:
/usr/include/c++/10.2.0/bits/predefined_ops.h: In instantiation of bool __gnu_cxx::__ops::_Iter_equals_val<_Value>::operator()(_Iterator) [with _Iterator = __gnu_cxx::__normal_iterator<std::vector<int>*, std::vector<std::vector<int> > >; _Value = const int]:
/usr/include/c++/10.2.0/bits/stl_algobase.h:1932:14: required from _RandomAccessIterator std::__find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate, std::random_access_iterator_tag) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::vector<int>*, std::vector<std::vector<int> > >; _Predicate = __gnu_cxx::__ops::_Iter_equals_val<const int>]
/usr/include/c++/10.2.0/bits/stl_algobase.h:1977:23: required from _Iterator std::__find_if(_Iterator, _Iterator, _Predicate) [with _Iterator = __gnu_cxx::__normal_iterator<std::vector<int>*, std::vector<std::vector<int> > >; _Predicate = __gnu_cxx::__ops::_Iter_equals_val<const int>]
/usr/include/c++/10.2.0/bits/stl_algo.h:3902:28: required from _IIter std::find(_IIter, _IIter, const _Tp&) [with _IIter = __gnu_cxx::__normal_iterator<std::vector<int>*, std::vector<std::vector<int> > >; _Tp = int]
error.cpp:7:87: required from here
/usr/include/c++/10.2.0/bits/predefined_ops.h:268:17: error: no match for operator== (operand types are std::vector<int> and const int)
268 | { return *__it == _M_value; }
| ~~~~~~^~~~~~~~~~~
In file included from /usr/include/c++/10.2.0/bits/stl_algobase.h:67,
from /usr/include/c++/10.2.0/vector:60,
from error.cpp:1:
/usr/include/c++/10.2.0/bits/stl_iterator.h:1064:5: note: candidate: template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator==(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)
1064 | operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
| ^~~~~~~~
/usr/include/c++/10.2.0/bits/stl_iterator.h:1064:5: note: template argument deduction/substitution failed:</samp></pre></li><li>If you forget a semicolon…<p>Credit goes to <a href="https://codegolf.stackexchange.com/a/205268/98955">this StackExchange answer</a>.</p><pre><code>constexpr double pi = 3.0 // An engineer approximation
#include &lt;iostream&gt;
int main() {
std::cout &lt;&lt; "Enter the radius: " &lt;&lt; std::flush;
double radius;
std::cin &gt;&gt; radius;
std::cout &lt;&lt; "Area: " &lt;&lt; pi * radius * radius &lt;&lt; std::endl;
}</code></pre><a href="https://tio.run/##ZY7NCsIwEITveYpBLypoBW9tLXjwQWKy6kK7CfkBQXz2WrXVg7dl@PabMd6vL8b0vXESE918gHX51BI8Y4/dZouiwEFAcmEhCtDeB3fjTid2otScxbTZEmp2MQXSXaMUS0KnWRZL3BUQky1L43JCXWN2lDRo0pUQtOUcS8xe@Rs6tzleq@FlHPEhqq@DBU3zl07mw1A/2ob1q5H7HVMLiW0r9ej7Jw">Try it online!</a><p>The error message (compiled with GCC 10.2.0) has 3244 lines with about 250 kB of content, starting with:</p><pre><samp>In file included from /usr/include/c++/10.2.0/iostream:38,
from error.cpp:3:
/usr/include/c++/10.2.0/x86_64-pc-linux-gnu/bits/c++config.h:258:1: error: expected , or ; before namespace
258 | namespace std
| ^~~~~~~~~
In file included from /usr/include/c++/10.2.0/iosfwd:40,
from /usr/include/c++/10.2.0/ios:38,
from /usr/include/c++/10.2.0/ostream:38,
from /usr/include/c++/10.2.0/iostream:39,
from error.cpp:3:
/usr/include/c++/10.2.0/bits/postypes.h:98:11: error: ptrdiff_t does not name a type
98 | typedef ptrdiff_t streamsize; // Signed integral type
| ^~~~~~~~~
/usr/include/c++/10.2.0/bits/postypes.h:41:1: note: ptrdiff_t is defined in header &lt;cstddef&gt;; did you forget to #include &lt;cstddef&gt;?
40 | #include &lt;cwchar&gt; // For mbstate_t
+++ |+#include &lt;cstddef&gt;
41 |
In file included from /usr/include/c++/10.2.0/bits/exception_ptr.h:40,
from /usr/include/c++/10.2.0/exception:147,
from /usr/include/c++/10.2.0/ios:39,
from /usr/include/c++/10.2.0/ostream:38,
from /usr/include/c++/10.2.0/iostream:39,
from error.cpp:3:
/usr/include/c++/10.2.0/new:126:26: error: declaration of operator new as non-function
126 | _GLIBCXX_NODISCARD void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc)
| ^~~~~~~~
/usr/include/c++/10.2.0/new:126:44: error: size_t is not a member of std; did you mean size_t?
126 | _GLIBCXX_NODISCARD void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc)
| ^~~~~~</samp></pre><p>I guess the fourth line does tell you that you missed a semicolon (if you have the patience to scroll to it), but it's not exactly clear where.</p></li><li>Would you prefer an error that I actually encountered? Here is a simplified version of some code I wrote in a programming contest:<pre><code>#include &lt;algorithm&gt;
#include &lt;iostream&gt;
#include &lt;numeric&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
std::string decrypt(std::string& k, std::string& m) {
std::vector&lt;std::string&gt; c(k.length());
int n = m.length() % k.length() == 0 ? m.length() / k.length() : m.length() / k.length() + 1;
int a = 0;
for (std::string& s : c) {
for (int i = 0; i &lt; n; i++) {
s += a &gt;= m.length() ? ' ' : m[a];
a++;
}
}
std::vector&lt;int&gt; j(k.length());
std::iota(j.begin(), j.end(), 0);
std::sort(j.begin(), j.end(), [&k](int x, int y) { return k[x] &lt; k[y]; });
std::vector&lt;int&gt; q(k.length());
for (int i = 0; i &lt; k.length(); i++) {
q[j[i]] = i;
}
std::string r = "";
for (int i = 0; i &lt; n; i++) {
for (int ii = 0; ii &lt; k.length(); ii++) {
char h = c[q[ii]][i];
if (c != ' ') {
r += c;
}
}
}
return r;
}
int main() {
std::string k;
std::getline(std::cin, k);
std::string m;
std::getline(std::cin, m);
std::cout &lt;&lt; decrypt(k, m) &lt;&lt; std::endl;
}</code></pre><a href="https://tio.run/##fZPbboMwDIbveQqv0zYQrOtuy6EPgrhgaQrhENoQplYTz87MqQldOyFE8P/F/LYDOR7fE0K67plxUjR7Cl5cJJVgMi0DQwVZVUtB40WMNyUVjOghhBhP9Mg3JbISgWHUcr/djjrsKRGXozS12CvkDizeSwt@DBhjYxZP0wMgZr4uKE9kalqWiyTjEjj4UF7D8AKKAd@HDex0@UOXtw8VGz7n/DHm3/Qvh0rA0n@NGcjoeZL7DWzYgA8POD5seyawMrB9TBgsHO/gDS/0EsaRO4GxbY/L1hhvvSf4kQCy214MBKtkbGbrL5owbloOZGvK9/1io5i6EvIuE77m0VDB2Rkqv6BxEFQ2gkMeniMsKA8vkQutSqZbOt1autcShSx6cwqzkEURcszVS56Oj0BhtXqUc9lmRczIn@8uhkLSWECKKAlPIUMTaGSeAzuASeDJ70ekdgD6wUGSmWoXo5o6JlyjNYzeRxn3jVZHe6opvzYxobJgnI6HizDuQK6Na6TLf@hS0aRqJHje9X/Le7UPDCoOukBbXfcL">Try it online!</a><p>The error message does tell you where the error is, but you have to scroll through 228 lines with over 22 kB of content.</p></li></ul></li></ul></body></html>

View File

@ -69,17 +69,214 @@ block content
std::cout &lt;&lt; std::endl;
}
a(href="https://tio.run/##ZY/NTsMwEITveYqRONSRAlIpQSINfRXkOE66wrEj24ED6rMH2/kBxM2e@WZ2V4zjfS/EPN@RFmpqJWoyzlvJh0v2o31I4Y39rXDVG0v@GrCMtMfASbMcXxngfFtVS6IO1gV6Gtx5M0I56R6kxyh9XklJsOT00ivScvkI0kWEChxwyJdipKYHOYyKC/nWcPHO1k5DLMB5Hjtv@yhjPUuRRvZxvWIt0C1b0MYYhY6s83iFt5OMYmcsWLwpwKhSZJtPHVjCNwF7uuPKpXhYADK8d2K5x0wedR2vWaHsnxcm/dl/09MnLK3O2W2eT8cnHEu84PEZJU7lNw") Try it online!
h2 Features
ul
li Despite being a very large language, C++ doesn't have basic features like sum types or pattern matching.
li Many features duplicate other features, adding their own advantages and drawbacks (and more unnecessary syntactic rules to learn). Examples: initializer lists,
code typedef
| /
code using
| ,
code #define
| /
code constexpr
| ,
code char[]
| /
code std::string
| ,
code int[]
| /
code std::array&lt;int&gt;
| ,
code printf
| /
code cout
| ,
code struct
| /
code class
h2 Syntax
p C++ took the horrible syntax of C and somehow managed to make it even worse.
ul
li
| The
li The
a(href="https://en.wikipedia.org/wiki/Most_vexing_parse") most vexing parse
| (and similar rules). I can't fathom what could possibly cause someone to think this is a good idea.
li
a(href="https://blog.reverberate.org/2013/08/parsing-c-is-literally-undecidable.html") Parsing C++ is literally undecidable.
li Using less-than and greater-than signs as brackets, which hinders auto-pairing and complicates parsing while also looking ugly.
li
| Who decided that
li The semicolon after a
code struct
| /
code class
| definition. Just why?
li Keywords that have multiple meanings depending on where you use them:
code static
| ,
code using
| ,
code typename
| .
li The keyword
code const
| is used to declare immutable variables (not constants, for which there is
code constexpr
| ) and it can be placed in various positions inside a type, which completely changes its meaning.
li Who decided that
code ::
| is a good path separator?
h2 Standard library
ul
li Despite being quite extensive, the standard library doesn't have basic things like
ul
li basic functions for working with strings (split, join)
li functional abstractions (map, filter, fold, …) [C++20 partially solves this with “range adaptors” (what a weird name), but the usage is unbearably cumbersome]
li optional/result types
li Using the term “vector” for a resizable array, even though the word has a completely different meaning in mathematics.
li There is no convenient way to pass a whole array/vector/list to a function, you have to do something like
code std::sort(arr.begin(), arr.end())
| .
li Weird function names: from C crypticisms (
code stoi
| ,
code fscanf
| ) to unusual words (
code emplace_back
| ).
h2 Tooling
ul
li Error messages.
ul
li If you try to search a “vector” (array) of a wrong type…
p Credit goes to
a(href="https://codegolf.stackexchange.com/a/10470/98955") this StackExchange answer
| .
pre
code.
#include &lt;vector&gt;
#include &lt;algorithm&gt;
int main() {
int a;
std::vector&lt;std::vector&lt;int&gt;&gt; v;
std::vector&lt;std::vector&lt;int&gt;&gt;::const_iterator it = std::find(v.begin(), v.end(), a);
}
a(href="https://tio.run/##jY1BDoIwEEX3PcUkbiBRDlCwVzF1OtZJoCVl7MZ49lJgoUv/6uXl/3yc54tHLOXEAceXIxgyocRk1NfY0cfE8pyMUhwEJsuhaeGtoGYTtt9xEaf1MR9@uVaMgfxHSWuMYZEbCyVbLbDA9Zg8OLgmd3fy2/kZckdVVLBtrz6lrA") Try it online!
p The error message (compiled with GCC 10.2.0) has 148 lines with about 12 kB of content, starting with:
pre
samp.
In file included from /usr/include/c++/10.2.0/bits/stl_algobase.h:71,
from /usr/include/c++/10.2.0/vector:60,
from error.cpp:1:
/usr/include/c++/10.2.0/bits/predefined_ops.h: In instantiation of bool __gnu_cxx::__ops::_Iter_equals_val<_Value>::operator()(_Iterator) [with _Iterator = __gnu_cxx::__normal_iterator<std::vector<int>*, std::vector<std::vector<int> > >; _Value = const int]:
/usr/include/c++/10.2.0/bits/stl_algobase.h:1932:14: required from _RandomAccessIterator std::__find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate, std::random_access_iterator_tag) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::vector<int>*, std::vector<std::vector<int> > >; _Predicate = __gnu_cxx::__ops::_Iter_equals_val<const int>]
/usr/include/c++/10.2.0/bits/stl_algobase.h:1977:23: required from _Iterator std::__find_if(_Iterator, _Iterator, _Predicate) [with _Iterator = __gnu_cxx::__normal_iterator<std::vector<int>*, std::vector<std::vector<int> > >; _Predicate = __gnu_cxx::__ops::_Iter_equals_val<const int>]
/usr/include/c++/10.2.0/bits/stl_algo.h:3902:28: required from _IIter std::find(_IIter, _IIter, const _Tp&) [with _IIter = __gnu_cxx::__normal_iterator<std::vector<int>*, std::vector<std::vector<int> > >; _Tp = int]
error.cpp:7:87: required from here
/usr/include/c++/10.2.0/bits/predefined_ops.h:268:17: error: no match for operator== (operand types are std::vector<int> and const int)
268 | { return *__it == _M_value; }
| ~~~~~~^~~~~~~~~~~
In file included from /usr/include/c++/10.2.0/bits/stl_algobase.h:67,
from /usr/include/c++/10.2.0/vector:60,
from error.cpp:1:
/usr/include/c++/10.2.0/bits/stl_iterator.h:1064:5: note: candidate: template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator==(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)
1064 | operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
| ^~~~~~~~
/usr/include/c++/10.2.0/bits/stl_iterator.h:1064:5: note: template argument deduction/substitution failed:
li If you forget a semicolon…
p Credit goes to
a(href="https://codegolf.stackexchange.com/a/205268/98955") this StackExchange answer
| .
pre
code.
constexpr double pi = 3.0 // An engineer approximation
#include &lt;iostream&gt;
int main() {
std::cout &lt;&lt; "Enter the radius: " &lt;&lt; std::flush;
double radius;
std::cin &gt;&gt; radius;
std::cout &lt;&lt; "Area: " &lt;&lt; pi * radius * radius &lt;&lt; std::endl;
}
a(href="https://tio.run/##ZY7NCsIwEITveYpBLypoBW9tLXjwQWKy6kK7CfkBQXz2WrXVg7dl@PabMd6vL8b0vXESE918gHX51BI8Y4/dZouiwEFAcmEhCtDeB3fjTid2otScxbTZEmp2MQXSXaMUS0KnWRZL3BUQky1L43JCXWN2lDRo0pUQtOUcS8xe@Rs6tzleq@FlHPEhqq@DBU3zl07mw1A/2ob1q5H7HVMLiW0r9ej7Jw") Try it online!
p The error message (compiled with GCC 10.2.0) has 3244 lines with about 250 kB of content, starting with:
pre
samp.
In file included from /usr/include/c++/10.2.0/iostream:38,
from error.cpp:3:
/usr/include/c++/10.2.0/x86_64-pc-linux-gnu/bits/c++config.h:258:1: error: expected , or ; before namespace
258 | namespace std
| ^~~~~~~~~
In file included from /usr/include/c++/10.2.0/iosfwd:40,
from /usr/include/c++/10.2.0/ios:38,
from /usr/include/c++/10.2.0/ostream:38,
from /usr/include/c++/10.2.0/iostream:39,
from error.cpp:3:
/usr/include/c++/10.2.0/bits/postypes.h:98:11: error: ptrdiff_t does not name a type
98 | typedef ptrdiff_t streamsize; // Signed integral type
| ^~~~~~~~~
/usr/include/c++/10.2.0/bits/postypes.h:41:1: note: ptrdiff_t is defined in header &lt;cstddef&gt;; did you forget to #include &lt;cstddef&gt;?
40 | #include &lt;cwchar&gt; // For mbstate_t
+++ |+#include &lt;cstddef&gt;
41 |
In file included from /usr/include/c++/10.2.0/bits/exception_ptr.h:40,
from /usr/include/c++/10.2.0/exception:147,
from /usr/include/c++/10.2.0/ios:39,
from /usr/include/c++/10.2.0/ostream:38,
from /usr/include/c++/10.2.0/iostream:39,
from error.cpp:3:
/usr/include/c++/10.2.0/new:126:26: error: declaration of operator new as non-function
126 | _GLIBCXX_NODISCARD void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc)
| ^~~~~~~~
/usr/include/c++/10.2.0/new:126:44: error: size_t is not a member of std; did you mean size_t?
126 | _GLIBCXX_NODISCARD void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc)
| ^~~~~~
p I guess the fourth line does tell you that you missed a semicolon (if you have the patience to scroll to it), but it's not exactly clear where.
li Would you prefer an error that I actually encountered? Here is a simplified version of some code I wrote in a programming contest:
pre
code.
#include &lt;algorithm&gt;
#include &lt;iostream&gt;
#include &lt;numeric&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
std::string decrypt(std::string& k, std::string& m) {
std::vector&lt;std::string&gt; c(k.length());
int n = m.length() % k.length() == 0 ? m.length() / k.length() : m.length() / k.length() + 1;
int a = 0;
for (std::string& s : c) {
for (int i = 0; i &lt; n; i++) {
s += a &gt;= m.length() ? ' ' : m[a];
a++;
}
}
std::vector&lt;int&gt; j(k.length());
std::iota(j.begin(), j.end(), 0);
std::sort(j.begin(), j.end(), [&k](int x, int y) { return k[x] &lt; k[y]; });
std::vector&lt;int&gt; q(k.length());
for (int i = 0; i &lt; k.length(); i++) {
q[j[i]] = i;
}
std::string r = "";
for (int i = 0; i &lt; n; i++) {
for (int ii = 0; ii &lt; k.length(); ii++) {
char h = c[q[ii]][i];
if (c != ' ') {
r += c;
}
}
}
return r;
}
int main() {
std::string k;
std::getline(std::cin, k);
std::string m;
std::getline(std::cin, m);
std::cout &lt;&lt; decrypt(k, m) &lt;&lt; std::endl;
}
a(href="https://tio.run/##fZPbboMwDIbveQqv0zYQrOtuy6EPgrhgaQrhENoQplYTz87MqQldOyFE8P/F/LYDOR7fE0K67plxUjR7Cl5cJJVgMi0DQwVZVUtB40WMNyUVjOghhBhP9Mg3JbISgWHUcr/djjrsKRGXozS12CvkDizeSwt@DBhjYxZP0wMgZr4uKE9kalqWiyTjEjj4UF7D8AKKAd@HDex0@UOXtw8VGz7n/DHm3/Qvh0rA0n@NGcjoeZL7DWzYgA8POD5seyawMrB9TBgsHO/gDS/0EsaRO4GxbY/L1hhvvSf4kQCy214MBKtkbGbrL5owbloOZGvK9/1io5i6EvIuE77m0VDB2Rkqv6BxEFQ2gkMeniMsKA8vkQutSqZbOt1autcShSx6cwqzkEURcszVS56Oj0BhtXqUc9lmRczIn@8uhkLSWECKKAlPIUMTaGSeAzuASeDJ70ekdgD6wUGSmWoXo5o6JlyjNYzeRxn3jVZHe6opvzYxobJgnI6HizDuQK6Na6TLf@hS0aRqJHje9X/Le7UPDCoOukBbXfcL") Try it online!
p The error message does tell you where the error is, but you have to scroll through 228 lines with over 22 kB of content.

View File

@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>Language Criticism | xigoi</title></head><body><a href="/"><header><svg id="xigoi-logo" width="20" height="20" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>Language Criticism</h1><p>Here I'm going to criticize all kinds of languages: spoken languages, programming languages, markup languages, etc. Prepare your pitchforks.</p><h2>Programming language constructs</h2><ul><li><a href="braces-semicolons.html">Braces &amp; Semicolons</a></li></ul><h2>Programming languages</h2><ul><li><a href="c.html">C</a></li><li class="wip"><a href="cpp.html">C++</a></li></ul></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>Language Criticism | xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>Language Criticism</h1><p>Here I'm going to criticize all kinds of languages: spoken languages, programming languages, markup languages, etc. Prepare your pitchforks.</p><h2>Programming language constructs</h2><ul class="index"><li><a href="braces-semicolons.html">Braces &amp; Semicolons</a></li></ul><h2>Programming languages</h2><ul class="index"><li><a href="c.html">C</a></li><li><a href="cpp.html">C++</a></li><li><a href="python.html">Python</a></li></ul></body></html>

View File

@ -7,12 +7,14 @@ block content
h1 Language Criticism
p Here I'm going to criticize all kinds of languages: spoken languages, programming languages, markup languages, etc. Prepare your pitchforks.
h2 Programming language constructs
ul
ul.index
li
a(href="braces-semicolons.html") Braces &amp; Semicolons
h2 Programming languages
ul
ul.index
li
a(href="c.html") C
li.wip
li
a(href="cpp.html") C++
li
a(href="python.html") Python

View File

@ -0,0 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>Python | Language Criticism | xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>Python Language Criticism</h1><p>I like Python. It's a very easy to use language with clean syntax and a rich library system. However, there are several things I don't exactly like about it, which I'm going to cover here.</p><h2>General Characteristics</h2><ul><li>Python is dynamically typed. That used to be a great thing, but now that most statically typed languages have type inference, dynamic typing has pretty much only drawbacks. Yes, there are type annotations and MyPy, but you can't always rely on them, especially if using a library that doesn't have annotations.</li></ul><h2>Language Features</h2><ul><li>There are no enums, instead strings are used for their purpose, which is slow and error-prone.</li><li>Why are decorators limited to functions and classes? They would be useful for other things.</li></ul><h2>Syntax</h2><ul><li>Anonymous functions require a long keyword (which would sometimes be useful as a variable name) and they're restricted to a single expression. Note that, contrary to popular belief, this limitation is not a consequence of indentation-based syntax: CoffeeScript and Nim, which are both indentation-based, manage to have multiple-statement anonymous functions just fine.</li><li>The syntax for conditional expressions has the condition in the middle, which looks jumbled up.</li><li>In comprehensions, <code>for</code> loops are written in reverse order than normal (first inner, then outer).</li><li>The distinction between statements and expressions is quite unnecessary. See Ruby as an example of a language which is similar to Python, but takes the “everything is an expression” approach.</li><li>The set of operators is limited, with no way to define new ones.</li><li>“Dunder” methods are incredibly ugly. Even C++ has better syntax for constructors and operator overloading.</li><li>There's no syntax for documentation comments, but instead… string literals???</li><li>It uses up valuable characters for bitwise operators, which are very rarely needed in high-level programming. Especially <code>^</code> would be useful for exponentiation. Bitwise operators could very well be functions tucked away in a standard library module.</li></ul><h2>Built-ins & Standard library</h2><ul><li>The language is really inconsistent about what is a function and what is a method. For example, <code>lst.sort()</code>, but <code>sorted(lst)</code>. And some of these functions actually just call a method with the same name, but surrounded in double underscores! What's the point of that? Why not just directly make it a method?</li><li>The <code>unittest</code> module uses <code>camelCase</code> identifiers, even though the language convention is <code>snake_case</code>. How does something like this even happen? Did nobody catch this in the review? If they even have a review process?<p><a href="https://stackoverflow.com/questions/17014763/why-are-unittest2-methods-camelcase-if-names-with-underscores-are-preferred">According to StackOverflow</a>, it's based on some old Smalltalk library. I get that copying a good library from another language is often a good idea, but did it have to be so verbatim that it won't even adapt to the language's most basic conventions?</p></li></ul><h2>Tooling</h2><ul><li>Installation management is <a href="https://xkcd.com/1987/">an absolute chaos</a>.</li></ul></body></html>

View File

@ -0,0 +1,51 @@
extends ../templates/main.jade
block title
| Python | Language Criticism | xigoi
block content
h1 Python Language Criticism
p I like Python. It's a very easy to use language with clean syntax and a rich library system. However, there are several things I don't exactly like about it, which I'm going to cover here.
h2 General Characteristics
ul
li Python is dynamically typed. That used to be a great thing, but now that most statically typed languages have type inference, dynamic typing has pretty much only drawbacks. Yes, there are type annotations and MyPy, but you can't always rely on them, especially if using a library that doesn't have annotations.
h2 Language Features
ul
li There are no enums, instead strings are used for their purpose, which is slow and error-prone.
li Why are decorators limited to functions and classes? They would be useful for other things.
h2 Syntax
ul
li Anonymous functions require a long keyword (which would sometimes be useful as a variable name) and they're restricted to a single expression. Note that, contrary to popular belief, this limitation is not a consequence of indentation-based syntax: CoffeeScript and Nim, which are both indentation-based, manage to have multiple-statement anonymous functions just fine.
li The syntax for conditional expressions has the condition in the middle, which looks jumbled up.
li In comprehensions,
code for
| loops are written in reverse order than normal (first inner, then outer).
li The distinction between statements and expressions is quite unnecessary. See Ruby as an example of a language which is similar to Python, but takes the “everything is an expression” approach.
li The set of operators is limited, with no way to define new ones.
li “Dunder” methods are incredibly ugly. Even C++ has better syntax for constructors and operator overloading.
li There's no syntax for documentation comments, but instead… string literals???
li It uses up valuable characters for bitwise operators, which are very rarely needed in high-level programming. Especially
code ^
| would be useful for exponentiation. Bitwise operators could very well be functions tucked away in a standard library module.
h2 Built-ins & Standard library
ul
li The language is really inconsistent about what is a function and what is a method. For example,
code lst.sort()
| , but
code sorted(lst)
| . And some of these functions actually just call a method with the same name, but surrounded in double underscores! What's the point of that? Why not just directly make it a method?
li The
code unittest
| module uses
code camelCase
| identifiers, even though the language convention is
code snake_case
| . How does something like this even happen? Did nobody catch this in the review? If they even have a review process?
p
a(href="https://stackoverflow.com/questions/17014763/why-are-unittest2-methods-camelcase-if-names-with-underscores-are-preferred") According to StackOverflow
| , it's based on some old Smalltalk library. I get that copying a good library from another language is often a good idea, but did it have to be so verbatim that it won't even adapt to the language's most basic conventions?
h2 Tooling
ul
li Installation management is
a(href="https://xkcd.com/1987/") an absolute chaos
| .

1
logo.html Normal file
View File

@ -0,0 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>xigoi logo | xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>The xigoi logo</h1><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg" style="width: 100%; height: 100%;"><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><p>The shape is meant to be an “x” overlapping with an “i”, drawn with a single stroke — except for the dot, which is singled out. I realized later that it looks like a thinking person, which is a nice coincidence.</p><p>This version of the logo is made in SVG and designed so that the cyan part consists entirely of straight line segments and circular arcs, whose endpoints all lie on a square lattice. The dot lies in the center of the most complete circular arc and is distinguished by both size and color. It was a nice exercise in geometry.</p><p>The colors don't really mean anything, I just like them.</p></body></html>

13
logo.jade Normal file
View File

@ -0,0 +1,13 @@
extends templates/main.jade
block title
| xigoi logo | xigoi
block content
h1 The xigoi logo
svg(id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg" style="width: 100%; height: 100%;")
path(d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1")
circle(cx="5" cy="5" r="1" fill="#f80")
p The shape is meant to be an “x” overlapping with an “i”, drawn with a single stroke — except for the dot, which is singled out. I realized later that it looks like a thinking person, which is a nice coincidence.
p This version of the logo is made in SVG and designed so that the cyan part consists entirely of straight line segments and circular arcs, whose endpoints all lie on a square lattice. The dot lies in the center of the most complete circular arc and is distinguished by both size and color. It was a nice exercise in geometry.
p The colors don't really mean anything, I just like them.

View File

@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>Not Found | xigoi</title></head><body><a href="/"><header><svg id="xigoi-logo" width="20" height="20" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>404 Not Found</h1><p>Sorry, this page doesn't exist on my website. Would you like to go to the <a href="/">main page</a>?</p></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>Not Found | xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>404 Not Found</h1><p>Sorry, this page doesn't exist on my website. Sometimes I move things around, so it's possible that it's somewhere else now. Would you like to go to the <a href="/">main page</a> and try to find it?</p></body></html>

View File

@ -6,6 +6,6 @@ block title
block content
h1 404 Not Found
p
| Sorry, this page doesn't exist on my website. Would you like to go to the
| Sorry, this page doesn't exist on my website. Sometimes I move things around, so it's possible that it's somewhere else now. Would you like to go to the
a(href="/") main page
| ?
| and try to find it?

View File

@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>Opinions | xigoi</title></head><body><a href="/"><header><svg id="xigoi-logo" width="20" height="20" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>Opinions</h1><p>Here are some of my opinions that could be considered controversial. Fell free to argue about them with me.</p><h2>Casual</h2><ul><li>Pineapple pizza is the best pizza.</li><li>Teeth should be brushed after breakfast, not before.</li></ul><h2>Mathematics</h2><ul><li>0 is a Natural number.</li><li>The Axiom of Choice is intuitively false.</li></ul><h2>Programming</h2><ul><li>C is a badly designed programming language with ugly syntax.</li><li>Semicolons and braces are syntactic noise and should not be necessary in modern languages.</li><li>Indexing from 0 is <a href="https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html">objectively better</a> than indexing from 1 even if we disregard how it internally works.</li></ul></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>Opinions | xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>Opinions</h1><p>Here are some of my opinions that could be considered controversial. Fell free to argue about them with me.</p><h2>Casual</h2><ul><li>Pineapple pizza is the best pizza.</li><li>Teeth should be brushed after breakfast, not before.</li></ul><h2>Mathematics</h2><ul><li>0 is a Natural number.</li><li>The Axiom of Choice is intuitively false.</li></ul><h2>Programming</h2><ul><li>C is a badly designed programming language with ugly syntax.</li><li>Semicolons and braces are syntactic noise and should not be necessary in modern languages.</li><li>Indexing from 0 is <a href="https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html">objectively better</a> than indexing from 1 even if we disregard how it internally works.</li></ul></body></html>

1
quantum-games.html Normal file
View File

@ -0,0 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><link rel="stylesheet" href="/styles/katex.min.css"><script defer src="/scripts/katex.min.js" onload="renderMathInElement(document.body)"></script><title>Quantum Games | xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><h1>Quantum games</h1><h2>Quantum tic-tac-toe</h2><p>Some time ago, I discovered the game of <a href="https://en.wikipedia.org/wiki/Quantum_tic-tac-toe">quantum tic-tac-toe</a> on Quora. It's played like regular tic-tac-toe, but instead of writing one mark, each player writes two small marks labeled with a unique number, which represent a mark in superposition. There may be multiple small marks in one space and whenever they create a cycle, the player who did not create the cycle can choose the way they will be collapsed — that is, write one regular mark for each pair of small marks in the cycle. If this destroys any other small marks, their counterpart will also turn into a regular mark, and this can chain. The rulas for winning are as usual — three regular marks in a row. It may even happen that both players win at once.</p><h2>Quantum chess</h2><p>When I played quantum tic-tac-toe with my friend, the idea really intrigued us and we wondered how the same concept could apply to a more complex game. And what better game to use for this purpose than chess? So we quickly decided on the rules, took out a chessboard and started playing. Unfortunately, we didn't finish the game, but here is a rough idea of the rules:</p><ul><li>In their turn, a player can choose between doing a quantum move and a collapse.</li><li>A <dfn>quantum move</dfn> consists of choosing two moves that could be played in regular chess and writing them down. This will create two possible positions. When there are already multiple positions, the player can make any two moves that are valid in <em>some</em> positions and they will be applied to all positions where they're legal.</li><li>With a <dfn>quantum collapse</dfn>, the player can choose a quantum move and discard one of the possible moves, which will also remove all possible positions resulting from this move and makes the other move the reality. If it turns out that some other move is now impossible, it will also be discarded, and this can chain.</li><li>A player wins when the opponent's king is captured in <em>all</em> possible positions. Note that the usual rules of check and checkmate would not get on well with quantum chess where a piece may or may not be somewhere, so all rules associated with check and checkmate (such and the king being unable to move through an endangered position when castling) are done away with.</li></ul><h2>Generalized quantum games</h2><p>We soon realized that these rules are not very precise and result in a lot of ambiguity. Therefore, we decided to formalize them. However, since the quantum part is pretty much separate from the rules of normal chess, why not define it in a way that can be used for all games? (Or at least for all deterministic turn-based games.) Therefore, we came up with the concept of game quantumification.</p><p>First, we need a formal idea of a game. I haven't really studied much game theory, so excuse me for using non-standard definitions and symbols.</p><ul><li>A <dfn>game</dfn> consists of a set of states \(S\) and moves \(M\) and is played by a sequence of players \(P\).</li><li>There is always a current state \(s_c \in S\) and a current player \(p_c \in P\).</li><li>A <dfn>move</dfn> \(m \in M\) is a partial function \(S \to S\).</li><li>There is a set of <dfn>available moves</dfn> \(M_a(s_c,p_c) \subseteq M\) that depends on the current state and player. The set may be empty.</li><li>The current player is allowed to choose one move \(m \in M_a\). The current state is then changed to \(m(s_c)\) and the current played is changed based on rules that depend on the game — usually to the cyclically next player in the sequence \(P\).</li><li>Some states are <dfn>final</dfn>. When the game reaches a final state, certain players win and certain players lose, depending on the game.</li></ul></body></html>

31
quantum-games.jade Normal file
View File

@ -0,0 +1,31 @@
extends templates/main.jade
block head
include templates/katex.jade
block title
| Quantum Games | xigoi
block content
h1 Quantum games
h2 Quantum tic-tac-toe
p Some time ago, I discovered the game of
a(href="https://en.wikipedia.org/wiki/Quantum_tic-tac-toe") quantum tic-tac-toe
| on Quora. It's played like regular tic-tac-toe, but instead of writing one mark, each player writes two small marks labeled with a unique number, which represent a mark in superposition. There may be multiple small marks in one space and whenever they create a cycle, the player who did not create the cycle can choose the way they will be collapsed — that is, write one regular mark for each pair of small marks in the cycle. If this destroys any other small marks, their counterpart will also turn into a regular mark, and this can chain. The rulas for winning are as usual — three regular marks in a row. It may even happen that both players win at once.
h2 Quantum chess
p When I played quantum tic-tac-toe with my friend, the idea really intrigued us and we wondered how the same concept could apply to a more complex game. And what better game to use for this purpose than chess? So we quickly decided on the rules, took out a chessboard and started playing. Unfortunately, we didn't finish the game, but here is a rough idea of the rules:
ul
li In their turn, a player can choose between doing a quantum move and a collapse.
li A <dfn>quantum move</dfn> consists of choosing two moves that could be played in regular chess and writing them down. This will create two possible positions. When there are already multiple positions, the player can make any two moves that are valid in <em>some</em> positions and they will be applied to all positions where they're legal.
li With a <dfn>quantum collapse</dfn>, the player can choose a quantum move and discard one of the possible moves, which will also remove all possible positions resulting from this move and makes the other move the reality. If it turns out that some other move is now impossible, it will also be discarded, and this can chain.
li A player wins when the opponent's king is captured in <em>all</em> possible positions. Note that the usual rules of check and checkmate would not get on well with quantum chess where a piece may or may not be somewhere, so all rules associated with check and checkmate (such and the king being unable to move through an endangered position when castling) are done away with.
h2 Generalized quantum games
p We soon realized that these rules are not very precise and result in a lot of ambiguity. Therefore, we decided to formalize them. However, since the quantum part is pretty much separate from the rules of normal chess, why not define it in a way that can be used for all games? (Or at least for all deterministic turn-based games.) Therefore, we came up with the concept of game quantumification.
p First, we need a formal idea of a game. I haven't really studied much game theory, so excuse me for using non-standard definitions and symbols.
ul
li A <dfn>game</dfn> consists of a set of states \(S\) and moves \(M\) and is played by a sequence of players \(P\).
li There is always a current state \(s_c \in S\) and a current player \(p_c \in P\).
li A <dfn>move</dfn> \(m \in M\) is a partial function \(S \to S\).
li There is a set of <dfn>available moves</dfn> \(M_a(s_c,p_c) \subseteq M\) that depends on the current state and player. The set may be empty.
li The current player is allowed to choose one move \(m \in M_a\). The current state is then changed to \(m(s_c)\) and the current played is changed based on rules that depend on the game — usually to the cyclically next player in the sequence \(P\).
li Some states are <dfn>final</dfn>. When the game reaches a final state, certain players win and certain players lose, depending on the game.

View File

@ -7,17 +7,18 @@
margin-right: 2mm;
}
a[href^="mailto:"]::after, a[href^="https://en.wikipedia.org/"]::after, a[href^="https://www.reddit.com/"]::after, a[href^="https://www.linux.com/"]::after, a[href^="http://"]::after, a[href^="https://"]::after {
a[href^="mailto:"]::after, a[href^="https://en.wikipedia.org/"]::after, a[href^="http://"]::after, a[href^="https://"]::after {
font-family: IcoFont;
}
@font-face {
font-family: Merriweather;
src: url(fonts/Merriweather-Regular.woff);
src: url(/styles/fonts/Merriweather-Regular.woff);
font-display: swap;
}
@font-face {
font-family: IcoFont;
src: url(fonts/icofont.woff2), url(fonts/icofont.woff);
src: url(/styles/fonts/icofont.woff2), url(/styles/fonts/icofont.woff);
}
a {
color: #0e0;
@ -28,14 +29,6 @@ a[href^="http://"]::after, a[href^="https://"]::after {
content: " ";
}
a[href^="https://www.linux.com/"]::after {
content: " ";
}
a[href^="https://www.reddit.com/"]::after {
content: " ";
}
a[href^="https://en.wikipedia.org/"]::after {
content: " ";
}
@ -56,9 +49,14 @@ body {
line-height: 1.4;
}
pre {
background-color: #002;
padding: 2mm;
figure {
display: flex;
flex-direction: column;
align-items: center;
}
figure figcaption {
color: #999;
font-size: 10pt;
}
h1, h2, h3, h4, h5, h6 {
@ -75,6 +73,15 @@ header {
font-size: 36pt;
}
pre {
overflow-x: auto;
padding: 2mm;
}
pre, code {
background-color: #002;
}
.comparison {
display: flex;
flex-direction: row;

View File

@ -10,11 +10,12 @@
@font-face
font-family: Merriweather
src: url(fonts/Merriweather-Regular.woff)
src: url(/styles/fonts/Merriweather-Regular.woff)
font-display: swap
@font-face
font-family: IcoFont
src: url(fonts/icofont.woff2), url(fonts/icofont.woff)
src: url(/styles/fonts/icofont.woff2), url(/styles/fonts/icofont.woff)
a
color: #0e0
@ -25,16 +26,6 @@ a[href^="http://"], a[href^="https://"]
&::after
content: " \ef1f"
a[href^="https://www.linux.com/"]
@extend %external-link
&::after
content: " \e900"
a[href^="https://www.reddit.com/"]
@extend %external-link
&::after
content: " \ed62"
a[href^="https://en.wikipedia.org/"]
@extend %external-link
&::after
@ -56,9 +47,13 @@ body
text-align: justify
line-height: 1.4
pre
background-color: #002
padding: 2mm
figure
display: flex
flex-direction: column
align-items: center
figcaption
color: #999
font-size: 10pt
h1, h2, h3, h4, h5, h6
color: #f80
@ -72,6 +67,13 @@ header
margin-bottom: 1cm
font-size: 36pt
pre
overflow-x: auto
padding: 2mm
pre, code
background-color: #002
.comparison
display: flex
flex-direction: row

15
styles/mathsessions.css Normal file
View File

@ -0,0 +1,15 @@
.has-background {
padding: 3mm;
}
.has-light-blue-background-color {
background-color: #003567;
}
.has-bright-red-background-color {
background-color: #9c0000;
}
.has-yellow-background-color {
background-color: #735900;
}

11
styles/mathsessions.sass Normal file
View File

@ -0,0 +1,11 @@
.has-background
padding: 3mm
.has-light-blue-background-color
background-color: #003567
.has-bright-red-background-color
background-color: #9c0000
.has-yellow-background-color
background-color: #735900

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,16 @@ block title
block content
h1 Susan and Male Privilege
p.disclaimer This story is completely fictional. Take whatever you want from it.
p “Men are so privileged.” Susan closed the browser tab with Huffington Post because the newest feminist article criticizing the construction of a unisex shelter for domestic violence victims made her shake with rage. She put her phone into her pocket and continued walking through the marketplace. “I with I could experience being a man. I would show them how to use the privilege correctly!” she muttered to herself.
p “Then I have something exactly for you,” an old man sitting inside an aged wooden stall said slowly in a slightly unsettling voice. Susan turned to him with a disgusted expression and shouted: “Look at this <em>white male</em> with an opinion! Stop mansplaining!” The man, completely untouched by her hostility, slowly handed over an item from his stall. “This is the Monkey's Paw. It can grant you any with you want.” Susan rolled her eyes. As a Sagittarius, she didn't believe in such superstitions. “I'm not giving any money to a man. You're already rich because of the wage gap, so you should be giving money to me.” “I don't need money,” said the man. “I'll happily let you use it for free. But be careful what you wish for, wishes always come with unexpected consequences.”
p Susan thought — what unexpected consequences could come with being a man? They have literally everything handed to them on a silver platter. “Fine, I'll try it. Monkey's Paw, I would like to become a man. And make it so that people forget that I used to be a woman.” The paw suddenly curled one of its fingers. Susan started feeling weird. Her waist got narrower. Her chest got wider, but the breasts disappeared and left only the nipples behind. She felt various parts of her body getting covered in hair. And her genitalia completely changed shape. She became… Sean.
p “Wow, it wor… AAAAAH!” he screamed as he realized that his voice had become rougher. “It's okay, I'll get used to this.” He threw another disgusted look at the stallkeeper — who was still a white male after all — and began walking home, excited to try out his newly acquired privilege. He decided that he's going to go through the shady neighborhood, where some random men would call him beautiful when he was a woman. Finally he doesn't have to worry about that!
p “Hey, mate.” Sean was approached by a dirty and stinky guy in a black hoodie. “I ain't ate nothing today, would you spare some money for me?” Normally Sean wouldn't give him anything to avoid supporting his male privilege, but since now he was a man too, there was no power imbalance and he might as well do it. He took out his wallet and before he could think about how much money he's going to give, the beggar snatched the wallet out of his hands and ran away.
p Sean was baffled. “Í thought men were immune to crimes when walking in a shady neighborhood!” After recovering from the shock, he decided that he won't make much out of it. The wallet had the key to his house, but his boyfriend had a backup key, so he could just… and thinking about that, he realized that he doesn't feel attracted to his boyfriend anymore. In fact, the thought of having sex with him was kind of disgusting. “I guess I'll have to find a girlfriend now. Surely that won't be a problem… After all, I used to be a woman, so I know exactly how they work.”
p “Hi, Andy,” Sean said after a tall, handsome man opened the door for him. “Heya, Sean,” Andrew replied. As per the wish, he had forgotten that they had ever been in a romantic relationship. “What brings you here? I have two of my bitches here right now, so I'm quite busy.” “No problem, I just lost my wallet today, so I need—” Before Sean could finish his sentence, a young woman came into the room and looked at him with a disgusted face. “What is this ugly goblin doing here?” Sean was dumbfounded. As a woman, he had never been called ugly. Did the change make him less attractive? Fortunately, Andrew came to his rescue. “Shut up, whore, or I'll give you another smack in the face!” Has he always been this mean to his girlfriends?
p Having received the backup key, Sean went home and decided to call the locksmith straight away to get a new lock. While waiting for her to arrive, he went to check the mail. “Conscription Notice,” he read. What? Apparently, he was required to serve in the national army for two years, without getting paid — or else he would go to prison! Before he could think much about it, the locksmith arrived. She changed his lock, gave him a new pair of keys, and then demanded payment. Sean's face went pale when he realized that all his money was in the wallet. Fortunately, he had a backup plan that has previosly always worked in such situations. “Ahem… do you accept sex as payment?”
p “RAPIST!!!” The woman's voice resonated around the neighborhood. Sean watched in horror as a few people started picking up their phones and calling the police. He had to think of something to save the situation, quick. Just as the police arrived and started inquiring about the situation, a nearby pink-haired person of uncertain gender with a septum ring made a brilliant excuse for him. “This is a trans woman and this TERF is refusing to suck her girldick!” “Y-yeah, right!” Sean confirmed. The locksmith tried to defend herself, but she was promptly given handcuffs and sent to prison.
p “Phew, that was close. I need to get some money so this doesn't happen again.” He worked at BuzzFeed, so feeling inspired by the incident, he decided to write an article about how cisgender people are trash. He had already copy-pasted seven images from Twitter when he got a call from his boss. “Due to a new company policy to promote gender diversity and abolish the wage gap, we're not allowed to have any male employees. You're fired!” Before Sean could say anything, the boss hung up.
p Sean thought about going to his partner and talking about it, but he realized he still doesn't have one. Well, what's a better time to go and find a girlfriend than now? He opened a dating app and started filling out his new profile. He decided that it would be a good idea to base his description on what kind of boyfriend he always wanted as a woman. “I'm a honest and caring feminist guy with a lot of interests. I love writing, music and adventures. I'm looking for a strong woman who can stand up for herself and treats me as inferior.” Perfect.
p After swiping for two hours and not getting a single match, he figured that the app had probably been hacked and decided to try a more traditional form of dating. There was a nice bar close to his home, so he promptly headed there.

View File

@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>xigoi</title></head><body><a href="/"><header><svg id="xigoi-logo" width="20" height="20" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><title>xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a></body></html>

View File

@ -11,9 +11,10 @@ html(lang="en")
block title
| xigoi
body
a(href="/")
a(href="/" aria-label="Go to main page")
header
svg(id="xigoi-logo" width="20" height="20" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg")
svg(id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg")
title xigoi logo
path(d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1")
circle(cx="5" cy="5" r="1" fill="#f80")
.xigoi xigoi

View File

@ -0,0 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/images/xigoi-thicc.svg"><link rel="stylesheet" href="/styles/main.css"><script async src="/scripts/counter.js"></script><link rel="stylesheet" href="/styles/mathsessions.css"><link rel="stylesheet" href="/styles/katex.min.css"><script defer src="/scripts/katex.min.js" onload="renderMathInElement(document.body)"></script><title>xigoi</title></head><body><a href="/" aria-label="Go to main page"><header><svg id="xigoi-logo" viewBox="-7 -2 24 24" xmlns="http://www.w3.org/2000/svg"><title>xigoi logo</title><path d="M 0 20 L 9 8 A 5 5 0 1 0 1 8 L 4 12 A 5 5 0 0 0 8 14 A 2 2 0 0 1 10 16 A 4 4 0 0 1 2 16 A 5 5 0 0 1 3 13 A 10 10 0 0 0 5 7" stroke="#0ff" stroke-width="1"></path><circle cx="5" cy="5" r="1" fill="#f80"></circle></svg><div class="xigoi">xigoi</div></header></a><p class="notice">Tento článek je zkopírován ze stránky <a href="http://mathsessions.klusik.cz/">Matematická setkání</a>.</p></body></html>

View File

@ -0,0 +1,11 @@
extends main.jade
block head
link(rel="stylesheet" href="/styles/mathsessions.css")
include katex.jade
block content
p.notice Tento článek je zkopírován ze stránky
a(href="http://mathsessions.klusik.cz/") Matematická setkání
| .
block article