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 .