2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -1,20 +1,31 @@
{{omit from|GUISS}}
A [[set]] is a collection (container) of certain values,
A   [[set]]   is a collection (container) of certain values,
without any particular order, and no repeated values.
It corresponds with a finite set in mathematics.
A set can be implemented as an associative array (partial mapping)
in which the value of each key-value pair is ignored.
Given a set S, the [[wp:Power_set|power set]] (or powerset) of S, written P(S), or 2<sup>S</sup>, is the set of all subsets of S.<br />
'''Task : ''' By using a library or built-in set type, or by defining a set type with necessary operations, write a function with a set S as input that yields the power set 2<sup>S</sup> of S.
Given a set S, the [[wp:Power_set|power set]] (or powerset) of S, written P(S), or 2<sup>S</sup>, is the set of all subsets of S.
For example, the power set of {1,2,3,4} is {{}, {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}}.
;Task:
By using a library or built-in set type, or by defining a set type with necessary operations, write a function with a set S as input that yields the power set 2<sup>S</sup> of S.
For example, the power set of &nbsp; &nbsp; {1,2,3,4} &nbsp; &nbsp; is
::: {{}, {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}}.
For a set which contains n elements, the corresponding power set has 2<sup>n</sup> elements, including the edge cases of [[wp:Empty_set|empty set]].<br />
The power set of the empty set is the set which contains itself (2<sup>0</sup> = 1):<br />
<math>\mathcal{P}</math>(<math>\varnothing</math>) = { <math>\varnothing</math> }<br />
::: <math>\mathcal{P}</math>(<math>\varnothing</math>) = { <math>\varnothing</math> }<br />
And the power set of the set which contains only the empty set, has two subsets, the empty set and the set which contains the empty set (2<sup>1</sup> = 2):<br />
<math>\mathcal{P}</math>({<math>\varnothing</math>}) = { <math>\varnothing</math>, { <math>\varnothing</math> } }<br>
::: <math>\mathcal{P}</math>({<math>\varnothing</math>}) = { <math>\varnothing</math>, { <math>\varnothing</math> } }<br>
'''Extra credit: ''' Demonstrate that your language supports these last two powersets.
<br><br>

View file

@ -0,0 +1,83 @@
(* ****** ****** *)
//
#include
"share/atspre_define.hats" // defines some names
#include
"share/atspre_staload.hats" // for targeting C
#include
"share/HATS/atspre_staload_libats_ML.hats" // for ...
//
(* ****** ****** *)
//
extern
fun
Power_set(xs: list0(int)): void
//
(* ****** ****** *)
// Helper: fast power function.
fun power(n: int, p: int): int =
if p = 1 then n
else if p = 0 then 1
else if p % 2 = 0 then power(n*n, p/2)
else n * power(n, p-1)
fun print_list(list: list0(int)): void =
case+ list of
| nil0() => println!(" ")
| cons0(car, crd) =>
let
val () = begin print car; print ','; end
val () = print_list(crd)
in
end
fun get_list_length(list: list0(int), length: int): int =
case+ list of
| nil0() => length
| cons0(car, crd) => get_list_length(crd, length+1)
fun get_list_from_bit_mask(mask: int, list: list0(int), result: list0(int)): list0(int) =
if mask = 0 then result
else
case+ list of
| nil0() => result
| cons0(car, crd) =>
let
val current: int = mask % 2
in
if current = 0 then
get_list_from_bit_mask(mask >> 1, crd, result)
else
get_list_from_bit_mask(mask >> 1, crd, list0_cons(car, result))
end
implement
Power_set(xs) = let
val len: int = get_list_length(xs, 0)
val pow: int = power(2, len)
fun loop(mask: int, list: list0(int)): void =
if mask > 0 && mask >= pow then ()
else
let
val () = print_list(get_list_from_bit_mask(mask, list, list0_nil()))
in
loop(mask+1, list)
end
in
loop(0, xs)
end
(* ****** ****** *)
implement
main0() =
let
val xs: list0(int) = cons0(1, list0_pair(2, 3))
in
Power_set(xs)
end (* end of [main0] *)
(* ****** ****** *)

View file

