diff options
| author | Jörg Sommrey <28217714+jo-37@users.noreply.github.com> | 2020-07-28 08:29:10 +0200 |
|---|---|---|
| committer | Jörg Sommrey <28217714+jo-37@users.noreply.github.com> | 2020-07-30 17:56:23 +0200 |
| commit | 80c31f681a661b3f4c7356d2bba5caa2f10939c6 (patch) | |
| tree | 326a579601e7f272f2a8660b6743f63970166ce4 | |
| parent | 1ff0e52d796f5ad1602bdf014df2650f98993217 (diff) | |
| download | perlweeklychallenge-club-80c31f681a661b3f4c7356d2bba5caa2f10939c6.tar.gz perlweeklychallenge-club-80c31f681a661b3f4c7356d2bba5caa2f10939c6.tar.bz2 perlweeklychallenge-club-80c31f681a661b3f4c7356d2bba5caa2f10939c6.zip | |
solution for task 2
| -rwxr-xr-x | challenge-071/jo-37/perl/ch-2.pl | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/challenge-071/jo-37/perl/ch-2.pl b/challenge-071/jo-37/perl/ch-2.pl new file mode 100755 index 0000000000..e999078810 --- /dev/null +++ b/challenge-071/jo-37/perl/ch-2.pl @@ -0,0 +1,66 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use LinkedList::Single; + +# Print the node data from a linked list. +sub list_print { + my $list = shift; + + for ($list->head; $list->has_next; $list->next) { + print $list->node_data->[0], " -> "; + } + print $list->node_data->[0], "\n" +} + +# Remove n-th last element from the list. +sub remove_from_end { + my ($list, $n) = @_; + + # Create a new singly linked list that will hold at most $n + # "position pointers" into the original list. 'undef' is used + # as a pseudo-pointer referencing the original list's first node + # and is stored in the new list's first node. + my $record = LinkedList::Single->new(undef); + my $len = 1; + + # Process all nodes but the last from the original list. + for ($list->head; $list->has_next; $list->next) { + + # Record the position and skip over the new node. + $record->add($list->node)->next; + + # Discard the first recorded position if the maximum length + # is exceeded. + $record->shift if ++$len > $n; + } + + # Retrieve the cut-node position from the first node of the record + # list, reposition the original list and cut the next node or + # remove the first node. + # Note: "cut" removes the next node after the current and thus + # cannot be used to remove the first node, where a "shift" is + # required. + my $node = $record->head->node_data->[0]; + if ($node) { + $list->node($node); + $list->cut; + } else { + $list->shift; + } + + $list; +} + +my $L = 5; + +for my $N (1 .. 6) { + my $list = LinkedList::Single->new(1 .. $L); + if ($N == 1) { + print "List:\n"; + list_print $list; + } + print "N=$N\n"; + list_print remove_from_end $list, $N; +} |
