Kaktovik post
This commit is contained in:
parent
bc627a0db4
commit
e1996a975a
|
@ -0,0 +1,77 @@
|
|||
---
|
||||
date: 2023-04-14
|
||||
title: Kaktovik numerals
|
||||
scripts:
|
||||
- kaktovik.mjs
|
||||
draft: true
|
||||
---
|
||||
|
||||
I just saw a Scientific American article about the recent inclusion in Unicode of the
|
||||
[Kaktovik Numerals](https://en.wikipedia.org/wiki/Kaktovik_numerals),
|
||||
a base-20 counting system invented in 1990 by schoolchildren in northern Alaska.
|
||||
|
||||
Let's do some counting!
|
||||
|
||||
<div class="flex wrap counter" data-min="0" data-max="19">
|
||||
<div>
|
||||
<h3 class="justify-center">Apple-inator</h3>
|
||||
<button class="add" data-amount="-1">- 🍏</button>
|
||||
<button class="add" data-amount="+1">+ 🍏</button>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="justify-center">Apples</h3>
|
||||
<div class="apples"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Seems pretty easy, right?
|
||||
I had it group apples in rows, so it's easier to visually see how many apples you have.
|
||||
|
||||
Let's use 🍊 instead of 🍏🍏🍏🍏🍏,
|
||||
to make it even easier to see how many rows we have.
|
||||
|
||||
<div class="flex wrap counter" data-min="0" data-max="19">
|
||||
<div>
|
||||
<h3 class="justify-center">Apple-inator</h3>
|
||||
<button class="add" data-amount="-1">- 🍏</button>
|
||||
<button class="add" data-amount="+1">+ 🍏</button>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="justify-center">Fruit</h3>
|
||||
<div class="fruit"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="justify-center">Apples</h3>
|
||||
<div class="apples"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
<div class="flex wrap counter" data-min="0" data-max="19">
|
||||
<div>
|
||||
<h3 class="justify-center">Apple-inator</h3>
|
||||
<button class="add" data-amount="-1">- 🍏</button>
|
||||
<button class="add" data-amount="+1">+ 🍏</button>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="justify-center">Kaktovik</h3>
|
||||
<div class="kaktovik justify-left"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="justify-center">Fruit</h3>
|
||||
<div class="fruit"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="justify-center">Apples</h3>
|
||||
<div class="apples"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="justify-center">Arabic</h3>
|
||||
<div class="arabic justify-right"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Can you see how
|
||||
the number of left-and-right lines is the number of complete rows of apples,
|
||||
and the number of up-and-down lines is the number of apples left?
|
|
@ -0,0 +1,113 @@
|
|||
const FruitNumerals = [
|
||||
"", "🍏", "🍏🍏", "🍏🍏🍏", "🍏🍏🍏🍏",
|
||||
"🍊", "🍊🍏", "🍊🍏🍏", "🍊🍏🍏🍏", "🍊🍏🍏🍏🍏",
|
||||
"🍊🍊", "🍊🍊🍏", "🍊🍊🍏🍏", "🍊🍊🍏🍏🍏", "🍊🍊🍏🍏🍏🍏",
|
||||
"🍊🍊🍊", "🍊🍊🍊🍏", "🍊🍊🍊🍏🍏", "🍊🍊🍊🍏🍏🍏", "🍊🍊🍊🍏🍏🍏🍏",
|
||||
]
|
||||
|
||||
const KaktovikNumerals = [
|
||||
"𝋀", "𝋁", "𝋂", "𝋃", "𝋄",
|
||||
"𝋅", "𝋆", "𝋇", "𝋈", "𝋉",
|
||||
"𝋊", "𝋋", "𝋌", "𝋍", "𝋎",
|
||||
"𝋏", "𝋐", "𝋑", "𝋒", "𝋓",
|
||||
]
|
||||
|
||||
function ToNumerals(numerals, n) {
|
||||
let base = numerals.length
|
||||
let its = []
|
||||
if (n < base) {
|
||||
return [numerals[n]]
|
||||
}
|
||||
while (n > 0) {
|
||||
its.unshift(numerals[n % base])
|
||||
n = Math.floor(n / base)
|
||||
}
|
||||
return its
|
||||
}
|
||||
|
||||
function ToFruit(n) {
|
||||
let its = ToNumerals(FruitNumerals, n)
|
||||
let doc = new DocumentFragment()
|
||||
for (let it of its) {
|
||||
let row = doc.appendChild(document.createElement("div"))
|
||||
row.classList.add("row")
|
||||
row.textContent = it
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
function ToKaktovik(n) {
|
||||
let its = ToNumerals(KaktovikNumerals, n)
|
||||
return its.join("")
|
||||
}
|
||||
|
||||
function ToApples(n) {
|
||||
let doc = new DocumentFragment()
|
||||
while (n > 0) {
|
||||
let apples = Math.min(n, 5)
|
||||
let row = doc.appendChild(document.createElement("div"))
|
||||
row.classList.add("row")
|
||||
row.textContent = "🍏".repeat(apples)
|
||||
n -= apples
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
|
||||
class Counter {
|
||||
/**
|
||||
* Initialize a counter element.
|
||||
*
|
||||
* This makes buttons active,
|
||||
* and does an initial render.
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
*/
|
||||
constructor(element, n=1) {
|
||||
this.element = element
|
||||
this.n = n
|
||||
this.min = Number(this.element.dataset.min) || 0
|
||||
this.max = Number(this.element.dataset.max) || Infinity
|
||||
|
||||
for (let e of this.element.querySelectorAll("button.add")) {
|
||||
let amount = Number(e.dataset.amount) || 1
|
||||
e.addEventListener("click", e => this.add(e, amount))
|
||||
}
|
||||
this.render()
|
||||
}
|
||||
|
||||
add(event, amount) {
|
||||
let n = this.n + amount
|
||||
n = Math.min(n, this.max)
|
||||
n = Math.max(n, this.min)
|
||||
if (n != this.n) {
|
||||
this.n = n
|
||||
this.render()
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
for (let e of this.element.querySelectorAll(".kaktovik")) {
|
||||
e.textContent = ToKaktovik(this.n)
|
||||
}
|
||||
for (let e of this.element.querySelectorAll(".fruit")) {
|
||||
while (e.firstChild) e.firstChild.remove()
|
||||
e.appendChild(ToFruit(this.n))
|
||||
}
|
||||
for (let e of this.element.querySelectorAll(".apples")) {
|
||||
while (e.firstChild) e.firstChild.remove()
|
||||
e.appendChild(ToApples(this.n))
|
||||
}
|
||||
for (let e of this.element.querySelectorAll(".arabic")) {
|
||||
e.textContent = this.n
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
for (let e of document.querySelectorAll(".counter")) {
|
||||
new Counter(e)
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", init)
|
|
@ -178,6 +178,9 @@ caption {
|
|||
caption-side: bottom;
|
||||
font-size: small;
|
||||
}
|
||||
.jistify-center {
|
||||
text-align: center;
|
||||
}
|
||||
.justify-right, input[type="number"] {
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -203,6 +206,16 @@ caption {
|
|||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.flex.wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
html {
|
||||
background-image: url("../images/bg-dark.jpg");
|
||||
|
|
Loading…
Reference in New Issue