The first of this week’s PWC 268 tasks is called Magic Number.
Task 1: Magic Number
You are given two arrays of integers of same size, @x
and @y
.
Write a script to find the magic number that when added to each elements of one of the array gives the second array. Elements order is not important.
Example 1
Input: @x = (3, 7, 5)
@y = (9, 5, 7)
Output: 2
The magic number is 2.
@x = (3, 7, 5)
+ 2 2 2
@y = (5, 9, 7)
Example 2
Input: @x = (1, 2, 1)
@y = (5, 4, 4)
Output: 3
The magic number is 3.
@x = (1, 2, 1)
+ 3 3 3
@y = (5, 4, 4)
Example 3
Input: @x = (2)
@y = (5)
Output: 3
In my Raku / Perl / Python implementations of this task, I sorted the two lists, then found the difference between the first elements on both lists, then confirmed that the difference was the same for each pair of elements in the two lists.
Writing this up functionally wasn’t that hard… but it took me a while to get past how I was going to do the last part:
def magicNumber(x, y) do
xS = Enum.sort(x)
yS = Enum.sort(y)
magic = Enum.at(yS, 0) - Enum.at(xS, 0)
# there be dragons here
end
I thought about looping over both lists xS
and yS
(x-sorted and y-sorted) in some kind of double-indexed loop:
for i <- xS, j <- yS do
# there be dragons here
end
But my big concern was being able to return the information about whether or not the magic number applied to each number pair across xS
and yS
. Then I remembered the pattern-matching I did with task 2 last week where I defined a function two ways: once to pull an element off a list passed in as a parameter, and another time to handle when the list was exhausted. I could do the same here: the “pull the first element off the list” version could pull the first element off both lists and make sure that their difference matched the magic
number we’ve already established (and, if not, returning an error condition) and the “empty list” version could return the success condition saying everything matched. This would leave me with this:
defp checkNums(magic, [], []) do
{ :ok, magic }
end
defp checkNums(magic, [x | rX], [y | rY]) do
if y - x == magic do
checkNums(magic, rX, rY)
else
{ :err, 0 }
end
end
def magicNumber(x, y) do
xS = Enum.sort(x)
yS = Enum.sort(y)
magic = Enum.at(yS, 0) - Enum.at(xS, 0)
checkNums(magic, xS, yS)
end
In my code that was calling magicNumber(x, y)
, I wanted to be able to check to see if we succeeded in finding a “magic number” by checking if we returned an atom :ok
. So I wound up with my entire solution looking like this:
#!/usr/bin/env elixir
defmodule PWC do
defp checkNums(magic, [], []) do
{ :ok, magic }
end
defp checkNums(magic, [x | rX], [y | rY]) do
if y - x == magic do
checkNums(magic, rX, rY)
else
{ :err, 0 }
end
end
def magicNumber(x, y) do
xS = Enum.sort(x)
yS = Enum.sort(y)
magic = Enum.at(yS, 0) - Enum.at(xS, 0)
checkNums(magic, xS, yS)
end
def solution(x, y) do
IO.puts("Input: @x = (" <> Enum.join(x, ", ") <> ")")
IO.puts(" @y = (" <> Enum.join(y, ", ") <> ")")
case PWC.magicNumber(x, y) do
{:ok, magic} ->
IO.puts("Output: #{to_string(magic)}")
IO.puts("\nThe magic number is #{to_string(magic)}.")
IO.puts("@x = (" <> Enum.join(x, ", ") <> ")")
IO.puts(" + " <> Enum.join(
Enum.map(x, fn _ -> magic end), " "
))
IO.puts("@y = (" <> Enum.join(
Enum.map(x, fn n -> n + magic end), ", "
) <> ")")
{:err, _} ->
IO.puts('Output: no magic number')
end
end
end
IO.puts("Example 1:")
PWC.solution([3, 7, 5], [9, 5, 7])
IO.puts("\nExample 2:")
PWC.solution([1, 2, 1], [5, 4, 4])
IO.puts("\nExample 3:")
PWC.solution([2], [5])
IO.puts("\nExample 4:")
PWC.solution([1, 2], [4, 2])
$ elixir/ch-1.exs
Example 1:
Input: @x = (3, 7, 5)
@y = (9, 5, 7)
Output: 2
The magic number is 2.
@x = (3, 7, 5)
+ 2 2 2
@y = (5, 9, 7)
Example 2:
Input: @x = (1, 2, 1)
@y = (5, 4, 4)
Output: 3
The magic number is 3.
@x = (1, 2, 1)
+ 3 3 3
@y = (4, 5, 4)
Example 3:
Input: @x = (2)
@y = (5)
Output: 3
The magic number is 3.
@x = (2)
+ 3
@y = (5)
Example 4:
Input: @x = (1, 2)
@y = (4, 2)
Output: no magic number
The code can be found on GitHub at https://github.com/packy/perlweeklychallenge-club/tree/master/challenge-268/packy-anderson/elixir