Home » Identify Kaprekar Numbers

Identify Kaprekar Numbers

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
                    
                  

&&

Leave a Reply