typestar

word_freq.odin in Odin

A word-frequency table from a split iterator, a map, a sort, and a bar chart.

// Count word frequencies in a passage and chart the leaders.
package main

import "core:fmt"
import "core:slice"
import "core:strings"

PASSAGE :: "the rain in maine falls mainly on the plain and " +
    "the rain stays on the plain"

Entry :: struct {
    word:  string,
    count: int,
}

more_first :: proc(a, b: Entry) -> bool {
    return a.count > b.count
}

main :: proc() {
    // Tally every word into a map keyed by its slice of the passage.
    counts := make(map[string]int)
    defer delete(counts)
    rest := PASSAGE
    for word in strings.split_iterator(&rest, " ") {
        counts[word] += 1
    }

    // Pull the entries out and sort by count, biggest first.
    ranked: [dynamic]Entry
    defer delete(ranked)
    for word, n in counts {
        append(&ranked, Entry{word, n})
    }
    slice.sort_by(ranked[:], more_first)

    fmt.println(len(ranked), "distinct words")
    fmt.println("word    ct bar")
    bars := "####################"
    for e in ranked {
        fmt.printfln("%-7s %2d %s", e.word, e.count, bars[:e.count])
    }
}

How it works

  1. split_iterator walks the passage; counts[word] += 1 tallies into the map.
  2. The entries move to a [dynamic]Entry and slice.sort_by ranks them.
  3. Slicing a bar of hashes to e.count draws each word's line.

Keywords and builtins used here

The run, in numbers

Lines
43
Characters to type
955
Tokens
207
Three-star pace
65 tpm

At the three-star pace of 65 tokens a minute, this run takes about 191 seconds.

Type this snippet

Step 1 of 3 in Encore, step 25 of 27 in Language basics.

← Previous Next →