Power set: Difference between revisions

Content added Content deleted
(→‎{{header|jq}}: recursive version)
(→‎{{header|Go}}: Fix June 2 change that made it not even compile! Tweak set output and demonstrate it works as expected with empty sets. gofmt.)
Line 846: Line 846:


import (
import (
"bytes"
"bytes"
"fmt"
"fmt"
"strconv"
"strconv"
)
)


Line 856: Line 856:
// implemented and stored in sets.
// implemented and stored in sets.
type elem interface {
type elem interface {
// an element must be distinguishable from other elements to satisfy
// an element must be distinguishable from other elements to satisfy
// the mathematical definition of a set. a.eq(b) must give the same
// the mathematical definition of a set. a.eq(b) must give the same
// result as b.eq(a).
// result as b.eq(a).
Eq(element) bool
Eq(elem) bool
// String result is used only for printable output. Given a, b where
// String result is used only for printable output. Given a, b where
// a.eq(b), it is not required that a.String() == b.String().
// a.eq(b), it is not required that a.String() == b.String().
fmt.Stringer
fmt.Stringer
}
}


Line 869: Line 869:


func (i Int) Eq(e elem) bool {
func (i Int) Eq(e elem) bool {
j, ok := e.(Int)
j, ok := e.(Int)
return ok && i == j
return ok && i == j
}
}


func (i Int) String() string {
func (i Int) String() string {
return strconv.Itoa(int(i))
return strconv.Itoa(int(i))
}
}


Line 883: Line 883:
// uniqueness of elements can be ensured by using add method
// uniqueness of elements can be ensured by using add method
func (s *set) add(e elem) {
func (s *set) add(e elem) {
if !s.has(e) {
if !s.has(e) {
*s = append(*s, e)
*s = append(*s, e)
}
}
}
}


func (s *set) has(e elem) bool {
func (s *set) has(e elem) bool {
for _, ex := range *s {
for _, ex := range *s {
if e.Eq(ex) {
if e.Eq(ex) {
return true
return true
}
}
}
}
return false
return false
}
}


// elem.Eq
// elem.Eq
func (s set) Eq(e elem) bool {
func (s set) Eq(e elem) bool {
t, ok := e.(set)
t, ok := e.(set)
if !ok {
if !ok {
return false
return false
}
}
if len(s) != len(t) {
if len(s) != len(t) {
return false
return false
}
}
for _, se := range s {
for _, se := range s {
if !t.has(se) {
if !t.has(se) {
return false
return false
}
}
}
}
return true
return true
}
}


// elem.String
// elem.String
func (s set) String() string {
func (s set) String() string {
if len(s) == 0 {
var buf bytes.Buffer
return "∅"
buf.WriteRune('{')
}
for _, e := range s {
var buf bytes.Buffer
if len(r) > 1 {
buf.WriteRune(' ')
buf.WriteRune('{')
}
for i, e := range s {
if i > 0 {
buf.WriteString(e.String())
buf.WriteRune(',')
}
}
buf.WriteRune('}')
return buf.String()
buf.WriteString(e.String())
}
buf.WriteRune('}')
return buf.String()
}
}


// method required for task
// method required for task
func (s set) powerSet() set {
func (s set) powerSet() set {
r := set{set{}}
r := set{set{}}
for _, es := range s {
for _, es := range s {
var u set
var u set
for _, er := range r {
for _, er := range r {
u = append(u, append(er.(set), es))
u = append(u, append(er.(set), es))
}
}
r = append(r, u...)
r = append(r, u...)
}
}
return r
return r
}
}


func main() {
func main() {
var s set
var s set
for _, i := range []Int{1, 2, 2, 3, 4, 4, 4} {
for _, i := range []Int{1, 2, 2, 3, 4, 4, 4} {
s.add(i)
s.add(i)
}
}
fmt.Println(" s:", s, "length:", len(s))
fmt.Println(s)
ps := s.powerSet()
fmt.Println("length =", len(s))
fmt.Println(" 𝑷(s):", ps, "length:", len(ps))
ps := s.powerSet()

fmt.Println(ps)
var empty set
fmt.Println("length =", len(ps))
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))
}</lang>
}</lang>
{{out}}
{{out}}
<pre>
<pre>
{1 2 3 4}
s: {1,2,3,4} length: 4
𝑷(s): {∅,{1},{2},{1,2},{3},{1,3},{2,3},{1,2,3},{4},{1,4},{2,4},{1,2,4},{3,4},{1,3,4},{2,3,4},{1,2,3,4}} length: 16
length = 4
empty: ∅ len: 0
{{} {1} {2} {1 2} {3} {1 3} {2 3} {1 2 3} {4} {1 4} {2 4} {1 2 4} {3 4} {1 3 4} {2 3 4} {1 2 3 4}}
𝑷(∅): {∅} len: 1
length = 16
𝑷(𝑷(∅)): {∅,{∅}} len: 2
</pre>
</pre>