This is my response to The Weekly Challenge #263.
@ints
and a target element $k
.
Input: @ints = (1, 5, 3, 2, 4, 2), $k = 2
Output: (1, 2)
Sorted array: (1, 2, 2, 3, 4, 5)
Target indices: (1, 2) as $ints[1] = 2 and $ints[2] = 2
Example 2:
Input: @ints = (1, 2, 4, 3, 5), $k = 6
Output: ()
No element in the given array matching the given target.
Example 3:
Input: @ints = (5, 3, 2, 4, 2, 1), $k = 4
Output: (4)
Sorted array: (1, 2, 2, 3, 4, 5)
Target index: (4) as $ints[4] = 4
#! /usr/bin/env raku
unit sub MAIN (Int $k, # [1]
*@ints where @ints.elems > 0 && all(@ints) ~~ Int, # [2]
:v(:$verbose));
say ": Sorted: { @ints.sort.join(",") }" if $verbose;
say '(', (@ints.sort.grep: $k, :k).join(", "), ')'; # [3]
[1] First the $k
value, which must be an integer.
[2] Then the array of integers, at least one element.
[3] sort
the array, then use grep
to filter
out the $k
values - or rather the indices instead of the values
themselves as indicated with the :k
adverb. Pretty print the
result.
See docs.raku.org/routine/grep for more information about grep
.
See Unique Rank with Raku
for a short description of the :k
(keys) adverb.
Running it:
$ ./target-index 2 1 5 3 2 4 2
(1, 2)
$ ./target-index 6 1 2 4 3 5
()
$ ./target-index 4 5 3 2 4 2 1
(4)
With verbose mode:
: Sorted: 1,2,2,3,4,5
(1, 2)
$ ./target-index -v 6 1 2 4 3 5
: Sorted: 1,2,3,4,5
()
$ ./target-index -v 4 5 3 2 4 2 1
: Sorted: 1,2,2,3,4,5
(4)
$items1
and $items2
where element is pair of (item_id, item_quantity).
Input: $items1 = [ [1,1], [2,1], [3,2] ]
$items2 = [ [2,2], [1,3] ]
Output: [ [1,4], [2,3], [3,2] ]
Item id (1) appears 2 times: [1,1] and [1,3]. Merged item now (1,4)
Item id (2) appears 2 times: [2,1] and [2,2]. Merged item now (2,3)
Item id (3) appears 1 time: [3,2]
Example 2:
Input: $items1 = [ [1,2], [2,3], [1,3], [3,2] ]
$items2 = [ [3,1], [1,3] ]
Output: [ [1,8], [2,3], [3,3] ]
Example 3:
Input: $items1 = [ [1,1], [2,2], [3,3] ]
$items2 = [ [2,3], [2,4] ]
Output: [ [1,1], [2,9], [3,3] ]
#! /usr/bin/env raku
unit sub MAIN ($items1, $items2, :v(:$verbose)); # [1]
my @items1 = $items1.split("|")>>.words>>.Int; # [2]
my @items2 = $items2.split("|")>>.words>>.Int; # [2]
if $verbose
{
say ": items1: { @items1.raku }";
say ": items2: { @items2.raku }";
}
my %count; # [3]
for @items1 -> $item # [4]
{
say ": item1 ID $item[0] with frequency $item[1]";
%count{$item[0]} += $item[1]; # [4a]
}
for @items2 -> $item # [5]
{
say ": item2 ID $item[0] with frequency $item[1]";
%count{$item[0]} += $item[1]; # [5a]
}
my @output; # [6]
for sort keys %count -> $key # [7]
{
@output.push: ($key.Int, %count{$key}); # [7a]
}
say @output.raku; # [8]
[1] The two two dimentional arrays. See the "Running it" section below for how to specify the values.
[2] Convert the strings into two dimentional arrays.
[3] We are going to count the frequencies, using this hash.
[4] Iterate over the first array; add the count (the second part of the pair) to the value (the first part of the pair) in the hash [4a].
[5] As above, for the second array.
[6] The two dimentional array for the output output will end up here.
[7] Iterate over the keys (the original values) in sorted order. Add the key and the value (frequency) as a pair to the result. Note the coersion to integer, as it is a string otherwise.
[8] Print the result, uisng the raku
method.
See docs.raku.org/routine/raku for more information about raku
.
Running it:
$ ./merge-items "1 1 | 2 1 | 3 2" "2 2 | 1 3"
[(1, 4), (2, 3), (3, 2)]
$ ./merge-items "1 2 | 2 3 | 1 3 | 3 2" "3 1 | 1 3"
[(1, 8), (2, 3), (3, 3)]
$ ./merge-items "1 1 | 2 2 | 3 3" "2 3 | 2 4"
[(1, 1), (2, 9), (3, 3)]
Looking good.
With verbose mode:
$ ./merge-items -v "1 1 | 2 1 | 3 2" "2 2 | 1 3"
: items1: [(1, 1), (2, 1), (3, 2)]
: items2: [(2, 2), (1, 3)]
: item1 ID 1 with frequency 1
: item1 ID 2 with frequency 1
: item1 ID 3 with frequency 2
: item2 ID 2 with frequency 2
: item2 ID 1 with frequency 3
[(1, 4), (2, 3), (3, 2)]
$ ./merge-items -v "1 2 | 2 3 | 1 3 | 3 2" "3 1 | 1 3"
: items1: [(1, 2), (2, 3), (1, 3), (3, 2)]
: items2: [(3, 1), (1, 3)]
: item1 ID 1 with frequency 2
: item1 ID 2 with frequency 3
: item1 ID 1 with frequency 3
: item1 ID 3 with frequency 2
: item2 ID 3 with frequency 1
: item2 ID 1 with frequency 3
[(1, 8), (2, 3), (3, 3)]
$ ./merge-items -v "1 1 | 2 2 | 3 3" "2 3 | 2 4"
: items1: [(1, 1), (2, 2), (3, 3)]
: items2: [(2, 3), (2, 4)]
: item1 ID 1 with frequency 1
: item1 ID 2 with frequency 2
: item1 ID 3 with frequency 3
: item2 ID 2 with frequency 3
: item2 ID 2 with frequency 4
[(1, 1), (2, 9), (3, 3)]
And that's it.