Own digits power sum: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Mathematica}}/{{header|Wolfram Language}}: link Pascal to Narcissistic_decimal_number)
m (→‎{{header|Wren}}: Changed to Wren S/H)
(31 intermediate revisions by 7 users not shown)
Line 1:
{{draft task}}
 
; Description
Line 468:
Same as before.
</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="c++">
#include <cmath>
#include <cstdint>
#include <iostream>
#include <vector>
 
int main() {
std::vector<uint32_t> powers = { 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 };
 
std::cout << "Own digits power sums for N = 3 to 9 inclusive:" << std::endl;
 
for ( uint32_t n = 3; n <= 9; ++n ) {
for ( uint32_t d = 2; d <= 9; ++d ) {
powers[d] *= d;
}
 
uint64_t number = std::pow(10, n - 1);
uint64_t maximum = number * 10;
uint32_t last_digit = 0;
uint32_t digit_sum = 0;
 
while ( number < maximum ) {
if ( last_digit == 0 ) {
digit_sum = 0;
uint64_t copy = number;
while ( copy > 0 ) {
digit_sum += powers[copy % 10];
copy /= 10;
}
} else if ( last_digit == 1 ) {
digit_sum++;
} else {
digit_sum += powers[last_digit] - powers[last_digit - 1];
}
 
if ( digit_sum == number ) {
std::cout << number << std::endl;
if ( last_digit == 0 ) {
std::cout << number + 1 << std::endl;
}
number += 10 - last_digit;
last_digit = 0;
} else if ( digit_sum > number ) {
number += 10 - last_digit;
last_digit = 0;
} else if ( last_digit < 9 ) {
number++;
last_digit++;
} else {
number++;
last_digit = 0;
}
}
}
}
</syntaxhighlight>
{{ out }}
<pre>
Own digits power sums for N = 3 to 9 inclusive:
153
370
371
407
1634
8208
9474
54748
92727
93084
548834
1741725
4210818
9800817
9926315
24678050
24678051
88593477
146511208
472335975
534494836
912985153
</pre>
 
=={{header|D}}==
===Slow===
<syntaxhighlight lang="d">
import std.stdio;
import std.conv;
import std.algorithm;
import std.range;
 
bool isOwnDigitsPowerSum(uint n)
{
auto nStr = n.text;
return nStr.map!(d => (d - '0') ^^ nStr.length).sum == n;
}
 
void main()
{
iota(10^^2, 10^^9).filter!isOwnDigitsPowerSum.writeln;
}
</syntaxhighlight>
{{out}}
<pre>
[153, 370, 371, 407, 1634, 8208, 9474, 54748, 92727, 93084, 548834, 1741725, 4210818, 9800817, 9926315, 24678050, 24678051, 88593477, 146511208, 472335975, 534494836, 912985153]
</pre>
 
===Faster===
{{trans|Delphi}}
<syntaxhighlight lang="d">
import std.stdio;
 
const int[10][10] powerTable = [
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512],
[1, 3, 9, 27, 81, 243, 729, 2_187, 6_561, 19_683],
[1, 4, 16, 64, 256, 1_024, 4_096, 16_384, 65_536, 262_144],
[1, 5, 25, 125, 625, 3125, 15_625, 78_125, 390_625, 1_953_125],
[1, 6, 36, 216, 1_296, 7_776, 46_656, 279_936, 1_679_616, 10_077_696],
[1, 7, 49, 343, 2_401, 16_807, 117_649, 823_543, 57_64_801, 40_353_607],
[1, 8, 64, 512, 4_096, 32_768, 262_144, 2_097_152, 16_777_216, 134_217_728],
[1, 9, 81, 729, 6_561, 59_049, 531_441, 4_782_969, 43_046_721, 387_420_489]
];
 
void digitsPowerSum(ref int Number, ref int DigitCount, int Level, int Sum) {
if (Level == 0) {
for (int Digits = 0; Digits <= 9; ++Digits) {
if (((Sum + powerTable[Digits][DigitCount]) == Number) && (Number >= 100)) {
writefln("%s: %s", DigitCount, Number);
}
 
++Number;
switch (Number) {
case 10:
case 100:
case 1_000:
case 10_000:
case 100_000:
case 1_000_000:
case 10_000_000:
case 100_000_000:
++DigitCount;
break;
default:
break;
}
}
}
else {
for (int Digits = 0; Digits <= 9; ++Digits) {
digitsPowerSum(Number, DigitCount, Level - 1, Sum + powerTable[Digits][DigitCount]);
}
}
}
 
