package add import ( "container/list" "fmt" "log" ) // Set is ordered set of alphabet type Set struct{ *list.List } // Element of ordered set type Element struct{ *list.Element } var ( alphabet Set zero, one Element ) const maxValue = 1000 func init() { alphabet = Set{list.New()} for i := 0; i <= maxValue; i++ { alphabet.PushBack(i) } zero = Element{alphabet.Front()} one = Element{zero.Next()} } func (m Element) next() Element { if nxt := m.Next(); nxt != nil { return Element{nxt} } log.Fatal("out of range ", m) return Element{} } func (m Element) prev() Element { if prv := m.Prev(); prv != nil { return Element{prv} } return zero } // Add defines addition func Add(m, n Element) Element { return m.add(n) } func (m Element) add(n Element) Element { if m == zero { return n } return m.prev().add(n).next() } // Mul defines mutiplication func Mul(m, n Element) Element { return m.mul(n) } func (m Element) mul(n Element) Element { if m == zero { return zero } return m.prev().mul(n).add(n) } // Pow defines power function func Pow(m, n Element) Element { return m.pow(n) } func (m Element) pow(n Element) Element { if n == zero { return one } return m.pow(n.prev()).mul(m) } // Sub defines substraction func Sub(m, n Element) Element { return m.sub(n) } func (m Element) sub(n Element) Element { if n == zero { return m } return m.sub(n.prev()).prev() } // Equals compares two elements func (m Element) Equals(n Element) bool { return m.Value == n.Value } // String pretty-prints value func (m Element) String() string { return fmt.Sprint(m.Value) } // Index returns n-th Element func Index(n int) Element { if n > alphabet.Len() { log.Fatal("out of range ", n) return Element{} } e := alphabet.Front() for i := 0; i < n; i++ { e = e.Next() } return Element{e} }