# RogerBW's Blog

The Weekly Challenge 208: Missing Index? Just Duplicate! 19 March 2023

I’ve been doing the Weekly Challenges. The latest involved searching through arrays. (Note that this is closes today.)

You are given two arrays of strings.

Write a script to find out all common strings in the given two arrays with minimum index sum. If no common strings found returns an empty list.

i.e., from the examples, if "Word" occurs at index 2 in array A and index 1 in array B, the index sum of "Word" is 3. Order of output is not specified.

Ruby:

Convert a list of words into a hash (dict, hashmap) mapping each word to its lowest index. (There may be duplicates in the list.)

``````def v2hm(a)
h = Hash.new
a.each_with_index do |x, i|
if !h.has_key?(x) then
h[x] = i
end
end
return h
end

def minindexsum(a, b)
``````

Set up the lookup hash for each word.

``````  ah = v2hm(a)
bh = v2hm(b)
``````

Set up the output list and a minimum index sum higher than any we'll encounter.

``````  out = []
mi = a.length + b.length
``````

For each word in `a`:

``````  a.each do |w|
``````

confirm that it's in `b`.

``````    if bh.has_key?(w) then
``````

Calculate the index sum.

``````      mv = ah[w] + bh[w]
``````

If it's lower than any we've seen before, clear the output list and set this as the new target.

``````      if mv < mi then
out = []
mi = mv
end
``````

If it equals the target, add the word to the list.

``````      if mv == mi then
out.push(w)
end
end
end
return out
end
``````

You are given an array of integers in sequence with one missing and one duplicate.

Write a script to find the duplicate and missing integer in the given array. Return -1 if none found.

For the sake of this task, let us assume the array contains no more than one duplicate and missing.

If there is no missing number found in the sequence, we assume that it would have been the next one after the end. (It could have been the one before the beginning. No way to know.) Anyway, Raku:

``````sub duplicateandmissing(@a) {
``````

Set up flags for which anomalous entries I've found, holders for duplicate and missing, and an expected value.

``````    my \$flags = 0;
my \$dup = 0;
my \$mis = 0;
my \$exp = @a[0];
``````

Check each entry…

``````    for @a -> \$n {
``````

If it's lower than expected, this is a "duplicate" value. (If it's lower than `exp - 1`, it's an anomaly of a type we're not expecting, so ignore that.) Store it and set flag bit 0. (Yeah, Raku weird bitwise operators. Sigh.)

``````        if (\$n < \$exp) {
\$dup = \$n;
\$flags +|= 1;
``````

If it's higher, there was a "missing" value. (Again, this is only strictly true if there was a gap of 1, but if it's higher there's more then one missing value and we're told that won't happen..) Store it and set flag bit 1.

``````        } elsif (\$n > \$exp) {
\$mis = \$exp;
\$flags +|= 2;
}
``````

If we've found both "duplicate" and "missing" values, return.

``````        if (\$flags == 3) {
return [\$dup, \$mis];
}
``````

The next expected value is one more than this value.

``````        \$exp = \$n + 1;
}
``````

If we found a duplicate but not a missing, assume the missing is the one after the end.

``````    if (\$flags == 1) {
return [\$dup, \$exp];
}
``````

Otherwise, give up.

``````    return [-1];
}
``````

Full code on github.