Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/std-types/exercise.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ It uses a
to keep track of what values have been seen and how many times each one has
appeared.

The initial version of `Counter` is hardcoded to only work for `u32` values.
The initial version of `Counter` is hardcoded to only work for `char` values.
Make the struct and its methods generic over the type of value being tracked,
that way `Counter` can track any type of value.

Expand All @@ -32,29 +32,29 @@ use std::collections::HashMap;

/// Counter counts the number of times each value of type T has been seen.
struct Counter {
values: HashMap<u32, u64>,
counts: HashMap<char, u64>,
}

impl Counter {
/// Create a new Counter.
fn new() -> Self {
Counter {
values: HashMap::new(),
counts: HashMap::new(),
}
}

/// Count an occurrence of the given value.
fn count(&mut self, value: u32) {
if self.values.contains_key(&value) {
*self.values.get_mut(&value).unwrap() += 1;
fn count(&mut self, value: char) {
if self.counts.contains_key(&value) {
*self.counts.get_mut(&value).unwrap() += 1;
} else {
self.values.insert(value, 1);
self.counts.insert(value, 1);
}
}

/// Return the number of times the given value has been seen.
fn times_seen(&self, value: u32) -> u64 {
self.values.get(&value).copied().unwrap_or_default()
fn times_seen(&self, value: char) -> u64 {
self.counts.get(&value).copied().unwrap_or_default()
}
}

Expand Down
38 changes: 24 additions & 14 deletions src/std-types/exercise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,38 +20,48 @@ use std::hash::Hash;

/// Counter counts the number of times each value of type T has been seen.
struct Counter<T> {
values: HashMap<T, u64>,
counts: HashMap<T, u64>,
}

impl<T: Eq + Hash> Counter<T> {
/// Create a new Counter.
fn new() -> Self {
Counter { values: HashMap::new() }
Counter { counts: HashMap::new() }
}

/// Count an occurrence of the given value.
fn count(&mut self, value: T) {
*self.values.entry(value).or_default() += 1;
fn count(&mut self, item: T) {
*self.counts.entry(item).or_default() += 1;
}

/// Return the number of times the given value has been seen.
fn times_seen(&self, value: T) -> u64 {
self.values.get(&value).copied().unwrap_or_default()
fn times_seen(&self, item: T) -> u64 {
self.counts.get(&item).copied().unwrap_or_default()
}
}

// ANCHOR: main
fn main() {
let mut ctr = Counter::new();
ctr.count(13);
ctr.count(14);
ctr.count(16);
ctr.count(14);
ctr.count(14);
ctr.count(11);
let mut charctr = Counter::new();
charctr.count(' ');
charctr.count('a');
charctr.count('¥');
charctr.count('a');
println!(
"most common character: {:?}",
charctr.counts.keys().max_by_key(|&c| charctr.times_seen(*c))
);

let mut intctr = Counter::new();
intctr.count(13);
intctr.count(14);
intctr.count(16);
intctr.count(14);
intctr.count(14);
intctr.count(11);
Comment on lines +55 to +61

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it'd better to not use ints as the thing we're counting? At least I think it's a little confusing since there's the number we're counting and then the number of times we've seen that number. Maybe have this one count strings instead?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We count strings and characters in the other uses of Counter in main, so I think this is probably clear in context.


for i in 10..20 {
println!("saw {} values equal to {}", ctr.times_seen(i), i);
println!("saw {} values equal to {}", intctr.times_seen(i), i);
}

let mut strctr = Counter::new();
Expand Down