Kaprekar Number = Take an n digit number, square it, divide it into 2 parts such that part1 + part 2 = n where part1 or part2 should not be 0, then it is a Kaprekar number. Ex. 297 => 297^2 = 88209 => sum of two parts = 88 + 209 = 297 which is the original number itself. 10 => 10^2 = 100 => 10 + 0 = 10 which is the original number itself but it is not a Kaprekar number as one part is 0. Note – I am excluding 1 to 3 as their squares are in single digits, hence can’t be divided into 2 parts. List first 50 Kaprekar numbers.
📌 Challenge Details and Links
ExcelBI Excel Challenge Number: 554
Challenge Difficulty: ⭐️⭐️⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn
Solving the challenge of Identify Kaprekar Numbers with Power Query
Power Query solution 1 for Identify Kaprekar Numbers, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
Source = List.RemoveNulls(
List.Generate(
() => [x = 0, y = 0, z = null],
each [y] <= 50,
each [
x = [x] + 1,
z =
let
a = Text.From(Number.Power(x, 2)),
b = {1 .. Text.Length(a) - 1},
c = List.Transform(
b,
each (Number.From(Text.Start(a, _)) + Number.From(Text.End(a, Text.Length(a) - _)))
= x and Number.From(Text.End(a, Text.Length(a) - _))
<> 0
),
d = List.AnyTrue(c),
e = if d then x else null
in
e,
y = if z <> null then [y] + 1 else [y]
],
each [z]
)
)
in
Source
Power Query solution 2 for Identify Kaprekar Numbers, proposed by Abdallah Ally:
let
is_kaprekar = (num) =>
[
a = Text.From(Number.Power(num, 2)),
b = Text.Length(a),
c = List.Transform(
{1 .. b - 1},
each [
p = Number.From(Text.Start(a, _)),
q = Number.From(Text.End(a, b - _)),
r = Byte.From(p + q = num and p <> 0 and q <> 0)
][r]
),
d = List.Sum(c) > 0 and b > 1
][d],
Result = List.RemoveNulls(
List.Generate(
() => [num = 1, cond = is_kaprekar(num), counter = 0],
each [counter] <= 50,
each [num = [num] + 1, cond = is_kaprekar(num), counter = [counter] + Byte.From(cond)],
each if [cond] then [num] else null
)
)
in
Result
Power Query solution 3 for Identify Kaprekar Numbers, proposed by Rafael González B.:
let
Kapre = (Nu) =>
let
NF = Number.From, TF = Text.From, TC = Text.Combine,
Sq = Text.ToList(TF(Nu*Nu)),
d = Text.Length(TF(Nu)),
S1 = NF(TC(List.RemoveLastN(Sq,d))) ,
S2 = NF(TC(List.LastN(Sq,d))),
Sum = S1 + S2,
Ch = Sum = Nu
in
Ch,
KaprekarNum = (count, Iterations) =>
let
GN = List.Generate(() => 1, each _ <= Iterations, each _ + 1),
KN = List.Select(GN, each Kapre(_)),
FirstKN = List.FirstN(KN, count)
in
FirstKN
in
KaprekarNum(50, 5000000)
Is a little slow but works.
🧙🏻♂️🧙🏻♂️🧙🏻♂️
Power Query solution 4 for Identify Kaprekar Numbers, proposed by Rafael González B.:
let
Kapre = (Nu) =>
let
N = Text.From(Nu),
SQ = Text.From(Nu * Nu),
TL = Text.Length(SQ),
LP = {0 .. TL},
LA = List.Skip(
List.Accumulate(
LP,
{},
(s, c) =>
let
TN = Splitter.SplitTextByRanges({{0, c}, {c, TL}})(SQ),
LT = List.Transform(TN, each Number.From(_)),
LS = if List.Last(LT) > 0 then List.Sum(LT) else 0
in
s & {LS}
)
),
LC = try List.Contains(LA, Number.From(N)) otherwise false
in
LC,
KaprekarNum = (count as number, Iterations as number) =>
let
GN = List.Generate(() => 1, each _ <= Iterations, each _ + 1),
KN = List.Select(GN, each Kapre(_)),
FirstKN = List.FirstN(KN, count)
in
FirstKN
in
KaprekarNum(50, 1000000)
Power Query solution 5 for Identify Kaprekar Numbers, proposed by Tyler N.:
let
a = {4 .. 900000},
b = List.Transform(
a,
each
let
c = _,
d = Number.Power(_, 2),
e = Number.From(Number.Mod(Number.Log10(_), 1) <> 0),
f = List.Transform(
{1 .. Text.Length(Text.From(_ * e))},
each
let
g = Text.From(d * e),
h = List.Sum(
List.Transform(
{Text.Start(g, _), Text.End(g, Text.Length(g) - _)},
each Number.From(_)
)
)
in
h
)
in
List.Select(f, each _ = c)
),
i = List.Combine(b)
in
i
Solving the challenge of Identify Kaprekar Numbers with Excel
Excel solution 1 for Identify Kaprekar Numbers, proposed by Bo Rydobon 🇹🇭:
=REDUCE(9,SEQUENCE(5),LAMBDA(a,i,LET(n,SEQUENCE(9*10^i,,10^i),p,10^(i+{1,2,3}),VSTACK(a,TOCOL(n/(n=INT(n^2/p)+MOD(n^2,p)),3)))))
0.36 second
=REDUCE(9,SEQUENCE(5),LAMBDA(a,i,LET(n,SEQUENCE(9*10^i,,10^i),p,10^(i+IFS(i>4,{1,2},i=3,{1,2,3},1,1)),VSTACK(a,TOCOL(n/(n=INT(n^2/p)+MOD(n^2,p)),3)))))
Excel solution 2 for Identify Kaprekar Numbers, proposed by Rick Rothstein:
=LET(c,SEQUENCE(900000,,4),FILTER(c,MAP(c,LAMBDA(x,LET(n,x*x,s,SEQUENCE(LEN(n)-1),l,LEFT(n,s),r,MID(n,1+s,11),IF(x<>0+("1"&REPT(0,LEN(x)-1)),OR(l+r=x)))))))
Excel solution 3 for Identify Kaprekar Numbers, proposed by John V.:
=TOCOL(MAP(SEQUENCE(95^3,,4),LAMBDA(x,LET(c,x^2,n,LEN(c),s,SEQUENCE(n-1),i,LEFT(c,s),d,RIGHT(c,n-s),x/OR((x=i+d)*i*d)))),2)
Excel solution 4 for Identify Kaprekar Numbers, proposed by Kris Jaganah:
=TAKE(TOCOL(MAP(SEQUENCE(
10^6
),
LAMBDA(x,
LET(a,
x^2,
b,
LEN(
a
),
c,
SEQUENCE(
b
),
d,
MID(
a,
1,
c
),
e,
b-c,
f,
--RIGHT(
a,
e
),
x/SUM(TOCOL(((d+f)=x)*(e>0)*(f>0),
3))))),
3),
50)
Excel solution 5 for Identify Kaprekar Numbers, proposed by Julian Poeltl:
=LET(S,SEQUENCE(900000,,4),SQ,S^2,TOCOL(MAP(S,SQ,LAMBDA(A,B,LET(L,LEN(B)-1,LL,--LEFT(B,SEQUENCE(L)),RR,--RIGHT(B,SEQUENCE(L,,L,-1)),IF(SUM((RR+LL=A)*(LL>0)*(RR>0)),A,X)))),3))
Excel solution 6 for Identify Kaprekar Numbers, proposed by Timothée BLIOT:
=LET(A,SEQUENCE(10^6,,4),B,A^2,C,LEN(B)/2,D,--LEFT(B,FLOOR(C,1)),E,--RIGHT(B,CEILING(C,1)),F,QUOTIENT(D,10),SORT(UNIQUE(VSTACK(FILTER(A,E+D=A),FILTER(A,IF((MOD(D,10)=0)*(F<>0),F,D)+E=A)))))
Excel solution 7 for Identify Kaprekar Numbers, proposed by Sunny Baggu:
=LET(
t,
SEQUENCE(
900000,
,
9
),
TAKE(
FILTER(
t,
MAP(
t,
LAMBDA(n,
LET(
_sq,
n ^ 2,
_a,
SEQUENCE(
LEN(
_sq
) - 1
),
_b,
LEN(
_sq
) - _a,
_c,
LEFT(
_sq,
_a
) + 0,
_d,
RIGHT(
_sq,
_b
) + 0,
_e,
(_c <> 0) * (_d <> 0) * (_c + _d),
_f,
OR(
n = _e
),
_f
)
)
)
),
50
)
)
Excel solution 8 for Identify Kaprekar Numbers, proposed by LEONARD OCHEA 🇷🇴:
=TAKE(TOCOL(MAP(SEQUENCE(10^6,,4),LAMBDA(a,LET(b,a^2,l,LEN(b),k,SEQUENCE(l-1),i,--LEFT(b,k),j,--RIGHT(b,l-k),a/OR(i*j*(i+j=a))))),3),50)
Excel solution 9 for Identify Kaprekar Numbers, proposed by Anshu Bantra:
= n ** 2
n_squared_str = str(n_squared)
length = len(n_squared_str)
for i in range(1, length):
left_part = int(n_squared_str[:i]) if n_squared_str[:i] else 0
right_part = int(n_squared_str[i:]) if n_squared_str[i:] else 0
if left_part + right_part == n and right_part != 0:
return True
return n == 1 # Special case for 1
# Example usage:
rng = range(4, 860000)
list(filter(is_kaprekar_number, rng))
Excel solution 10 for Identify Kaprekar Numbers, proposed by ferhat CK:
=LET(n,SEQUENCE(5000,,4),r,DROP(REDUCE(0,n,LAMBDA(i,j,VSTACK(i,LET(a,j^2,b,MID(a,1,SEQUENCE(LEN(a)-1)),c,BYROW(b,LAMBDA(x,SUBSTITUTE(a,x,""))),d,BYROW(--HSTACK(b,c),SUM),ISNUMBER(XLOOKUP(j,d,d)))))),1),FILTER(n,(r=TRUE)*(n<>10^(LEN(n)-1))))
Excel solution 11 for Identify Kaprekar Numbers, proposed by Bilal Mahmoud kh.:
=REDUCE(,ROW(4:999999),LAMBDA(y,x,LET(a,x^2,b,IF(OR(MAP(SEQUENCE(LEN(a)-1),LAMBDA(y,LET(n,--MID(a,1,y),m,--MID(a,y+1,LEN(a)-y),IF(AND(n<>0,m<>0,n+m=x),TRUE,FALSE))))),x,0),IF(b<>0,VSTACK(y,b),y))))
Excel solution 12 for Identify Kaprekar Numbers, proposed by MANUEL DE ACUÑA RIVERO:
=ELEGIRFILAS(ENCOL(MAP(SECUENCIA(
900000;
;
4
);
LAMBDA(_x;
LET(
_n;
_x;
_n2;
_n^2;
_long;
LARGO(
_n2
)-1;
_sec;
SECUENCIA(
_long
);
_secb;
SECUENCIA(
_long;
;
_long;
-1
);
_izda;
--IZQUIERDA(
_n2;
_sec
);
_dcha;
--SUSTITUIR(
_n2;
_izda;
""
);
_apdo;
APILARH(
_izda;
_dcha
);
_fil;
FILTRAR(
_apdo;
_dcha>0
);
SI(SUMA(--(BYROW(
_fil;
SUMA
)=_n));
_x;
NOD())
)));
2);
SECUENCIA(
50
))
Solving the challenge of Identify Kaprekar Numbers with Python
Python solution 1 for Identify Kaprekar Numbers, proposed by Konrad Gryczan, PhD:
import pandas as pd
import math
path = "554 Kaprekar Numbers.xlsx"
test = pd.read_excel(path, usecols="A", nrows=51)
def check_kaprekar_fast(n):
nsqr = n ** 2
digits = math.floor(math.log10(nsqr)) + 1
for split_pos in range(1, digits):
right_part = nsqr % (10 ** split_pos)
left_part = nsqr // (10 ** split_pos)
if right_part > 0 and left_part + right_part == n:
return True
return False
n_values = range(4, 1000001)
kaprekar_flags = [check_kaprekar_fast(n) for n in n_values]
df = pd.DataFrame({'n': n_values, 'is_kaprekar': kaprekar_flags})
df = df[df['is_kaprekar']].head(50).loc[:, ['n']].reset_index(drop=True)
print(df["n"].equals(test["Answer Expected"])) # True
Python solution 2 for Identify Kaprekar Numbers, proposed by Ümit Barış Köse, MSc:
from itertools import islice, count
def is_kaprekar(num):
square_str = str(num ** 2)
d = len(str(num))
for i in range(1, len(square_str)):
p = int(square_str[:i])
q = int(square_str[i:]) if i < len(square_str) else 0
if p + q == num and q > 0:
return True
return False
numbers = islice((n for n in count(1) if is_kaprekar(n)), 50)
df = pd.DataFrame({'My Answer': numbers})
df
Solving the challenge of Identify Kaprekar Numbers with Python in Excel
Python in Excel solution 1 for Identify Kaprekar Numbers, proposed by Alejandro Campos:
def is_kaprekar_number(n):
if n < 4:
return False
square = n ** 2
str_square = str(square)
for i in range(1, len(str_square)):
part1 = int(str_square[:i])
part2 = int(str_square[i:])
if part1 > 0 and part2 > 0 and part1 + part2 == n:
return True
return False
kaprekar_numbers = []
num = 4
while len(kaprekar_numbers) < 50:
if is_kaprekar_number(num):
kaprekar_numbers.append(num)
num += 1
df = pd.DataFrame(kaprekar_numbers, columns=["Kaprekar Numbers"])
df
Python in Excel solution 2 for Identify Kaprekar Numbers, proposed by Abdallah Ally:
from itertools import islice, count
# Function to check if a number is Kaprekar
def is_kaprekar(num):
a = str(num ** 2)
if len(a) < 2:
return False
b = [
p + q == num for i in range(len(a) - 1)
if (p:=int(a[: i + 1])) and (q:=int(a[i + 1: ]))
]
return any(b)
# Perform data wrangling
numbers = islice(filter(is_kaprekar, count(1)), 50)
df = pd.DataFrame({'My Answer': numbers})
df
Solving the challenge of Identify Kaprekar Numbers with R
R solution 1 for Identify Kaprekar Numbers, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
library(parallel)
path = "Excel/554 Kaprekar Numbers.xlsx"
test = read_excel(path, range = "A1:A51")
check_kaprekar_fast = function(n) {
nsqr = n^2
digits = floor(log10(nsqr)) + 1
for (split_pos in 1:(digits - 1)) {
right_part = nsqr %% 10^split_pos
left_part = nsqr %/% 10^split_pos
if (right_part > 0 && left_part + right_part == n) {
return(TRUE)
}
}
return(FALSE)
}
parallel_kaprekar_check = function(n_values) {
num_cores = detectCores() - 1
cl = makeCluster(num_cores)
clusterExport(cl, "check_kaprekar_fast")
result = parLapply(cl, n_values, check_kaprekar_fast)
stopCluster(cl)
return(unlist(result))
}
n_values = 4:1000000
kaprekar_flags = parallel_kaprekar_check(n_values)
df = data.frame(n = n_values, is_kaprekar = kaprekar_flags) %>%
filter(is_kaprekar) %>%
head(50) %>%
select(n)
all.equal(df, test, check.attributes = FALSE) # TRUE
Solving the challenge of Identify Kaprekar Numbers with Excel VBA
Excel VBA solution 1 for Identify Kaprekar Numbers, proposed by Enrico Giorgi:
Option Explicit
Sub Kaprekar()
Dim Check, i, L, j, part1, part2, Sq As LongLong
Dim Condition As Boolean
Application.ScreenUpdating = False
Check = 0 'count how many Kaprekar numbers have been found
i = 4
Do While Check < 50
Sq = (i * i)
L = Application.RoundDown(Application.WorksheetFunction.Log10(Sq), 0) + 1
j = 1
Condition = False
Do While j < L And Condition = False
part1 = CLngLng(Left(Sq, j))
part2 = CLngLng(Right(Sq, L - j))
If (part1 > 0) And (part2 > 0) And (part1 + part2) = i Then
Check = Check + 1
Condition = True
ThisWorkbook.Sheets(1).Cells(Check + 1, "B") = i
End If
j = j + 1
Loop
i = i + 1
Loop
MsgBox "Computation completed"
End Sub
&&
