Penholodigital squares are perfect square numbers that contain digits from 1 to 9 exactly once. List all Penholodigital square numbers. Ex. n = 139854276, its square root is 11826 (i.e. n is perfect square) and n contains digits from 1 to 9 exactly once. Note – This problem calls for an efficient algorithm to generate the numbers. Brute force method will be too much. You will need to think through this. I am including a reference to the source in Excel file from where this is taken. Comments section provides the algorithm also, in case you need help.
📌 Challenge Details and Links
ExcelBI Excel Challenge Number: 447
Challenge Difficulty: ⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn
Solving the challenge of Find Penholodigital Squares with Power Query
Power Query solution 1 for Find Penholodigital Squares, proposed by Bo Rydobon 🇹🇭:
let
Source = List.Select(
List.Transform(
List.Sort(
List.Accumulate(
{"2" .. "9"},
{"1"},
(s, l) =>
List.Combine(
List.Transform(
s,
each List.Transform({0 .. Number.From(l) - 1}, (n) => Text.ReplaceRange(_, n, 0, l))
)
)
)
),
Number.From
),
each Number.Mod(Number.Sqrt(_), 1) = 0
)
in
Source
Power Query solution 2 for Find Penholodigital Squares, proposed by Rick de Groot:
let
Min = Int64.From( Number.Sqrt( 123456789 ) ),
Max = Int64.From( Number.Sqrt( 987654321 ) ),
List = List.Transform( { Min..Max }, each Text.From( Number.Power(_, 2) ) ),
Select = List.Select( List, each List.ContainsAll( Text.ToList( _ ), {"1".."9" } ) )
in
Select
hashtag#bigorilla hashtag#powerqueryhow
Power Query solution 3 for Find Penholodigital Squares, proposed by Aditya Kumar Darak 🇮🇳:
let
Start = Number.IntegerDivide(Number.Sqrt(123456789), 1),
End = Number.IntegerDivide(Number.Sqrt(987654321), 1),
List = List.TransformMany(
{Start .. End},
(x) => {Text.From(x * x)},
(x, y) => if List.ContainsAll(Text.ToList(y), {"1" .. "9"}) then y else null
),
Return = List.RemoveNulls(List)
in
Return
Power Query solution 4 for Find Penholodigital Squares, proposed by Aditya Kumar Darak 🇮🇳:
let
Generate = List.Transform(
List.Accumulate(
{"2" .. "9"},
{},
(a, i) =>
[
N = {"1" .. i},
R = List.Accumulate(
N,
{""},
(s, l) =>
List.Combine(
List.Transform(
s,
each List.RemoveNulls(
List.Transform(N, (n) => if Text.Contains(_, n) then null else _ & n)
)
)
)
)
][R]
),
each Number.From(_)
),
Return = List.Select(Generate, each Number.Mod(Number.Sqrt(_), 1) = 0)
in
Return
Power Query solution 5 for Find Penholodigital Squares, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
A = Table.SelectRows(
Table.Combine(
List.Transform(
{11000 .. 31000},
each
let
a = _ * _,
b = Text.From(a),
c = List.Transform({"1" .. "9"}, each Text.Length(Text.Select(b, _))),
d = List.AllTrue(List.Transform(c, each _ = 1)),
e = Table.FromRows({{b, d}}, {"Answer", "C2"})
in
e
)
),
each [C2]
)[[Answer]]
in
A
Power Query solution 6 for Find Penholodigital Squares, proposed by Alexis Olson:
let
Min = Number.Round(Number.Sqrt(123456789)), //11,112
Max = Number.Round(Number.Sqrt(987654321)), //31,427
Candidates = List.Transform({Min .. Max}, (n) => n * n),
Result = List.Select(Candidates, each List.Sort(Text.ToList(Number.ToText(_))) = {"1" .. "9"})
in
Result
Power Query solution 7 for Find Penholodigital Squares, proposed by Brian Julius:
let
Source = Table.FromList(
{Number.RoundDown(Number.Sqrt(100000000), 0) .. Number.RoundDown(Number.Sqrt(999999999), 0)},
Splitter.SplitByNothing(),
{"X"},
null,
ExtraValues.Error
),
AddSq = Table.AddColumn(Source, "X2", each Number.Power([X], 2)),
AddContains0 = Table.SelectRows(
Table.AddColumn(AddSq, "Contains0", each List.Contains(Text.ToList(Text.From([X2])), "0")),
each [Contains0] = false
),
Adddistinct = Table.SelectColumns(
Table.SelectRows(
Table.AddColumn(AddContains0, "Distinct", each List.IsDistinct(Text.ToList(Text.From([X2])))),
each [Distinct] = true
),
"X2"
)
in
Adddistinct
Power Query solution 8 for Find Penholodigital Squares, proposed by Mihai Radu O:
let
s = Number.RoundUp(Number.Sqrt(123456789), 0),
f = Number.RoundDown(Number.Sqrt(987654321), 0),
l = List.Transform({s .. f}, each Text.From(_ * _)),
a = List.Select(l, each List.Sort(Text.ToList(_)) = {"1" .. "9"})
in
a
Solving the challenge of Find Penholodigital Squares with Excel
Excel solution 1 for Find Penholodigital Squares, proposed by Bo Rydobon 🇹🇭:
=LET(
s,
SEQUENCE(
20315,
,
11111
)^2,
TOCOL(
s/BYROW(
FIND(
SEQUENCE(
,
9
),
s
),
AND
),
3
)
)
Excel solution 2 for Find Penholodigital Squares, proposed by Bo Rydobon 🇹🇭:
=LET(
s,
SEQUENCE(
12^4,
,
10^4
)^2,
TOCOL(
s/BYROW(
FIND(
SEQUENCE(
,
9
),
s
),
AND
),
3
)
)
Excel solution 3 for Find Penholodigital Squares, proposed by Rick Rothstein:
=LET(
b,
INT(
SQRT(
123456789
)
),
t,
INT(
SQRT(
987654321
)
),
s,
SEQUENCE(
t-b+1,
,
b
),
f,
FILTER(
s,
MOD(
s,
3
)=0
)^2,
n,
FILTER(
f,
ISERROR(
0+TEXTBEFORE(
f,
0
)
)
),
m,
MID(
n,
SEQUENCE(
,
9
),
1
),
TOCOL(
IF(
BYROW(
m,
LAMBDA(
r,
LEN(
CONCAT(
UNIQUE(
r,
1,
1
)
)
)
)
)=9,
n,
1/0
),
3
)
)
Excel solution 4 for Find Penholodigital Squares, proposed by John V.:
=LET(
s,
ROW(
1:30400
)^2,
TOCOL(
s/BYROW(
FIND(
COLUMN(
A:I
),
s
),
AND
),
2
)
)
Excel solution 5 for Find Penholodigital Squares, proposed by محمد حلمي:
=LET(
s,
SEQUENCE(
9
),
TOCOL(
MAP(
SEQUENCE(
18560,
,
11826
)^2,
LAMBDA(
a,
a/AND(
s=SORT(
--MID(
a,
s,
1
)
)
)
)
),
2
)
)
Excel solution 6 for Find Penholodigital Squares, proposed by Kris Jaganah:
=LET(a,
SEQUENCE(
9
),
b,
INT(
CONCAT(
a
)^0.5
),
c,
SEQUENCE(
CONCAT(
SORT(
a,
,
-1
)
)^0.5-b,
,
b
)^2,
TOCOL(c/(MAP(c,
LAMBDA(x,
SUM(--((a-SORT(
MID(
x,
a,
1
)
))=0))))=9),
3))
Excel solution 7 for Find Penholodigital Squares, proposed by Julian Poeltl:
=LET(S,
SEQUENCE(
20315,
,
11111
),
Sq,
S^2,
R,
(ISNUMBER(
SEARCH(
0,
Sq
)
)=FALSE)*(MAP(
Sq,
LAMBDA(
A,
COUNTA(
UNIQUE(
MID(
A,
SEQUENCE(
,
9
),
1
),
TRUE
)
)=9
)
)),
FILTER(
Sq,
R
))
Excel solution 8 for Find Penholodigital Squares, proposed by Timothée BLIOT:
=LET(
S,
SEQUENCE(
10^5
)^2,
FILTER(
S,
MAP(
S,
LAMBDA(
x,
CONCAT(
SORT(
MID(
x,
SEQUENCE(
LEN(
x
)
),
1
)
)
)="123456789"
)
)
)
)
Excel solution 9 for Find Penholodigital Squares, proposed by Sunny Baggu:
=LET(
s,
SEQUENCE(
20315,
,
11112
),
FILTER(
s ^ 2,
BYROW(
SEARCH(
SEQUENCE(
,
9
),
s ^ 2
),
LAMBDA(
a,
AND(
ISNUMBER(
a
)
)
)
)
)
)
Excel solution 10 for Find Penholodigital Squares, proposed by Sunny Baggu:
=LET(
s,
SEQUENCE(
20315,
,
11112
),
n,
s ^ 2,
m,
LAMBDA(
x,
--MID(
x,
SEQUENCE(
9
),
1
)
),
_c1,
(MOD(
n,
3
) = 0) *
MAP(n,
LAMBDA(a,
(SUM(
m(
a
)
) = 45) * (ROWS(
UNIQUE(
m(
a
)
)
) = 9))),
FILTER(
n,
_c1
)
)
Excel solution 11 for Find Penholodigital Squares, proposed by Sunny Baggu:
=LET(
s,
SEQUENCE(
9
),
n,
SEQUENCE(
20315,
,
11112
),
FILTER(
n ^ 2,
MAP(
n ^ 2,
LAMBDA(
a,
AND(
SORT(
MID(
a,
s,
1
)
) = "" & s
)
)
)
)
)
Excel solution 12 for Find Penholodigital Squares, proposed by LEONARD OCHEA 🇷🇴:
=LET(
s,
SEQUENCE(
6425,
,
11112,
3
)^2,
TOCOL(
s/BYROW(
FIND(
SEQUENCE(
,
9
),
s
),
AND
),
3
)
)
Excel solution 13 for Find Penholodigital Squares, proposed by Andy Heybruch:
=LET(
_n,
SEQUENCE(
987654321^0.5
)^2,
_filter,
BYROW(
_n,
LAMBDA(
a,
CONCAT(
SORT(
MID(
a,
SEQUENCE(
9
),
1
),
1,
1
)
)="123456789"
)
),
FILTER(
_n,
_filter=TRUE
)
)
Excel solution 14 for Find Penholodigital Squares, proposed by Ziad A.:
=TOCOL(
MAP(
ROW(
11826:30384
)^2,
LAMBDA(
c,
c/AND(
FIND(
ROW(
1:9
),
c
)
)
)
),
2
)
Excel solution 15 for Find Penholodigital Squares, proposed by Ernesto Vega Castillo:
=LET(
g,
POWER(
SEQUENCE(
18560,
,
11826
),
2
),
h,
LET(
a,
g,
MAP(
a,
LAMBDA(
x,
SUM(
IF(
SORT(
--MID(
x,
SEQUENCE(
LEN(
x
)
),
1
)
)=SEQUENCE(
9
),
1
)
)
)
)
)=9,
FI<ER(
g,
h
)
)
Excel solution 16 for Find Penholodigital Squares, proposed by Burhan Cesur:
=LET(
Min,
INT(
SQRT(
123456789
)
),
Max,
INT(
SQRT(
987654321
)
),
List,
POWER(
SEQUENCE(
Max-Min+1,
1,
Min
),
2
),
FILTER(List,
MAP(List,
LAMBDA(x,
SUM(--(BYCOL(1*(-- MID(
x,
SEQUENCE(
LEN(
x
)
),
1
)=SEQUENCE(
,
9
)),
SUM)=1))=9
))))
Excel solution 17 for Find Penholodigital Squares, proposed by Josh Brodrick:
=LET(a,
MAP(
SEQUENCE(
20000,
,
11500,
1
)^2,
LAMBDA(
x,
IF(
ISERR(
CONCAT(
FIND(
{1,
2,
3,
4,
5,
6,
7,
8,
9},
x
)
)
),
"NA",
x
)
)
),
(FILTER(
a,
a<>"NA"
)))
Excel solution 18 for Find Penholodigital Squares, proposed by Tyler Cameron:
=LET(
b,
MAP(
SEQUENCE(
21622,
,
10000
)^2,
LAMBDA(
a,
LET(
d,
--MID(
a,
SEQUENCE(
LEN(
a
)
),
1
),
IF(
AND(
SUM(
d
)=45,
SORT(
d
)=SEQUENCE(
9
)
),
a,
0
)
)
)
),
c,
FILTER(
b,
b<>0
),
FILTER(
c,
MOD(
SQRT(
c
),
1
)=0
)
)
Excel solution 19 for Find Penholodigital Squares, proposed by Tyler Cameron:
=LET(
b,
SEQUENCE(
,
21622,
10000
)^2,
TOCOL(
MAP(
b,
LAMBDA(
x,
IF(
SUM(
FIND(
SEQUENCE(
9
),
x
)
)=45,
x
)
)
),
3
)
)
Excel solution 20 for Find Penholodigital Squares, proposed by Ben Gutscher:
=LET(
sq,
UNIQUE(
ROUNDDOWN(
SEQUENCE(
SQRT(
10^9
)-SQRT(
10^8
),
,
SQRT(
10^8
)
),
0
)
)^2,
FILTER(
sq,
BYROW(
sq,
LAMBDA(
r,
AND(
LEN(
r
)-LEN(
SUBSTITUTE(
r,
SEQUENCE(
,
9
),
""
)
)=1
)
)
)
)
)
Solving the challenge of Find Penholodigital Squares with Python
Python solution 1 for Find Penholodigital Squares, proposed by Konrad Gryczan, PhD:
import math
from itertools import permutations
import time
import pandas as pd
test = pd.read_excel("447 Penholodigital Squares.xlsx", usecols = "A", nrows = 30)
start_time = time.time()
penholodigital_numbers = [
num for num in (
int(''.join(map(str, perm))) for perm in permutations('123456789')
) if int(math.sqrt(num)) ** 2 == num
]
end_time = time.time()
execution_time = end_time - start_time
# for validation purpose
penholodigital_numbers = pd.DataFrame(penholodigital_numbers, columns = ["Answer Expected"])
print(penholodigital_numbers.equals(test)) # True
print("Execution time:", execution_time, "seconds") # 0.2874 seconds
Solving the challenge of Find Penholodigital Squares with Python in Excel
Python in Excel solution 1 for Find Penholodigital Squares, proposed by Abdallah Ally:
import pandas as pd
file_path = 'Excel_Challenge_447 - Penholodigital Squares.xlsx'
df = pd.read_excel(file_path)
# Perform data transformation and cleansing
digits = [str(x) for x in range(1, 10)]
interval = range(int(123456789 ** 0.5), int(987654321 ** 0.5) + 1)
numbers = [c for x in interval if all(item in list(str(c := x ** 2)) for item in digits)]
df['My Answer'] = pd.Series(numbers)
df['Check'] = df['Answer Expected'] == df['My Answer']
print(f'Random sample of records:nn {df.sample(n=10, replace=False)}')
Solving the challenge of Find Penholodigital Squares with R
R solution 1 for Find Penholodigital Squares, proposed by Konrad Gryczan, PhD:
library(gtools)
library(tictoc)
library(tidyverse)
library(readxl)
test = read_excel("Excel/447 Penholodigital Squares.xlsx", range = "A1:A31")
test$`Answer Expected` = as.numeric(test$`Answer Expected`)
# Approach 1
tic()
penholodigital_numbers <- apply(permutations(9, 9, 1:9, set = FALSE), 1, function(x) {
num <- as.numeric(paste0(x, collapse = ""))
root <- sqrt(num)
if (root == floor(root)) num else NA
})
penholodigital_numbers <- na.omit(penholodigital_numbers)
toc() # 3.59 sec
# Validation
p1 = penholodigital_numbers %>%
tibble(`Answer Expected` = .)
attributes(p1$`Answer Expected`) <- NULL
identical(p1$`Answer Expected`, test$`Answer Expected`)
# [1] TRUE
# Approach 2
tic()
penholodigital_numbers2 = permutations(9,9,1:9) %>%
as_tibble() %>%
unite(num, V1:V9, sep = "") %>%
mutate(num = as.numeric(num)) %>%
filter(sqrt(num) == floor(sqrt(num)))
toc() # 3.3 sec
# Validation
identical(penholodigital_numbers2$num, test$`Answer Expected`)
# [1] TRUE
R solution 2 for Find Penholodigital Squares, proposed by Anil Kumar Goyal:
Off late, but a bit faster approach. Comments and suggestions invited Konrad Gryczan, PhD
Penholodigital <- numeric(0)
for(i in ceiling(sqrt(123456789)):floor(sqrt(987654321))){
x <- unique(unlist(str_split(as.character(i^2), "")))
if("0" %in% x){
next
} else if (length(x) == 9){
Penholodigital <- c(Penholodigital, i^2)
}
}
&&
