From 485100c9c5b4676305a90dce746b8c7f153866b8 Mon Sep 17 00:00:00 2001 From: static Date: Wed, 20 Nov 2024 06:25:30 +0000 Subject: [PATCH] Assignment 8 Done --- src/assignments/assignment08/church.rs | 46 +++++++++++++++---- .../assignment08/small_exercises.rs | 36 +++++++++++++-- 2 files changed, 68 insertions(+), 14 deletions(-) diff --git a/src/assignments/assignment08/church.rs b/src/assignments/assignment08/church.rs index 1e99fa6..14372aa 100644 --- a/src/assignments/assignment08/church.rs +++ b/src/assignments/assignment08/church.rs @@ -35,17 +35,28 @@ pub fn zero() -> Church { /// Implement a function to add 1 to a given Church numeral. pub fn succ(n: Church) -> Church { - todo!() + Rc::new(move |f| { + let n = n.clone(); + Rc::new(move |x| f(n(f.clone())(x))) + }) } /// Implement a function to add two Church numerals. pub fn add(n: Church, m: Church) -> Church { - todo!() + Rc::new(move |f| { + let n = n.clone(); + let m = m.clone(); + Rc::new(move |x| m(f.clone())(n(f.clone())(x))) + }) } /// Implement a function to multiply (mult) two Church numerals. pub fn mult(n: Church, m: Church) -> Church { - todo!() + Rc::new(move |f| { + let n = n.clone(); + let m = m.clone(); + Rc::new(move |x| m(n(f.clone()))(x)) + }) } /// Implement a function to raise one Church numeral to the power of another. @@ -56,18 +67,35 @@ pub fn mult(n: Church, m: Church) -> Church { /// base). Note: This function should be implemented *WITHOUT* using the `to_usize` or any /// `pow`-like method. pub fn exp(n: usize, m: usize) -> Church { - // ACTION ITEM: Uncomment the following lines and replace `todo!()` with your code. - // let n = from_usize(n); - // let m = from_usize(m); - todo!() + let n = from_usize(n); + let m = from_usize(m); + m(n) } /// Implement a function to convert a Church numeral to a usize type. pub fn to_usize(n: Church) -> usize { - todo!() + let result = Rc::new(RefCell::new(0)); + { + let result = result.clone(); + let _unused = n(Rc::new(move |x| { + *result.borrow_mut() += 1; + x + }))(T::default()); + } + { + let result = *result.borrow(); + result + } } /// Implement a function to convert a usize type to a Church numeral. pub fn from_usize(n: usize) -> Church { - todo!() + Rc::new(move |f| { + Rc::new(move |mut x| { + for _ in 0..n { + x = f(x) + } + x + }) + }) } diff --git a/src/assignments/assignment08/small_exercises.rs b/src/assignments/assignment08/small_exercises.rs index 2fb8860..15ee43a 100644 --- a/src/assignments/assignment08/small_exercises.rs +++ b/src/assignments/assignment08/small_exercises.rs @@ -7,8 +7,12 @@ /// /// Refer `test_repeat` in `assignment08_grade.rs` for detailed examples. pub fn repeat T>(n: usize, mut f: F) -> impl FnMut(T) -> T { - todo!(); - f // This line has been added to prevent compile error. You can erase this line. + move |mut x| { + for i in 0..n { + x = f(x) + } + x + } } /// Funny Map @@ -20,7 +24,13 @@ pub fn repeat T>(n: usize, mut f: F) -> impl FnMut(T) -> T { /// /// Refer `test_funny_map` in `assignment08_grade.rs` for detailed examples. pub fn funny_map T>(f: F, vs: Vec) -> Vec { - todo!() + let mut result = vec![]; + + for element in vs { + result.push(repeat(result.len(), &f)(element)); + } + + result } /// Count Repeat @@ -33,7 +43,20 @@ pub fn count_repeat T>(f: F, x: T) -> usize where T: PartialEq + Copy, { - todo!() + let mut set = vec![x]; + let mut x = x; + + loop { + x = f(x); + + if set.contains(&x) { + break; + } else { + set.push(x); + } + } + + set.len() } /// Either `T1`, or `T2`. @@ -64,6 +87,9 @@ impl Either2 { F1: FnOnce(T1) -> U1, F2: FnOnce(T2) -> U2, { - todo!() + match self { + Self::Case1 { inner } => Either2::Case1 { inner: f1(inner) }, + Self::Case2 { inner } => Either2::Case2 { inner: f2(inner) }, + } } }