void main() {
int Number = 0;
int DigitCount = 1;
//
digitsPowerSum(Number, DigitCount, 9-1, 0);
}
</syntaxhighlight>
{{out}}
<pre>
3: 153
3: 370
3: 371
3: 407
4: 1634
4: 8208
4: 9474
5: 54748
5: 92727
5: 93084
6: 548834
7: 1741725
7: 4210818
7: 9800817
7: 9926315
8: 24678050
8: 24678051
8: 88593477
9: 146511208
9: 472335975
9: 534494836
9: 912985153
</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
Started with brute force method which took over a minute to do the 8-digit problem. Then borrowed ideas from everywhere, especially the XPL0 implementation.
 
<syntaxhighlight lang="Delphi">
{Table to speed up power(X,Y) calculation }
 
const PowerTable: array [0..9] of array [0..9] of integer = (
(1, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
(1, 2, 4, 8, 16, 32, 64, 128, 256, 512),
(1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683),
(1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144),
(1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125),
(1, 6, 36, 216, 1296, 7776, 46656, 279936, 1679616, 10077696),
(1, 7, 49, 343, 2401, 16807, 117649, 823543, 5764801, 40353607),
(1, 8, 64, 512, 4096, 32768, 262144, 2097152, 16777216, 134217728),
(1, 9, 81, 729, 6561, 59049, 531441, 4782969, 43046721, 387420489)
);
 
 
 
procedure DigitsPowerSum(Memo: TMemo; var Number, DigitCount: integer; Level, Sum: integer);
{Recursively process DigitCount power}
var Digits: integer;
begin
{Finish when recursion = Level Zero}
if Level = 0 then
begin
for Digits:= 0 to 9 do
begin
{Test combinations of digits and previous sum against number}
if ((Sum + PowerTable[Digits, DigitCount]) = Number) and
(Number >= 100) then
begin
Memo.Lines.Add(IntToStr(DigitCount)+' '+IntToStr(Number));
end;
Inc(Number);
{Keep track of digit count - increases on even power of 10}
case Number of
10, 100, 1000, 10000, 100000,
1000000, 10000000, 100000000: Inc(DigitCount);
end;
end;
end
else for Digits:= 0 to 9 do
begin
{Recurse through all digits/levels}
DigitsPowerSum(Memo, Number, DigitCount,
Level-1, Sum + PowerTable[Digits, DigitCount]);
end;
end;
 
 
procedure ShowDigitsPowerSum(Memo: TMemo);
var Number, DigitCount: integer;
begin
Number:= 0;
DigitCount:= 1;
DigitsPowerSum(Memo, Number, DigitCount, 9-1, 0);
end;
 
 
</syntaxhighlight>
{{out}}
<pre>
3 153
3 370
3 371
3 407
4 1634
4 8208
4 9474
5 54748
5 92727
5 93084
6 548834
7 1741725
7 4210818
7 9800817
7 9926315
8 24678050
8 24678051
8 88593477
9 146511208
9 472335975
9 534494836
9 912985153
Elapsed Time: 3.058 Sec.
</pre>
 
=={{header|EasyLang}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang=easylang>
fastfunc next curr n limit .
repeat
curr += 1
if curr = limit
return -1
.
sum = 0
tmp = curr
repeat
dig = tmp mod 10
tmp = tmp div 10
h = n
r = 1
while h > 0
r *= dig
h -= 1
.
sum += r
until tmp = 0
.
until sum = curr
.
return curr
.
for n = 3 to 8
curr = pow 10 (n - 1)
repeat
curr = next curr n pow 10 n
until curr = -1
print curr
.
.
</syntaxhighlight>
 
=={{header|F_Sharp|F#}}==
Line 485 ⟶ 805:
9 digit are: 146511208 472335975 534494836 912985153
</pre>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">
Line 755 ⟶ 1,076:
 
See [[Narcissistic_decimal_number#J]]
 
=={{header|Java}}==
<syntaxhighlight lang="java">
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
 
public final class OwnDigitsPowerSum {
 
public static void main(String[] args) {
List<Integer> powers = IntStream.rangeClosed(0, 9).boxed().map( i -> i * i ).collect(Collectors.toList());
System.out.println("Own digits power sums for N = 3 to 9 inclusive:");
 
for ( int n = 3; n <= 9; n++ ) {
for ( int d = 2; d <= 9; d++ ) {
powers.set(d, powers.get(d) * d);
}
long number = (long) Math.pow(10, n - 1);
long maximum = number * 10;
int lastDigit = 0;
int sum = 0;
while ( number < maximum ) {
if ( lastDigit == 0 ) {
sum = String.valueOf(number)
.chars().map(Character::getNumericValue).map( i -> powers.get(i) ).sum();
} else if ( lastDigit == 1 ) {
sum += 1;
} else {
sum += powers.get(lastDigit) - powers.get(lastDigit - 1);
}
if ( sum == number ) {
System.out.println(number);
if ( lastDigit == 0 ) {
System.out.println(number + 1);
}
number += 10 - lastDigit;
lastDigit = 0;
} else if ( sum > number ) {
number += 10 - lastDigit;
lastDigit = 0;
} else if ( lastDigit < 9 ) {
number += 1;
lastDigit += 1;
} else {
number += 1;
lastDigit = 0;
}
}
}
}
 
}
</syntaxhighlight>
{{ out }}
<pre>
Own digits power sums for N = 3 to 9 inclusive:
153
370
371
407
1634
8208
9474
54748
92727
93084
548834
1741725
4210818
9800817
9926315
24678050
24678051
88593477
146511208
472335975
534494836
912985153
</pre>
 
=={{header|jq}}==
Line 866 ⟶ 1,270:
912985153
</pre>
 
=={{header|Nim}}==
{{trans|Wren}}
<syntaxhighlight lang="Nim">import std/[algorithm, sequtils, strutils]
 
const MaxBase = 10
 
type UsedDigits = array[MaxBase, int]
 
var
usedDigits: UsedDigits
numbers: seq[int]
 
 
proc initPowerDigits(): array[MaxBase, array[MaxBase, int]] {.compileTime.} =
for i in 1..<MaxBase:
result[0][i] = 1
for j in 1..<MaxBase:
for i in 0..<MaxBase:
result[j][i] = result[j - 1][i] * i
 
const PowerDigits = initPowerDigits()
 
 
proc calcNum(depth: int; used: UsedDigits) =
var used = used
var depth = depth
if depth < 3: return
var result = 0
for i in 1..<MaxBase:
if used[i] > 0:
result += used[i] * PowerDigits[depth][i]
 
if result == 0: return
var n = result
while true:
let r = n div MaxBase
dec used[n - r * MaxBase]
n = r
dec depth
if r == 0: break
if depth != 0: return
 
var i = 1
while i < MaxBase and used[i] == 0:
inc i
if i == MaxBase:
numbers.add result
 
 
proc nextDigit(digit, depth: int) =
var depth = depth
if depth < MaxBase - 1:
for i in digit..<MaxBase:
inc usedDigits[digit]
nextDigit(i, depth + 1)
dec usedDigits[digit]
let digit = if digit == 0: 1 else: digit
for i in digit..<MaxBase:
inc usedDigits[i]
calcNum(depth, usedDigits)
dec usedDigits[i]
 
nextDigit(0, 0)
 
numbers.sort()
numbers = numbers.deduplicate(true)
echo "Own digits power sums for N = 3 to 9 inclusive:"
echo numbers.join("\n")
</syntaxhighlight>
 
{{out}}
<pre>Own digits power sums for N = 3 to 9 inclusive:
153
370
371
407
1634
8208
9474
54748
92727
93084
548834
1741725
4210818
9800817
9926315
24678050
24678051
88593477
146511208
472335975
534494836
912985153</pre>
 
=={{header|Pascal}}==
Line 878 ⟶ 1,377:
{{out}}
<pre>{153, 370, 371, 407, 1634, 8208, 9474, 54748, 92727, 93084, 548834, 1741725, 4210818, 9800817, 9926315, 24678050, 24678051, 88593477}</pre>
 
 
=={{header|PARI/GP}}==
 
You should have enough memory to avoid stack overflow and configure GP accordingly...
 
<syntaxhighlight lang="parigp">
select(is_Armstrong(n)={n==vecsum([d^#n|d<-n=digits(n)])}, [100..999999999])
</syntaxhighlight>
 
{{out}}
<pre>%1 = [153,370,371,407,1634,8208,9474,54748,92727,93084,548834,1741725,4210818,9800817,9926315, 24678050,24678051,88593477,146511208,472335975,534494836,912985153]</pre>
 
 
 
 
=={{header|Perl}}==
Line 1,249 ⟶ 1,763:
534494836
912985153</pre>
 
=={{header|Quackery}}==
 
<code>narcissistic</code> is defined at [[Narcissistic decimal number#Quackery]].
 
<syntaxhighlight lang="Quackery"> 100000000 100 - times
[ i^ 100 + narcissistic if
[ i^ 100 + echo cr ] ]
</syntaxhighlight>
 
{{out}}
 
<pre>153
370
371
407
1634
8208
9474
54748
92727
93084
548834
1741725
4210818
9800817
9926315
24678050
24678051
88593477</pre>
 
=={{header|Raku}}==
Line 1,361 ⟶ 1,905:
=={{header|Ruby}}==
Repeated combinations allow for N=18 in less than a minute.
<syntaxhighlight lang="ruby">DIGITS = (0..9).to_a
DIGITS = (0..9).to_a
range = (3..18)
 
Line 1,373 ⟶ 1,918:
end
 
puts "Own digits power sums for N = #{range}:", res</syntaxhighlight>
</syntaxhighlight>
 
{{out}}
<pre>
<pre>Own digits power sums for 3..18
Own digits power sums for 3..18
153
370
Line 1,413 ⟶ 1,961:
35641594208964132
35875699062250035
</pre>
 
=={{header|Rust}}==
 
===Slow===
{{trans|D}}
 
<syntaxhighlight lang="rust">
fn is_own_digits_power_sum(n: u32) -> bool {
let n_str = n.to_string();
n_str.chars()
.map(|c| {
let digit = c.to_digit(10).unwrap();
digit.pow(n_str.len() as u32)
})
.sum::<u32>()
== n
}
 
fn main() {
let result: Vec<u32> = (10u32.pow(2)..10u32.pow(9))
.filter(|&n| is_own_digits_power_sum(n))
.collect();
 
println!("{:?}", result);
}
</syntaxhighlight>
 
{{out}}
<pre>
[153, 370, 371, 407, 1634, 8208, 9474, 54748, 92727, 93084, 548834, 1741725, 4210818, 9800817, 9926315, 24678050, 24678051, 88593477, 146511208, 472335975, 534494836, 912985153]
</pre>
 
===Faster===
{{trans|Wren}}
 
<syntaxhighlight lang="rust">
fn main() {
let mut powers = vec![0, 1, 4, 9, 16, 25, 36, 49, 64, 81];
println!("Own digits power sums for N = 3 to 9 inclusive:");
 
for n in 3..=9 {
for d in 2..=9 {
powers[d] *= d;
}
 
let mut i = 10u64.pow(n - 1);
let max = i * 10;
let mut last_digit = 0;
let mut sum = 0;
let mut digits: Vec<u32>;
 
while i < max {
if last_digit == 0 {
digits = i.to_string()
.chars()
.map(|c| c.to_digit(10).unwrap())
.collect();
sum = digits.iter().map(|&d| powers[d as usize]).sum();
} else if last_digit == 1 {
sum += 1;
} else {
sum += powers[last_digit as usize] - powers[(last_digit - 1) as usize];
}
 
if sum == i.try_into().unwrap() {
println!("{}", i);
if last_digit == 0 {
println!("{}", i + 1);
}
i += 10 - last_digit;
last_digit = 0;
} else if sum > i.try_into().unwrap() {
i += 10 - last_digit;
last_digit = 0;
} else if last_digit < 9 {
i += 1;
last_digit += 1;
} else {
i += 1;
last_digit = 0;
}
}
}
}
</syntaxhighlight>
 
{{out}}
<pre>
Own digits power sums for N = 3 to 9 inclusive:
153
370
371
407
1634
8208
9474
54748
92727
93084
548834
1741725
4210818
9800817
9926315
24678050
24678051
88593477
146511208
472335975
534494836
912985153
</pre>
 
Line 1,674 ⟶ 2,335:
{{libheader|Wren-math}}
Includes some simple optimizations to try and quicken up the search. However, getting up to N = 9 still took a little over 4 minutes on my machine.
<syntaxhighlight lang="ecmascriptwren">import "./math" for Int
 
var powers = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Line 1,743 ⟶ 2,404:
{{libheader|Wren-seq}}
Astonishing speed-up. Runtime now only 0.5 seconds!
<syntaxhighlight lang="ecmascriptwren">import "./seq" for Lst
 
var maxBase = 10
9,476

edits