diff options
| author | James Smith <js5@sanger.ac.uk> | 2023-04-29 01:31:43 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-29 01:31:43 +0100 |
| commit | 93286b085a8ddf82818839c2f5ea9dc7c39ddec4 (patch) | |
| tree | 28ce2c3eddc50c4d6f74b2e7438de52127d115df | |
| parent | 66610716f555bb2fa355efcffe254e2e15569e61 (diff) | |
| download | perlweeklychallenge-club-93286b085a8ddf82818839c2f5ea9dc7c39ddec4.tar.gz perlweeklychallenge-club-93286b085a8ddf82818839c2f5ea9dc7c39ddec4.tar.bz2 perlweeklychallenge-club-93286b085a8ddf82818839c2f5ea9dc7c39ddec4.zip | |
Update README.md
| -rw-r--r-- | challenge-214/james-smith/README.md | 83 |
1 files changed, 46 insertions, 37 deletions
diff --git a/challenge-214/james-smith/README.md b/challenge-214/james-smith/README.md index 453d499639..6ca4fd0e74 100644 --- a/challenge-214/james-smith/README.md +++ b/challenge-214/james-smith/README.md @@ -1,7 +1,7 @@ -[< Previous 212](https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-212/james-smith) | -[Next 214 >](https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-214/james-smith) +[< Previous 213](https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-213/james-smith) | +[Next 215 >](https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-215/james-smith) -# The Weekly Challenge 213 - Another one rides the bus! +# The Weekly Challenge 214 - Another one rides the bus! You can find more information about this weeks, and previous weeks challenges at: @@ -15,55 +15,64 @@ You can find the solutions here on github at: https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-214/james-smith -# Task 1: Fun Sort +# TASK #1: Rank Score -***You are given a list of positive integers. Write a script to sort the all even integers first then all odds in ascending order.*** +***You are given a list of scores (>=1). Write a script to rank each score in descending order. First three will get medals i.e. G (Gold), S (Silver) and B (Bronze). Rest will just get the ranking number.*** ## Solution ```perl -sub fun_sort { - sort { $a%2 <=> $b%2 || $a <=> $b } @_ +sub rank { + map { ['','G','S','B']->[$_] || $_ } + map { //; 1 + grep { $_ > $' } @_ } + @_ } ``` -This was a simple challenge this week - firstly to sort odd from even we look at the last bit of the string - if even it is `0`, if odd `1`. So to get the even numbers before the odds we just sort on `$a%2 <=> $b%2` - we complete the sort by then sorting numerically. +Simple solution we get the rank for each value by counting the number of elements greater than it and then coverting 1,2,3 to GSB -This is faster than splitting the numbers into two lists and sorting separately and recombining... and much shorter. +## Complex solution -# Task 2: Shortest Route - -***You are given a list of bidirectional routes defining a network of nodes, as well as source and destination node numbers. Write a script to find the route from source to destination that passes through fewest nodes.*** - -## Solution - -We use a graph walking algorithm. We start by generating a graph of all the nodes in the tree storing their neighbours. +```perl +sub rank2 { + my $pos=0; + @_ = sort { $b->[0] <=> $a->[0] } + map { [$_,$pos++,1] } + @_; + $_[$_][2] = $_[$_][0] == $_[$_-1][0] + ? $_[$_-1][2] + : $_ + 1 for 1..$#_; + map { ['','G','S','B']->[$_->[2]] || $_->[2] } + sort { $a->[1] <=> $b->[1] } + @_ +} +``` -We then need to try out all paths. +# TASK #2: Collect Points -Note in this solution we walk backwards (this is due to the golf trick in line which creates the initial queue element as -a wrapper round the end node - can't do this with the start node as `my(@q,$e)` would put all values in `@q`. +***You are given a list of numbers. You will perform a series of removal operations. For each operation, you remove from the list N (one or more) equal and consecutive numbers, and add to your score N × N. Determine the maximum possible score.*** -So we start with a list of length 0 ($e), we then look to all neighbough's and compute the lists of length for the neighbours 1. At any point if we reach the start node then we return the list. +## Solution -The nice thing with this solution is that the code is `O(n^2)` +A brute force approach is best here - we look for sequences of digits - remove from the list and add the "collect" call on the list with the sequence removed.. And we collect the best score ```perl -sub shortest_route { - my( $s, @q, %n, %d ) = ( shift, [my $e = shift] ); ## Get start end, and initialize queue - return $s if $s eq $e; ## special case - as the soln only - ## returns list of length 1 or more - for my $r (@_) { ## Compute neighbour map. - $n{ $r->[$_-1] }{ $r->[$_] } = ## We need to walk both ways along the - $n{ $r->[$_] }{ $r->[$_-1] } = 1 for 1..$#$r; ## route - so we start from the 2nd - } ## so we don't fall off the LH end - while( my $p = shift @q ) { ## For each queue - $d{$p->[0]}=1; ## mark element as seen.. - $_ eq $s ? return ($_,@{$p}) : $push @q, [$_,@{$p}] ## For each new node. If it is the - for grep{ !$d{$_} } keys %{$n{$p->[0]}}; ## start we return the list, o/w push - } ## it to the find all neighbours of - ## the current point we haven't - ## already seen - () ## Empty list - as no route +sub collect_cache { ## We will use recursion here. we take out each number in + ## turn and pass it back to the function + return 0 unless @_; ## The score for an empty list is 0 + my $m = 0; ## Create a variable for the max value + for ( my $e = my $o = 0; $o<@_; ) { ## Loop from start to finish - + ## there is no inc as the $o = $e at + ## the does the same think + my $e = $o; ## Reset the end of the list to the start + $e++ while $_[$o]==$_[$e]; ## Increment until we get to a different value + sub { $m=$_[0] if $m<$_[0] }->( ## Use and IIFE to collect max value + ($e-$o)**2 + ## Add square of elements to value + collect( @_[ 0..$o-1, $e..$#_ ] ## for the reduced list + ), $o = $e; + } + $m; } + + ``` |
