Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update list-ops #702

Merged
merged 2 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,7 @@
"uuid": "21c90e54-55b3-4f23-af90-00323964027b",
"practices": [],
"prerequisites": [],
"difficulty": 1,
"status": "wip"
"difficulty": 5
},
{
"slug": "luhn",
Expand Down
9 changes: 5 additions & 4 deletions exercises/practice/list-ops/.meta/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
"contributors": [
"kytrinyx",
"m-dango",
"rfilipo"
"rfilipo",
"glennj"
],
"files": {
"solution": [
"ListOps.pm"
"lib/ListOps.pm"
],
"test": [
"list-ops.t"
"t/list-ops.t"
],
"example": [
".meta/solutions/ListOps.pm"
".meta/solutions/lib/ListOps.pm"
]
},
"blurb": "Implement basic list operations."
Expand Down
43 changes: 0 additions & 43 deletions exercises/practice/list-ops/.meta/solutions/ListOps.pm

This file was deleted.

50 changes: 50 additions & 0 deletions exercises/practice/list-ops/.meta/solutions/lib/ListOps.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package ListOps;

use strict;
use warnings;
use experimental qw<signatures postderef postderef_qq>;

sub append ( $list1, $list2 ) {
return [ @$list1, @$list2 ];
}

sub foldl ( $func, $initial, $list ) {
my $a = $initial;
foreach my $e (@$list) {
$a = $func->( $a, $e );
}
return $a;
}

# all the rest can be implemented with append and foldl
sub concat ($lists) {
foldl sub ( $acc, $list ) { append $acc, $list }, [], $lists;
}

sub map ( $func, $list ) {
my $f = sub ( $acc, $el ) { append $acc, [ $func->($el) ] };
foldl $f, [], $list;
}

sub filter ( $func, $list ) {
my $f = sub ( $acc, $el ) {
$acc = append $acc, [$el] if $func->($el);
$acc;
};
foldl $f, [], $list;
}

sub length ($list) {
foldl sub ( $len, $el ) { $len + 1 }, 0, $list;
}

sub reverse ($list) {
my $f = sub ( $acc, $el ) { append [$el], $acc };
foldl $f, [], $list;
}

sub foldr ( $func, $initial, $list ) {
foldl $func, $initial, ListOps::reverse $list;
}

1;
1 change: 0 additions & 1 deletion exercises/practice/list-ops/.meta/solutions/list-ops.t

This file was deleted.

1 change: 1 addition & 0 deletions exercises/practice/list-ops/.meta/solutions/t/list-ops.t
227 changes: 227 additions & 0 deletions exercises/practice/list-ops/.meta/template-data.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
subs:
modules:
- use: experimental qw<signatures>;

properties:
append:
test: |-
use Data::Dmp;
sprintf(<<'END', map {dmp($_)} $case->{input}{list1}, $case->{input}{list2}, $case->{expected}, $case->{description});
{
my $appended = ListOps::append %s, %s;
is(
$appended,
%s,
%s,
);
}
END

concat:
test: |-
use Data::Dmp;
sprintf(<<'END', map {dmp($_)} $case->{input}{lists}, $case->{expected}, $case->{description});
{
my $concatenated = ListOps::concat %s;
is(
$concatenated,
%s,
%s,
);
}
END

filter:
test: |-
use Data::Dmp;
if ($case->{input}{function} ne '(x) -> x modulo 2 == 1') {
die "template-data needs updating for new canonical data: $case->{description}";
}
sprintf(<<'END', 'sub ($el) {$el % 2 == 1}', map {dmp($_)} $case->{input}{list}, $case->{expected}, $case->{description});
{
my $filtered = ListOps::filter %s, %s;
is(
$filtered,
%s,
%s,
);
}
END

length:
test: |-
use Data::Dmp;
sprintf(<<'END', dmp($case->{input}{list}), $case->{expected}, dmp($case->{description}));
{
my $len = ListOps::length %s;
is(
$len,
%s,
%s,
);
}
END

map:
test: |-
use Data::Dmp;
if ($case->{input}{function} ne '(x) -> x + 1') {
die "template-data needs updating for new canonical data: $case->{description}";
}
sprintf(<<'END', 'sub ($el) {$el + 1}', map {dmp($_)} $case->{input}{list}, $case->{expected}, $case->{description});
{
my $mapped = ListOps::map %s, %s;
is(
$mapped,
%s,
%s,
);
}
END

foldl:
test: |-
use Data::Dmp;
my $func;
if ($case->{input}{function} =~ /\*/) {
$func = 'sub ($acc, $el) { $acc * $el }';
}
elsif ($case->{input}{function} =~ /\+/) {
$func = 'sub ($acc, $el) { $acc + $el }';
}
elsif ($case->{input}{function} =~ /\//) {
$func = 'sub ($acc, $el) { $el / $acc }';
}
else {
die;
}
sprintf(<<'END', $func, $case->{input}{initial}, dmp($case->{input}{list}), $case->{expected}, dmp($case->{description}));
{
my $func = %s;
my $result = ListOps::foldl $func, %s, %s;
is(
$result,
%s,
%s,
);
}
END

foldr:
test: |-
use Data::Dmp;
my $func;
if ($case->{input}{function} =~ /\*/) {
$func = 'sub ($acc, $el) { $el * $acc }';
}
elsif ($case->{input}{function} =~ /\+/) {
$func = 'sub ($acc, $el) { $el + $acc }';
}
elsif ($case->{input}{function} =~ /\//) {
$func = 'sub ($acc, $el) { $el / $acc }';
}
else {
die;
}
sprintf(<<'END', $func, $case->{input}{initial}, dmp($case->{input}{list}), $case->{expected}, dmp($case->{description}));
{
my $func = %s;
my $result = ListOps::foldr $func, %s, %s;
is(
$result,
%s,
%s,
);
}
END

reverse:
test: |-
use Data::Dmp;
sprintf(<<'END', map {dmp($_)} $case->{input}{list}, $case->{expected}, $case->{description});
{
my $reversed = ListOps::reverse %s;
is(
$reversed,
%s,
%s,
);
}
END

stub: |-
sub append ($list1, $list2) {
return undef;
}

sub concat ($lists) {
return undef;
}

sub filter ($func, $list) {
return undef;
}

sub length ($list) {
return undef;
}

sub map ($func, $list) {
return undef;
}

sub foldl ($func, $initial, $list) {
return undef;
}

sub foldr ($func, $initial, $list) {
return undef;
}

sub reverse ($list) {
return undef;
}

example: |-
sub append ($list1, $list2) {
return [@$list1, @$list2];
}

sub foldl ($func, $initial, $list) {
my $a = $initial;
foreach my $e (@$list) {
$a = $func->($a, $e);
}
return $a;
}

# all the rest can be implemented with append and foldl
sub concat ($lists) {
foldl sub ($acc, $list) { append $acc, $list }, [], $lists;
}

sub map ($func, $list) {
my $f = sub ($acc, $el) { append $acc, [$func->($el)] };
foldl $f, [], $list;
}

sub filter ($func, $list) {
my $f = sub ($acc, $el) {
$acc = append $acc, [$el] if $func->($el);
$acc;
};
foldl $f, [], $list;
}

sub length ($list) {
foldl sub ($len, $el) { $len + 1 }, 0, $list;
}

sub reverse ($list) {
my $f = sub ($acc, $el) { append [$el], $acc };
foldl $f, [], $list;
}

sub foldr ($func, $initial, $list) {
foldl $func, $initial, ListOps::reverse $list;
}
Loading