Add solutions for sheet6

This commit is contained in:
Lukas Kalbertodt 2016-12-05 17:57:47 +01:00
parent 509cdd453d
commit 08a4b2fccc
7 changed files with 197 additions and 0 deletions

View File

@ -0,0 +1,6 @@
[package]
name = "sol1"
version = "0.1.0"
authors = ["Lukas Kalbertodt <lukas.kalbertodt@gmail.com>"]
[dependencies]

52
aufgaben/sheet6/sol1/src/lib.rs Executable file
View File

@ -0,0 +1,52 @@
use std::ops::{Add, Mul};
#[cfg(test)]
mod tests;
/// Clamps a value into a given range. This function returns the value closest
/// to `value` which lies in between `min` and `max`.
///
/// *Note*: it's not clear whether `PartialOrd` or `Ord` is the correct bound
/// here. With `PartialEq`, some results may look strange to some.
/// `clamp(NaN, 0.0, 5.0)` would return `NaN` for example. `NaN` as min or max
/// wouldn't do anything.
pub fn clamp<T>(value: T, min: T, max: T) -> T
where T: PartialOrd
{
// This is a small little trick. We want to avoid using if-else here, so
// we match the unit value `()` (void) and use the match guards.
match () {
() if value < min => min,
() if value > max => max,
_ => value,
}
}
/// Returns the sum and the product of the two given parameters.
///
/// *Note*: Either a Clone or Copy bound is necessary. Clone was choosen here,
/// because it's more general.
pub fn sum_product<T, U>(a: T, b: U)
-> (<T as Add<U>>::Output, <T as Mul<U>>::Output)
where T: Add<U> + Mul<U> + Clone,
U: Clone
{
(a.clone() + b.clone(), a * b)
}
/// Extension trait for simple conversion from `bool` to `Option<T>`
pub trait BoolOptionExt {
/// If `self` is `true`, `Some(value)` is returned, `None` otherwise.
fn into_option<T>(self, value: T) -> Option<T>;
}
impl BoolOptionExt for bool {
fn into_option<T>(self, value: T) -> Option<T> {
match self {
true => Some(value),
false => None,
}
}
}

View File

@ -0,0 +1,28 @@
#[test]
fn clamp() {
use clamp;
assert_eq!(clamp(3, 5, 10), 5);
assert_eq!(clamp(6, 5, 10), 6);
assert_eq!(clamp(11, 5, 10), 10);
assert_eq!(clamp(3.0, 5.0, 10.0), 5.0);
assert_eq!(clamp(6.0, 5.0, 10.0), 6.0);
assert_eq!(clamp(11.0, 5.0, 10.0), 10.0);
}
#[test]
fn sum_product() {
use sum_product;
assert_eq!(sum_product(3, 4), (7, 12));
assert_eq!(sum_product(3.0, 4.0), (7.0, 12.0));
}
#[test]
fn bool_option() {
use BoolOptionExt;
assert_eq!(false.into_option(3), None);
assert_eq!( true.into_option(3), Some(3));
}

View File

@ -0,0 +1,7 @@
[package]
name = "sol2"
version = "0.1.0"
authors = ["Lukas Kalbertodt <lukas.kalbertodt@gmail.com>"]
[dependencies]
num-traits = "0.1"

59
aufgaben/sheet6/sol2/src/lib.rs Executable file
View File

@ -0,0 +1,59 @@
extern crate num_traits;
use num_traits::{Zero, One};
use std::ops;
#[cfg(test)]
mod tests;
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Vector2<T> {
pub x: T,
pub y: T,
}
impl<T> Vector2<T> {
pub fn new(x: T, y: T) -> Self {
Vector2 {
x: x,
y: y,
}
}
}
impl<T: Zero> Vector2<T> {
pub fn origin() -> Self {
Self::new(T::zero(), T::zero())
}
}
impl<T: Zero + One> Vector2<T> {
pub fn unit_x() -> Self {
Self::new(T::one(), T::zero())
}
pub fn unit_y() -> Self {
Self::new(T::zero(), T::one())
}
}
impl<T, U> ops::Add<Vector2<U>> for Vector2<T>
where T: ops::Add<U>
{
type Output = Vector2<T::Output>;
fn add(self, rhs: Vector2<U>) -> Self::Output {
Vector2::new(self.x + rhs.x, self.y + rhs.y)
}
}
impl<T, U> ops::Mul<U> for Vector2<T>
where T: ops::Mul<U>,
U: Clone
{
type Output = Vector2<T::Output>;
fn mul(self, rhs: U) -> Self::Output {
Vector2::new(self.x * rhs.clone(), self.y * rhs)
}
}

View File

@ -0,0 +1,18 @@
use Vector2;
#[test]
fn constructors() {
assert_eq!(Vector2::new(27, 42), Vector2 { x: 27, y: 42 });
assert_eq!(Vector2::origin(), Vector2 { x: 0, y: 0 });
assert_eq!(Vector2::unit_x(), Vector2 { x: 1, y: 0 });
assert_eq!(Vector2::unit_y(), Vector2 { x: 0, y: 1 });
}
#[test]
fn operators() {
let a = Vector2::new(3, 7);
let b = Vector2::new(-2, 5);
assert_eq!(a + b, Vector2::new(1, 12));
assert_eq!(a * 2, Vector2::new(6, 14));
}

27
aufgaben/sheet6/sol3/swagger.rs Executable file
View File

@ -0,0 +1,27 @@
use std::fmt;
struct Swagger<T>(pub T);
impl<T: fmt::Display> fmt::Display for Swagger<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "yolo {} swag", self.0)
}
}
trait SwaggerExt: Sized {
fn with_swag(self) -> Swagger<Self>;
}
impl<T> SwaggerExt for T {
fn with_swag(self) -> Swagger<Self> {
Swagger(self)
}
}
fn main() {
let pi = 3.14;
println!("{}", pi);
println!("{}", Swagger(pi));
println!("{}", pi.with_swag());
}