Skip to content

Commit aaba081

Browse files
sshineDaniel Mita
authored andcommitted
custom-set: Stub, order of methods, rename some methods (#286)
1 parent d4014ab commit aaba081

File tree

3 files changed

+179
-125
lines changed

3 files changed

+179
-125
lines changed

exercises/custom-set/.meta/solutions/CustomSet.pm

Lines changed: 33 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,74 @@
11
package CustomSet;
2-
32
use strict;
43
use warnings;
54

65
sub new {
7-
my $class = shift;
8-
6+
my ($class, @members) = @_;
97
my %set;
10-
@set{ @_ } = ();
11-
8+
@set{ @members } = ();
129
bless \%set, $class;
1310
}
1411

1512
sub add {
16-
my( $self, $new ) = @_;
17-
18-
$self->{$new} = 1;
13+
my ($self, $member) = @_;
14+
$self->{$member} = 1;
1915
return $self;
2016
}
2117

22-
sub delete :method {
23-
my( $self, $member ) = @_;
24-
18+
sub remove {
19+
my ($self, $member) = @_;
2520
delete $self->{$member};
2621
return $self;
2722
}
2823

29-
sub union {
30-
my( $self, $other ) = @_;
31-
32-
return __PACKAGE__->new( keys %$self, keys %$other );
24+
sub is_empty {
25+
my ($self) = @_;
26+
return !%$self;
3327
}
3428

35-
sub difference {
36-
my( $self, $other ) = @_;
37-
38-
return __PACKAGE__->new( grep { ! $other->is_member($_) } keys %$self );
29+
sub is_member {
30+
my ($self, $member) = @_;
31+
return exists $self->{$member};
3932
}
4033

41-
42-
sub is_disjoint {
43-
my( $self, $other ) = @_;
44-
45-
return $self->intersect( $other )->size() == 0;
34+
sub size {
35+
my ($self) = @_;
36+
return scalar keys %$self;
4637
}
4738

48-
sub empty {
49-
my $self = shift;
39+
sub to_list {
40+
my ($self) = @_;
41+
return keys %$self;
42+
}
5043

51-
%$self = ();
52-
return $self;
44+
sub union {
45+
my ($self, $other) = @_;
46+
return __PACKAGE__->new( keys %$self, keys %$other );
5347
}
5448

5549
sub intersect {
56-
my( $self, $other ) = @_;
57-
50+
my ($self, $other) = @_;
5851
return __PACKAGE__->new( grep { $self->is_member($_) } keys %$other );
5952
}
6053

61-
sub is_member {
62-
my( $self, $member ) = @_;
63-
64-
return exists $self->{$member};
54+
sub difference {
55+
my ($self, $other) = @_;
56+
return __PACKAGE__->new( grep { !$other->is_member($_) } keys %$self );
6557
}
6658

67-
sub size {
68-
my $self = shift;
69-
70-
return scalar keys %$self;
59+
sub is_disjoint {
60+
my ($self, $other) = @_;
61+
return $self->intersect($other)->is_empty;
7162
}
7263

7364
sub is_subset {
74-
my( $self, $other ) = @_;
75-
76-
return $self->intersect( $other )->size() == $other->size();
77-
}
78-
79-
sub to_list {
80-
my $self = shift;
81-
82-
return keys %$self;
65+
my ($self, $other) = @_;
66+
return $other->difference($self)->is_empty;
8367
}
8468

8569
sub is_equal {
86-
my( $self, $other ) = @_;
87-
88-
return $self->intersect($other)->size() == $self->size() && $self->size() == $other->size();
70+
my ($self, $other) = @_;
71+
return $self->is_subset($other) && $other->is_subset($self);
8972
}
9073

9174
1;

exercises/custom-set/CustomSet.pm

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package CustomSet;
2+
use strict;
3+
use warnings;
4+
5+
# Replace `...` with a correct implementation.
6+
# https://perldoc.pl/perlsyn#The-Ellipsis-Statement
7+
8+
sub new {
9+
my ($class, @members) = @_;
10+
...;
11+
}
12+
13+
sub add {
14+
my ($self, $member) = @_;
15+
...;
16+
}
17+
18+
sub remove {
19+
my ($self, $member) = @_;
20+
...;
21+
}
22+
23+
sub is_empty {
24+
my ($self) = @_;
25+
...;
26+
}
27+
28+
sub is_member {
29+
my ($self, $member) = @_;
30+
...;
31+
}
32+
33+
sub size {
34+
my ($self) = @_;
35+
...;
36+
}
37+
38+
sub to_list {
39+
my ($self) = @_;
40+
...;
41+
}
42+
43+
sub union {
44+
my ($self, $other) = @_;
45+
...;
46+
}
47+
48+
sub intersect {
49+
my ($self, $other) = @_;
50+
...;
51+
}
52+
53+
sub difference {
54+
my ($self, $other) = @_;
55+
...;
56+
}
57+
58+
sub is_disjoint {
59+
my ($self, $other) = @_;
60+
...;
61+
}
62+
63+
sub is_subset {
64+
my ($self, $other) = @_;
65+
...;
66+
}
67+
68+
sub is_equal {
69+
my ($self, $other) = @_;
70+
...;
71+
}
72+
73+
1;

exercises/custom-set/custom-set.t

Lines changed: 73 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ my $module = 'CustomSet';
1010

1111
use_ok($module) or BAIL_OUT("You need to create a module called $module.pm");
1212

13-
foreach my $f (qw/new delete difference is_disjoint empty intersect
14-
is_member add size is_subset to_list union is_equal/) {
15-
can_ok($module, $f) or BAIL_OUT("You need to implement the function '$f'");
13+
for my $method (qw(
14+
new add remove is_empty
15+
is_member size to_list
16+
union intersect difference
17+
is_disjoint is_equal is_subset)) {
18+
can_ok($module, $method) or BAIL_OUT("You need to implement the method '$method'");
1619
}
1720

1821
sub set { return $module->new(@_) };
@@ -23,15 +26,65 @@ subtest 'Tested new()' => sub {
2326
isa_ok( $module->new(), $module, "return value of new()" );
2427
};
2528

26-
subtest 'Tested equal()' => sub {
27-
plan tests => 6;
29+
subtest 'Tested add()' => sub {
30+
plan tests => 4;
2831

29-
ok( set(1,3)->is_equal( set(3,1) ), "order doesn't matter" );
30-
ok( set()->is_equal( set() ), "empty sets are equal" );
31-
ok( ! set(1..3)->is_equal( set(3..5) ), "different sets are not equal" );
32-
ok( ! set()->is_equal( set(1..3) ), "empty set is not equal to non-empty set" );
33-
ok( ! set(1..3)->is_equal( set() ), "non-empty set is not equal to empty set" );
34-
ok( ! set(1..4)->is_equal( set(3..6) ), "partial subsets are not equal" );
32+
isa_ok( set()->add(1), $module, "return value of add()" );
33+
ok( set()->add(1)->is_equal( set(1) ), "adding to empty set" );
34+
ok( set(1,2,4)->add(3)->is_equal( set(1..4) ), "adding to non-empty set" );
35+
ok( set(1,2,3)->add(3)->is_equal( set(1..3) ), "adding existing member is noop" );
36+
};
37+
38+
subtest 'Tested remove()' => sub {
39+
plan tests => 3;
40+
41+
isa_ok( set(3,2,1)->remove(2), $module, "return value of remove()" );
42+
ok( set(3,2,1)->remove(2)->is_equal( set(1,3) ), "removing single element" );
43+
ok( set(3,2,1)->remove(4)->is_equal( set(1..3) ), "removing non-existant element" );
44+
};
45+
46+
subtest 'Tested is_empty()' => sub {
47+
plan tests => 2;
48+
49+
ok( set()->is_empty(), "sets with no elements are empty" );
50+
ok( !set(1)->is_empty(), "sets with elements are not empty" );
51+
};
52+
53+
subtest 'Tested is_member()' => sub {
54+
plan tests => 4;
55+
56+
ok( set(1,2,3)->is_member(2), "element is member" );
57+
ok( set(1..10)->is_member(10), "edge element is also member" );
58+
ok( ! set(1..10)->is_member(11), "element is not member" );
59+
ok( ! set()->is_member(1), "nothing is member of the empty set" );
60+
};
61+
62+
subtest 'Tested size()' => sub {
63+
plan tests => 3;
64+
65+
is( set()->size(), 0, "size of empty set is 0" );
66+
is( set(1..3)->size(), 3, "size of set with 3 members is 3!" );
67+
is( set(1,2,3,2)->size(), 3, "size of set with 3 members is still 3!" );
68+
};
69+
70+
subtest 'Tested to_list()' => sub {
71+
plan tests => 3;
72+
73+
is_deeply( [ sort +set()->to_list() ], [], "empty set results in empty list" );
74+
is_deeply( [ sort +set(1..3)->to_list() ], [1,2,3], "set with elements results in list with elements" );
75+
is_deeply( [ sort +set(3,1,2,1)->to_list() ], [1,2,3], "set with duplicate elements still results in list with uniq elements" );
76+
};
77+
78+
subtest 'Tested union()' => sub {
79+
plan tests => 7;
80+
81+
isa_ok( set()->union( set() ), $module, "return value of union()" );
82+
ok( set()->union( set() )->is_equal( set() ), "union of empty sets is an empty set" );
83+
ok( set(2)->union( set() )->is_equal( set(2) ), "union of non-empty set and empty set is non-empty set" );
84+
ok( set()->union( set(2) )->is_equal( set(2) ), "union of empty set and non-empty set is non-empty set" );
85+
ok( set(1,3)->union( set(3,1) )->is_equal( set(1,3) ), "union with self is self" );
86+
ok( set(1,3)->union( set(2,4) )->is_equal( set(1..4) ), "small union" );
87+
ok( set(1..10, 20..30)->union( set(5..25) )->is_equal( set(1..30) ), "large union" );
3588
};
3689

3790
subtest 'Tested intersect()' => sub {
@@ -43,24 +96,7 @@ subtest 'Tested intersect()' => sub {
4396
ok( set(1..3)->intersect( set(4..6) )->is_equal( set() ), "nothing in common" );
4497
ok( set(1,3,5,7,9)->intersect( set(3..7) )->is_equal( set(3,5,7) ), "intersect with odd numbers" );
4598
ok( set()->intersect( set() )->is_equal( set() ), "an empty set is an empty set" );
46-
ok( set(1..3)->intersect( set(3) )->is_equal( set(3) ), "Intersect with unary set results in unary set" );
47-
};
48-
49-
subtest 'Tested delete()' => sub {
50-
plan tests => 3;
51-
52-
isa_ok( set(3,2,1)->delete(2), $module, "return value of delete()" );
53-
ok( set(3,2,1)->delete(2)->is_equal( set(1,3) ), "removing single element" );
54-
ok( set(3,2,1)->delete(4)->is_equal( set(1..3) ), "removing non-existant element" );
55-
};
56-
57-
subtest 'Tested add()' => sub {
58-
plan tests => 4;
59-
60-
isa_ok( set()->add(1), $module, "return value of add()" );
61-
ok( set()->add(1)->is_equal( set(1) ), "adding to empty set" );
62-
ok( set(1,2,4)->add(3)->is_equal( set(1..4) ), "adding to non-empty set" );
63-
ok( set(1,2,3)->add(3)->is_equal( set(1..3) ), "adding existing member is noop" );
99+
ok( set(1..3)->intersect( set(3) )->is_equal( set(3) ), "Intersect with unary set results in unary set" );
64100
};
65101

66102
subtest 'Tested difference()' => sub {
@@ -84,35 +120,6 @@ subtest 'Tested is_disjoint()' => sub {
84120
ok( set(1..3)->is_disjoint( set() ), "a non-empty set is disjoint to an empty set" );
85121
};
86122

87-
subtest 'Tested empty()' => sub {
88-
plan tests => 4;
89-
90-
isa_ok( set()->empty(), $module, "return value of empty()" );
91-
ok( set()->empty()->is_equal( set() ), "emptying empty set results in an empty set" );
92-
ok( set(1..3)->empty()->is_equal( set() ), "set empty after emptying (duh!)" );
93-
94-
my $set = set(1..3);
95-
$set->empty();
96-
ok( $set->is_equal( set() ), "not just an empty set returned, but set was emptied" );
97-
};
98-
99-
subtest 'Tested is_member()' => sub {
100-
plan tests => 4;
101-
102-
ok( set(1,2,3)->is_member(2), "element is member" );
103-
ok( set(1..10)->is_member(10), "edge element is also member" );
104-
ok( ! set(1..10)->is_member(11), "element is not member" );
105-
ok( ! set()->is_member(1), "nothing is member of the empty set" );
106-
};
107-
108-
subtest 'Tested size()' => sub {
109-
plan tests => 3;
110-
111-
is( set()->size(), 0, "size of empty set is 0" );
112-
is( set(1..3)->size(), 3, "size of set with 3 members is 3!" );
113-
is( set(1,2,3,2)->size(), 3, "size of set with 3 members is still 3!" );
114-
};
115-
116123
subtest 'Tested is_subset()' => sub {
117124
plan tests => 8;
118125

@@ -126,22 +133,13 @@ subtest 'Tested is_subset()' => sub {
126133
ok( ! set(1..10)->is_subset( set(1..3, 11) ), "smaller number of elements but still not a subset" );
127134
};
128135

129-
subtest 'Tested union()' => sub {
130-
plan tests => 7;
131-
132-
isa_ok( set()->union( set() ), $module, "return value of union()" );
133-
ok( set()->union( set() )->is_equal( set() ), "union of empty sets is an empty set" );
134-
ok( set(2)->union( set() )->is_equal( set(2) ), "union of non-empty set and empty set is non-empty set" );
135-
ok( set()->union( set(2) )->is_equal( set(2) ), "union of empty set and non-empty set is non-empty set" );
136-
ok( set(1,3)->union( set(3,1) )->is_equal( set(1,3) ), "union with self is self" );
137-
ok( set(1,3)->union( set(2,4) )->is_equal( set(1..4) ), "small union" );
138-
ok( set(1..10, 20..30)->union( set(5..25) )->is_equal( set(1..30) ), "large union" );
139-
};
140-
141-
subtest 'Tested to_list()' => sub {
142-
plan tests => 3;
136+
subtest 'Tested equal()' => sub {
137+
plan tests => 6;
143138

144-
is_deeply( [ sort +set()->to_list() ], [], "empty set results in empty list" );
145-
is_deeply( [ sort +set(1..3)->to_list() ], [1,2,3], "set with elements results in list with elements" );
146-
is_deeply( [ sort +set(3,1,2,1)->to_list() ], [1,2,3], "set with duplicate elements still results in list with uniq elements" );
139+
ok( set(1,3)->is_equal( set(3,1) ), "order doesn't matter" );
140+
ok( set()->is_equal( set() ), "empty sets are equal" );
141+
ok( ! set(1..3)->is_equal( set(3..5) ), "different sets are not equal" );
142+
ok( ! set()->is_equal( set(1..3) ), "empty set is not equal to non-empty set" );
143+
ok( ! set(1..3)->is_equal( set() ), "non-empty set is not equal to empty set" );
144+
ok( ! set(1..4)->is_equal( set(3..6) ), "partial subsets are not equal" );
147145
};

0 commit comments

Comments
 (0)