sum of missing numbers
20.11.2023 2 min readCreate a function that returns the sum of missing numbers.
sumMissingNumbers([1, 3, 5, 7, 10]) ➞ 29
// 2 + 4 + 6 + 8 + 9
sumMissingNumbers([10, 7, 5, 3, 1]) ➞ 29
sumMissingNumbers([10, 20, 30, 40, 50, 60]) ➞ 1575
Crystal:
def create_range_between(i, j : Int32)
(i + 1..j - 1).map do |n|
n
end
end
def sum_missing_numbers(a : Array(Int32))
missing_nos = a.sort.each_cons_pair.reduce([] of Int32) do |acc, el|
i, j = el
acc.concat(create_range_between(i, j))
end
missing_nos.sum
end
Crystal has a nice each_cons_pair
that doesn’t go out of bounds so we don’t have to care about not having a next
.
Nim:
func createRangeBetween(i, j: int): seq[int] =
collect(newSeq):
for i in countup(i + 1, j - 1): i
func sumMissingNumbers(s: seq[int]): int =
let sorted = s.sorted
let missing = collect(newSeq):
for i in 0 .. sorted.len - 2:
createRangeBetween(sorted[i], sorted[i + 1])
missing.foldl(a & b).sum
We avoid IndexDefect
by only going up to len - 2
.
Raku:
sub create-range-between($i, $j) {
do for $i+1..$j-1 {$_}
}
sub sum-missing-numbers(@a) {
my $sorted := @a.sort.cache;
my $missing := do for $sorted.kv -> $k, $v {
next if $k == @a.elems - 1;
create-range-between($v, $sorted[$k+1]);
}
[+] $missing.flat;
}
We need to cache
the list, if not Raku complains that the Seq
is already being consumed (or something to that effect. I honestly don’t know how to predict when these things will happen. I only know that throwing a .cache
will usually sort it out). Classic for
loops in Raku are “discouraged”, and I had some difficulty finding the syntax for them in the official documentation. However, I did find an example here.
loop (my $i = 1; $i <= 3; $i++) {
say $i;
}
Just putting this here in case I ever decide I want to use one (I doubt it).
Last one, Javascript:
function createRangeBetween(i: number, j: number) {
return Array(j - i - 1)
.fill(null)
.map((_, k) => i + 1 + k);
}
function sumMissingNumbers(a: number[]) {
const sorted = [...a.sort((a, b) => a - b)];
const missingNos = sorted.reduce((acc, curr, i) => {
const next = sorted[i + 1];
if (!next) return acc;
return [...acc, ...createRangeBetween(curr, next)];
}, [] as number[]);
return missingNos.reduce((a, b) => a + b, 0);
}
In recent days, I’ve really come to appreciate Javascript’s reduce
. I wish Nim’s foldl
worked like this, but it seems to only support simple operations for now. Maybe one day.