OpenViSTAI · Agents · Blockchain · Crypto
Menu
OPENVIST RECIPES

Build sorted integer frequency tables with Rust

Rust

Count repeated bounded numeric values and arrange their counts by numeric key.

Rust code excerpt: Build sorted integer frequency tables with Rust. Version 0.1.0. Read the full recipe for code, sources and recorded test scope.

Count repeated bounded numeric values and arrange their counts by numeric key. Work only with supplied input; this does not contact external services or modify input.

Before you start

  • Save as recipe.rs and compile with Rust 1.99.0: rustc --edition=2021 recipe.rs -o recipe. Uses only the standard library, without Cargo or external crates.
  • Run recipe with no arguments, including no help flag. Supply input through stdin.
  • Reads at most 65537 bytes and rejects input longer than 65536 bytes, stdin-read failures, invalid UTF-8, a leading UTF-8 BOM, and every CR.
  • Splits only at LF and discards exactly empty segments. Before numeric parsing or grouping, enforces at most 100 retained lines and at most 256 UTF-8 bytes per retained line. No trimming or normalization occurs.
  • Each retained line must contain canonical ASCII decimal in 0..1000000. Signs, whitespace, non-ASCII digits, and leading zeroes other than the single digit 0 are rejected.
  • Success exits 0 with no stderr and writes exactly one JSON object followed by a newline. Its frequencies array contains each distinct numeric value once, in ascending numeric order, with counts of retained lines. Empty input or input containing only LF produces {"frequencies":[]}.
  • Invalid arguments, invalid input, and stdin-read failures exit 2 without stdout and attempt to write exactly error: invalid input followed by a newline to stderr. Diagnostics never contain input values.

Build and check

  1. Save the example as recipe.rs.
  2. Compile with Rust 1.99.0 using rustc --edition=2021 recipe.rs -o recipe.
  3. Prepare UTF-8 input.txt following the documented operation-specific conventions.
  4. Run ./recipe < input.txt.
  5. Inspect the JSON result. Exit 2 with exactly error: invalid input followed by a newline on stderr and no stdout identifies rejected input or stdin-read failure. Output-write failures may also exit nonzero, without that diagnostic and potentially after partial stdout; these are outside the input-error guarantee.

Limits to understand

  • Stdin may block while waiting for EOF or until the 65537-byte read bound is reached.
  • Memory use is O(B + L + D), where B is buffered input of at most 65537 bytes, L is at most 100 retained lines, and D is at most 100 distinct values. This includes line references, parsed values, the ordered frequency table, and the output buffer; allocator overhead and capacity rounding add overhead.
  • Successful output exposes every distinct input value and its count and may therefore be sensitive.
  • Memory-allocation and output-write failures are outside the input-error guarantee. Allocation failure may terminate the program. A detected stdout write or flush failure exits 2 without an added diagnostic and may leave partial stdout; a stderr failure may prevent the complete error diagnostic from being written.

Run it

rustc --edition=2021 recipe.rs -o recipe
./recipe < input.txt

Example input

2
1
2
0
1

Expected output

{"frequencies":[[0,1],[1,2],[2,2]]}
INSPECT THE SCRIPT

Inspect, copy and run the documented checks.

This browser preview builds code locally. It does not contact an API or run the code.

Default example ready.

Rust example
use std::io::{self, Read, Write};
use std::collections::BTreeMap;

fn invalid_input() -> ! {
    let _ = io::stderr().lock().write_all(b"error: invalid input\n");
    std::process::exit(2);
}

fn prepare_output() -> Result<String, ()> {
    let stdin = io::stdin();
    let mut reader = stdin.lock().take(65_537);
    let mut input = Vec::new();
    reader.read_to_end(&mut input).map_err(|_| ())?;
    if input.len() > 65_536 {
        return Err(());
    }

    let text = std::str::from_utf8(&input).map_err(|_| ())?;
    if text.starts_with('\u{feff}') || text.contains('\r') {
        return Err(());
    }

    // Enforce all retained-line limits before parsing or grouping values.
    let mut lines = Vec::new();
    for line in text.split('\n') {
        if line.is_empty() {
            continue;
        }
        if line.len() > 256 || lines.len() >= 100 {
            return Err(());
        }
        lines.push(line);
    }

    let mut values = Vec::new();
    for line in lines {
        let bytes = line.as_bytes();
        if bytes.len() > 1 && bytes[0] == b'0' {
            return Err(());
        }
        let mut value = 0u32;
        for &byte in bytes {
            if !byte.is_ascii_digit() {
                return Err(());
            }
            // The previous value is at most 1,000,000, so this cannot overflow.
            value = value * 10 + u32::from(byte - b'0');
            if value > 1_000_000 {
                return Err(());
            }
        }
        values.push(value);
    }

    let mut frequencies = BTreeMap::<u32, u32>::new();
    for value in values {
        *frequencies.entry(value).or_insert(0) += 1;
    }

    let mut output = String::from("{\"frequencies\":[");
    let mut first = true;
    for (value, count) in frequencies {
        if !first {
            output.push(',');
        }
        first = false;
        output.push_str(&format!("[{},{}]", value, count));
    }
    output.push_str("]}\n");
    Ok(output)
}

fn main() {
    if std::env::args_os().skip(1).next().is_some() {
        invalid_input();
    }

    let output = match prepare_output() {
        Ok(output) => output,
        Err(()) => invalid_input(),
    };

    let stdout = io::stdout();
    let mut writer = stdout.lock();
    if writer.write_all(output.as_bytes()).is_err() || writer.flush().is_err() {
        std::process::exit(2);
    }
}
What to verify after running
  • The example must produce the documented JSON result.
  • Empty stdin must produce the documented empty result.
  • Reject extra arguments, malformed UTF-8, a leading BOM, oversized input and unreadable stdin with the fixed input-error diagnostic and no stdout.

Request or format preview

Illustrative preview. No provider response, price or balance is fetched.

Change a setting to inspect the preview.

Official sources and related profiles

    Code license: MIT. Keep the license notice with your copy.

    Example version 0.1.0 · Documentation reviewed 2026-10-14.

    Six independent CLI fixtures and 18 supplementary cases are executed in pinned, offline Rust 1.99.0 containers. These checks do not establish exhaustive correctness or behavior on other versions.