Wrote program for Day 47
This commit is contained in:
parent
ee7740c90d
commit
cd79043caa
@ -93,7 +93,7 @@ We encourage you to share your progress and ask questions in the Discussions sec
|
|||||||
| Day #44 | [Maximum Edge Of A Triangle](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-07/Day-44_Maximum-Edge-Of-A-Triangle) | :white_check_mark: |
|
| Day #44 | [Maximum Edge Of A Triangle](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-07/Day-44_Maximum-Edge-Of-A-Triangle) | :white_check_mark: |
|
||||||
| Day #45 | [Subtract The Swapped Bits...](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-07/Day-45_Subtract-The-Swapped-Bits-Without-Temp-Storage) | :white_check_mark: |
|
| Day #45 | [Subtract The Swapped Bits...](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-07/Day-45_Subtract-The-Swapped-Bits-Without-Temp-Storage) | :white_check_mark: |
|
||||||
| Day #46 | [Hot Pics Of Danny Devito](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-07/Day-46_Hot-Pics-Of-Danny-Devito) | :white_check_mark: |
|
| Day #46 | [Hot Pics Of Danny Devito](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-07/Day-46_Hot-Pics-Of-Danny-Devito) | :white_check_mark: |
|
||||||
| Day #47 | [Zip It](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-07/Day-47_Zip-It) | :white_large_square: |
|
| Day #47 | [Zip It](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-07/Day-47_Zip-It) | :white_check_mark: |
|
||||||
| Day #48 | [Christmas Tree](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-07/Day-48_Christmas-Tree) | :white_large_square: |
|
| Day #48 | [Christmas Tree](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-07/Day-48_Christmas-Tree) | :white_large_square: |
|
||||||
| Day #49 | [Swimming Pool](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-07/Day-49_Swimming-Pool) | :white_large_square: |
|
| Day #49 | [Swimming Pool](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-07/Day-49_Swimming-Pool) | :white_large_square: |
|
||||||
| Day #50 | [Tic Tac Toe](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-08/Day-50_Tic-Tac-Toe) | :white_large_square: |
|
| Day #50 | [Tic Tac Toe](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-08/Day-50_Tic-Tac-Toe) | :white_large_square: |
|
||||||
|
6
Week-07/Day-47_Zip-It/day47/Cargo.toml
Normal file
6
Week-07/Day-47_Zip-It/day47/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "day47"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
109
Week-07/Day-47_Zip-It/day47/src/lib.rs
Normal file
109
Week-07/Day-47_Zip-It/day47/src/lib.rs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fs;
|
||||||
|
use std::io::{BufWriter, Write};
|
||||||
|
|
||||||
|
fn get_bit(byte: u8, position: u8) -> u8 {
|
||||||
|
(byte >> position) & 1
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compress(source: &str, destination: &str) -> Result<(), std::io::Error> {
|
||||||
|
let file_content = fs::read(source)?;
|
||||||
|
|
||||||
|
let mut association = HashMap::new();
|
||||||
|
for char in file_content.iter() {
|
||||||
|
if !association.contains_key(char) {
|
||||||
|
association.insert(char, association.len() as u8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let file = fs::File::create(destination)?;
|
||||||
|
let mut dest_file = BufWriter::new(file);
|
||||||
|
|
||||||
|
let mut occurrence: Vec<_> = association.iter().collect();
|
||||||
|
occurrence.sort_by_key(|&(_, v)| v);
|
||||||
|
|
||||||
|
for (key, _) in occurrence.iter() {
|
||||||
|
dest_file.write_all(&[***key])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest_file.write_all(&[**occurrence.last().unwrap().0])?;
|
||||||
|
|
||||||
|
let nbits = (association.len() as f32).log2().ceil() as u8;
|
||||||
|
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
let mut byte = 0;
|
||||||
|
let mut pos = 0;
|
||||||
|
for char in file_content.iter() {
|
||||||
|
let tmp = association[char];
|
||||||
|
for i in 0..nbits {
|
||||||
|
byte |= get_bit(tmp, i) << (7 - pos);
|
||||||
|
|
||||||
|
pos += 1;
|
||||||
|
if pos == 8 {
|
||||||
|
pos = 0;
|
||||||
|
bytes.push(byte);
|
||||||
|
byte = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if pos != 0 {
|
||||||
|
bytes.push(byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
dest_file.write_all(&bytes)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reverse_bits(mut n: u8) -> u8 {
|
||||||
|
let mut result = 0;
|
||||||
|
for _ in 0..8 {
|
||||||
|
result = (result << 1) | (n & 1);
|
||||||
|
n >>= 1;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn uncompress(source: &str, destination: &str) -> Result<(), std::io::Error> {
|
||||||
|
let file_content = fs::read(source)?;
|
||||||
|
|
||||||
|
let mut association = Vec::new();
|
||||||
|
let mut i = 1;
|
||||||
|
for char in file_content.iter() {
|
||||||
|
if !association.is_empty() && &char == association.last().unwrap() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
association.push(char);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let nbits = (association.len() as f32).log2().ceil() as u8;
|
||||||
|
let bytes = &file_content[i..];
|
||||||
|
|
||||||
|
let mut nbit = 0;
|
||||||
|
let mut current_bits = 0;
|
||||||
|
let mut uncompressed = Vec::new();
|
||||||
|
for byte in bytes {
|
||||||
|
let byte = reverse_bits(*byte);
|
||||||
|
for i in 0..8 {
|
||||||
|
let bit = get_bit(byte, i);
|
||||||
|
current_bits = (current_bits << 1) | bit;
|
||||||
|
nbit += 1;
|
||||||
|
if nbit == nbits {
|
||||||
|
current_bits = reverse_bits(current_bits);
|
||||||
|
current_bits >>= 8 - nbits;
|
||||||
|
uncompressed.push(*association[current_bits as usize]);
|
||||||
|
nbit = 0;
|
||||||
|
current_bits = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let file = fs::File::create(destination)?;
|
||||||
|
let mut dest_file = BufWriter::new(file);
|
||||||
|
|
||||||
|
dest_file.write_all(&uncompressed)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
28
Week-07/Day-47_Zip-It/day47/src/main.rs
Normal file
28
Week-07/Day-47_Zip-It/day47/src/main.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use std::{env, process::exit};
|
||||||
|
|
||||||
|
use day47::{compress, uncompress};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args: Vec<_> = env::args().collect();
|
||||||
|
if args.len() != 4 {
|
||||||
|
eprintln!("Usage: day47 (c|u) <source file> <destination file>");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let f = match args[1].as_str() {
|
||||||
|
"c" => compress,
|
||||||
|
"u" => uncompress,
|
||||||
|
_ => {
|
||||||
|
eprintln!("The first argument should be c (compress) or u (uncompress)");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match f(&args[2], &args[3]) {
|
||||||
|
Ok(_) => println!("Done!"),
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("{}", e);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
50
Week-07/Day-47_Zip-It/day47/tests/compress_uncompress.rs
Normal file
50
Week-07/Day-47_Zip-It/day47/tests/compress_uncompress.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
use day47::{compress, uncompress};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn librs() {
|
||||||
|
assert!(compress("src/lib.rs", "compressed1").is_ok());
|
||||||
|
assert!(uncompress("compressed1", "uncompressed1").is_ok());
|
||||||
|
let original = fs::read("src/lib.rs").unwrap();
|
||||||
|
let uncompressed = fs::read("uncompressed1").unwrap();
|
||||||
|
assert_eq!(original, uncompressed);
|
||||||
|
fs::remove_file("compressed1").unwrap();
|
||||||
|
fs::remove_file("uncompressed1").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mainrs() {
|
||||||
|
assert!(compress("src/main.rs", "compressed2").is_ok());
|
||||||
|
assert!(uncompress("compressed2", "uncompressed2").is_ok());
|
||||||
|
let original = fs::read("src/main.rs").unwrap();
|
||||||
|
let uncompressed = fs::read("uncompressed2").unwrap();
|
||||||
|
assert_eq!(original, uncompressed);
|
||||||
|
fs::remove_file("compressed2").unwrap();
|
||||||
|
fs::remove_file("uncompressed2").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cargotoml() {
|
||||||
|
assert!(compress("Cargo.toml", "compressed3").is_ok());
|
||||||
|
assert!(uncompress("compressed3", "uncompressed3").is_ok());
|
||||||
|
let original = fs::read("Cargo.toml").unwrap();
|
||||||
|
let uncompressed = fs::read("uncompressed3").unwrap();
|
||||||
|
assert_eq!(original, uncompressed);
|
||||||
|
fs::remove_file("compressed3").unwrap();
|
||||||
|
fs::remove_file("uncompressed3").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cargolock() {
|
||||||
|
assert!(compress("Cargo.lock", "compressed4").is_ok());
|
||||||
|
assert!(uncompress("compressed4", "uncompressed4").is_ok());
|
||||||
|
let original = fs::read("Cargo.lock").unwrap();
|
||||||
|
let uncompressed = fs::read("uncompressed4").unwrap();
|
||||||
|
assert_eq!(original, uncompressed);
|
||||||
|
fs::remove_file("compressed4").unwrap();
|
||||||
|
fs::remove_file("uncompressed4").unwrap();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user