@ -0,0 +1,10 @@
cat power_set.awk
#!/usr/local/bin/gawk -f
# User defined function
function tochar(l,n, r) {
while (l) { n--; if (l%2 != 0) r = r sprintf(" %c ",49+n); l = int(l/2) }; return r
}
# For each input
{ for (i=0;i<=2^NF-1;i++) if (i == 0) printf("empty\n"); else printf("(%s)\n",tochar(i,NF)) }

View file

@ -0,0 +1,77 @@
-- powerset :: [a] -> [[a]]
on powerset(xs)
script subSet
on lambda(acc, x)
script consX
on lambda(y)
{x} & y
end lambda
end script
acc & map(consX, acc)
end lambda
end script
foldr(subSet, {{}}, xs)
end powerset
--------------------------------------------------------------------------------------
-- TEST
on run
script test
on lambda(x)
set {setName, setMembers} to x
{setName, powerset(setMembers)}
end lambda
end script
map(test, [¬
["Set [1,2,3]", {1, 2, 3}], ¬
["Empty set", {}], ¬
["Set containing only empty set", {{}}]])
--> {{"Set [1,2,3]", {{}, {3}, {2}, {2, 3}, {1}, {1, 3}, {1, 2}, {1, 2, 3}}},
--> {"Empty set", {{}}},
--> {"Set containing only empty set", {{}, {{}}}}}
end run
-- GENERIC FUNCTIONS ---------------------------------------------------------------
-- foldr :: (a -> b -> a) -> a -> [b] -> a
on foldr(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from lng to 1 by -1
set v to lambda(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldr
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to lambda(item i of xs, i, xs)
end repeat
return lst
end tell
end map
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property lambda : f
end script
end if
end mReturn

View file

@ -0,0 +1,3 @@
{{"Set [1,2,3]", {{}, {3}, {2}, {2, 3}, {1}, {1, 3}, {1, 2}, {1, 2, 3}}},
{"Empty set", {{}}},
{"Set containing only empty set", {{}, {{}}}}}

View file

@ -1,9 +1,9 @@
package main
import (
"bytes"
"fmt"
"strconv"
"bytes"
"fmt"
"strconv"
)
// types needed to implement general purpose sets are element and set
@ -11,25 +11,25 @@ import (
// element is an interface, allowing different kinds of elements to be
// implemented and stored in sets.
type elem interface {
// 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
// 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
}
// integer type satisfying element interface
type Int int
func (i Int) Eq(e elem) bool {
j, ok := e.(Int)
return ok && i == j
j, ok := e.(Int)
return ok && i == j
}
func (i Int) String() string {
return strconv.Itoa(int(i))
return strconv.Itoa(int(i))
}
// a set is a slice of elem's. methods are added to implement
@ -38,80 +38,104 @@ type set []elem
// uniqueness of elements can be ensured by using add method
func (s *set) add(e elem) {
if !s.has(e) {
*s = append(*s, e)
}
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
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
}
// elem.Eq
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
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
}
// elem.String
func (s set) String() string {
if len(s) == 0 {
return "∅"
}
var buf bytes.Buffer
buf.WriteRune('{')
for i, e := range s {
if i > 0 {
buf.WriteRune(',')
}
buf.WriteString(e.String())
}
buf.WriteRune('}')
return buf.String()
if len(s) == 0 {
return "∅"
}
var buf bytes.Buffer
buf.WriteRune('{')
for i, e := range s {
if i > 0 {
buf.WriteRune(',')
}
buf.WriteString(e.String())
}
buf.WriteRune('}')
return buf.String()
}
// method required for task
func (s set) powerSet() set {
r := set{set{}}
for _, es := range s {
var u set
for _, er := range r {
u = append(u, append(er.(set), es))
}
r = append(r, u...)
}
return r
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))
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))
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(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")
}
}
}

View file

@ -1 +1,2 @@
powerSet :: [a] -> [[a]]
powerset = foldr (\x acc -> acc ++ map (x:) acc) [[]]

View file

