In this series, we’ve been looking at operators as something that takes an input and turns it into an output, and we’ve been looking at chains of such operators, which we’ve called trains. In the last post, we posed the question of how to recover what the input was if we know the output – or, equivalently, how to produce a desired output by picking an appropriate input. We approached that by inverting each car in the train (finding a car that undoes the effect of the original car). In this post, I’m going to start by showing that picture in slightly different form:
On top is the original train of operators, and we were trying to determine what input would produce 99 for its output. Of course, we could have guessed, and we might have been lucky and guessed 45. Or we could have guessed one stage at a time, and started by guessing what the output of c must have been to produce an output of 99 on d. But since we had already looked at pairs of cars that undo the effect of each other, the train on the bottom of the figure is a more systematic way of finding what the initial input must have been. The bottom train is composed of cars e, f, g and h; car e undoes the effect of car d, car f undoes the effect of car c, and so on. On the line separating the top train and the bottom train, I’ve indicated the numbers that would appear on the various inputs and outputs. I’m assuming here that we dutifully start at the right, at 99, since that was the value we wanted to see on the output of d. If we put 99 on the input of car e, we can trace back – that is, from right to left – what the output of e, f, g, and h must be. If we read this series of numbers from left to right, 45 must be the input of a, 50 must be the output of a (and the input of b), and so on, and indeed resulting in 99 as the output of d.
In our work so far, we have played with four different flavors of operators (add a number, subtract a number, multiply by a number, and divide by a number), all operating on single numbers. It is time to broaden the horizon somewhat, and introduce additional operators that operate on single numbers. Some of these have matching “undo” operators, some have not.
The first one of these features a subtraction, just like the “subtract 4” operator did. However, in this one, the number you subtract from is fixed and given, but the number you subtract from it is not. The operator in box a subtracts the number on its input from 100. So, if “20” is presented on the input, “80” will show up on the output. You may note that this is the first operator we’ve shown where increasing the number on the input will be accompanied by a decrease of the number on the output. At this point, you may want to stop and think what the operator is that “undoes” the effect of the “subtract from 100” operator.
The operator in box b does division, where the number on the input determines what 60 is divided by. If “10” is presented on the input, the output will show “6”. If “20” is presented on the input, the output will show “3”. Like the “100-” operator, if the input goes up, the output goes down. And like the “100-” operator, there is something very interesting about the operator that undoes the effect of “60÷”. Still, the two operators behave quite differently in other respects.
The operator in box c does remainder. Specifically, after dividing by 2. So if 13 is presented on the input, the output shows “1”. For 13 divided by 2 is 6 wholes, and that accounts for 12, so 1 is left. If 14 is presented on the input, the output shows “0”. For 14 divided by 2 is 7 wholes, and that accounts for all of the 14, so nothing is left: remainder is 0.
The operator in box d computes a square. It takes the input number, and multiplies it by itself. If 3 is presented on the input, the output shows 9, since 9 = 3×3.
These four new operators, either the operators themselves or their undo-partners, all have limitations, some serious, some not at all. It is useful to look at these (potential) limitations, since that will help make explicit what up to this point we’ve been able to ignore.
Let’s start with the “100-” box. One way to view what this box does is to imagine you pay with a dollar bill, and you want to know how much change you should expect. Depending on the price of the item, in cents, you will get more or less back in change. If the item costs more, you will get less in change; if the item costs less, you will get more back in change from your 100 cents. But there is a difference between the box and this scenario, and that is that the scenario only really makes sense for prices up to a dollar. The box, in contrast, may have no problem accepting inputs that go greater than 100, and still produce an output. A calculator, similarly, has no problem giving you an answer for “100-120”. It produces a negative number as its output, in that case. A calculator can also handle a negative input. If you present ⁻20 at the input (which, on the calculator, may require the use of the “change sign” key), subtracting from 100 will result in 120. Similarly, the “100-” box may not need to restrict its inputs to whole numbers. It could handle decimal numbers just as well.
Now, how about the box that does the divide? We could make it, too, handle small numbers, large numbers, positive numbers, negative numbers, whole numbers, decimal numbers. There is only one number on its input that really causes problems, and that is the value zero. Many calculators, if you try 60÷0, you will get “Error”. We could have our box do the same thing: produce “Error” on its output. It just makes it hard to chain that box with further boxes that expect numbers on its input. Alternatively, we could make sure that all the other boxes pass through an “Error” on their input and put it right back on their outputs. It would be interesting to see if there is a consistent design that produces consistent useful results in the presence of the “Error” possibility.
Some new issues show up in the “remainder from dividing by 2” box. This box really only makes sense if the input is a whole number. We could argue whether that number needs to be positive or whether we could make it work with a negative input as well. What is fairly clear, though, is that we can’t have a simple box that undoes its effect. Many different inputs, e.g. 3, 5, 7, 17 would all produce the same remainder of 1 on the output. From the output alone, there is no way to tell what appeared on the input.
The square operator, box d, also exhibits the phenomenon of not being able to uniquely determine, from looking at the output, what must have been on the input. However, this effect is somewhat subtle. If a “9” appears on the output, we know that it might have been “3” on the input, but we must also account for the possibility that “⁻3” was on the input. In the case of this particular operator, we could make things unique and deterministic by restricting the inputs of the “square” operator to positive numbers only. Yet the inputs to “square” aren’t usually restricted in this way, instead, the usual practice is to make some corresponding restrictions to the “square root” operator, but we’ll be looking at that some other time.