2013-04-10 23:57:08 -07:00
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2016-12-05 22:15:40 +01:00
|
|
|
|
"fmt"
|
|
|
|
|
|
"strconv"
|
2018-06-22 20:57:24 +00:00
|
|
|
|
"strings"
|
2013-04-10 23:57:08 -07:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// types needed to implement general purpose sets are element and set
|
|
|
|
|
|
|
|
|
|
|
|
// element is an interface, allowing different kinds of elements to be
|
|
|
|
|
|
// implemented and stored in sets.
|
2015-02-20 00:35:01 -05:00
|
|
|
|
type elem interface {
|
2016-12-05 22:15:40 +01:00
|
|
|
|
// an element must be distinguishable from other elements to satisfy
|
|
|
|
|
|
// the mathematical definition of a set. a.eq(b) must give the same
|
|
|
|
|
|
// result as b.eq(a).
|
|
|
|
|
|
Eq(elem) bool
|
|
|
|
|
|
// String result is used only for printable output. Given a, b where
|
|
|
|
|
|
// a.eq(b), it is not required that a.String() == b.String().
|
|
|
|
|
|
fmt.Stringer
|
2013-04-10 23:57:08 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// integer type satisfying element interface
|
2015-02-20 00:35:01 -05:00
|
|
|
|
type Int int
|
2013-04-10 23:57:08 -07:00
|
|
|
|
|
2015-02-20 00:35:01 -05:00
|
|
|
|
func (i Int) Eq(e elem) bool {
|
2016-12-05 22:15:40 +01:00
|
|
|
|
j, ok := e.(Int)
|
|
|
|
|
|
return ok && i == j
|
2013-04-10 23:57:08 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-02-20 00:35:01 -05:00
|
|
|
|
func (i Int) String() string {
|
2016-12-05 22:15:40 +01:00
|
|
|
|
return strconv.Itoa(int(i))
|
2013-04-10 23:57:08 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-02-20 00:35:01 -05:00
|
|
|
|
// a set is a slice of elem's. methods are added to implement
|
|
|
|
|
|
// the element interface, to allow nesting.
|
|
|
|
|
|
type set []elem
|
2013-04-10 23:57:08 -07:00
|
|
|
|
|
|
|
|
|
|
// uniqueness of elements can be ensured by using add method
|
2015-02-20 00:35:01 -05:00
|
|
|
|
func (s *set) add(e elem) {
|
2016-12-05 22:15:40 +01:00
|
|
|
|
if !s.has(e) {
|
|
|
|
|
|
*s = append(*s, e)
|
|
|
|
|
|
}
|
2013-10-27 22:24:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-02-20 00:35:01 -05:00
|
|
|
|
func (s *set) has(e elem) bool {
|
2016-12-05 22:15:40 +01:00
|
|
|
|
for _, ex := range *s {
|
|
|
|
|
|
if e.Eq(ex) {
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (s set) ok() bool {
|
|
|
|
|
|
for i, e0 := range s {
|
|
|
|
|
|
for _, e1 := range s[i+1:] {
|
|
|
|
|
|
if e0.Eq(e1) {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return true
|
2013-04-10 23:57:08 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-02-20 00:35:01 -05:00
|
|
|
|
// elem.Eq
|
|
|
|
|
|
func (s set) Eq(e elem) bool {
|
2016-12-05 22:15:40 +01:00
|
|
|
|
t, ok := e.(set)
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(s) != len(t) {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
for _, se := range s {
|
|
|
|
|
|
if !t.has(se) {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return true
|
2013-04-10 23:57:08 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-02-20 00:35:01 -05:00
|
|
|
|
// elem.String
|
2013-04-10 23:57:08 -07:00
|
|
|
|
func (s set) String() string {
|
2016-12-05 22:15:40 +01:00
|
|
|
|
if len(s) == 0 {
|
|
|
|
|
|
return "∅"
|
|
|
|
|
|
}
|
2018-06-22 20:57:24 +00:00
|
|
|
|
var buf strings.Builder
|
2016-12-05 22:15:40 +01:00
|
|
|
|
buf.WriteRune('{')
|
|
|
|
|
|
for i, e := range s {
|
|
|
|
|
|
if i > 0 {
|
|
|
|
|
|
buf.WriteRune(',')
|
|
|
|
|
|
}
|
|
|
|
|
|
buf.WriteString(e.String())
|
|
|
|
|
|
}
|
|
|
|
|
|
buf.WriteRune('}')
|
|
|
|
|
|
return buf.String()
|
2013-04-10 23:57:08 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// method required for task
|
|
|
|
|
|
func (s set) powerSet() set {
|
2016-12-05 22:15:40 +01:00
|
|
|
|
r := set{set{}}
|
|
|
|
|
|
for _, es := range s {
|
|
|
|
|
|
var u set
|
|
|
|
|
|
for _, er := range r {
|
|
|
|
|
|
er := er.(set)
|
2018-06-22 20:57:24 +00:00
|
|
|
|
u = append(u, append(er[:len(er):len(er)], es))
|
2016-12-05 22:15:40 +01:00
|
|
|
|
}
|
|
|
|
|
|
r = append(r, u...)
|
|
|
|
|
|
}
|
|
|
|
|
|
return r
|
2013-04-10 23:57:08 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func main() {
|
2016-12-05 22:15:40 +01:00
|
|
|
|
var s set
|
|
|
|
|
|
for _, i := range []Int{1, 2, 2, 3, 4, 4, 4} {
|
|
|
|
|
|
s.add(i)
|
|
|
|
|
|
}
|
|
|
|
|
|
fmt.Println(" s:", s, "length:", len(s))
|
|
|
|
|
|
ps := s.powerSet()
|
|
|
|
|
|
fmt.Println(" 𝑷(s):", ps, "length:", len(ps))
|
|
|
|
|
|
|
|
|
|
|
|
fmt.Println("\n(extra credit)")
|
|
|
|
|
|
var empty set
|
|
|
|
|
|
fmt.Println(" empty:", empty, "len:", len(empty))
|
|
|
|
|
|
ps = empty.powerSet()
|
|
|
|
|
|
fmt.Println(" 𝑷(∅):", ps, "len:", len(ps))
|
|
|
|
|
|
ps = ps.powerSet()
|
|
|
|
|
|
fmt.Println("𝑷(𝑷(∅)):", ps, "len:", len(ps))
|
|
|
|
|
|
|
|
|
|
|
|
fmt.Println("\n(regression test for earlier bug)")
|
|
|
|
|
|
s = set{Int(1), Int(2), Int(3), Int(4), Int(5)}
|
|
|
|
|
|
fmt.Println(" s:", s, "length:", len(s), "ok:", s.ok())
|
|
|
|
|
|
ps = s.powerSet()
|
|
|
|
|
|
fmt.Println(" 𝑷(s):", "length:", len(ps), "ok:", ps.ok())
|
|
|
|
|
|
for _, e := range ps {
|
|
|
|
|
|
if !e.(set).ok() {
|
|
|
|
|
|
panic("invalid set in ps")
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2013-04-10 23:57:08 -07:00
|
|
|
|
}
|