> Input
> Input
>> 1²
>> (3]
>> 1%L
>> L=2
>> Each 5 4
>> Each 6 7
>> L⋅R
>> Each 9 4 8
> {0}
>> {10}
>> 12∖11
>> Output 13
Try it online!
Returns a set of all possible solutions, and the empty set (i.e. \$\emptyset\$) when no solution exists.
How it works
Unsurprisingly, it works almost identically to most other answers: it generates a list of numbers and checks each one for inverse modulus with the argument.
If you're familiar with how Whispers' program structure works, feel free to skip ahead to the horizontal line. If not: essentially, Whispers works on a line-by-line reference system, starting on the final line. Each line is classed as one of two options. Either it is a nilad line, or it is a operator line.
Nilad lines start with >
, such as > Input
or > {0}
and return the exact value represented on that line i.e > {0}
returns the set \$\{0\}\$. > Input
returns the next line of STDIN, evaluated if possible.
Operator lines start with >>
, such as >> 1²
or >> (3]
and denote running an operator on one or more values. Here, the numbers used do not reference those explicit numbers, instead they reference the value on that line. For example, ²
is the square command (\$n \to n^2\$), so >> 1²
does not return the value \$1^2\$, instead it returns the square of line 1, which, in this case, is the first input.
Usually, operator lines only work using numbers as references, yet you may have noticed the lines >> L=2
and >> L⋅R
. These two values, L
and R
, are used in conjunction with Each
statements. Each
statements work by taking two or three arguments, again as numerical references. The first argument (e.g. 5
) is a reference to an operator line used a function, and the rest of the arguments are arrays. We then iterate the function over the array, where the L
and R
in the function represent the current element(s) in the arrays being iterated over. As an example:
Let \$A = [1, 2, 3, 4]\$, \$B = [4, 3, 2, 1]\$ and \$f(x, y) = x + y\$. Assuming we are running the following code:
> [1, 2, 3, 4]
> [4, 3, 2, 1]
>> L+R
>> Each 3 1 2
We then get a demonstration of how Each
statements work. First, when working with two arrays, we zip them to form \$C = [(1, 4), (2, 3), (3, 2), (4, 1)]\$ then map \$f(x, y)\$ over each pair, forming our final array \$D = [f(1, 4), f(2, 3), f(3, 2), f(4, 1)] = [5, 5, 5, 5]\$
Try it online!
How this code works
Working counter-intuitively to how Whispers works, we start from the first two lines:
> Input
> Input
This collects our two inputs, lets say \$x\$ and \$y\$, and stores them in lines 1 and 2 respectively. We then store \$x^2\$ on line 3 and create a range \$A := [1 ... x^2]\$ on line 4. Next, we jump to the section
>> 1%L
>> L=2
>> Each 5 4
>> Each 6 7
The first thing executed here is line 7, >> Each 5 4
, which iterates line 5 over line 4. This yields the array \$B := [i \: \% \: x \: | \: i \in A]\$, where \$a \: \% \: b\$ is defined as the modulus of \$a\$ and \$b\$.
We then execute line 8, >> Each 6 7
, which iterates line 6 over \$B\$, yielding an array \$C := [(i \: \% \: x) = y \: | \: i \in A]\$.
For the inputs \$x = 5, y = 2\$, we have \$A = [1, 2, 3, ..., 23, 24, 25]\$, \$B = [0, 1, 2, 1, 0, 5, 5, ..., 5, 5]\$ and \$C = [0, 0, 1, 0, 0, ..., 0, 0]\$
We then jump down to
>> L⋅R
>> Each 9 4 8
which is our example of a dyadic Each
statement. Here, our function is line 9 i.e >> L⋅R
and our two arrays are \$A\$ and \$C\$. We multiply each element in \$A\$ with it's corresponding element in \$C\$, which yields an array, \$E\$, where each element works from the following relationship:
$$E_i =
\begin{cases}
0 & C_i = 0 \\
A_i & C_i = 1
\end{cases}$$
We then end up with an array consisting of \$0\$s and the inverse moduli of \$x\$ and \$y\$. In order to remove the \$0\$s, we convert this array to a set (>> {10}
), then take the set difference between this set and \$\{0\}\$, yielding, then outputting, our final result.
Can it error if no solution is found? – clap – 2017-05-17T03:14:28.723
@ConfusedMr_C Technically that does indicate no solution, so yes. – Graviton – 2017-05-17T20:55:06.643