@ -0,0 +1,21 @@
(function () {
// translating: powerset = foldr (\x acc -> acc ++ map (x:) acc) [[]]
function powerset(xs) {
return xs.reduceRight(function (a, x) {
return a.concat(a.map(function (y) {
return [x].concat(y);
}));
}, [[]]);
}
// TEST
return {
'[1,2,3] ->': powerset([1, 2, 3]),
'empty set ->': powerset([]),
'set which contains only the empty set ->': powerset([[]])
}
})();

View file

@ -0,0 +1,5 @@
{
"[1,2,3] ->":[[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]],
"empty set ->":[[]],
"set which contains only the empty set ->":[[], [[]]]
}

View file

@ -0,0 +1,19 @@
(() => {
'use strict';
// powerset :: [a] -> [[a]]
const powerset = xs =>
xs.reduceRight((a, x) => a.concat(a.map(y => [x].concat(y))), [
[]
]);
// TEST
return {
'[1,2,3] ->': powerset([1, 2, 3]),
'empty set ->': powerset([]),
'set which contains only the empty set ->': powerset([
[]
])
};
})()

View file

@ -0,0 +1,3 @@
{"[1,2,3] ->":[[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]],
"empty set ->":[[]],
"set which contains only the empty set ->":[[], [[]]]}

View file

@ -1,30 +1,29 @@
/*REXX pgm displays a power set, items may be anything (but can't have blanks)*/
parse arg S /*allow the user specify optional set. */
if S='' then S='one two three four' /*None specified? Then use the default*/
N=words(S) /*the number of items in the list (set)*/
@='{}' /*start process with a null power set. */
do chunk=1 for N /*traipse through the items in the set.*/
@=@ combN(N,chunk) /*take N items, a CHUNK at a time. */
end /*chunk*/
w=length(2**N) /*the number of items in the power set.*/
do k=1 for words(@) /* [↓] show combinations, one per line*/
say right(k,w) word(@,k) /*display a single combination to term.*/
end /*k*/
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
combN: procedure expose S; parse arg x,y; base=x+1; bbase=base-y; !.=0
do p=1 for y; !.p=p; end /*p*/
$=
do j=1; L=
do d=1 for y; L=L','word(S,!.d)
end /*d*/
$=$ '{'strip(L,'L',",")'}'
!.y=!.y+1; if !.y==base then if .combU(y-1) then leave
end /*j*/
return strip($) /*return with a partial powerset chunk.*/
/*────────────────────────────────────────────────────────────────────────────*/
.combU: procedure expose !. y bbase; parse arg d; if d==0 then return 1; p=!.d
do u=d to y; !.u=p+1; if !.u==bbase+u then return .combU(u-1)
p=!.u
end /*u*/
return 0
/*REXX program displays a power set; items may be anything (but can't have blanks).*/
parse arg S /*allow the user specify optional set. */
if S='' then S= 'one two three four' /*Not specified? Then use the default.*/
@='{}' /*start process with a null power set. */
N=words(S); do chunk=1 for N /*traipse through the items in the set.*/
@=@ combN(N, chunk) /*take N items, a CHUNK at a time. */
end /*chunk*/
w=length(2**N) /*the number of items in the power set.*/
do k=1 for words(@) /* [↓] show combinations, one per line*/
say right(k, w) word(@, k) /*display a single combination to term.*/
end /*k*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
combN: procedure expose S; parse arg x,y; base=x+1; bbase=base-y; !.=0
do p=1 for y; !.p=p; end /*p*/
$=
do j=1; L=
do d=1 for y; L=L','word(S, !.d)
end /*d*/
$=$ '{'strip(L, "L", ',')"}"
!.y=!.y+1; if !.y==base then if .combU(y-1) then leave
end /*j*/
return strip($) /*return with a partial powerset chunk.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
.combU: procedure expose !. y bbase; parse arg d; if d==0 then return 1; p=!.d
do u=d to y; !.u=p+1; if !.u==bbase+u then return .combU(u-1)
p=!.u
end /*u*/
return 0

View file

@ -0,0 +1,7 @@
def powerset[A](s: Set[A]) = {
def powerset_rec(acc: List[Set[A]], remaining: List[A]): List[Set[A]] = remaining match {
case Nil => acc
case head :: tail => powerset_rec(acc ++ acc.map(_ + head), tail)
}
powerset_rec(List(Set.empty[A]), s.toList)
}