Assignment 9 Done

This commit is contained in:
static
2024-11-28 15:28:47 +00:00
parent 485100c9c5
commit e443fe6c81
3 changed files with 266 additions and 22 deletions

View File

@@ -38,7 +38,7 @@ pub struct BigInt {
impl BigInt {
/// Create a new `BigInt` from a `usize`.
pub fn new(n: u32) -> Self {
todo!()
BigInt { carrier: vec![n] }
}
/// Creates a new `BigInt` from a `Vec<u32>`.
@@ -48,7 +48,7 @@ impl BigInt {
/// Panics if `carrier` is empty.
pub fn new_large(carrier: Vec<u32>) -> Self {
assert!(!carrier.is_empty());
todo!()
BigInt { carrier }
}
}
@@ -57,17 +57,52 @@ const SIGN_MASK: u32 = 1 << 31;
impl BigInt {
/// Extend `self` to `len` bits.
fn sign_extension(&self, len: usize) -> Self {
todo!()
let mut carrier = vec![
if self.carrier[0] & SIGN_MASK == 0 {
0
} else {
0xFFFFFFFF
};
(len + 31) / 32 - self.carrier.len()
];
carrier.extend_from_slice(&self.carrier);
Self { carrier }
}
/// Compute the two's complement of `self`.
fn two_complement(&self) -> Self {
todo!()
let mut one_complement = self.clone();
for v in &mut one_complement.carrier {
*v = !*v;
}
one_complement + BigInt::new(1)
}
/// Truncate a `BigInt` to the minimum length.
fn truncate(&self) -> Self {
todo!()
let sign = (self.carrier[0] & SIGN_MASK) != 0;
for i in 0..(self.carrier.len() - 1) {
if (!sign
&& (self.carrier[i] != 0
|| (self.carrier[i + 1] != 0 && (self.carrier[i + 1] & SIGN_MASK) != 0)))
|| (sign
&& (self.carrier[i] != u32::MAX
|| (self.carrier[i + 1] != u32::MAX
&& (self.carrier[i + 1] & SIGN_MASK) == 0)))
{
return Self {
carrier: self.carrier[i..].to_vec(),
};
}
}
Self {
carrier: self.carrier[self.carrier.len() - 1..].to_vec(),
}
}
}
@@ -75,7 +110,33 @@ impl Add for BigInt {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
todo!()
let len = if self.carrier.len() > rhs.carrier.len() {
self.carrier.len()
} else {
rhs.carrier.len()
};
let len = (len + 1) * 32;
let (lhs, rhs) = (self.sign_extension(len), rhs.sign_extension(len));
let mut carrier = vec![];
let mut overflow = false;
for (&l, &r) in lhs.carrier.iter().zip(rhs.carrier.iter()).rev() {
let (v, of) = l.overflowing_add(r);
if overflow {
let (v, of) = v.overflowing_add(1);
carrier.push(v);
overflow = of;
} else {
carrier.push(v);
overflow = of;
}
}
let result = Self::Output {
carrier: carrier.iter().rev().copied().collect(),
};
result.truncate()
}
}
@@ -83,7 +144,7 @@ impl Sub for BigInt {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
todo!()
self.add(rhs.two_complement())
}
}

View File

