Skip to content

Instantly share code, notes, and snippets.

@foriequal0
Last active January 13, 2018 12:29
Show Gist options
  • Save foriequal0/a64ad9b2ab54f1ac7bcafbc2b2234a3e to your computer and use it in GitHub Desktop.
Save foriequal0/a64ad9b2ab54f1ac7bcafbc2b2234a3e to your computer and use it in GitHub Desktop.
비밀번호 특수문자 위치 히스토그램
#!/usr/bin/env run-cargo-script
use std::env;
use std::fs::File;
use std::io::{BufReader, BufRead};
use std::collections::HashMap;
use std::vec::Vec;
use std::iter::FromIterator;
fn main()
{
let file_name = env::args().nth(1).expect("First argument should be a file");
let file = File::open(file_name).expect("A File must exist");
let reader = BufReader::new(file);
let mut analysers: Vec<Box<Analyser>> = vec![
Box::new(Total { count: 0 }),
Box::new(NonAlnumPositionHistogram { hists: HashMap::new() }),
];
for line in reader.lines() {
let line = line.expect("Invalid line");
for analyser in &mut analysers {
analyser.feed(&line);
}
}
for analyser in &mut analysers {
println!("=============================================");
analyser.print();
}
}
trait Analyser {
fn feed(&mut self, line: &str);
fn print(&self);
}
struct Total {
count: i32
}
impl Analyser for Total {
fn feed(&mut self, line: &str) {
self.count += 1;
}
fn print(&self) {
println!("Total: ");
println!("{}", self.count);
}
}
const BINS: usize = 40;
struct Hist {
count: i32,
bins: [f64; BINS]
}
impl Hist {
fn new() -> Hist {
Hist {
count: 0,
bins: [0.0; BINS]
}
}
fn update(&mut self, length: i32, index: i32) {
self.count += 1;
let lower = BINS as i32 * index / length;
let upper = {
let x = BINS as i32 * (index + 1) / length;
if x == lower {
x+1
} else {
x
}
};
let weight = 1.0 / (upper - lower) as f64;
for i in lower as usize..upper as usize {
self.bins[i] += weight;
}
}
}
struct NonAlnumPositionHistogram
{
hists: HashMap<char, Hist>
}
impl Analyser for NonAlnumPositionHistogram
{
fn feed(&mut self, line: &str) {
let length = line.chars().count();
for (idx, ch) in line.chars().enumerate() {
if ch.is_alphanumeric() { continue; }
let hist = self.hists.entry(ch).or_insert_with(&Hist::new);
hist.update(length as i32, idx as i32);
}
}
fn print(&self) {
let keys = {
let mut keys = Vec::from_iter(self.hists.iter());
keys.sort_by(|&(_, u), &(_, v)| v.count.cmp(&u.count)); // reverse
Vec::from_iter(keys.iter().map(|&(k, v)| k))
};
println!("Histogram: ");
let height = 10;
for key in &keys {
let hist = &self.hists[key];
let max = hist.bins.iter().max_by(|x, y| x.partial_cmp(y).unwrap()).unwrap();
let bins = hist.bins;
for h in (0..height).rev() {
println!("");
for i in 0..BINS {
if bins[i] >= max * h as f64 / height as f64 {
print!("*");
} else {
print!(" ");
}
}
}
println!("");
println!("{}: {}", key, hist.count);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment