471 lines
31 KiB
Plaintext
471 lines
31 KiB
Plaintext
|
|
Episode: 1292
|
||
|
|
Title: HPR1292: Doomsday Remainders
|
||
|
|
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr1292/hpr1292.mp3
|
||
|
|
Transcribed: 2025-10-17 23:05:15
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
Hello, and welcome to Hacker Public Radio.
|
||
|
|
This is Charles from New Jersey, and I'm back with yet another episode on Recreational
|
||
|
|
Map.
|
||
|
|
But before I start this episode, we have a public service announcement from the Fake
|
||
|
|
Ken Fallon.
|
||
|
|
Hello, everyone.
|
||
|
|
This is the Fake Ken Fallon for Hacker Public Radio.
|
||
|
|
If you've got a pastime, a hobby, or a project that's interesting enough that you find
|
||
|
|
yourself spending time on it, or going on about it with your mates over a beer, you should
|
||
|
|
consider recording a few minutes of audio for Hacker Public Radio.
|
||
|
|
Don't worry about adding a bunch of detailed show notes like Charles and L.J., or producing
|
||
|
|
the perfect recording.
|
||
|
|
Just tell us what you're doing so we can learn about it.
|
||
|
|
You can record your piece using your music player, your computer, or your phone, and send
|
||
|
|
it to the admin, or you could just phone it in to our call-in lines.
|
||
|
|
The main thing is that we want to hear from you on Hacker Public Radio, your ideas and
|
||
|
|
projects podcasted.
|
||
|
|
Well, thanks, Fake Ken.
|
||
|
|
I'm sure that everyone listening will be eager to record their own show.
|
||
|
|
Hello, and welcome to Hacker Public Radio.
|
||
|
|
This is Charles and L.J., and I'm back with another episode on Recreational Now.
|
||
|
|
This is actually another one of those follow-up episodes, and I'm calling today's show,
|
||
|
|
Doomsday Remainters.
|
||
|
|
At the end of episode 1240 on the Doomsday Rule, I mentioned the mod function, which I used
|
||
|
|
in the sample spreadsheets and resource files for that show.
|
||
|
|
Now the name mod is short for modulus, which is just a fancy word for the divisor used
|
||
|
|
to look at remainders in integer division.
|
||
|
|
In terms also used in other contexts, so if you want to do a keyword search, you should
|
||
|
|
probably add remainder or integer to the word modulus to get better results.
|
||
|
|
Now the mod function and integer division go beyond spreadsheets.
|
||
|
|
Most programming language also have a mod function, or an operator that looks like 8% B
|
||
|
|
or A mod B, where mod is the actual word mod MOD in lowercase letters, because it's
|
||
|
|
useful in programming.
|
||
|
|
Now you may only use it for simple things like odd even parity checks, but there are a
|
||
|
|
number of different things you can do in a programming concept with the mod function.
|
||
|
|
As it turns out, and as I discovered as I rushed those files together, there are differences
|
||
|
|
in the behavior of mod operators and functions in different environments, so you have to pay
|
||
|
|
attention, which unfortunately I did not, but I did have a chance to fix them before they
|
||
|
|
went out.
|
||
|
|
Now it may be confusing that a function that comes from mathematics would work differently
|
||
|
|
in different places.
|
||
|
|
You might think that a math function would have a single unchanging definition, but that's
|
||
|
|
not really true here.
|
||
|
|
Now I'm going to explain a couple of the conventions that are used, and show that they're
|
||
|
|
not completely arbitrary, and that you can have a difference of opinion on this particular
|
||
|
|
function.
|
||
|
|
When I talk about using a mod operator that finds the remainder you get from dividing
|
||
|
|
say 77 by 3, I'm going to use the shorthand form 77 MOD 3.
|
||
|
|
That's going to be quicker and less cumbersome, I'm going to mention it a number of times.
|
||
|
|
But before we go on to these differences in implementation, let's talk about the basics
|
||
|
|
of integer division for a minute or so.
|
||
|
|
Now integer division is a little different from the floating point math you have on your
|
||
|
|
calculators and in your spreadsheets.
|
||
|
|
There are similarities, of course.
|
||
|
|
Both of them have a dividend, call it x, a divisor, d, and some kind of quotient.
|
||
|
|
For instance, we can compute 24 divided by 3 either way, and the quotient is the same
|
||
|
|
in either case.
|
||
|
|
In any case where you have integers as inputs and you can afford to just lock off any fraction
|
||
|
|
of bits after the decimal point, integer and floating point division will produce values
|
||
|
|
that are close enough for you for the quotient.
|
||
|
|
But floating point and integer division are not the same.
|
||
|
|
For one thing, integer division on computers is exact, whereas floating point division
|
||
|
|
even with answers that look like integers is always approximate.
|
||
|
|
The two operations are conceptually distinct, so we're not just talking about little differences
|
||
|
|
in how they're computed.
|
||
|
|
Strictly speaking, integer division always gives two answers, the quotient and the remainder.
|
||
|
|
The first example where we divided 24 by 3 was intended to highlight the common elements
|
||
|
|
between floating point and integer math.
|
||
|
|
The next example is going to emphasize the major difference, namely the remainder.
|
||
|
|
Now when I divide 77 by 3 using integer division, I would normally say that the quotient
|
||
|
|
is 25 would a remainder 2 because 25 times 3 or 75 and 26 times 3 or 78 come as close as
|
||
|
|
possible to 77.
|
||
|
|
Now 78 is actually closer to the target, so we could have gone the other way, but for
|
||
|
|
the moment we'll prefer positive remainders.
|
||
|
|
Now I've selected the number 25 as the quotient by convention to get the kind of remainder
|
||
|
|
that I want.
|
||
|
|
Now I normally like a remainder that's both non-negative and as small as possible, but
|
||
|
|
there are other perfectly consistent ways to define it that still work and that I'll
|
||
|
|
describe later on.
|
||
|
|
So integer division always has these two answers.
|
||
|
|
If the dividend x can be written as an integer quotient, call it q, times the divisor d,
|
||
|
|
we say that d divides x because x is equal to q times d.
|
||
|
|
Now indeed defines x, you might be tempted to say there's no remainder, but for both
|
||
|
|
programming and mathematical purposes, it's probably more convenient to say that we have
|
||
|
|
a remainder but it's equal to zero.
|
||
|
|
Now there's no law that says we have to track both the quotient and the remainder in every
|
||
|
|
problem, but both of them are always present by definition, they're always there.
|
||
|
|
In fact this is such an important property of integer arithmetic that the programming
|
||
|
|
languages Python and Ruby have a built-in function div mod that return both the quotient
|
||
|
|
and the remainder as an ordered pair.
|
||
|
|
So for example if I call 77 div mod 3, my return value would be 25 comma 2, it's an ordered
|
||
|
|
pair, where 25 is the quotient and 2 is the remainder.
|
||
|
|
Well technically that would be div mod 77 comma 3, but I can define an operator that does
|
||
|
|
the same thing.
|
||
|
|
Now what would prompt us to make use of either the quotient or the remainder but not both?
|
||
|
|
Well the Doomsday rule that we talked about last time makes use of integer division products
|
||
|
|
in three different ways on the way to finding its answer.
|
||
|
|
Now Conway's Doomsday algorithm for finding the day of the week for a given date has a
|
||
|
|
few steps and each one uses a kind of integer divide.
|
||
|
|
First we use target year div mod 100 to split the target year into its century and an
|
||
|
|
offset year.
|
||
|
|
The century number is used to get the baseline day of the week and the century offset is
|
||
|
|
that set of leftover years that go to the next step as the input.
|
||
|
|
So for example if the target year is 1944, century number is 19 and the offset year is 44.
|
||
|
|
Now going back a step, if you listen to episode 1240 you'll recall that the baseline
|
||
|
|
day is found by adding the results of 36,524 mod 7 for each century since the last 400
|
||
|
|
year cycle began.
|
||
|
|
Now to understand with that magic number came from you're going to have to listen to
|
||
|
|
the episode.
|
||
|
|
Okay now given the century offset year we can break the problem down further by using
|
||
|
|
century offset div mod 12 to get the pair of numbers that represent first the completed
|
||
|
|
cycles which add plus one to the offset for each one and then the cycle offset which
|
||
|
|
also adds plus one for each year into the incomplete cycle and then we do an additional
|
||
|
|
check on the cycle offset in a next step.
|
||
|
|
Now that next step is we need to adjust the count the total offset for the number of leap
|
||
|
|
years in the current incomplete 12 year cycle which is a quotient only division of the
|
||
|
|
cycle offset which is left over years by four years per leap year and we can call that
|
||
|
|
cycle offset div 4 where div is the integer divide that keeps only the quotient and throws
|
||
|
|
everything else out.
|
||
|
|
As you can recall the div would be the first element in the return value for div mod
|
||
|
|
so div mod and div and mod for the individual operators it's a consistent way of referring
|
||
|
|
to these things and people in some context do call them do call these operators by those
|
||
|
|
names.
|
||
|
|
Now the last part is a little messy and I refer you to the show to follow the process
|
||
|
|
to the end but it's all based on x mod 7 for quite a few different little values of
|
||
|
|
x.
|
||
|
|
So here we have in one calculation we see three different uses of integer division.
|
||
|
|
One we have the 12 year cycle and century adjustment that used both the quotient and
|
||
|
|
remainder.
|
||
|
|
We've got the leap year count that uses just the quotient because there are no partial
|
||
|
|
leap years and then for the final day of the week and a few other places the remainder
|
||
|
|
is the answer so we use remainder only math or the mod function.
|
||
|
|
Now I hadn't planned it this way at the start of this series emerging series but we keep
|
||
|
|
pulling layers off the mathematics onion as we're going along here.
|
||
|
|
Remember the first show had calendar counting which led to counting objects and then we
|
||
|
|
went to doomsday then doomsday led to a discussion of mod div and div mod and to some of
|
||
|
|
the foundations of grade school arithmetic and how and why we use it the way we do.
|
||
|
|
Now in this show I'm going to look mostly at mod because it's the least familiar of the
|
||
|
|
integer division use cases.
|
||
|
|
I think we've seen the others many times before.
|
||
|
|
I know we can skip the quotient only case because you can do that with a calculator and
|
||
|
|
just chop off everything after the decimal.
|
||
|
|
Actually even tracking quotient remainder pairs is not that new to us because we have
|
||
|
|
done this before.
|
||
|
|
Now every time we've used split unit measures those are just quotient remainder pairs.
|
||
|
|
So we don't think twice about referring to a marathon courses being 26 miles 385 yards
|
||
|
|
or giving the running time for a 1500 meter raise as 4 minutes 22 seconds.
|
||
|
|
Now we also use div mod more or less successfully to know when we should start roasting let's
|
||
|
|
say an 11 kilo turkey that needs to cook for 33 minutes per kilogram and then we have
|
||
|
|
to allow for a 90 minute cool down after cooking before we can carve and serve it.
|
||
|
|
Now if you botched that calculation you could have a house full of angry in laws waiting
|
||
|
|
for their dinner and probably most of them did not necessarily need a reason to dislike
|
||
|
|
you so this is a calculation you should learn to get right.
|
||
|
|
I told you this was going to be useful for life.
|
||
|
|
As for the less familiar remainder only form of integer division or the mod function but
|
||
|
|
we've seen that it's good for finding dates on the calendar dates of the week it's also
|
||
|
|
good for finding times of day on the clock.
|
||
|
|
Now we do this whenever we try to interpret Ken's countdown clock for the next HPR community
|
||
|
|
news which he usually starts up several days in advance with more than 100 hours to go.
|
||
|
|
Given our attendance record lately maybe we need to do an episode on figuring out what
|
||
|
|
time of day does the community news is held but that's another topic for another time.
|
||
|
|
Now there are other applications of the mod function that don't involve times or dates
|
||
|
|
and I guess we can touch on those a little later.
|
||
|
|
For now let's go back to the scripts and the spreadsheets from the Doomsday show so
|
||
|
|
I can explain a little bit more about how they work.
|
||
|
|
Now in the spreadsheets and the Python scripts and the functions for BC the mod operations
|
||
|
|
carried a lot of the freight in making the Doomsday rule algorithm work on your computer.
|
||
|
|
A few minutes ago I casually mentioned that we choose the properties of our remainders
|
||
|
|
to follow our preferred conventions and that we happen to like our remainders positive.
|
||
|
|
Now that word convention was carefully chosen.
|
||
|
|
There are other ways to define our remainder that are perfectly valid and self consistent.
|
||
|
|
The main differences in practice are in the sign of the remainder for expressions with
|
||
|
|
say negative input values.
|
||
|
|
Some implementations follow the sign of the divisor so say x mod minus 7 is always negative
|
||
|
|
and otherwise we're okay.
|
||
|
|
Now there are other systems that follow the sign of the number being divided, the dividend,
|
||
|
|
or they set the quotient to make the remainder as small as possible.
|
||
|
|
The third list of the sign plus or minus.
|
||
|
|
Now just for good measure there are some mod operators that just always give a positive
|
||
|
|
result.
|
||
|
|
And there's an argument you could make for each approach and each one of these should
|
||
|
|
generally work as long as you know what the assumptions are.
|
||
|
|
I guess the most important thing is to know the assumptions for the version of the mod function
|
||
|
|
or operator that you're going to use.
|
||
|
|
Now if you've done much programming you know that you'll eventually want to use someone
|
||
|
|
else's code or some cool libraries to do part of a job or maybe all of a job.
|
||
|
|
Now you're going to face the same issues in using their calling convention which is often
|
||
|
|
called by the Hoidy Toidy name application programming interface or API.
|
||
|
|
Now in the end an API is just a fancy term for a set of conventions and certain underlying
|
||
|
|
assumptions that you need to understand to use that library or program successfully.
|
||
|
|
You might as well learn to follow APIs using simple types like integers before we go on
|
||
|
|
to use APIs that have more complex structures as input output values where you have to pack
|
||
|
|
the inputs and unpack the outputs.
|
||
|
|
Inagers are very straightforward to use as calling arguments and return values.
|
||
|
|
So let's look at the different systems that we had to use for the sample code in episode
|
||
|
|
1240.
|
||
|
|
Well mod in the spreadsheet is a function because spreadsheets don't usually support
|
||
|
|
infix operators other than basic arithmetic.
|
||
|
|
Now spreadsheet mod functions follow the sign of the divisor.
|
||
|
|
So the call 67 mod 7 gives you the answer for.
|
||
|
|
Now that implies a quotient of 9 with the remainder for since 9 times 7 is 63 and when you add
|
||
|
|
4 you get 67 back.
|
||
|
|
Now 67 mod minus 7 returns minus 3 which results from a quotient of minus 10 and remainder
|
||
|
|
minus 3 since negative 10 times negative 7 is plus 70.
|
||
|
|
Now for the doomsday spreadsheet this is good news because my formula used an offset
|
||
|
|
function with expected values from 0 to plus 6 to look up the name of the day of the week
|
||
|
|
from the offset value and here's the dependency.
|
||
|
|
We use the function call mod x plus 7 to compute that offset value so we can always count
|
||
|
|
on a calculated index that's in the right range.
|
||
|
|
And that's pretty much all there is to say about the spreadsheet form of the mod function.
|
||
|
|
Now the mod operator the percent sign in python is consistent with the spreadsheet but it's
|
||
|
|
got a little extra twist that I wanted to report as well.
|
||
|
|
Nothing to do with mods or did it.
|
||
|
|
Now in python the mod operator the a percent sign b also returns a value with a sign that
|
||
|
|
follows the divisor.
|
||
|
|
So for this reason I didn't have to worry about whether I passed in a positive or negative
|
||
|
|
x value in expression x percent 7.
|
||
|
|
Now those of you who know python will see that my day of the week functions do their name
|
||
|
|
look up the last step using a python list object and that object set up with Sunday at
|
||
|
|
position 0, Monday at position 1 and so on up to Saturday at position 6.
|
||
|
|
Now since the python mod operator returns non negative values for a positive divisor
|
||
|
|
I didn't have to worry but there's a bonus application of mod in python and it turns
|
||
|
|
out that python would return the same value regardless of the sign of the remainder as
|
||
|
|
long as it's correct.
|
||
|
|
Huh?
|
||
|
|
That's right.
|
||
|
|
Python list objects support negative subscripts whose behavior follows the operation of x mod
|
||
|
|
minus 7 so the negative complement if you will of the positive subscript points the
|
||
|
|
same day of the week as the positive subscript itself.
|
||
|
|
Yeah.
|
||
|
|
Well if you don't use python you might just want to skip this or fire up a python interpreter
|
||
|
|
that's probably on your machine and try these things but I'll explain it and you can just
|
||
|
|
sort of fast forward through this part if it doesn't make sense.
|
||
|
|
Now when you're using subscripting on a 7 item python list let's call it my list.
|
||
|
|
The first item is located at my list 0 and the last item is well where is it.
|
||
|
|
If the sequence starts at 0 then the cocktail party is minus 1 so the seventh element is
|
||
|
|
at position minus 1 plus 7 or my list position 6.
|
||
|
|
So the positive values for the remainder work nicely as index into my list of day names.
|
||
|
|
Very good but here's a special bonus.
|
||
|
|
Negative subscripting analyst also works and it uses the convention that the last list
|
||
|
|
item is my list position minus 1.
|
||
|
|
The second the last is my list minus 2 and so on down to my list minus 6 but it will not
|
||
|
|
work for my list minus 7.
|
||
|
|
That doesn't work you would get an out of bounds error but that's not really a problem
|
||
|
|
when you're calculating the subscript using mod whether you have the positive or non-negative
|
||
|
|
or negative answers because what would have been pointed to by my list minus 7 is already
|
||
|
|
pointed to my list position 0.
|
||
|
|
Why is that?
|
||
|
|
Well remember that minus 7 mod minus 7 is equal to 0 almost trivially because the two numbers
|
||
|
|
divide evenly minus 7 divided by minus 7 would be 1 with no remainder with 0 remainder.
|
||
|
|
So I don't have to worry about a mod function mapping me into my list minus 7 so I won't
|
||
|
|
actually be trying to go there so this kind of code should be solid it should work.
|
||
|
|
So the minus 7 case I don't really have to worry about it will simplify to my list position
|
||
|
|
0 and that's the value I wanted anyway.
|
||
|
|
Now just to beat this to death let's say I'm running a doomsday calculation whose target
|
||
|
|
date is on a Saturday.
|
||
|
|
Now our storage convention puts this at my list position 6 the last element but for
|
||
|
|
mod I just finished saying this location can also be addressed as my list position minus
|
||
|
|
1.
|
||
|
|
Now if my call to x mod 7 had returned a negative value that corresponds to Saturday that
|
||
|
|
value would have been minus 1.
|
||
|
|
This makes sense because minus 1 and plus 6 are exactly 7 days apart.
|
||
|
|
Have you thought about it?
|
||
|
|
Minus 1 plus 1 is 0 plus 6 is plus 6.
|
||
|
|
So we've counted off 7 units from minus 1 to plus 6.
|
||
|
|
I hope you've convinced yourself of that.
|
||
|
|
Not draw a number line and actually trace it with your finger or with a pencil and it
|
||
|
|
will make sense.
|
||
|
|
Now either value should legitimately point to Saturday and in a Python list it's actually
|
||
|
|
work.
|
||
|
|
And Python was pretty easy.
|
||
|
|
Now for the mod operator in the BC program.
|
||
|
|
Well I put in BC as the last minute thing.
|
||
|
|
I did it in honor of Dan Washco's Linux in the Shell episode 25 which covered BC and
|
||
|
|
that episode aired right about the time I was about to post my show.
|
||
|
|
So like a dummy I decided to port my Python day of the week functions to using BC at
|
||
|
|
the last second.
|
||
|
|
And when I tested them I noticed that for some dates my functions got the correct answer
|
||
|
|
but they failed on other ones and I knew something was wrong.
|
||
|
|
It turned out there were a couple of things going on in my original functions.
|
||
|
|
Now there were two issues I overlooked in what I call my naive port from Python to BC
|
||
|
|
when I thought everything would work the same between the two environments.
|
||
|
|
In BC the sign of the mod operator I'll call it xmod7 or x%7 in the code follows x.
|
||
|
|
So I found out that when my reference states you'll have to listen to the doomsday episode
|
||
|
|
to find out what those are.
|
||
|
|
But when the reference states were earlier than the targets, x became negative in the expression
|
||
|
|
xmod7 and by the convention in an array in BC this was wrong.
|
||
|
|
Now this didn't come up in Python which is too bad because Python could have handled
|
||
|
|
it.
|
||
|
|
Now here's the second thing.
|
||
|
|
I originally saved the days of the week, the names of those days in an array in BC but
|
||
|
|
I couldn't get those shown in the display because BC wanted to return a number.
|
||
|
|
So I made a last minute change to show the day of the week the name of that day as a side
|
||
|
|
effect the function and my return value would be the offset I used to look that up.
|
||
|
|
And the way I implemented the mapping from the offset to the day of the week was through
|
||
|
|
a compound if statement, I checked if xmod7 is less than or equal to zero call it Sunday
|
||
|
|
and so on up to if xmod7 is equal to six and then call it Saturday.
|
||
|
|
So when I got negative values coming in it went through that incorrect logic on the first
|
||
|
|
branch and always gave me the answer Sunday which was wrong about six out of seven times
|
||
|
|
in row in the places where I was getting the negative values which was typically early
|
||
|
|
in the year.
|
||
|
|
Okay, now if you look carefully at the two day of the week functions that I included
|
||
|
|
for BC you'll see that I solved this negative x problem by just adding some magic numbers
|
||
|
|
to the original value of x in the xmod7 operations.
|
||
|
|
Now those magic numbers are all multiples of seven which is okay but their values may
|
||
|
|
seem a little bit arbitrary when you first look at it.
|
||
|
|
I added a multiple of seven to x to get a nice positive remainder without changing the
|
||
|
|
answer.
|
||
|
|
Since I only had a short time to make my fixes I chose values that had an excellent
|
||
|
|
chance to succeed.
|
||
|
|
Arbitrary?
|
||
|
|
Yes, but not completely arbitrary.
|
||
|
|
Now here's an insight, there's a better way to have done it and I guess I figured out
|
||
|
|
that some of you would probably have found it by now.
|
||
|
|
I found it and I'm about to tell you about it.
|
||
|
|
Now I wish I could say I had an ulterior motive in using these magic numbers in the xmod7
|
||
|
|
expressions so I could claim that I was trying to bait you into giving me feedback with
|
||
|
|
your better solutions to the problem or find out whether there was anybody who saw through
|
||
|
|
those algorithms and got it.
|
||
|
|
But the honest reason is that I was on deadline and I stuck in numbers that would get the
|
||
|
|
job done.
|
||
|
|
Now here's a question.
|
||
|
|
Is there anything I could have done to make those adjustments simpler?
|
||
|
|
It's easier for later readers to understand and more robust all at the same time.
|
||
|
|
Here's a spoiler alert, stop the podcast right now if you want to figure that out for
|
||
|
|
yourself.
|
||
|
|
I'll wait.
|
||
|
|
Okay, you're back.
|
||
|
|
Well that was easy, right?
|
||
|
|
Once you start to play around with the functions a little bit you start to see how you could
|
||
|
|
make this fix.
|
||
|
|
I'll go through it in probably more nauseating detail than you'll want to hear.
|
||
|
|
That's what the fast forward button is for.
|
||
|
|
Now suppose we assign the answer to Xmod7 to the name Y.
|
||
|
|
Now there are two possible cases for the value of Y.
|
||
|
|
A is the easy case.
|
||
|
|
Y is not negative so it's equal to 0, 1, 2, 3, 4, 5 or 6 and everything works.
|
||
|
|
B is the needs help case where Y is not positive which is minus 6 minus 5 so on down to minus
|
||
|
|
1 or 0 and my original table look-up code for the final answer always returned Sunday.
|
||
|
|
Now you may ask yourself what could I do to Y to make it work?
|
||
|
|
Well here's a trial balloon, suppose we add 7 to Y whenever it's negative.
|
||
|
|
That would fix things for Monday, Tuesday, Wednesday, Thursday, Friday and Saturday and
|
||
|
|
since it was 0 and Sunday it wasn't negative and we're good.
|
||
|
|
Well the first problem with this approach is it introduces an extra value check to see
|
||
|
|
whether Y is negative and that's kind of a nuisance.
|
||
|
|
But that's kind of an aesthetic objection.
|
||
|
|
The second problem with the add 7 when Y is less than 0 fix is that you can screw it up
|
||
|
|
if you try to move that check for negative values upstream by checking for negative X in
|
||
|
|
the first place.
|
||
|
|
Now if you try to anticipate a negative Y by checking X and then adding 7 when X is negative
|
||
|
|
you've got a problem because you've just broken Sunday which is a position 0 in my setup
|
||
|
|
so adding plus 7 to 0 takes you out of bounds.
|
||
|
|
Now the add 7 adjustment is almost right but there's an even better way to do it and
|
||
|
|
that's to add one more step.
|
||
|
|
You get a better result that works for all X's without checking if you just always add 7
|
||
|
|
and then use Y plus 7 mod 7 as your subscript.
|
||
|
|
Now if Y is negative adding plus 7 shifts its value into the range 1 to 7 which are all
|
||
|
|
positive.
|
||
|
|
So Y plus 7 mod 7 always gives the right answer and the right range is 0 to plus 6.
|
||
|
|
The numbers 1 to 6 don't move the plus 7 goes back to 0 and you're all good.
|
||
|
|
Now the added benefit of this adjustment is it doesn't screw up the answers when X is
|
||
|
|
positive.
|
||
|
|
When X is positive the expression X mod 7 gives you a Y value in the range 0 to 6.
|
||
|
|
Adding plus 7 gives you an adjusted value from 7 to 13 and then Y plus 7 mod 7 moves
|
||
|
|
the answer back into the range 0 to 6 and in the right places once again.
|
||
|
|
So the adjustment is simple, it involves no checking in the program code and there are
|
||
|
|
no magic numbers to conjure up or to have to test or worry about.
|
||
|
|
Now that should help you to understand and use the spreadsheets and the little code snippets
|
||
|
|
that I gave you with the Doomsday episode and understand why they are a little bit different
|
||
|
|
in some places in different environments.
|
||
|
|
Now I'm going to close with a couple of additional programming applications of the mod
|
||
|
|
operation that might help you if you have programs that you're writing that do things
|
||
|
|
a lot of times and you want to handle different cases.
|
||
|
|
Now the first pattern is the every 1000th record pattern.
|
||
|
|
Now if you do programming that has long processes that take a lot of steps, you may want to
|
||
|
|
stop every few records to send a status message or make a log entry but you don't necessarily
|
||
|
|
want to fill your disk with log messages every single step.
|
||
|
|
So let's say you have a loop counter n, you could stop every 1000 records with a simple
|
||
|
|
line of code say that your status message or log entry is done with a function called
|
||
|
|
show underscore status.
|
||
|
|
So your code would be in the middle of your loop if n mod 1000 is equal to zero.
|
||
|
|
So if I've got a multiple of the 1000 then show status and maybe include n if you want
|
||
|
|
a report where you are and some other arguments and that will make your log entry every 1000
|
||
|
|
records.
|
||
|
|
Now if your loop starts with zero it might put out a log entry immediately but you can
|
||
|
|
adjust for that.
|
||
|
|
And then there's a kind of a common pattern I run into it's called the every other record
|
||
|
|
pattern.
|
||
|
|
I frequently run into situations that lead to what I'll call even odd processing where
|
||
|
|
you have to switch between two handlers at every other record in the file or maybe an
|
||
|
|
event in a simulation.
|
||
|
|
Let's suppose you have some kind of a thing that can change states from on and off at
|
||
|
|
each step.
|
||
|
|
I mean even printed books have left and right hand page formats that are different in
|
||
|
|
a way that helps readers but it makes things a little trickier for the types that are
|
||
|
|
in printer.
|
||
|
|
That's the kind of thing I'm talking about.
|
||
|
|
Now when you need to distinguish between even an odd parity the mod function handles that
|
||
|
|
very naturally.
|
||
|
|
After all if n is even then n mod 2 would be zero and vice versa.
|
||
|
|
And likewise if n is odd then n mod 2 is one.
|
||
|
|
Now with a divisor of two life is simple there's only two possible outcomes.
|
||
|
|
Now I can shuttle back and forth in a read loop with index n pretty easily using the mod
|
||
|
|
function or mod operator.
|
||
|
|
If I have two functions that I'll call do when odd and do when even that I want to run
|
||
|
|
when n is odd and even respectively I can just write the compound if statement if n mod
|
||
|
|
2 is equal to one then do when odd else do an even done.
|
||
|
|
Very simple just put in that little snippet of code and I'm able to handle every other
|
||
|
|
record properly.
|
||
|
|
And finally there's the scene one cycle scene of all that you run into where the input
|
||
|
|
data spans several input lines in a predictable way with the same number of records for each
|
||
|
|
entity that I'm reading.
|
||
|
|
Then I could use mod or an equivalent to tell my code to do something each line in that
|
||
|
|
cyclical pattern.
|
||
|
|
Now let's say I have a pattern of eight items per cycle and loop variable n and for the
|
||
|
|
simplicity I had several cases that collapsed into one function call.
|
||
|
|
So first thing I do when I come through my loop is I compute my offset equals n mod
|
||
|
|
8 because I don't want to keep doing the division every every for every time I have to
|
||
|
|
check the value.
|
||
|
|
And then I go into my statement and then I go into my if statement and that's if my offset
|
||
|
|
equals zero then I'm going to get name and I call that function and it will get the name
|
||
|
|
and store it somewhere.
|
||
|
|
And then in my pigeon programming code I'm going to say else if my offset is greater than
|
||
|
|
zero but less than six then I'm going to call my function oh get details and I'll throw
|
||
|
|
in the value of my offset is the first argument and then maybe some other arguments and then
|
||
|
|
I'll handle the case where my offset is equal to six so that's else if my offset equals
|
||
|
|
six then I'll get city state and zip let's say very U.S.
|
||
|
|
Century come sorry I could have said postal code and so on but I was lazy and then else
|
||
|
|
let's say I'll get the phone numbers and that would handle the case where my offset equals
|
||
|
|
seven and that's all the values that you need to check those are the only possible outcomes
|
||
|
|
for an integer being divided by eight and checking the remainder.
|
||
|
|
Okay well there are other applications of integer division and creative uses of the
|
||
|
|
quotients and the remainder is in programming I think these examples will be enough to
|
||
|
|
get you started.
|
||
|
|
I think it would be not too long before you'll be creating your own useful examples from
|
||
|
|
your own work or maybe from hobby projects or play so I think we can safely leave this
|
||
|
|
topic and move on to the conclusion and I'm going to talk about some more things but
|
||
|
|
I think I've given you a lot to chew on I mean you can take this discussion of mod and
|
||
|
|
remainder is further to talk about nice techniques for factoring big numbers and I'm talking
|
||
|
|
about either huge numbers or numbers that are big to be playing within your head or for
|
||
|
|
working with number bases other than ten or predicting the form of repeating decimals
|
||
|
|
and that kind of thing and that exploration would really use the same kind of techniques
|
||
|
|
that our teachers showed us when we were in school I guess between the ages of six and
|
||
|
|
twelve rather than naming US centric great great numbers or names but I think we're going
|
||
|
|
to leave this here for now I think it's been enough for one show where are we going next
|
||
|
|
well I think the next thing we're going to do I'm going to probably leave the recreational
|
||
|
|
math theme behind and look into a couple of listener requests for what I would call practical
|
||
|
|
math topics before I start looking at things that I wanted to look at in terms of math
|
||
|
|
and statistics software now probably procrastinating a little during the summer by recording one
|
||
|
|
or two shows on how I got into computing partly because hpr needs shows that I can produce
|
||
|
|
quickly and partly to buy time to figure out how to explain some things in an audio only
|
||
|
|
podcast format well having said that if mr x can do a comprehensive two part show on
|
||
|
|
soldering I think there's hope for this planned math for the rest of a series to work so that
|
||
|
|
to end for today and now it's your turn to record your show for hacker public radio your
|
||
|
|
ideas and projects podcasted thanks for listening you have been listening to hacker public radio
|
||
|
|
at hackerpublicradio.org we are a community podcast network that releases shows every week
|
||
|
|
day Monday through Friday today's show like all our shows was contributed by a hpr listener
|
||
|
|
like yourself if you ever consider recording a podcast then visit our website to find out how
|
||
|
|
easy it really is hacker public radio was founded by the digital dot pound and the
|
||
|
|
economical computer cloud hpr is funded by the binary revolution at binref dot com all binref
|
||
|
|
projects are proudly sponsored by linear pages from shared hosting to custom private clouds go
|
||
|
|
to lunar pages dot com for all your hosting needs unless otherwise stasis today's show is
|
||
|
|
released on the creative commons attribution share a life lead us our lives
|