Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

multisetdemo.gno

2.82 Kb · 73 lines
 1// Package multisetdemo is a small gnoweb demo of the bag / frequency counter
 2// provided by the [p/moul/x/daily/multiset](/p/moul/x/daily/multiset/v0)
 3// library: word frequencies, ranking, and multiset algebra.
 4//
 5// It contains no counting logic of its own. Stateless, so Render is
 6// deterministic — which is precisely what the library is for.
 7package multisetdemo
 8
 9import (
10	"strconv"
11	"strings"
12
13	"gno.land/p/moul/x/daily/multiset/v0"
14)
15
16const sample = "the quick brown fox jumps over the lazy dog the fox barks and the dog barks"
17
18// Render renders the demo for gnoweb.
19func Render(path string) string {
20	var b strings.Builder
21	b.WriteString("# Multiset\n\n")
22	b.WriteString("A bag that counts duplicates, demoing the ")
23	b.WriteString("[`p/moul/x/daily/multiset`](/p/moul/x/daily/multiset/v0) library.\n\n")
24
25	m := multiset.FromSlice(strings.Split(sample, " "))
26
27	b.WriteString("## Word frequencies\n\n")
28	b.WriteString("> " + sample + "\n\n")
29	b.WriteString("`" + strconv.Itoa(m.Total()) + "` words, `")
30	b.WriteString(strconv.Itoa(m.Distinct()) + "` distinct.\n\n")
31
32	b.WriteString("## `MostCommon(5)`\n\n")
33	b.WriteString("| rank | word | count |\n|---|---|---|\n")
34	for i, e := range m.MostCommon(5) {
35		b.WriteString("| " + strconv.Itoa(i+1) + " | `" + e.Elem + "` | " +
36			strconv.Itoa(e.Count) + " |\n")
37	}
38	b.WriteString("\nNote the ties. `barks`, `dog` and `fox` all occur twice and are ")
39	b.WriteString("ranked **alphabetically** — the order is count descending, then ")
40	b.WriteString("element ascending. That second key is not decoration: without it the ")
41	b.WriteString("ranking would fall back on map iteration order, which gno leaves ")
42	b.WriteString("unspecified, and two nodes could render different tables.\n\n")
43
44	b.WriteString("## Algebra\n\n")
45	a := multiset.FromSlice([]string{"x", "x", "x", "y"})
46	c := multiset.FromSlice([]string{"x", "x", "z"})
47	b.WriteString("With `A = {x:3, y:1}` and `B = {x:2, z:1}`:\n\n")
48	b.WriteString("| op | meaning | result |\n|---|---|---|\n")
49	b.WriteString("| `Union` | max of each count | " + brief(a.Union(c)) + " |\n")
50	b.WriteString("| `Intersect` | min, common only | " + brief(a.Intersect(c)) + " |\n")
51	b.WriteString("| `Sum` | counts added | " + brief(a.Sum(c)) + " |\n")
52
53	b.WriteString("\n## Removal\n\n")
54	d := multiset.FromSlice([]string{"a", "a", "a"})
55	b.WriteString("Starting from " + brief(d) + ":\n\n")
56	d.Remove("a")
57	b.WriteString("- after `Remove(\"a\")` → " + brief(d) + "\n")
58	d.RemoveN("a", 100)
59	b.WriteString("- after `RemoveN(\"a\", 100)` → " + brief(d) +
60		" — over-removing clears the element instead of going negative\n")
61	return b.String()
62}
63
64func brief(m *multiset.MultiSet) string {
65	if m.IsEmpty() {
66		return "`{}`"
67	}
68	parts := []string{}
69	for _, e := range m.Elements() {
70		parts = append(parts, e+":"+strconv.Itoa(m.Count(e)))
71	}
72	return "`{" + strings.Join(parts, ", ") + "}`"
73}