From 2256df389f3b13902a95b0bad6b363e3ca2e7882 Mon Sep 17 00:00:00 2001 From: AnthonyMichaelTDM <68485672+AnthonyMichaelTDM@users.noreply.github.com> Date: Fri, 11 Mar 2022 13:45:24 -0800 Subject: [PATCH 1/4] started rust port of 95_weekday --- 95_Weekday/rust/Cargo.toml | 8 ++ 95_Weekday/rust/README.md | 3 + 95_Weekday/rust/src/main.rs | 144 ++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 95_Weekday/rust/Cargo.toml create mode 100644 95_Weekday/rust/README.md create mode 100644 95_Weekday/rust/src/main.rs diff --git a/95_Weekday/rust/Cargo.toml b/95_Weekday/rust/Cargo.toml new file mode 100644 index 00000000..1ec69633 --- /dev/null +++ b/95_Weekday/rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/95_Weekday/rust/README.md b/95_Weekday/rust/README.md new file mode 100644 index 00000000..7e85f9a1 --- /dev/null +++ b/95_Weekday/rust/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM) diff --git a/95_Weekday/rust/src/main.rs b/95_Weekday/rust/src/main.rs new file mode 100644 index 00000000..7f2a143b --- /dev/null +++ b/95_Weekday/rust/src/main.rs @@ -0,0 +1,144 @@ +use std::io::{self, stdout, Write}; + +struct DATE { + month: u32, + day: u32, + year:u32, + day_of_week:u32, +} +impl DATE { + //create one from user input + fn new_from_input(prompt:&str) -> DATE { + //DATA + let mut raw_date: Vec; + //get date + //input loop + loop { + //get user input, + raw_date = get_str_from_user(prompt) + .split(',')//split it up by ',''s + .filter_map(|s| s.parse::().ok()).collect();//convert it to numbers, ignore things that fail + + //if they didn't give enough data + if raw_date.len() == 3 { //is it long enough? (3 elements) + //are each ones valid things? + if (1..=12).contains(&raw_date[0]) { //valid month + if (1..=31).contains(&raw_date[1]) { //valid day + break; + } + } + } + //otherwise, print error message and go again + println!("Invalid date, try again!"); + } + + //create date + let mut date =DATE{ + month:raw_date[0], + day:raw_date[1], + year:raw_date[2], + day_of_week: 0 + }; + date.update_day_of_week(); + //return date + return date + } + + /** + * caluclates the day of the week (1-7) + */ + fn update_day_of_week(&mut self) { + let month_table:[u32;12] = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; + let i1 = (self.year - 1500) / 100; + let a = i1 * 5 + (i1 + 3)/4; + let i2 = a - (a/7) * 7; + let y2 = self.year/100; + let y3 = self.year - y2*100; + let a = y3 / 4 + y3 + self.day + month_table[(self.month - 1) as usize] + i2; + let b = a - (a/7) * 7; + + //adjust weekday and set it + if self.month <= 2 && self.is_leap_year() { + self.day_of_week = b-1; + } else { + self.day_of_week = b; + } + if self.day_of_week == 0 {self.day_of_week = 7;} + + } + + /** + * is the year a leap_year + */ + fn is_leap_year(&self) -> bool{ + if self.year % 4 != 0 { + return false; + } else if self.year %100 != 0 { + return true; + } else if self.year % 400 != 0 { + return false; + } else { + return true; + } + } +} +fn main() { + //DATA + let todays_date: DATE; + let other_date:DATE; + + //print welcome + welcome(); + + //get todays date + todays_date = DATE::new_from_input("ENTER TODAY'S DATE IN THE FORM: 3,24,1979 "); + //check todays date + if todays_date.year < 1582 { + println!("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII."); + return; + } + + //get other date + other_date = DATE::new_from_input("ENTER DAY OF BIRTH (OR OTHER DAY OF INTEREST) (like MM,DD,YYYY)"); + //check other date + if other_date.year < 1582 { + println!("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII."); + return; + } + +} + + +/** + * print welome message + */ +fn welcome() { + println!(" + WEEKDAY + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY + + + + WEEKDAY IS A COMPUTER DEMONSTRATION THAT + GIVES FACTS ABOUT A DATE OF INTEREST TO YOU. + "); +} + +/** + * gets a string from user input + */ +fn get_str_from_user(prompt:&str) -> String { + //DATA + let mut raw_input = String::new(); + + //print prompt + print!("{}",prompt); + //flust std out //allows prompt to be on same line as input + stdout().flush().expect("failed to flush"); + + //get input and trim whitespaces + io::stdin().read_line(&mut raw_input).expect("Failed to read input"); + + //return raw input + return raw_input.trim().to_string(); +} From 9d96f04bde8d5a7e7eb275b5dc506843fc0f2d37 Mon Sep 17 00:00:00 2001 From: AnthonyMichaelTDM <68485672+AnthonyMichaelTDM@users.noreply.github.com> Date: Tue, 15 Mar 2022 13:29:55 -0700 Subject: [PATCH 2/4] more work porting, day of week calculation works --- 95_Weekday/rust/src/main.rs | 121 +++++++++++++++++++++++++++++------- 1 file changed, 100 insertions(+), 21 deletions(-) diff --git a/95_Weekday/rust/src/main.rs b/95_Weekday/rust/src/main.rs index 7f2a143b..02cfe65d 100644 --- a/95_Weekday/rust/src/main.rs +++ b/95_Weekday/rust/src/main.rs @@ -7,7 +7,15 @@ struct DATE { day_of_week:u32, } impl DATE { - //create one from user input + /** + * create new date with given paramets + */ + fn new(month:u32,day:u32,year:u32,day_of_week:u32) -> DATE { + return DATE { month: month, day: day, year: year, day_of_week: day_of_week }; + } + /** + * create date from user input + */ fn new_from_input(prompt:&str) -> DATE { //DATA let mut raw_date: Vec; @@ -46,31 +54,27 @@ impl DATE { /** * caluclates the day of the week (1-7) + * uses the methodology found here: https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html */ fn update_day_of_week(&mut self) { - let month_table:[u32;12] = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5]; - let i1 = (self.year - 1500) / 100; - let a = i1 * 5 + (i1 + 3)/4; - let i2 = a - (a/7) * 7; - let y2 = self.year/100; - let y3 = self.year - y2*100; - let a = y3 / 4 + y3 + self.day + month_table[(self.month - 1) as usize] + i2; - let b = a - (a/7) * 7; - - //adjust weekday and set it - if self.month <= 2 && self.is_leap_year() { - self.day_of_week = b-1; + let day = self.day as isize; + let month = self.month as isize; + let year = self.year as isize; + let century = year/100; + let year_of_century = year - century*100; + let weekday; //as 0-6 + if self.month <= 2 { //if jan or feb + weekday = (day + (2.6 * ((month+10) as f64)-0.2)as isize - 2*century + (year_of_century-1) + (year_of_century-1)/4 + century/4) % 7; } else { - self.day_of_week = b; + weekday = (day + (2.6 * ((month-2) as f64)-0.2)as isize - 2*century + year_of_century + year_of_century/4 + century/4) % 7; } - if self.day_of_week == 0 {self.day_of_week = 7;} - + self.day_of_week=(weekday+1) as u32; //weekday as 1-7 } /** * is the year a leap_year */ - fn is_leap_year(&self) -> bool{ + fn _is_leap_year(&self) -> bool{ if self.year % 4 != 0 { return false; } else if self.year %100 != 0 { @@ -81,23 +85,55 @@ impl DATE { return true; } } + + /** + * calculates the day value, number of days the date represents + */ + fn calc_day_value(&self) -> u32 { + return (self.year*12 + self.month)*31 + self.day; + } + + /** + * returns true if passed date is before this date, false otherwise + */ + fn is_after(&self,other:&DATE) -> bool { + if self.calc_day_value() > other.calc_day_value() { + return true; + } + else { + return false; + } + } } +impl ToString for DATE { + fn to_string(&self) -> String { + return format!("{}/{}/{}",self.month,self.day,self.year); + } +} + + fn main() { //DATA - let todays_date: DATE; + let today_date: DATE; let other_date:DATE; + let delta_date:DATE; //represents the difference between the two dates + let today_value; + let other_day_value; + let mut other_is_today = false; //print welcome welcome(); - + //get todays date - todays_date = DATE::new_from_input("ENTER TODAY'S DATE IN THE FORM: 3,24,1979 "); + today_date = DATE::new_from_input("ENTER TODAY'S DATE IN THE FORM: 3,24,1979 "); //check todays date - if todays_date.year < 1582 { + if today_date.year < 1582 { println!("NOT PREPARED TO GIVE DAY OF WEEK PRIOR TO MDLXXXII."); return; } + println!(); + //get other date other_date = DATE::new_from_input("ENTER DAY OF BIRTH (OR OTHER DAY OF INTEREST) (like MM,DD,YYYY)"); //check other date @@ -106,6 +142,49 @@ fn main() { return; } + //do some calculations + today_value = today_date.calc_day_value(); + other_day_value = other_date.calc_day_value(); + + //print the other date in a nice format + println!( + "{} {} A {}", + other_date.to_string(), + { //use proper tense of To Be + if today_value < other_day_value {"WILL BE"} + else if today_value == other_day_value {other_is_today=true;"IS A"} + else {"WAS A"} + }, + other_date.day_of_week, + ); + + //do nothing if both days are the same, or if the other date is after the first + if other_is_today || other_date.is_after(&today_date) { + return; + } + + //create date representing the difference between the two dates + delta_date = DATE::new( //OVERFLOW ERROR, FIX LATER + today_date.month - other_date.month, + today_date.day - other_date.day, + today_date.year - other_date.year, + 0 + ); + + //print happy birthday message + if delta_date.month == 0 && delta_date.day == 0 { + println!("***HAPPY BIRTHDAY***"); + } + + //print report + print!(" + \tYEARS\tMONTHS\tDAYS + \t-----\t------\t---- + "); + println!("YOUR AGE (IF BIRTHDATE)\t{}\t{}\t{}", delta_date.year,delta_date.month,delta_date.day); + + + } From 90e1aa334fb1788a2ca051d12997d50e6d5e27d8 Mon Sep 17 00:00:00 2001 From: AnthonyMichaelTDM <68485672+AnthonyMichaelTDM@users.noreply.github.com> Date: Thu, 17 Mar 2022 13:30:17 -0700 Subject: [PATCH 3/4] more work with weekdays --- 95_Weekday/rust/src/main.rs | 109 +++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 25 deletions(-) diff --git a/95_Weekday/rust/src/main.rs b/95_Weekday/rust/src/main.rs index 02cfe65d..611e8d46 100644 --- a/95_Weekday/rust/src/main.rs +++ b/95_Weekday/rust/src/main.rs @@ -51,6 +51,30 @@ impl DATE { //return date return date } + /** + * create a new date from a number of days + */ + fn new_from_days(days:u32) -> DATE{ + let mut days_remaining = days; + let d; + let m; + let y; + + //get the years + y=(days_remaining as f64 / 365.25) as u32; + //deduct + days_remaining = (days_remaining as f64 % 365.25) as u32; + + //get months + m=(days_remaining as f64 / 30.437) as u32; + //deduct + days_remaining = (days_remaining as f64 % 30.437) as u32; + + //get days + d = days_remaining; + + return DATE { month: m, day: d, year: y, day_of_week: 0 } + } /** * caluclates the day of the week (1-7) @@ -89,21 +113,35 @@ impl DATE { /** * calculates the day value, number of days the date represents */ - fn calc_day_value(&self) -> u32 { - return (self.year*12 + self.month)*31 + self.day; + fn calc_days(&self) -> u32 { + return (self.year as f64 * 365.25)as u32 + self.month*30 + self.day + self.month/2; } /** - * returns true if passed date is before this date, false otherwise + * calculates the time difference between self and the passed date, */ - fn is_after(&self,other:&DATE) -> bool { - if self.calc_day_value() > other.calc_day_value() { - return true; - } - else { - return false; + fn time_since(&self, other: &DATE) -> Option { + //DATA + // /* + let diff = self.calc_days()as i32 - other.calc_days()as i32; + if diff < 0 { + return None; + } else { + return Some(DATE::new_from_days(diff as u32)); } } + + /** + * formats the date in a different format, used for time table + */ + fn format_ymd(&self, spacer:&str) -> String { + return format!( + "{}{}{}{}{}", + self.year, spacer, + self.month, spacer, + self.day, + ); + } } impl ToString for DATE { fn to_string(&self) -> String { @@ -143,8 +181,8 @@ fn main() { } //do some calculations - today_value = today_date.calc_day_value(); - other_day_value = other_date.calc_day_value(); + today_value = today_date.calc_days(); + other_day_value = other_date.calc_days(); //print the other date in a nice format println!( @@ -152,24 +190,19 @@ fn main() { other_date.to_string(), { //use proper tense of To Be if today_value < other_day_value {"WILL BE"} - else if today_value == other_day_value {other_is_today=true;"IS A"} - else {"WAS A"} + else if today_value == other_day_value {other_is_today=true;"IS"} + else {"WAS"} }, other_date.day_of_week, ); - //do nothing if both days are the same, or if the other date is after the first - if other_is_today || other_date.is_after(&today_date) { + //end if both days are the same + if other_is_today { return; } //create date representing the difference between the two dates - delta_date = DATE::new( //OVERFLOW ERROR, FIX LATER - today_date.month - other_date.month, - today_date.day - other_date.day, - today_date.year - other_date.year, - 0 - ); + delta_date = if let Some(d) = today_date.time_since(&other_date) {d} else {return;}; //print happy birthday message if delta_date.month == 0 && delta_date.day == 0 { @@ -177,13 +210,39 @@ fn main() { } //print report - print!(" + println!(" \tYEARS\tMONTHS\tDAYS - \t-----\t------\t---- - "); - println!("YOUR AGE (IF BIRTHDATE)\t{}\t{}\t{}", delta_date.year,delta_date.month,delta_date.day); + \t-----\t------\t----" + ); + println!("YOUR AGE (IF BIRTHDATE)\t{}", delta_date.format_ymd("\t")); + + //how much have they slept + println!( + "YOU HAVE SLEPT\t\t{}", + DATE::new_from_days( (0.35 * delta_date.calc_days() as f64) as u32).format_ymd("\t"), //35% of their life + ); + //how much they have eaten + println!( + "YOU HAVE EATEN\t\t{}", + DATE::new_from_days( (0.17 * delta_date.calc_days() as f64) as u32).format_ymd("\t"), //17% of their life + ); + //how much they have worked + println!( + "YOU HAVE {}\t{}", + { + if delta_date.year <= 3 {"PLAYED"} + else if delta_date.year <= 9 {"PLAYED/STUDIED"} + else {"WORKED/PLAYED"} + }, + DATE::new_from_days( (0.23 * delta_date.calc_days() as f64) as u32).format_ymd("\t"), //23% of their life + ); + //how much they have relaxed + println!( + "YOU HAVE RELAXED\t{}", + DATE::new_from_days( ( (1.0-0.35-0.17-0.23) * delta_date.calc_days() as f64) as u32).format_ymd("\t"), //remaining% of their life + ); } From 3d1c246fe2612467053a1b7d68e64b94f0356d48 Mon Sep 17 00:00:00 2001 From: AnthonyMichaelTDM <68485672+AnthonyMichaelTDM@users.noreply.github.com> Date: Sat, 19 Mar 2022 11:03:06 -0700 Subject: [PATCH 4/4] finished rust port of 95_Weekday --- 95_Weekday/rust/src/main.rs | 45 ++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/95_Weekday/rust/src/main.rs b/95_Weekday/rust/src/main.rs index 611e8d46..47d3ae9a 100644 --- a/95_Weekday/rust/src/main.rs +++ b/95_Weekday/rust/src/main.rs @@ -41,12 +41,7 @@ impl DATE { } //create date - let mut date =DATE{ - month:raw_date[0], - day:raw_date[1], - year:raw_date[2], - day_of_week: 0 - }; + let mut date =DATE::new(raw_date[0], raw_date[1], raw_date[2], 0); date.update_day_of_week(); //return date return date @@ -73,7 +68,8 @@ impl DATE { //get days d = days_remaining; - return DATE { month: m, day: d, year: y, day_of_week: 0 } + //return new date + return DATE::new(m, d, y, 0); } /** @@ -81,20 +77,44 @@ impl DATE { * uses the methodology found here: https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html */ fn update_day_of_week(&mut self) { + //DATA let day = self.day as isize; let month = self.month as isize; let year = self.year as isize; let century = year/100; let year_of_century = year - century*100; let weekday; //as 0-6 + + //calculate weekday if self.month <= 2 { //if jan or feb weekday = (day + (2.6 * ((month+10) as f64)-0.2)as isize - 2*century + (year_of_century-1) + (year_of_century-1)/4 + century/4) % 7; } else { weekday = (day + (2.6 * ((month-2) as f64)-0.2)as isize - 2*century + year_of_century + year_of_century/4 + century/4) % 7; } + + //update weekday self.day_of_week=(weekday+1) as u32; //weekday as 1-7 } + /** + * return the string for the weekday + */ + fn day_of_week_as_string(&self) -> String { + match self.day_of_week { + 1 => {return String::from("SUNDAY")}, + 2 => {return String::from("MONDAY")}, + 3 => {return String::from("TUESDAY")}, + 4 => {return String::from("WEDNESDAY")}, + 5 => {return String::from("THURSDAY")}, + 6 => { + if self.day == 13 {return String::from("FRIDAY THE THIRTEENTH---BEWARE!")} + else {return String::from("FRIDAY")} + }, + 7 => {return String::from("SATURDAY")}, + _ => {return String::from("")}, + } + } + /** * is the year a leap_year */ @@ -149,7 +169,6 @@ impl ToString for DATE { } } - fn main() { //DATA let today_date: DATE; @@ -193,7 +212,7 @@ fn main() { else if today_value == other_day_value {other_is_today=true;"IS"} else {"WAS"} }, - other_date.day_of_week, + other_date.day_of_week_as_string(), ); //end if both days are the same @@ -202,7 +221,7 @@ fn main() { } //create date representing the difference between the two dates - delta_date = if let Some(d) = today_date.time_since(&other_date) {d} else {return;}; + delta_date = today_date.time_since(&other_date).unwrap(); //print happy birthday message if delta_date.month == 0 && delta_date.day == 0 { @@ -243,7 +262,11 @@ fn main() { "YOU HAVE RELAXED\t{}", DATE::new_from_days( ( (1.0-0.35-0.17-0.23) * delta_date.calc_days() as f64) as u32).format_ymd("\t"), //remaining% of their life ); - + //when they can retire + println!( + "YOU MAY RETIRE IN\t{}", + DATE::new(other_date.month, other_date.day, other_date.year + 65, 0).time_since(&today_date).unwrap().format_ymd("\t") + ); }