Home » Generate First Disarium List

Generate First Disarium List

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)
                    
                  

&&&

Leave a Reply