Task: Power set




Go: package main

import (
    "fmt"
    "strconv"
    "strings"
)





type elem interface {
    
    
    
    Eq(elem) bool
    
    
    fmt.Stringer
}


type Int int

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

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



type set []elem


func (s *set) add(e elem) {
    if !s.has(e) {
        *s = append(*s, e)
    }
}

func (s *set) has(e elem) bool {
    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
}


func (s set) Eq(e elem) bool {
    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
}


func (s set) String() string {
    if len(s) == 0 {
        return "∅"
    }
    var buf strings.Builder
    buf.WriteRune('{')
    for i, e := range s {
        if i > 0 {
            buf.WriteRune(',')
        }
        buf.WriteString(e.String())
    }
    buf.WriteRune('}')
    return buf.String()
}


func (s set) powerSet() set {
    r := set{set{}}
    for _, es := range s {
        var u set
        for _, er := range r {
            er := er.(set)
            u = append(u, append(er[:len(er):len(er)], es))
        }
        r = append(r, u...)
    }
    return r
}

func main() {
    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")
        }
    }
}





VB: Option Base 1
Private Function power_set(ByRef st As Collection) As Collection
    Dim subset As Collection, pwset As New Collection
    For i = 0 To 2 ^ st.Count - 1
        Set subset = New Collection
        For j = 1 To st.Count
            If i And 2 ^ (j - 1) Then subset.Add st(j)
        Next j
        pwset.Add subset
    Next i
    Set power_set = pwset
End Function
Private Function print_set(ByRef st As Collection) As String
    
    Dim s() As String, t() As String
    ReDim s(st.Count)
    
    For i = 1 To st.Count
        If st(i).Count > 0 Then
            ReDim t(st(i).Count)
            For j = 1 To st(i).Count
                Select Case TypeName(st(i)(j))
                    Case "Integer": t(j) = CStr(st(i)(j))
                    Case "Collection": t(j) = "{}" 
                End Select
            Next j
            s(i) = "{" & Join(t, ", ") & "}"
        Else
            s(i) = "{}"
        End If
    Next i
    print_set = "{" & Join(s, ", ") & "}"
End Function
Public Sub rc()
    Dim rcset As New Collection, result As Collection
    For i = 1 To 4
        rcset.Add i
    Next i
    Debug.Print print_set(power_set(rcset))
    Set rcset = New Collection
    Debug.Print print_set(power_set(rcset))
    Dim emptyset As New Collection
    rcset.Add emptyset
    Debug.Print print_set(power_set(rcset))
    Debug.Print
End Sub