Last active
April 18, 2018 17:05
-
-
Save erochest/75af350bcc96253d47a3f27e553992bc to your computer and use it in GitHub Desktop.
Print 7-digit numbers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(test)] | |
#[cfg(test)] | |
extern crate spectral; | |
extern crate test; | |
/// Takes a string containing a number and increments it in place. Returns whether the operation | |
/// was successful. The only time it isn't successful is if the input is empty or the operation | |
/// overflows. | |
/// | |
/// ```rust | |
/// use print_numbers::increment_string; | |
/// | |
/// let mut number = String::from("000"); | |
/// | |
/// assert!(increment_string(&mut number)); | |
/// assert_eq!(number, String::from("001")); | |
/// | |
/// for _ in 0..10 { | |
/// assert!(increment_string(&mut number)); | |
/// } | |
/// assert_eq!(number, String::from("011")); | |
/// ``` | |
pub fn increment_string(n: &mut str) -> bool { | |
if n.len() == 0 { | |
return false; | |
} | |
unsafe { | |
let n_bytes = n.as_bytes_mut(); | |
let mut i = n_bytes.len() - 1; | |
while n_bytes[i] == b'9' { | |
if i == 0 { | |
return false; | |
} | |
n_bytes[i] = b'0'; | |
i -= 1; | |
} | |
n_bytes[i] += 1; | |
} | |
true | |
} | |
#[cfg(test)] | |
mod tests { | |
use super::*; | |
use spectral::prelude::*; | |
#[test] | |
fn increments_the_right_digit() { | |
let mut buffer = String::from("000"); | |
assert_that(&increment_string(&mut buffer)).is_true(); | |
assert_that(&buffer).is_equal_to(String::from("001")); | |
assert_that(&increment_string(&mut buffer)).is_true(); | |
assert_that(&buffer).is_equal_to(String::from("002")); | |
assert_that(&increment_string(&mut buffer)).is_true(); | |
assert_that(&buffer).is_equal_to(String::from("003")); | |
} | |
#[test] | |
fn carries() { | |
let mut buffer = String::from("009"); | |
assert_that(&increment_string(&mut buffer)).is_true(); | |
assert_that(&buffer).is_equal_to(String::from("010")); | |
let mut buffer = String::from("099"); | |
assert_that(&increment_string(&mut buffer)).is_true(); | |
assert_that(&buffer).is_equal_to(String::from("100")); | |
let mut buffer = String::from("109"); | |
assert_that(&increment_string(&mut buffer)).is_true(); | |
assert_that(&buffer).is_equal_to(String::from("110")); | |
let mut buffer = String::from("199"); | |
assert_that(&increment_string(&mut buffer)).is_true(); | |
assert_that(&buffer).is_equal_to(String::from("200")); | |
} | |
#[test] | |
fn returns_false_when_overflows() { | |
let mut buffer = String::from("998"); | |
assert_that(&increment_string(&mut buffer)).is_true(); | |
assert_that(&increment_string(&mut buffer)).is_false(); | |
} | |
#[test] | |
fn returns_false_on_empty_string() { | |
let mut buffer = String::from(""); | |
assert_that(&increment_string(&mut buffer)).is_false(); | |
} | |
} | |
#[cfg(test)] | |
mod bench { | |
mod iterate { | |
use super::super::*; | |
use test::{black_box, Bencher}; | |
#[bench] | |
fn bench_iterate_format(b: &mut Bencher) { | |
b.iter(|| { | |
(0..1_000_000) | |
.into_iter() | |
.map(|i| format!("{:07}", i)) | |
.for_each(|n| { | |
black_box(n); | |
() | |
}); | |
}); | |
} | |
#[bench] | |
fn bench_for_format(b: &mut Bencher) { | |
b.iter(|| { | |
for i in 0..1_000_000 { | |
black_box(format!("{:07}", &i)); | |
} | |
}); | |
} | |
#[bench] | |
fn bench_mutate_string(b: &mut Bencher) { | |
b.iter(|| { | |
let mut buffer = String::from("0000000"); | |
while increment_string(&mut buffer) { | |
black_box(&buffer); | |
} | |
}); | |
} | |
#[bench] | |
fn bench_mutate_clone(b: &mut Bencher) { | |
b.iter(|| { | |
let mut buffer = String::from("0000000"); | |
while increment_string(&mut buffer) { | |
black_box(buffer.clone()); | |
} | |
}); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
test bench::iterate::bench_for_format ... bench: 115,474,903 ns/iter (+/- 7,441,441) | |
test bench::iterate::bench_iterate_format ... bench: 114,379,497 ns/iter (+/- 8,669,838) | |
test bench::iterate::bench_mutate_clone ... bench: 337,568,166 ns/iter (+/- 24,854,535) | |
test bench::iterate::bench_mutate_string ... bench: 10,936,343 ns/iter (+/- 592,779) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment