A Disarium number is that number where sum of each digit raised to the power of its position in the number is equal to number itself. Position follows index 1 method not index 0. Ex. 175 is a Disarium number. 1^1+7^2+5^3 = 1+49+125=175 Challenge – Generate the list of first 18 Disarium numbers.
📌 Challenge Details and Links
ExcelBI Excel Challenge Number: 164
Challenge Difficulty: ⭐️⭐️⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn
Solving the challenge of Generate First Disarium List with Power Query
Power Query solution 1 for Generate First Disarium List, proposed by Zoran Milokanović:
let
fx_calc_dn = (num as text) =>
let
NumToList = Text.ToList(num),
dn = List.Accumulate(
List.Positions(NumToList),
0,
(s, d) => s + Number.Power(Number.FromText(NumToList{d}), (d + 1))
)
in
dn,
Source = List.Select(
List.Generate(
() => [dn = 1, f = true, i = 1],
each [i] <= 18,
each [
dn = [dn] + 1,
f = (dn = fx_calc_dn(Text.From(dn))),
i = [i] + (if f = true or [i] = 18 then 1 else 0)
],
each if [f] = true then [dn] else null
),
each _ <> null
)
in
Source
Power Query solution 2 for Generate First Disarium List, proposed by Aditya Kumar Darak 🇮🇳:
let
MyFun = (Number) =>
let
T = Text.From(Number),
C = List.Accumulate(
{1 .. Text.Length(T)},
0,
(s, c) => s + Number.Power(Number.From(Text.At(T, c - 1)), c)
)
= Number
in
C,
FirstN = 18,
Generate = List.Buffer(
List.Generate(
() => [x = 1, y = true, z = 0],
each [z] < FirstN,
each [x = [x] + 1, y = MyFun(x), z = [z] + Number.From(MyFun([x]))]
)
),
Select = List.Select(Generate, each [y]),
Return = List.Transform(Select, each [x])
in
Return
Power Query solution 3 for Generate First Disarium List, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
Source = Table.FromColumns({List.Buffer({1 .. 5000000})}),
Sol = Table.FirstN(
Table.SelectRows(
Table.AddColumn(
Source,
"Disarium",
each
let
a = [Column1],
b = Text.ToList(Text.From(a)),
c = List.Count(b),
d = List.Transform(b, Number.From),
e = List.Sum(List.Transform({1 .. c}, each Number.Power(d{_ - 1}, _)))
in
e
),
each [Column1] = [Disarium]
)[[Disarium]],
18
)
in
Sol
Power Query solution 4 for Generate First Disarium List, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
Record = List.Last(List.Skip(List.Buffer(List.Generate(
()=> [ y = 1, x = 9, Rec = {}],
each [y] < 18,
each [Rec = List.Skip(List.Select(List.Transform(List.Transform( {0..Number.Factorial([x])*3/4}, each
[
a = _,
b = Text.ToList(Text.From(a)),
c = List.Count(b),
d = List.Transform(b, Number.From),
e = List.Sum(List.Transform({1..c}, each Number.Power(d{_-1},_))),
f = List.Intersect({{e},{a}})
] [f]), each try _{0} otherwise null), each _ <> null)),
x = [x] + 1, y = List.Count([Rec])
],
each [Rec]))))
in
Record
Forcé el inicio para que el cálculo fuera más rápido. Si embargo, si el resultado va más allá de la posición 18, el proceso se haria extremadamente largo.
Show translation
Show translation of this comment
Power Query solution 5 for Generate First Disarium List, proposed by Luan Rodrigues:
let
Fonte = List.Buffer({num1 .. num2}),
Tab = Table.FromList(Fonte, Splitter.SplitByNothing(), null, null),
Resultado = Table.AddColumn(
Tab,
"Personalizar",
each [
a = Text.ToList(Text.From([Column1])),
b = List.Count(a),
c = List.Sum(List.Transform({1 .. b}, (x) => Number.Power(Number.From(a{x - 1}), x))),
d = c = [Column1]
][d]
),
res = List.FirstN(Table.SelectRows(Resultado, each ([Personalizar] = true))[Column1], 18)
in
res
Solving the challenge of Generate First Disarium List with Excel
Excel solution 1 for Generate First Disarium List, proposed by Bo Rydobon 🇹🇭:
=LET(t,SEQUENCE(,10,0),
TAKE(REDUCE(SEQUENCE(9),SEQUENCE(6)+1,LAMBDA(x,n,LET(
r,REDUCE(0,SEQUENCE(n-1,,0),LAMBDA(a,x,LET(b,TOCOL(TAKE(a,,1)+t*10^x),c,TOCOL(TAKE(a,,-1)+t^(n-x)),
FILTER(HSTACK(b,c),c+SUM(9^SEQUENCE(n-x-1))>10^(n-1))))),b,TAKE(r,,1),c,DROP(r,,1),m,MOD(b-c,10),d,m*10^(n-1)+b,f,FILTER(d,d=c+m),
IF(COUNT(f),VSTACK(x,f),x)))),18))
This one takes 0.35 seconds on 10M number
for 10^6-10^7 9M number only calculate 221,000 times
=LET(st,NOW(),t,SEQUENCE(,10,0),
rs,TAKE(REDUCE(SEQUENCE(9),SEQUENCE(6)+1,LAMBDA(x,n,LET(
r,REDUCE(0,SEQUENCE(n-1,,0),LAMBDA(a,x,LET(b,TOCOL(TAKE(a,,1)+t*10^x),
c,TOCOL(TAKE(a,,-1)+t^(n-x)),
FILTER(HSTACK(b,c),c+SUM(9^SEQUENCE(n-x-1))>10^(n-1))))),
b,TAKE(r,,1),c,DROP(r,,1),m,MOD(b-c,10),d,m*10^(n-1)+b,f,FILTER(d,d=c+m),
IF(COUNT(f),VSTACK(x,f),x)))),18),TEXT(NOW()-st,"[s].00 s"))
while brutal force for 3 M number takes 15 second
=LET(st,NOW(),rs,TOCOL(MAP(SEQUENCE(10^6,3),LAMBDA(n,IFS(n=SUM(MID(n,SEQUENCE(LEN(n)),1)^SEQUENCE(LEN(n))),n))),3),TEXT(NOW()-st,"[s].00 s"))
Excel solution 2 for Generate First Disarium List, proposed by Rick Rothstein:
=LET(d,LAMBDA(x,LET(s,SEQUENCE(LEN(x)),SUM(MID(x,s,1)^s)=x)),t,TEXTSPLIT(REDUCE("",SEQUENCE(1048575),LAMBDA(a,z,a&","&IF(d(z),z,""))),,","),FILTER(t,LEN(t)))
Excel solution 3 for Generate First Disarium List, proposed by John V.:
=TOCOL(MAP(SEQUENCE(2^20,3),LAMBDA(x,LET(s,SEQUENCE(LEN(x)),x/(x=SUM(MID(x,s,1)^s))))),2)
Excel solution 4 for Generate First Disarium List, proposed by محمد حلمي:
=FILTER(SEQUENCE(3000),
MAP(SEQUENCE(3000),LAMBDA(a,LET(
s,SEQUENCE(LEN(a)),SUM(MID(a,s,1)^s)=a))))
Excel solution 5 for Generate First Disarium List, proposed by Julian Poeltl:
=TEXTSPLIT(TEXTJOIN(",",,MAP(SEQUENCE(10^6,3),LAMBDA(A,LET(S,SEQUENCE(LEN(A)),IF(SUM(MID(A,S,1)^S)=A,A,""))))),,",")
Excel solution 6 for Generate First Disarium List, proposed by Timothée BLIOT:
=LET(A, SEQUENCE(10^6,3), B, MAP(A, LAMBDA(z, SUM(MAP(SEQUENCE(LEN(z)), LAMBDA(x, (MID(z,x,1)*1)^x))) )), C, IF(B=A,A,""), TEXTSPLIT(TEXTJOIN(":",,C),,":")*1)
Excel solution 7 for Generate First Disarium List, proposed by Md. Zohurul Islam:
=LET(n,SEQUENCE(500000),
u,MAP(n,LAMBDA(x,LET(sq,SEQUENCE(LEN(x)),a,--MID(x,sq,1),b,SUM(a^sq)=x,b))),
v,FILTER(n,u),
v)
Excel solution 8 for Generate First Disarium List, proposed by Tolga Demirci, PMP, PMI-ACP, MOS-Expert:
=FILTER(IF(MAP(SEQUENCE(1048575);LAMBDA(x;SUM(POWER(MID(x;SEQUENCE(LEN(x));1);ROW(INDIRECT("a1:"&"a"&LEN(x)))))))=SEQUENCE(1048575);SEQUENCE(1048575);"");IF(MAP(SEQUENCE(1048575);LAMBDA(x;SUM(POWER(MID(x;SEQUENCE(LEN(x));1);ROW(INDIRECT("a1:"&"a"&LEN(x)))))))=SEQUENCE(1048575);SEQUENCE(1048575);"")<>"")
Excel solution 9 for Generate First Disarium List, proposed by Tolga Demirci, PMP, PMI-ACP, MOS-Expert:
=VSTACK(LET(e;LET(q;MAP(SEQUENCE(1048576);LAMBDA(a;SUM(POWER(MID(a;SEQUENCE(LEN(a));1);ROW(INDIRECT("A1:"&"A"&LEN(a)))))));w;SEQUENCE(1048576);IF(q=w;w;""));FILTER(e;e<>""));LET(a;IF(MAP(2097150+SEQUENCE(1048575);LAMBDA(x;SUM(POWER(MID(x;SEQUENCE(LEN(x));1);ROW(INDIRECT("a1:"&"a"&LEN(x)))))))=2097150+SEQUENCE(1048575);2097150+SEQUENCE(1048575);"");FILTER(a;a<>"")))
Excel solution 10 for Generate First Disarium List, proposed by Guillermo Arroyo:
=TOCOL(MAP(SEQUENCE(1048576,3),LAMBDA(b,LET(x,SEQUENCE(LEN(b)),y,MID(b,x,1),z,SUM((--y)^x),IF(z=b,b,CHAR(0))))),3)
Excel solution 11 for Generate First Disarium List, proposed by Ibrahim Sadiq:
=LET(a,SEQUENCE(10^5),b,SEQUENCE(,9),c,FILTER(a,a=MMULT(--(0&MID(a,b,1))^b,TOCOL(b)^0)),d,SMALL(c,SEQUENCE(18)),IFERROR(d,2646798))
Solving the challenge of Generate First Disarium List with Python in Excel
Python in Excel solution 1 for Generate First Disarium List, proposed by Alejandro Campos:
def is_disarium(number):
digits = list(map(int, str(number)))
return sum(d ** (i + 1) for i, d in enumerate(digits)) == number
disarium_numbers = []
number = 1
while len(disarium_numbers) < 18:
if is_disarium(number):
disarium_numbers.append(number)
number += 1
disarium_numbers
Solving the challenge of Generate First Disarium List with Excel VBA
Excel VBA solution 1 for Generate First Disarium List, proposed by Rick Rothstein:
Function ListDisariums(Nth) As Variant()
Dim N As Variant, Arr As Variant
Dim C As Long, X As Long, Sum As Long
ReDim Arr(1 To Nth, 1 To 1)
For N = 1 To 2147483647
Sum = 0
For X = 1 To Len(N)
Sum = Sum + Mid(N, X, 1) ^ X
Next
If Sum = N Then
C = C + 1
Arr(C, 1) = N
End If
If C = Nth Then Exit For
Next
ListDisariums = Arr
End Function
=ListDisariums(18)
&&&
