Refactor rust/clock solution

This commit is contained in:
Avery Winters 2023-10-11 12:53:26 -05:00
parent da1f927d22
commit 00eaf8d75f
Signed by: avery
SSH key fingerprint: SHA256:eesvLB5MMqHLZrAMFt6kEhqJWnASMLcET6Sgmw0FqZI

View file

@ -1,4 +1,4 @@
use std::fmt::{Display, Formatter, self}; use std::fmt::{self, Display, Formatter};
const HOURS_PER_DAY: i32 = 24; const HOURS_PER_DAY: i32 = 24;
const MINUTES_PER_HOUR: i32 = 60; const MINUTES_PER_HOUR: i32 = 60;
@ -15,16 +15,12 @@ impl Clock {
pub fn new(hours: i32, minutes: i32) -> Self { pub fn new(hours: i32, minutes: i32) -> Self {
let since_midnight = MinutesSinceMidnight::new(minutes); let since_midnight = MinutesSinceMidnight::new(minutes);
let since_midnight = HOUR_SINCE_MIDNIGHT * hours + since_midnight; let since_midnight = HOUR_SINCE_MIDNIGHT * hours + since_midnight;
Self { Self { since_midnight }
since_midnight,
}
} }
pub fn add_minutes(&self, minutes: i32) -> Self { pub fn add_minutes(&self, minutes: i32) -> Self {
let since_midnight = self.since_midnight + minutes; let since_midnight = self.since_midnight + minutes;
Self { Self { since_midnight }
since_midnight,
}
} }
} }
@ -47,6 +43,15 @@ impl<const N: i32> RingI32<N> {
const fn val(&self) -> i32 { const fn val(&self) -> i32 {
self.0 self.0
} }
fn op<O>(&self, rhs: i32, op: O) -> Self
where
O: FnOnce(i32, i32) -> i32,
{
let lhs = self.val();
let rhs = rhs.rem_euclid(N);
Self(op(lhs, rhs).rem_euclid(N))
}
} }
impl<const N: i32> Display for RingI32<N> { impl<const N: i32> Display for RingI32<N> {
@ -58,63 +63,55 @@ impl<const N: i32> Display for RingI32<N> {
impl<const N: i32> std::ops::Add<i32> for RingI32<N> { impl<const N: i32> std::ops::Add<i32> for RingI32<N> {
type Output = Self; type Output = Self;
fn add(self, rhs: i32) -> Self { fn add(self, rhs: i32) -> Self {
let lhs = self.val(); self.op(rhs, i32::add)
let rhs = rhs.rem_euclid(N);
Self((lhs + rhs).rem_euclid(N))
} }
} }
impl<const N: i32> std::ops::Mul<i32> for RingI32<N> { impl<const N: i32> std::ops::Mul<i32> for RingI32<N> {
type Output = Self; type Output = Self;
fn mul(self, rhs: i32) -> Self { fn mul(self, rhs: i32) -> Self {
let lhs = self.val(); self.op(rhs, i32::mul)
let rhs = rhs.rem_euclid(N);
Self((lhs * rhs).rem_euclid(N))
} }
} }
impl<const N: i32> std::ops::Div<i32> for RingI32<N> { impl<const N: i32> std::ops::Div<i32> for RingI32<N> {
type Output = Self; type Output = Self;
fn div(self, rhs: i32) -> Self { fn div(self, rhs: i32) -> Self {
let lhs = self.val(); self.op(rhs, i32::div)
let rhs = rhs.rem_euclid(N);
Self((lhs / rhs).rem_euclid(N))
} }
} }
impl<const N: i32> std::ops::Rem<i32> for RingI32<N> { impl<const N: i32> std::ops::Rem<i32> for RingI32<N> {
type Output = Self; type Output = Self;
fn rem(self, rhs: i32) -> Self { fn rem(self, rhs: i32) -> Self {
let lhs = self.val(); self.op(rhs, i32::rem)
let rhs = rhs.rem_euclid(N);
Self((lhs % rhs).rem_euclid(N))
} }
} }
impl<const N: i32> std::ops::Add for RingI32<N> { impl<const N: i32> std::ops::Add for RingI32<N> {
type Output = Self; type Output = Self;
fn add(self, rhs: Self) -> Self { fn add(self, rhs: Self) -> Self {
self + rhs.val() self.add(rhs.val())
} }
} }
impl<const N: i32> std::ops::Mul for RingI32<N> { impl<const N: i32> std::ops::Mul for RingI32<N> {
type Output = Self; type Output = Self;
fn mul(self, rhs: Self) -> Self { fn mul(self, rhs: Self) -> Self {
self * rhs.val() self.mul(rhs.val())
} }
} }
impl<const N: i32> std::ops::Div for RingI32<N> { impl<const N: i32> std::ops::Div for RingI32<N> {
type Output = Self; type Output = Self;
fn div(self, rhs: Self) -> Self { fn div(self, rhs: Self) -> Self {
self / rhs.val() self.div(rhs.val())
} }
} }
impl<const N: i32> std::ops::Rem for RingI32<N> { impl<const N: i32> std::ops::Rem for RingI32<N> {
type Output = Self; type Output = Self;
fn rem(self, rhs: Self) -> Self { fn rem(self, rhs: Self) -> Self {
self % rhs.val() self.rem(rhs.val())
} }
} }