@@ -15,7 +15,13 @@ use itertools::*;
/// assert_eq!(res, vec![2.0, 4.0, 6.0, 8.0, 10.0]);
/// ```
pub fn vec_add(lhs: &[f64], rhs: &[f64]) -> Vec<f64> {
todo!()
let mut result = vec![];
for (l, r) in lhs.iter().zip(rhs) {
result.push(l + *r);
}
result
}
/// dot product of two arrays
@@ -35,7 +41,13 @@ pub fn vec_add(lhs: &[f64], rhs: &[f64]) -> Vec<f64> {
/// assert_eq!(res, 55.0);
/// ```
pub fn dot_product(lhs: &[f64], rhs: &[f64]) -> f64 {
todo!()
let mut result = 0.0;
for (l, r) in lhs.iter().zip(rhs) {
result += l * *r;
}
result
}
/// Matrix multiplication
@@ -68,5 +80,17 @@ pub fn dot_product(lhs: &[f64], rhs: &[f64]) -> f64 {
/// assert_eq!(ans, res);
/// ```
pub fn matmul(lhs: &[Vec<f64>], rhs: &[Vec<f64>]) -> Vec<Vec<f64>> {
todo!()
let mut result = vec![];
for (i, l) in lhs.iter().enumerate() {
let mut temp = vec![];
for (j, r) in rhs.iter().enumerate() {
temp.push(dot_product(l, r));
}
result.push(temp);
}
result
}

View File

@@ -18,7 +18,28 @@ use itertools::Itertools;
/// assert_eq!(is_fibonacci([1, 1, 2, 3, 5, 8, 14].into_iter()), false);
/// ```
pub fn is_fibonacci(inner: impl Iterator<Item = i64>) -> bool {
todo!()
let mut inner = inner;
let mut first = if let Some(v) = inner.next() {
v
} else {
return true;
};
let mut second = if let Some(v) = inner.next() {
v
} else {
return true;
};
for third in inner {
if first + second == third {
first = second;
second = third;
} else {
return false;
}
}
true
}
/// Returns the sum of `f(v)` for all element `v` the given array.
@@ -32,7 +53,7 @@ pub fn is_fibonacci(inner: impl Iterator<Item = i64>) -> bool {
/// assert_eq!(sigma([1, 2].into_iter(), |x| x * 4), 12);
/// ```
pub fn sigma<T, F: Fn(T) -> i64>(inner: impl Iterator<Item = T>, f: F) -> i64 {
todo!()
inner.map(f).sum()
}
/// Alternate elements from three iterators until they have run out.
@@ -54,7 +75,22 @@ pub fn interleave3<T>(
list2: impl Iterator<Item = T>,
list3: impl Iterator<Item = T>,
) -> Vec<T> {
todo!()
let mut list1 = list1;
let mut list2 = list2;
let mut list3 = list3;
let mut result = vec![];
for e1 in list1 {
let e2 = list2.next().unwrap();
let e3 = list3.next().unwrap();
result.push(e1);
result.push(e2);
result.push(e3);
}
result
}
/// Alternate elements from array of n iterators until they have run out.
@@ -74,8 +110,20 @@ pub fn interleave3<T>(
pub fn interleave_n<T, const N: usize>(
mut iters: [impl Iterator<Item = T>; N],
) -> impl Iterator<Item = T> {
todo!();
std::iter::empty()
struct MyIterator<I: Iterator, const N: usize> {
iters: [I; N],
counter: usize,
}
impl<I: Iterator, const N: usize> Iterator for MyIterator<I, N> {
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
let item = self.iters[self.counter % N].next();
self.counter += 1;
item
}
}
MyIterator { iters, counter: 0 }
}
/// Returns mean of k smallest value's mean.
@@ -95,7 +143,14 @@ pub fn interleave_n<T, const N: usize>(
/// );
/// ```
pub fn k_smallest_mean(inner: impl Iterator<Item = i64>, k: usize) -> f64 {
todo!()
let mut vec = inner.collect_vec();
if vec.is_empty() {
return 0.0;
}
let k = if k <= vec.len() { k } else { vec.len() };
vec.sort();
(vec[0..k].iter().sum::<i64>() as f64) / (k as f64)
}
/// Returns mean for each class.
@@ -125,7 +180,24 @@ pub fn k_smallest_mean(inner: impl Iterator<Item = i64>, k: usize) -> f64 {
/// );
/// ```
pub fn calculate_mean(inner: impl Iterator<Item = (String, i64)>) -> HashMap<String, f64> {
todo!()
let mut sum = HashMap::new();
let mut count = HashMap::new();
for (class, score) in inner {
*sum.entry(class.clone()).or_insert(0) += score;
*count.entry(class).or_insert(0) += 1;
}
let mut result = HashMap::new();
for (class, sum) in sum {
let _ = result.insert(
class.clone(),
(sum as f64) / (*count.get(&class).unwrap() as f64),
);
}
result
}
/// Among the cartesian product of input vectors, return the number of sets whose sum equals `n`.
@@ -147,7 +219,31 @@ pub fn calculate_mean(inner: impl Iterator<Item = (String, i64)>) -> HashMap<Str
/// assert_eq!(sum_is_n(vec![vec![1, 2, 3], vec![2, 3]], 2), 0);
/// ```
pub fn sum_is_n(inner: Vec<Vec<i64>>, n: i64) -> usize {
todo!()
let mut products = vec![vec![]];
for vec in inner {
let mut temp = vec![];
for v in vec {
for product in &products {
let mut new_product = product.clone();
new_product.push(v);
temp.push(new_product);
}
}
products = temp;
}
let mut result = 0;
for product in products {
if product.iter().sum::<i64>() == n {
result += 1;
}
}
result
}
/// Returns a new vector that contains the item that appears `n` times in the input vector in
@@ -164,7 +260,22 @@ pub fn sum_is_n(inner: Vec<Vec<i64>>, n: i64) -> usize {
/// assert_eq!(find_count_n(vec![1, 2, 3, 4, 4], 1), vec![1, 2, 3]);
/// ```
pub fn find_count_n(inner: Vec<usize>, n: usize) -> Vec<usize> {
todo!()
let mut map = HashMap::new();
for v in inner {
*map.entry(v).or_insert(0) += 1;
}
let mut result = vec![];
for (key, value) in map {
if value == n {
result.push(key);
}
}
result.sort();
result
}
/// Return the position of the median element in the vector.
@@ -188,7 +299,41 @@ pub fn find_count_n(inner: Vec<usize>, n: usize) -> Vec<usize> {
/// assert_eq!(position_median(vec![1, 3, 3, 3]), Some(1));
/// ```
pub fn position_median<T: Ord>(inner: Vec<T>) -> Option<usize> {
todo!()
if inner.is_empty() {
return None;
}
let mut vec = vec![];
for (i, v) in inner.iter().enumerate() {
vec.push((i, v));
}
vec.sort_by(|(i1, v1), (i2, v2)| match (**v1).cmp(*v2) {
std::cmp::Ordering::Equal => (*i1).cmp(i2),
r => r,
});
let mut result = 0;
let mut prev: Option<&T> = None;
for (i, (j, v)) in vec.iter().enumerate() {
if let Some(prev) = prev {
if *prev != **v {
result = *j;
}
} else {
result = *j;
}
prev = Some(*v);
if i >= vec.len() / 2 {
return Some(result);
}
}
unreachable!();
}
/// Returns the sum of all elements in a two-dimensional array.
@@ -203,7 +348,7 @@ pub fn position_median<T: Ord>(inner: Vec<T>) -> Option<usize> {
/// );
/// ```
pub fn two_dimensional_sum(inner: impl Iterator<Item = impl Iterator<Item = i64>>) -> i64 {
todo!()
inner.map(|iter| iter.sum::<i64>()).sum()
}
/// Returns whether the given string is palindrome or not.
@@ -215,5 +360,19 @@ pub fn two_dimensional_sum(inner: impl Iterator<Item = impl Iterator<Item = i64>
///
/// Consult <https://en.wikipedia.org/wiki/Palindrome>.
pub fn is_palindrome(s: String) -> bool {
todo!()
if s.len() <= 1 {
return true;
}
let mut front = s.chars().enumerate();
let mut back = s.chars().rev();
for ((i, f), b) in front.zip(back) {
if i >= s.len() / 2 {
return true;
} else if f != b {
return false;
}
}
unreachable!();
}