collision_average/
collision_average.rs

1// Copyright (c) 2023 Tony Barbitta
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7use tinyid::TinyId;
8
9const TIMES: usize = 100;
10
11fn main() {
12    println!(
13        "Checking average iterations until collision using N = {TIMES}, this WILL TAKE SEVERAL (OR MORE) MINUTES..."
14    );
15    println!();
16    println!("Progress: 00%");
17    let mut total_iters = 0;
18    for i in 0..TIMES {
19        total_iters += run_until_collision();
20        let percent = ((i + 1) as f64 / TIMES as f64) * 100.0;
21        // Move cursor to beginning of previous line
22        print!("\u{1b}[1F");
23        // Clear from cursor to end of line
24        print!("\u{1b}[2K");
25        // Rewrite progress. This doesn't seem to work with `print!`, it seems to need the `println!`.
26        println!("Progress: {percent:02.0}%");
27    }
28    println!();
29    let avg_iters = total_iters / TIMES;
30    let pretty_iters = avg_iters
31        .to_string()
32        .as_bytes()
33        .rchunks(3)
34        .rev()
35        .map(std::str::from_utf8)
36        .collect::<Result<Vec<&str>, _>>()
37        .unwrap()
38        .join(","); // separator
39    println!("Average iterations until collision after {TIMES} attempts: {pretty_iters}");
40}
41
42fn run_until_collision() -> usize {
43    let mut ids = std::collections::HashSet::new();
44    let mut iters = 0;
45    loop {
46        iters += 1;
47        let id = TinyId::random();
48        if !ids.insert(id) {
49            break;
50        }
51    }
52    iters
53}