132 lines
3.0 KiB
Go
132 lines
3.0 KiB
Go
package main
|
||
|
||
import "fmt"
|
||
|
||
// Define set as a type to hold a set of complex numbers. A type
|
||
// could be defined similarly to hold other types of elements. A common
|
||
// variation is to make a map of interface{} to represent a set of
|
||
// mixed types. Also here the map value is a bool. By always storing
|
||
// true, the code is nicely readable. A variation to use less memory
|
||
// is to make the map value an empty struct. The relative advantages
|
||
// can be debated.
|
||
type set map[complex128]bool
|
||
|
||
func main() {
|
||
// task: set creation
|
||
s0 := make(set) // create empty set
|
||
s1 := set{3: true} // create set with one element
|
||
s2 := set{3: true, 1: true} // create set with two elements
|
||
|
||
// option: another way to create a set
|
||
s3 := newSet(3, 1, 4, 1, 5, 9)
|
||
|
||
// option: output!
|
||
fmt.Println("s0:", s0)
|
||
fmt.Println("s1:", s1)
|
||
fmt.Println("s2:", s2)
|
||
fmt.Println("s3:", s3)
|
||
|
||
// task: element predicate
|
||
fmt.Printf("%v ∈ s0: %t\n", 3, s0.hasElement(3))
|
||
fmt.Printf("%v ∈ s3: %t\n", 3, s3.hasElement(3))
|
||
fmt.Printf("%v ∈ s3: %t\n", 2, s3.hasElement(2))
|
||
|
||
// task: union
|
||
b := set{4: true, 2: true}
|
||
fmt.Printf("s3 ∪ %v: %v\n", b, union(s3, b))
|
||
|
||
// task: intersection
|
||
fmt.Printf("s3 ∩ %v: %v\n", b, intersection(s3, b))
|
||
|
||
// task: difference
|
||
fmt.Printf("s3 \\ %v: %v\n", b, difference(s3, b))
|
||
|
||
// task: subset predicate
|
||
fmt.Printf("%v ⊆ s3: %t\n", b, subset(b, s3))
|
||
fmt.Printf("%v ⊆ s3: %t\n", s2, subset(s2, s3))
|
||
fmt.Printf("%v ⊆ s3: %t\n", s0, subset(s0, s3))
|
||
|
||
// task: equality
|
||
s2Same := set{1: true, 3: true}
|
||
fmt.Printf("%v = s2: %t\n", s2Same, equal(s2Same, s2))
|
||
|
||
// option: proper subset
|
||
fmt.Printf("%v ⊂ s2: %t\n", s2Same, properSubset(s2Same, s2))
|
||
fmt.Printf("%v ⊂ s3: %t\n", s2Same, properSubset(s2Same, s3))
|
||
|
||
// option: delete. it's built in.
|
||
delete(s3, 3)
|
||
fmt.Println("s3, 3 deleted:", s3)
|
||
}
|
||
|
||
func newSet(ms ...complex128) set {
|
||
s := make(set)
|
||
for _, m := range ms {
|
||
s[m] = true
|
||
}
|
||
return s
|
||
}
|
||
|
||
func (s set) String() string {
|
||
if len(s) == 0 {
|
||
return "∅"
|
||
}
|
||
r := "{"
|
||
for e := range s {
|
||
r = fmt.Sprintf("%s%v, ", r, e)
|
||
}
|
||
return r[:len(r)-2] + "}"
|
||
}
|
||
|
||
func (s set) hasElement(m complex128) bool {
|
||
return s[m]
|
||
}
|
||
|
||
func union(a, b set) set {
|
||
s := make(set)
|
||
for e := range a {
|
||
s[e] = true
|
||
}
|
||
for e := range b {
|
||
s[e] = true
|
||
}
|
||
return s
|
||
}
|
||
|
||
func intersection(a, b set) set {
|
||
s := make(set)
|
||
for e := range a {
|
||
if b[e] {
|
||
s[e] = true
|
||
}
|
||
}
|
||
return s
|
||
}
|
||
|
||
func difference(a, b set) set {
|
||
s := make(set)
|
||
for e := range a {
|
||
if !b[e] {
|
||
s[e] = true
|
||
}
|
||
}
|
||
return s
|
||
}
|
||
|
||
func subset(a, b set) bool {
|
||
for e := range a {
|
||
if !b[e] {
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
func equal(a, b set) bool {
|
||
return len(a) == len(b) && subset(a, b)
|
||
}
|
||
|
||
func properSubset(a, b set) bool {
|
||
return len(a) < len(b) && subset(a, b)
|
||
}
|