use std::fmt;


struct CompoundTime {
    w: usize,
    d: usize,
    h: usize,
    m: usize,
    s: usize,
}

macro_rules! reduce {
    ($s: ident, $(($from: ident, $to: ident, $factor: expr)),+) => {{
        $(
            $s.$to += $s.$from / $factor;
            $s.$from%= $factor;
        )+
    }}
}

impl CompoundTime {
    #[inline]
    fn new(w: usize, d: usize, h: usize, m: usize, s: usize) -> Self{
        CompoundTime { w: w, d: d, h: h, m: m, s: s, }
    }

    #[inline]
    fn balance(&mut self) {
        reduce!(self, (s, m, 60), (m, h, 60),
                      (h, d, 24), (d, w, 7));
    }
}

impl fmt::Display for CompoundTime {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}w {}d {}h {}m {}s", 
               self.w, self.d, self.h, self.m, self.s)
    }
}

fn main() {
    let mut ct = CompoundTime::new(0,3,182,345,2412);
    println!("Before: {}", ct);
    ct.balance();
    println!("After: {}", ct);
}