Stream and points
Weekly challenge 122 — 19 July 2021
Week 122: 19 Jul 2021
You are given a final score $score.
You can score 1 point, 2 points or 3 points in basketball.
Write a script to find out the different ways you can score $score.
Example 1 Input: $S = 4 Output: 1 1 1 1 1 1 2 1 2 1 1 3 2 1 1 2 2 3 1 Example 2: Input: $S = 5 Output: 1 1 1 1 1 1 1 1 2 1 1 2 1 1 1 3 1 2 1 1 1 2 2 1 3 1 2 1 1 1 2 1 2 2 2 1 2 3 3 1 1 3 2
Basketball scores can be quite large numbers, so the number of possible patterns of points won can be huge: for example, in a recent game Newcastle Eagles scored 99 against the Surrey 89ers 72.
The 99 score could be anything from 99 scores of 1 down to 33 scores of 3. So we might be thinking of looking at all the permutations of 99 numbers in the range 0 to 3 and discarding those where the sum exceeded 99. But there are more than 10**155 such permutations, so that's not practical.
Instead, I have gone for a recursive solution. Recusrion is relatively slow in Perl and the code is not always easy to follow (or to write), but as we're not looking at scores of 99 it should work.
The principle is this. The subroutine next_point
takes 3 inputs:
$score, which is the score so far
$target, which is the end score we are investigating, say 5
$so_far, which is a text string of the scores so farSo initially we call next_point(0, 5, ''). We try adding
1, 2 or 3 points to $score, and if:
$score == $target we record this as a candidate answer
$score > $target we return because this can't be the path to an allowed total score
$score < $target we append the current score to $so_far
and recursively call next_point to try adding the score of the next playThat works in milliseonds for a score up to 10, in a few seconds for 20 and 45 seconds for 25, but most of that time is spent outputting the numbers.
And we can with virtual certainty assert that the order in which the points were scored in the Newcastle/Surrey game had never happened before and will never happen again!
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2021-07-19 use utf8; # Week 122 - task 2 - Basketball points use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; basketball_points(1); basketball_points(5); basketball_points(8); sub basketball_points { my ($points, $max, $k, $this); # initialise $points = shift; say qq[\nInput: $points\nOutput: ]; next_point(0, $points, ' '); } sub next_point { my ($score, $target, $this_point, $so_far, $score_in, $score_this); # initialise ($score, $target, $so_far) = @_; # try adding 1, 2 or 3 for $this_point (1, 2, 3) { $score_this = $score + $this_point; # found a possible, report it if ($score_this == $target) { say qq[$so_far $this_point]; return; # still below target so add more } elsif ($score_this < $target) { next_point($score_this + 0, $target, qq[$so_far $this_point] . ''); # above target so give up } else { return; } } }
last updated 2026-03-07 — 17 lines of code
Input: 1 Output: 1 Input: 5 Output: 1 1 1 1 1 1 1 1 2 1 1 2 1 1 1 3 1 2 1 1 1 2 2 1 3 1 2 1 1 1 2 1 2 2 2 1 2 3 3 1 1 3 2 Input: 8 Output: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 2 1 1 1 1 1 1 3 1 1 1 1 2 1 1 1 1 1 1 2 2 1 1 1 1 3 1 1 1 1 2 1 1 1 1 1 1 2 1 2 1 1 1 2 2 1 1 1 1 2 3 1 1 1 3 1 1 1 1 1 3 2 1 1 2 1 1 1 1 1 1 2 1 1 2 1 1 2 1 2 1 1 1 2 1 3 1 1 2 2 1 1 1 1 2 2 2 1 1 2 3 1 1 1 3 1 1 1 1 1 3 1 2 1 1 3 2 1 1 1 3 3 1 2 1 1 1 1 1 1 2 1 1 1 2 1 2 1 1 2 1 1 2 1 1 3 1 2 1 2 1 1 1 2 1 2 2 1 2 1 3 1 1 2 2 1 1 1 1 2 2 1 2 1 2 2 2 1 1 2 2 3 1 2 3 1 1 1 2 3 2 1 3 1 1 1 1 1 3 1 1 2 1 3 1 2 1 1 3 1 3 1 3 2 1 1 1 3 2 2 1 3 3 1 2 1 1 1 1 1 1 2 1 1 1 1 2 2 1 1 1 2 1 2 1 1 1 3 2 1 1 2 1 1 2 1 1 2 2 2 1 1 3 1 2 1 2 1 1 1 2 1 2 1 2 2 1 2 2 1 2 1 2 3 2 1 3 1 1 2 1 3 2 2 2 1 1 1 1 2 2 1 1 2 2 2 1 2 1 2 2 1 3 2 2 2 1 1 2 2 2 2 2 2 3 1 2 3 1 1 1 2 3 1 2 2 3 2 1 2 3 3 3 1 1 1 1 1 3 1 1 1 2 3 1 1 2 1 3 1 1 3 3 1 2 1 1 3 1 2 2 3 1 3 1 3 2 1 1 1 3 2 1 2 3 2 2 1 3 2 3 3 3 1 1 3 3 2
Any content of this website which has been created by Peter Campbell Smith is in the public domain