Wrote program for Day 66
This commit is contained in:
parent
c43287d0eb
commit
880f4595c9
@ -112,7 +112,7 @@ We encourage you to share your progress and ask questions in the Discussions sec
|
||||
| Day #63 | [The Rabbit Problem](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-09/Day-63_The-Rabbit-Problem) | :white_check_mark: |
|
||||
| Day #64 | [First Recurring Character](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-10/Day-64_First-Recurring-Character) | :white_check_mark: |
|
||||
| Day #65 | [ISBN Validator](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-10/Day-65_ISBN-Validator) | :white_check_mark: |
|
||||
| Day #66 | [ISBN Generator](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-10/Day-66_ISBN-Generator) | :white_large_square: |
|
||||
| Day #66 | [ISBN Generator](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-10/Day-66_ISBN-Generator) | :white_check_mark: |
|
||||
| Day #67 | [Color Maze](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-10/Day-67_Color-Maze) | :white_large_square: |
|
||||
| Day #68 | [Clarence The Slow Typist](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-10/Day-68_Clarence-The-Slow-Typist) | :white_large_square: |
|
||||
| Day #69 | [Garage Door Opener](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-10/Day-69-Garage-Door-Opener) | :white_large_square: |
|
||||
|
7
Week-10/Day-66_ISBN-Generator/day66/Cargo.toml
Normal file
7
Week-10/Day-66_ISBN-Generator/day66/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "day66"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
lazy_static = "1.5.0"
|
83
Week-10/Day-66_ISBN-Generator/day66/src/lib.rs
Normal file
83
Week-10/Day-66_ISBN-Generator/day66/src/lib.rs
Normal file
@ -0,0 +1,83 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref RNG: Arc<Mutex<Rng>> = Arc::new(Mutex::new(Rng::new()));
|
||||
}
|
||||
|
||||
pub fn isbn_generator() -> String {
|
||||
let mut rng = RNG.lock().unwrap();
|
||||
let mut partial_isbn = rng.random_number(1e8 as u128, 1e9 as u128);
|
||||
let mut isbn = partial_isbn.to_string();
|
||||
|
||||
let mut val = 0;
|
||||
let mut counter = 1;
|
||||
while partial_isbn > 0 {
|
||||
counter += 1;
|
||||
val += partial_isbn % 10 * counter;
|
||||
partial_isbn /= 10;
|
||||
}
|
||||
|
||||
isbn.push(if (val + 10) % 11 == 0 {
|
||||
'X'
|
||||
} else if val % 11 == 0 {
|
||||
'0'
|
||||
} else {
|
||||
(11 - val % 11).to_string().chars().last().unwrap()
|
||||
});
|
||||
|
||||
isbn
|
||||
}
|
||||
|
||||
pub fn isbn_validator(digits: &str) -> Result<bool, String> {
|
||||
if digits.len() != 10 {
|
||||
return Err("Invalid length for the ISBN".to_owned());
|
||||
}
|
||||
let mut val: usize = 0;
|
||||
for (i, digit) in digits[..digits.len() - 1].chars().enumerate() {
|
||||
if !digit.is_ascii_digit() {
|
||||
return Err("Only digits allowed".to_owned());
|
||||
}
|
||||
val += (digit as u8 - b'0') as usize * (10 - i);
|
||||
}
|
||||
let digit = digits.chars().last().unwrap();
|
||||
if digit == 'X' {
|
||||
val += 10;
|
||||
} else {
|
||||
val += (digit as u8 - b'0') as usize;
|
||||
}
|
||||
Ok(val % 11 == 0)
|
||||
}
|
||||
|
||||
pub struct Rng {
|
||||
seed: u128,
|
||||
}
|
||||
|
||||
impl Rng {
|
||||
pub fn new() -> Rng {
|
||||
let time_since_epoch = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("Error in getting time")
|
||||
.as_millis();
|
||||
Rng {
|
||||
seed: time_since_epoch,
|
||||
}
|
||||
}
|
||||
|
||||
fn linear_congruent_generator(&mut self, a: u128, c: u128, m: u128) -> u128 {
|
||||
let result = (a * self.seed + c) % m;
|
||||
self.seed = result;
|
||||
result
|
||||
}
|
||||
|
||||
pub fn random_number(&mut self, from: u128, to: u128) -> u128 {
|
||||
let random_number = self.linear_congruent_generator(1103515245, 12345, 2u128.pow(31));
|
||||
(random_number % (to - from)) + from
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Rng {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
14
Week-10/Day-66_ISBN-Generator/day66/src/main.rs
Normal file
14
Week-10/Day-66_ISBN-Generator/day66/src/main.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use std::io::{self, Write};
|
||||
|
||||
use day66::isbn_generator;
|
||||
|
||||
fn main() {
|
||||
let mut _buffer = String::new();
|
||||
println!("Press <enter> to generate a new ISBN, or <c-C> to exit the program");
|
||||
loop {
|
||||
let isbn = isbn_generator();
|
||||
print!("{isbn}");
|
||||
io::stdout().flush().unwrap();
|
||||
io::stdin().read_line(&mut _buffer).unwrap();
|
||||
}
|
||||
}
|
27
Week-10/Day-66_ISBN-Generator/day66/tests/checker.rs
Normal file
27
Week-10/Day-66_ISBN-Generator/day66/tests/checker.rs
Normal file
@ -0,0 +1,27 @@
|
||||
#[cfg(test)]
|
||||
mod checker {
|
||||
use day66::*;
|
||||
|
||||
fn check() {
|
||||
assert!(isbn_validator(isbn_generator().trim()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gen1() {
|
||||
check();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gen10() {
|
||||
for _ in 0..10 {
|
||||
check();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gen100() {
|
||||
for _ in 0..100 {
|
||||
check();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user