' Puzzlet #023.
' Find a 6-digit integer with the
' following properties:
' Take the rightmost digit and place
' it in front of the integer to form
' a new number. (abcdef --> fabcde).
' The new one is the product of the
' old one and the shifted digit.
' (fabcde = f*abcdef).
' What was the original integer?
' By Dave Ellis.
declare shiftRight(f: int, s: int)
def factor, flag, n, shifted: int
openconsole
n = 99999
flag = 0
do
n = n + 1: increment the 6-digit integer
factor = n % 10: isolate the rightmost digit
if factor > 1: is rightmost digit other than zero?
shifted = shiftRight(factor, n): tack it on the front
if shifted = factor * n: does it multiply correctly?
flag = 1: yes
endif
endif
until flag = 1: quit if flag = 1 - a solution has been found
print n, "shifts to ", shifted,
print "= ", factor, "x ", n
print: print "That's all, folks!"
print: print "Press any key to exit ..."
do: until inkey$ <> ""
closeconsole
end
sub shiftRight(f, s)
' Shifts every digit one place to the right.
' The rightmost digit rolls around to become
' the new leftmost digit. Returns the result.
def nr: int
nr = s
nr = f * 10^5 + int(nr/10)
return nr
PROGRAM NOTES
This program was originally written in QBasic. In that version, it used string manipulation to get the answer. This permitted non-arithmetic operations like moving digits from one part of an integer to another. When I rewrote it in IBasic for this website, I decided to avoid the use of strings as an exercise.
The result is the code above. If you look at the main routine, the algorithm employed is clear. It's repeated here with line numbers to make the following explanation simpler.
1
2
3
4
5
6
7
8
9
10
do
n = n + 1
factor = n % 10
if factor > 0
shifted = shiftRight(factor, n)
if shifted = factor * n
flag = 1
endif
endif
until flag = 1
The code runs as a simple DO loop between lines 1 and 10. The current number being investigated is always held in variable n. The first action within the DO loop is for line 2 to increment n. Its value was initialised at 99999 before entering the loop for the first time, so it will be incremented to 100000 for the first investigation, the smallest possible 6-digit integer.
Line 3 performs an arithmetic division on n and stores the result in variable factor. An arithmetic division is the process whereby only the remainder of a division is retained, and the Ibasic language uses a percentage (%) sign to indicate its use. For example, 13 % 5 = 3, since 13 divided by 5 equals 2 remainder 3. Line 3 divides by 10, and 123456 % 10 would yield 6. So, in this context, it's just a way of separating out the last digit and storing it temporarily in factor.
We're going to use the separated digit to tack back onto the front of n. However, it could actually be a zero, in which case there's no point in doing it - 012345 has exactly the same value as 12345. Line 4 takes care of this. If factor is greater than 0, continue, otherwise increment n and try again.
Assuming factor is greater than zero, line 5 gets on with the business of forming the new number. We have already saved the value of the rightmost digit into factor, so all that remains to do is lop off the leftmost digit and replace it with factor. The aptly-named function ShiftRight accomplishes this and returns the result to be saved in variable shifted.
Finally, line 6 makes the arithmetic test. Does the product of the shifted digit and the original integer equal the new number, that is, does shifted equal factor times n?
If yes, line 7 sets variable flag to value 1, otherwise flag remains at its default value of 0. In this application, 1 means TRUE and 0 means FALSE.
Lines 8 and 9 are just the mandatory endifs to go with the two preceding ifs. Line 10 now takes a look at the value in flag. If it's a 1, a solution must have been found, and the DO loop is exited. Otherwise, the loop is executed again, incrementing n to look at the next value.
This code assumes an answer exists. If you weren't sure of this, you could place a trap in line 10 to stop when all the 6-digit integers have been checked, like this:
until flag = 1 | n > 999999
That merely says "until flag's value equals 1 or n's value is greater than 999999."
One final point of interest: How does ShiftRight work? A single line does all the work:
nr = f * 10^5 + int(nr/10)
nr holds the number to be manipulated, and f holds the rightmost digit of nr, already separated out. Let's do the bit in brackets first, using the example 123456. Remember, nr holds 123456, and f holds 6. The brackets do an ordinary division by 10, leaving 12345·6. Now we perform an int on this floating point number, which just means remove the decimal part - leaving 12345. Hold onto that thought.
Look at f * 10^5. This equates to 6 x 10^5, giving 600000. So now our expression effectively reads "nr = 600000 + 12345", which equals 612345. This is exactly what is required. Note that the final value is held in local variable nr, ready to be returned to the calling routine. This function will always produce the correct answer for any 6-digit integer which needs shifting right.
When you run the code, it will produce the inset screen.
This is the one and only solution.
102564 shifts to 410256 = 4 x 102564
That's all, folks!
Press any key to exit ...
MAIN MENU
DOWNLOAD CODE
ARCHIVES
Site design/maintenance: Dave Ellis E-mail me!
Last Updated: February 22nd, 2004.