Kaprekar’s Constant
On August 5th, 2018 Uwe Geiken posted a programming excercise in the Facebook group ‘BASIC on the ZX Spectrum’. The challenge had to do with something called the “Kaprekar’s Constant”. I had never heard of it before this post appeared in the group. Never too old to learn something new…
The post linked to a Wikipedia article about the Kaprekar’s Constant. The article lists the following properties for the constant (6174);
- Take any four-digit number, using at least two different digits. (Leading zeros are allowed.)
- Arrange the digits in descending and then in ascending order to get two four-digit numbers, adding leading zeros if necessary.
- Subtract the smaller number from the bigger number.
- Go back to step 2 and repeat.
It continues to give the following example
5432 — 2345 = 3087
8730 — 0378 = 8352
8532 — 2358 = 6174
7641 — 1467 = 6174
More details can be found on the Wikipedia page ‘Kaprekar’s routine’.
It has been a very long time since I did any programming on the ZX Spectrum, it must be over 25 years ago now, so I was keen to take a crack at it.
After some head scratching I ended up with the following piece of code and as usual checking and validating user input is a large piece of the code…
10 REM Display intro
20 CLS: PRINT "██ Kaprekar's Constant (6174) ██"
100 REM Get user input and validate input
110 INPUT "Enter a 4-digit number (leading zeros allowed): "; LINE a$
120 IF a$="x" OR a$="X" THEN PRINT "Goodbye!": STOP
130 IF LEN a$<>4 THEN PRINT "Enter exactly 4 digits!": GOTO 100
140 LET ct=0: FOR i=1 TO 3: IF a$(i)=a$(4) THEN LET ct=ct+1: NEXT i
150 IF ct=3 THEN PRINT "Enter at least two different digits!": GOTO 100
160 LET ct=0: FOR i=1 TO 4: IF a$(i)>="0" AND a$(i)<="9" THEN LET ct=ct+1: NEXT i
170 IF ct<>4 THEN PRINT "Enter only numbers!": GOTO 100
180 PRINT ""
200 REM Order numbers high to low
210 FOR i=1 TO LEN a$-1: FOR j=1 TO LEN a$-1
220 IF a$(j)<a$(j+1) THEN LET t$=a$(j): LET a$(j)=a$(j+1): LET a$(j+1)=t$
230 NEXT j: NEXT i
250 REM Reverse the number
260 LET b$="": FOR i=4 TO 1 STEP -1: LET b$=b$+a$(i): NEXT i
300 REM Calculate and display results
310 LET c=VAL a$-VAL b$
320 PRINT a$;" - ";b$;" = ";c
330 LET c$=STR$ c+"0000": LET a$=c$(1 TO 4)
400 REM Continue or Kaprekar's constant reached
410 IF c<>6174 THEN GOTO 200
420 PRINT "": PRINT "Reached Kaprekar's Constant.": PRINT "": GOTO 100
I am sure the code can be optimized further (surprised too see how much I have forgotten over the year, but also how quick some thing are coming back) but giving the fact it has been ages since I last coded for the ZX Spectrum I am happy with the results. At least it is working .
It also brought back memories about having sore fingertips after entering code for hours on end on that rubber keyboard .