Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Smith-numbers/00-META.yaml
Normal file
2
Task/Smith-numbers/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Smith_numbers
|
||||
27
Task/Smith-numbers/00-TASK.txt
Normal file
27
Task/Smith-numbers/00-TASK.txt
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
[[wp:Smith numbers|Smith numbers]] are numbers such that the [[Sum_digits_of_an_integer|sum of the decimal digits of the integers]] that make up that number is the same as the sum of the decimal digits of its prime factors excluding 1.
|
||||
|
||||
By definition, all primes are ''excluded'' as they (naturally) satisfy this condition!
|
||||
|
||||
Smith numbers are also known as ''joke'' numbers.
|
||||
|
||||
|
||||
;Example
|
||||
Using the number '''166'''<br>
|
||||
Find the prime factors of '''166''' which are: '''2''' x '''83'''<br>
|
||||
Then, take those two prime factors and sum all their decimal digits: '''2 + 8 + 3''' which is '''13'''<br>
|
||||
Then, take the decimal digits of '''166''' and add their decimal digits: '''1 + 6 + 6''' which is '''13'''<br>
|
||||
Therefore, the number '''166''' is a Smith number.
|
||||
|
||||
|
||||
;Task
|
||||
Write a program to find all Smith numbers ''below'' 10000.
|
||||
|
||||
|
||||
;See also
|
||||
* from Wikipedia: [[https://en.wikipedia.org/wiki/Smith_number Smith number]].
|
||||
* from MathWorld: [[http://mathworld.wolfram.com/SmithNumber.html Smith number]].
|
||||
* from OEIS A6753: [[https://oeis.org/A006753 OEIS sequence A6753]].
|
||||
* from OEIS A104170: [[https://oeis.org/A104170 Number of Smith numbers below 10^n]].
|
||||
* from The Prime pages: [[http://primes.utm.edu/glossary/xpage/SmithNumber.html Smith numbers]].
|
||||
<br><br>
|
||||
|
||||
48
Task/Smith-numbers/11l/smith-numbers.11l
Normal file
48
Task/Smith-numbers/11l/smith-numbers.11l
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
F factors(=n)
|
||||
[Int] rt
|
||||
V f = 2
|
||||
I n == 1
|
||||
rt.append(1)
|
||||
E
|
||||
L
|
||||
I 0 == (n % f)
|
||||
rt.append(f)
|
||||
n I/= f
|
||||
I n == 1
|
||||
R rt
|
||||
E
|
||||
f++
|
||||
R rt
|
||||
|
||||
F sum_digits(=n)
|
||||
V sum = 0
|
||||
L n > 0
|
||||
V m = n % 10
|
||||
sum += m
|
||||
n -= m
|
||||
n I/= 10
|
||||
R sum
|
||||
|
||||
F add_all_digits(lst)
|
||||
V sum = 0
|
||||
L(i) 0 .< lst.len
|
||||
sum += sum_digits(lst[i])
|
||||
R sum
|
||||
|
||||
F list_smith_numbers(cnt)
|
||||
[Int] r
|
||||
L(i) 4 .< cnt
|
||||
V fac = factors(i)
|
||||
I fac.len > 1
|
||||
I sum_digits(i) == add_all_digits(fac)
|
||||
r.append(i)
|
||||
R r
|
||||
|
||||
V sn = list_smith_numbers(10'000)
|
||||
print(‘Count of Smith Numbers below 10k: ’sn.len)
|
||||
print()
|
||||
print(‘First 15 Smith Numbers:’)
|
||||
print_elements(sn[0.<15])
|
||||
print()
|
||||
print(‘Last 12 Smith Numbers below 10000:’)
|
||||
print_elements(sn[(len)-12..])
|
||||
147
Task/Smith-numbers/360-Assembly/smith-numbers.360
Normal file
147
Task/Smith-numbers/360-Assembly/smith-numbers.360
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
* Smith numbers - 02/05/2017
|
||||
SMITHNUM CSECT
|
||||
USING SMITHNUM,R13 base register
|
||||
B 72(R15) skip savearea
|
||||
DC 17F'0' savearea
|
||||
STM R14,R12,12(R13) save previous context
|
||||
ST R13,4(R15) link backward
|
||||
ST R15,8(R13) link forward
|
||||
LR R13,R15 set addressability
|
||||
LA R10,PG pgi=0
|
||||
LA R6,4 i=4
|
||||
DO WHILE=(C,R6,LE,N) do i=4 to n
|
||||
LR R1,R6 i
|
||||
BAL R14,SUMD call sumd(i)
|
||||
ST R0,SS ss=sumd(i)
|
||||
LR R1,R6 i
|
||||
BAL R14,SUMFACTR call sumfactr(i)
|
||||
IF C,R0,EQ,SS THEN if sumd(i)=sumfactr(i) then
|
||||
L R2,NN nn
|
||||
LA R2,1(R2) nn+1
|
||||
ST R2,NN nn=nn+1
|
||||
XDECO R6,XDEC i
|
||||
MVC 0(5,R10),XDEC+7 output i
|
||||
LA R10,5(R10) pgi+=5
|
||||
L R4,IPG ipg
|
||||
LA R4,1(R4) ipg+1
|
||||
ST R4,IPG ipg=ipg+1
|
||||
IF C,R4,EQ,=F'16' THEN if ipg=16 then
|
||||
XPRNT PG,80 print buffer
|
||||
MVC PG,=CL80' ' clear buffer
|
||||
LA R10,PG pgi=0
|
||||
MVC IPG,=F'0' ipg=0
|
||||
ENDIF , endif
|
||||
ENDIF , endif
|
||||
LA R6,1(R6) i++
|
||||
ENDDO , enddo i
|
||||
L R4,IPG ipg
|
||||
IF LTR,R4,NZ,R4 THEN if ipg<>0 then
|
||||
XPRNT PG,80 print buffer
|
||||
ENDIF , endif
|
||||
L R1,NN nn
|
||||
XDECO R1,XDEC edit nn
|
||||
MVC PGT(4),XDEC+8 output nn
|
||||
L R1,N n
|
||||
XDECO R1,XDEC edit n
|
||||
MVC PGT+28(5),XDEC+7 output n
|
||||
XPRNT PGT,80 print
|
||||
L R13,4(0,R13) restore previous savearea pointer
|
||||
LM R14,R12,12(R13) restore previous context
|
||||
XR R15,R15 rc=0
|
||||
BR R14 exit
|
||||
*------- ---- ----------------------------------------
|
||||
SUMD EQU * sumd(x)
|
||||
SR R0,R0 s=0
|
||||
DO WHILE=(LTR,R1,NZ,R1) do while x<>0
|
||||
LR R2,R1 x
|
||||
SRDA R2,32 ~
|
||||
D R2,=F'10' x/10
|
||||
LR R1,R3 x=x/10
|
||||
AR R0,R2 s=s+x//10
|
||||
ENDDO , enddo while
|
||||
BR R14 return s
|
||||
*------- ---- ----------------------------------------
|
||||
SUMFACTR EQU * sumfactr(z)
|
||||
ST R14,SAVER14 store r14
|
||||
ST R1,ZZ z
|
||||
SR R8,R8 m=0
|
||||
SR R9,R9 f=0
|
||||
L R4,ZZ z
|
||||
SRDA R4,32 ~
|
||||
D R4,=F'2' z/2
|
||||
DO WHILE=(LTR,R4,Z,R4) do while z//2=0
|
||||
LA R8,2(R8) m=m+2
|
||||
LA R9,1(R9) f=f+1
|
||||
L R5,ZZ z
|
||||
SRA R5,1 z/2
|
||||
ST R5,ZZ z=z/2
|
||||
LA R4,0 z
|
||||
D R4,=F'2' z/2
|
||||
ENDDO , enddo while
|
||||
L R4,ZZ z
|
||||
SRDA R4,32 ~
|
||||
D R4,=F'3' z/3
|
||||
DO WHILE=(LTR,R4,Z,R4) do while z//3=0
|
||||
LA R8,3(R8) m=m+3
|
||||
LA R9,1(R9) f=f+1
|
||||
L R4,ZZ z
|
||||
SRDA R4,32 ~
|
||||
D R4,=F'3' z/3
|
||||
ST R5,ZZ z=z/3
|
||||
LA R4,0 z
|
||||
D R4,=F'3' z/3
|
||||
ENDDO , enddo while
|
||||
LA R7,5 do j=5 by 2 while j<=z and j*j<=n
|
||||
WHILEJ C R7,ZZ if j>z
|
||||
BH EWHILEJ then leave while
|
||||
LR R5,R7 j
|
||||
MR R4,R7 *j
|
||||
C R5,N if j*j>n
|
||||
BH EWHILEJ then leave while
|
||||
LR R4,R7 j
|
||||
SRDA R4,32 ~
|
||||
D R4,=F'3' j/3
|
||||
LTR R4,R4 if j//3=0
|
||||
BZ ITERJ then goto iterj
|
||||
L R4,ZZ z
|
||||
SRDA R4,32 ~
|
||||
DR R4,R7 z/j
|
||||
DO WHILE=(LTR,R4,Z,R4) do while z//j=0
|
||||
LA R9,1(R9) f=f+1
|
||||
LR R1,R7 j
|
||||
BAL R14,SUMD call sumd(j)
|
||||
AR R8,R0 m=m+sumd(j)
|
||||
L R4,ZZ z
|
||||
SRDA R4,32 ~
|
||||
DR R4,R7 z/j
|
||||
ST R5,ZZ z=z/j
|
||||
LA R4,0 ~
|
||||
DR R4,R7 z/j
|
||||
ENDDO , enddo while
|
||||
ITERJ LA R7,2(R7) j+=2
|
||||
B WHILEJ enddo
|
||||
EWHILEJ L R4,ZZ z
|
||||
IF C,R4,NE,=F'1' THEN if z<>1 then
|
||||
LA R9,1(R9) f=f+1
|
||||
L R1,ZZ z
|
||||
BAL R14,SUMD call sumd(z)
|
||||
AR R8,R0 m=m+sumd(z)
|
||||
ENDIF , endif
|
||||
IF C,R9,LT,=F'2' THEN if f<2 then
|
||||
SR R8,R8 mm=0
|
||||
ENDIF , endif
|
||||
LR R0,R8 return m
|
||||
L R14,SAVER14 restore r14
|
||||
BR R14 return
|
||||
SAVER14 DS A save r14
|
||||
* ---- ----------------------------------------
|
||||
N DC F'10000' n
|
||||
NN DC F'0' nn
|
||||
IPG DC F'0' ipg
|
||||
SS DS F ss
|
||||
ZZ DS F z
|
||||
PG DC CL80' ' buffer
|
||||
PGT DC CL80'xxxx smith numbers found <= xxxxx'
|
||||
XDEC DS CL12 temp
|
||||
YREGS
|
||||
END SMITHNUM
|
||||
72
Task/Smith-numbers/ALGOL-68/smith-numbers.alg
Normal file
72
Task/Smith-numbers/ALGOL-68/smith-numbers.alg
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# sieve of Eratosthene: sets s[i] to TRUE if i is prime, FALSE otherwise #
|
||||
PROC sieve = ( REF[]BOOL s )VOID:
|
||||
BEGIN
|
||||
# start with everything flagged as prime #
|
||||
FOR i TO UPB s DO s[ i ] := TRUE OD;
|
||||
# sieve out the non-primes #
|
||||
s[ 1 ] := FALSE;
|
||||
FOR i FROM 2 TO ENTIER sqrt( UPB s ) DO
|
||||
IF s[ i ] THEN FOR p FROM i * i BY i TO UPB s DO s[ p ] := FALSE OD FI
|
||||
OD
|
||||
END # sieve # ;
|
||||
|
||||
# construct a sieve of primes up to the maximum number required for the task #
|
||||
INT max number = 10 000;
|
||||
[ 1 : max number ]BOOL is prime;
|
||||
sieve( is prime );
|
||||
|
||||
# returns the sum of the digits of n #
|
||||
OP DIGITSUM = ( INT n )INT:
|
||||
BEGIN
|
||||
INT sum := 0;
|
||||
INT rest := ABS n;
|
||||
WHILE rest > 0 DO
|
||||
sum +:= rest MOD 10;
|
||||
rest OVERAB 10
|
||||
OD;
|
||||
sum
|
||||
END # DIGITSUM # ;
|
||||
|
||||
# returns TRUE if n is a Smith number, FALSE otherwise #
|
||||
# n must be between 1 and max number #
|
||||
PROC is smith = ( INT n )BOOL:
|
||||
IF is prime[ ABS n ] THEN
|
||||
# primes are not Smith numbers #
|
||||
FALSE
|
||||
ELSE
|
||||
# find the factors of n and sum the digits of the factors #
|
||||
INT rest := ABS n;
|
||||
INT factor digit sum := 0;
|
||||
INT factor := 2;
|
||||
WHILE factor < max number AND rest > 1 DO
|
||||
IF NOT is prime[ factor ] THEN
|
||||
# factor isn't a prime #
|
||||
factor +:= 1
|
||||
ELSE
|
||||
# factor is a prime #
|
||||
IF rest MOD factor /= 0 THEN
|
||||
# factor isn't a factor of n #
|
||||
factor +:= 1
|
||||
ELSE
|
||||
# factor is a factor of n #
|
||||
rest OVERAB factor;
|
||||
factor digit sum +:= DIGITSUM factor
|
||||
FI
|
||||
FI
|
||||
OD;
|
||||
( factor digit sum = DIGITSUM n )
|
||||
FI # is smith # ;
|
||||
|
||||
# print all the Smith numbers below the maximum required #
|
||||
INT smith count := 0;
|
||||
FOR n TO max number - 1 DO
|
||||
IF is smith( n ) THEN
|
||||
# have a smith number #
|
||||
print( ( whole( n, -7 ) ) );
|
||||
smith count +:= 1;
|
||||
IF smith count MOD 10 = 0 THEN
|
||||
print( ( newline ) )
|
||||
FI
|
||||
FI
|
||||
OD;
|
||||
print( ( newline, "THere are ", whole( smith count, -7 ), " Smith numbers below ", whole( max number, -7 ), newline ) )
|
||||
77
Task/Smith-numbers/AWK/smith-numbers.awk
Normal file
77
Task/Smith-numbers/AWK/smith-numbers.awk
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# syntax: GAWK -f SMITH_NUMBERS.AWK
|
||||
# converted from C
|
||||
BEGIN {
|
||||
limit = 10000
|
||||
printf("Smith Numbers < %d:\n",limit)
|
||||
for (a=4; a<limit; a++) {
|
||||
num_factors = num_prime_factors(a)
|
||||
if (num_factors < 2) {
|
||||
continue
|
||||
}
|
||||
prime_factors(a)
|
||||
if (sum_digits(a) == sum_factors(num_factors)) {
|
||||
printf("%4d ",a)
|
||||
if (++cr % 16 == 0) {
|
||||
printf("\n")
|
||||
}
|
||||
}
|
||||
delete arr
|
||||
}
|
||||
printf("\n")
|
||||
exit(0)
|
||||
}
|
||||
function num_prime_factors(x, p,pf) {
|
||||
p = 2
|
||||
pf = 0
|
||||
if (x == 1) {
|
||||
return(1)
|
||||
}
|
||||
while (1) {
|
||||
if (!(x % p)) {
|
||||
pf++
|
||||
x = int(x/p)
|
||||
if (x == 1) {
|
||||
return(pf)
|
||||
}
|
||||
}
|
||||
else {
|
||||
p++
|
||||
}
|
||||
}
|
||||
}
|
||||
function prime_factors(x, p,pf) {
|
||||
p = 2
|
||||
pf = 0
|
||||
if (x == 1) {
|
||||
arr[pf] = 1
|
||||
}
|
||||
else {
|
||||
while (1) {
|
||||
if (!(x % p)) {
|
||||
arr[pf++] = p
|
||||
x = int(x/p)
|
||||
if (x == 1) {
|
||||
return
|
||||
}
|
||||
}
|
||||
else {
|
||||
p++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function sum_digits(x, sum,y) {
|
||||
while (x) {
|
||||
y = x % 10
|
||||
sum += y
|
||||
x = int(x/10)
|
||||
}
|
||||
return(sum)
|
||||
}
|
||||
function sum_factors(x, a,sum) {
|
||||
sum = 0
|
||||
for (a=0; a<x; a++) {
|
||||
sum += sum_digits(arr[a])
|
||||
}
|
||||
return(sum)
|
||||
}
|
||||
51
Task/Smith-numbers/Action-/smith-numbers.action
Normal file
51
Task/Smith-numbers/Action-/smith-numbers.action
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
CARD FUNC SumDigits(CARD n)
|
||||
CARD res,a
|
||||
|
||||
res=0
|
||||
WHILE n#0
|
||||
DO
|
||||
res==+n MOD 10
|
||||
n==/10
|
||||
OD
|
||||
RETURN (res)
|
||||
|
||||
CARD FUNC PrimeFactors(CARD n CARD ARRAY f)
|
||||
CARD a,count
|
||||
|
||||
a=2 count=0
|
||||
DO
|
||||
IF n MOD a=0 THEN
|
||||
f(count)=a
|
||||
count==+1
|
||||
n==/a
|
||||
IF n=1 THEN
|
||||
RETURN (count)
|
||||
FI
|
||||
ELSE
|
||||
a==+1
|
||||
FI
|
||||
OD
|
||||
RETURN (0)
|
||||
|
||||
PROC Main()
|
||||
CARD n,i,s1,s2,count,tmp
|
||||
CARD ARRAY f(100)
|
||||
|
||||
FOR n=4 TO 10000
|
||||
DO
|
||||
count=PrimeFactors(n,f)
|
||||
IF count>=2 THEN
|
||||
s1=SumDigits(n)
|
||||
s2=0
|
||||
FOR i=0 TO count-1
|
||||
DO
|
||||
tmp=f(i)
|
||||
s2==+SumDigits(tmp)
|
||||
OD
|
||||
IF s1=s2 THEN
|
||||
PrintC(n) Put(32)
|
||||
FI
|
||||
FI
|
||||
Poke(77,0) ;turn off the attract mode
|
||||
OD
|
||||
RETURN
|
||||
27
Task/Smith-numbers/Ada/smith-numbers.ada
Normal file
27
Task/Smith-numbers/Ada/smith-numbers.ada
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
with Ada.Text_IO;
|
||||
|
||||
procedure smith is
|
||||
type Vector is array (natural range <>) of Positive;
|
||||
empty_vector : constant Vector(1..0):= (others=>1);
|
||||
|
||||
function digits_sum (n : Positive) return Positive is
|
||||
(if n < 10 then n else n mod 10 + digits_sum (n / 10));
|
||||
|
||||
function prime_factors (n : Positive; d : Positive := 2) return Vector is
|
||||
(if n = 1 then empty_vector elsif n mod d = 0 then prime_factors (n / d, d) & d
|
||||
else prime_factors (n, d + (if d=2 then 1 else 2)));
|
||||
|
||||
function vector_digits_sum (v : Vector) return Natural is
|
||||
(if v'Length = 0 then 0 else digits_sum (v(v'First)) + vector_digits_sum (v(v'First+1..v'Last)));
|
||||
|
||||
begin
|
||||
for n in 1..10000 loop
|
||||
declare
|
||||
primes : Vector := prime_factors (n);
|
||||
begin
|
||||
if primes'Length > 1 and then vector_digits_sum (primes) = digits_sum (n) then
|
||||
Ada.Text_IO.put (n'img);
|
||||
end if;
|
||||
end;
|
||||
end loop;
|
||||
end smith;
|
||||
24
Task/Smith-numbers/Arturo/smith-numbers.arturo
Normal file
24
Task/Smith-numbers/Arturo/smith-numbers.arturo
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
digitSum: function [v][
|
||||
n: new v
|
||||
result: new 0
|
||||
while [n > 0][
|
||||
'result + n % 10
|
||||
'n / 10
|
||||
]
|
||||
return result
|
||||
]
|
||||
|
||||
smith?: function [z][
|
||||
return
|
||||
(prime? z) ? -> false
|
||||
-> (digitSum z) = sum map factors.prime z 'num [digitSum num]
|
||||
]
|
||||
found: 0
|
||||
loop 1..10000 'x [
|
||||
if smith? x [
|
||||
found: found + 1
|
||||
prints (pad to :string x 6) ++ " "
|
||||
if 0 = found % 10 -> print ""
|
||||
]
|
||||
]
|
||||
print ""
|
||||
21
Task/Smith-numbers/BASIC/smith-numbers.basic
Normal file
21
Task/Smith-numbers/BASIC/smith-numbers.basic
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
10 DEFINT A-Z
|
||||
20 DIM F(32)
|
||||
30 FOR I=2 TO 9999
|
||||
40 F=0: N=I
|
||||
50 IF N>0 AND (N AND 1)=0 THEN N=N\2: F(F)=2: F=F+1: GOTO 50
|
||||
60 P=3
|
||||
70 GOTO 100
|
||||
80 IF N MOD P=0 THEN N=N\P: F(F)=P: F=F+1: GOTO 80
|
||||
90 P=P+2
|
||||
100 IF P<=N GOTO 80
|
||||
110 IF F<=1 GOTO 190
|
||||
120 N=I: S=0
|
||||
130 IF N>0 THEN S=S+N MOD 10: N=N\10: GOTO 130
|
||||
140 FOR J=0 TO F-1
|
||||
150 N=F(J)
|
||||
160 IF N>0 THEN S=S-N MOD 10: N=N\10: GOTO 160
|
||||
170 NEXT
|
||||
180 IF S=0 THEN PRINT USING " ####";I;: C=C+1
|
||||
190 NEXT
|
||||
200 PRINT
|
||||
210 PRINT "Found";C;"Smith numbers."
|
||||
52
Task/Smith-numbers/BCPL/smith-numbers.bcpl
Normal file
52
Task/Smith-numbers/BCPL/smith-numbers.bcpl
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
get "libhdr"
|
||||
|
||||
// Find the sum of the digits of N
|
||||
let digsum(n) =
|
||||
n<10 -> n,
|
||||
n rem 10 + digsum(n/10)
|
||||
|
||||
// Factorize N
|
||||
let factors(n, facs) = valof
|
||||
$( let count = 0 and fac = 3
|
||||
|
||||
// Powers of 2
|
||||
while n>0 & (n & 1)=0
|
||||
$( n := n >> 1
|
||||
facs!count := 2
|
||||
count := count + 1
|
||||
$)
|
||||
|
||||
// Odd factors
|
||||
while fac <= n
|
||||
$( while n rem fac=0
|
||||
$( n := n / fac
|
||||
facs!count := fac
|
||||
count := count + 1
|
||||
$)
|
||||
fac := fac + 2
|
||||
$)
|
||||
|
||||
resultis count
|
||||
$)
|
||||
|
||||
// Is N a Smith number?
|
||||
let smith(n) = valof
|
||||
$( let facs = vec 32
|
||||
let nfacs = factors(n, facs)
|
||||
let facsum = 0
|
||||
if nfacs<=1 resultis false // primes are not Smith numbers
|
||||
for fac = 0 to nfacs-1 do
|
||||
facsum := facsum + digsum(facs!fac)
|
||||
resultis digsum(n) = facsum
|
||||
$)
|
||||
|
||||
// Count and print Smith numbers below 10,000
|
||||
let start() be
|
||||
$( let count = 0
|
||||
for i = 2 to 9999 if smith(i)
|
||||
$( writed(i, 5)
|
||||
count := count + 1
|
||||
if count rem 16 = 0 then wrch('*N')
|
||||
$)
|
||||
writef("*NFound %N Smith numbers.*N", count)
|
||||
$)
|
||||
45
Task/Smith-numbers/C++/smith-numbers.cpp
Normal file
45
Task/Smith-numbers/C++/smith-numbers.cpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
|
||||
void primeFactors( unsigned n, std::vector<unsigned>& r ) {
|
||||
int f = 2; if( n == 1 ) r.push_back( 1 );
|
||||
else {
|
||||
while( true ) {
|
||||
if( !( n % f ) ) {
|
||||
r.push_back( f );
|
||||
n /= f; if( n == 1 ) return;
|
||||
}
|
||||
else f++;
|
||||
}
|
||||
}
|
||||
}
|
||||
unsigned sumDigits( unsigned n ) {
|
||||
unsigned sum = 0, m;
|
||||
while( n ) {
|
||||
m = n % 10; sum += m;
|
||||
n -= m; n /= 10;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
unsigned sumDigits( std::vector<unsigned>& v ) {
|
||||
unsigned sum = 0;
|
||||
for( std::vector<unsigned>::iterator i = v.begin(); i != v.end(); i++ ) {
|
||||
sum += sumDigits( *i );
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
void listAllSmithNumbers( unsigned n ) {
|
||||
std::vector<unsigned> pf;
|
||||
for( unsigned i = 4; i < n; i++ ) {
|
||||
primeFactors( i, pf ); if( pf.size() < 2 ) continue;
|
||||
if( sumDigits( i ) == sumDigits( pf ) )
|
||||
std::cout << std::setw( 4 ) << i << " ";
|
||||
pf.clear();
|
||||
}
|
||||
std::cout << "\n\n";
|
||||
}
|
||||
int main( int argc, char* argv[] ) {
|
||||
listAllSmithNumbers( 10000 );
|
||||
return 0;
|
||||
}
|
||||
57
Task/Smith-numbers/C-sharp/smith-numbers.cs
Normal file
57
Task/Smith-numbers/C-sharp/smith-numbers.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SmithNumbers {
|
||||
class Program {
|
||||
static int SumDigits(int n) {
|
||||
int sum = 0;
|
||||
while (n > 0) {
|
||||
n = Math.DivRem(n, 10, out int rem);
|
||||
sum += rem;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
static List<int> PrimeFactors(int n) {
|
||||
List<int> result = new List<int>();
|
||||
|
||||
for (int i = 2; n % i == 0; n /= i) {
|
||||
result.Add(i);
|
||||
}
|
||||
|
||||
for (int i = 3; i * i < n; i += 2) {
|
||||
while (n % i == 0) {
|
||||
result.Add(i);
|
||||
n /= i;
|
||||
}
|
||||
}
|
||||
|
||||
if (n != 1) {
|
||||
result.Add(n);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Main(string[] args) {
|
||||
const int SIZE = 8;
|
||||
int count = 0;
|
||||
for (int n = 1; n < 10_000; n++) {
|
||||
var factors = PrimeFactors(n);
|
||||
if (factors.Count > 1) {
|
||||
int sum = SumDigits(n);
|
||||
foreach (var f in factors) {
|
||||
sum -= SumDigits(f);
|
||||
}
|
||||
if (sum == 0) {
|
||||
Console.Write("{0,5}", n);
|
||||
if (count == SIZE - 1) {
|
||||
Console.WriteLine();
|
||||
}
|
||||
count = (count + 1) % SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
78
Task/Smith-numbers/C/smith-numbers.c
Normal file
78
Task/Smith-numbers/C/smith-numbers.c
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
int numPrimeFactors(unsigned x) {
|
||||
unsigned p = 2;
|
||||
int pf = 0;
|
||||
if (x == 1)
|
||||
return 1;
|
||||
else {
|
||||
while (true) {
|
||||
if (!(x % p)) {
|
||||
pf++;
|
||||
x /= p;
|
||||
if (x == 1)
|
||||
return pf;
|
||||
}
|
||||
else
|
||||
++p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void primeFactors(unsigned x, unsigned* arr) {
|
||||
unsigned p = 2;
|
||||
int pf = 0;
|
||||
if (x == 1)
|
||||
arr[pf] = 1;
|
||||
else {
|
||||
while (true) {
|
||||
if (!(x % p)) {
|
||||
arr[pf++] = p;
|
||||
x /= p;
|
||||
if (x == 1)
|
||||
return;
|
||||
}
|
||||
else
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned sumDigits(unsigned x) {
|
||||
unsigned sum = 0, y;
|
||||
while (x) {
|
||||
y = x % 10;
|
||||
sum += y;
|
||||
x /= 10;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
unsigned sumFactors(unsigned* arr, int size) {
|
||||
unsigned sum = 0;
|
||||
for (int a = 0; a < size; a++)
|
||||
sum += sumDigits(arr[a]);
|
||||
return sum;
|
||||
}
|
||||
|
||||
void listAllSmithNumbers(unsigned x) {
|
||||
unsigned *arr;
|
||||
for (unsigned a = 4; a < x; a++) {
|
||||
int numfactors = numPrimeFactors(a);
|
||||
arr = (unsigned*)malloc(numfactors * sizeof(unsigned));
|
||||
if (numfactors < 2)
|
||||
continue;
|
||||
primeFactors(a, arr);
|
||||
if (sumDigits(a) == sumFactors(arr,numfactors))
|
||||
printf("%4u ",a);
|
||||
free(arr);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
printf("All the Smith Numbers < 10000 are:\n");
|
||||
listAllSmithNumbers(10000);
|
||||
return 0;
|
||||
}
|
||||
62
Task/Smith-numbers/CLU/smith-numbers.clu
Normal file
62
Task/Smith-numbers/CLU/smith-numbers.clu
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
% Get all digits of a number
|
||||
digits = iter (n: int) yields (int)
|
||||
while n > 0 do
|
||||
yield(n // 10)
|
||||
n := n / 10
|
||||
end
|
||||
end digits
|
||||
|
||||
% Get all prime factors of a number
|
||||
prime_factors = iter (n: int) yields (int)
|
||||
% Take factors of 2 out first (the compiler should optimize)
|
||||
while n // 2 = 0 do yield(2) n := n/2 end
|
||||
|
||||
% Next try odd factors
|
||||
fac: int := 3
|
||||
while fac <= n do
|
||||
while n // fac = 0 do
|
||||
yield(fac)
|
||||
n := n/fac
|
||||
end
|
||||
fac := fac + 2
|
||||
end
|
||||
end prime_factors
|
||||
|
||||
% See if a number is a Smith number
|
||||
smith = proc (n: int) returns (bool)
|
||||
dsum: int := 0
|
||||
fac_dsum: int := 0
|
||||
|
||||
% Find the sum of the digits
|
||||
for d: int in digits(n) do dsum := dsum + d end
|
||||
|
||||
% Find the sum of the digits of all factors
|
||||
nfac: int := 0
|
||||
for fac: int in prime_factors(n) do
|
||||
nfac := nfac + 1
|
||||
for d: int in digits(fac) do fac_dsum := fac_dsum + d end
|
||||
end
|
||||
|
||||
% The number is a Smith number if these two are equal,
|
||||
% and the number is not prime (has more than one factor)
|
||||
return(fac_dsum = dsum cand nfac > 1)
|
||||
end smith
|
||||
|
||||
% Yield all Smith numbers up to a limit
|
||||
smiths = iter (max: int) yields (int)
|
||||
for i: int in int$from_to(1, max-1) do
|
||||
if smith(i) then yield(i) end
|
||||
end
|
||||
end smiths
|
||||
|
||||
% Display all Smith numbers below 10,000
|
||||
start_up = proc ()
|
||||
po: stream := stream$primary_output()
|
||||
count: int := 0
|
||||
for s: int in smiths(10000) do
|
||||
stream$putright(po, int$unparse(s), 5)
|
||||
count := count + 1
|
||||
if count // 16 = 0 then stream$putl(po, "") end
|
||||
end
|
||||
stream$putl(po, "\nFound " || int$unparse(count) || " Smith numbers.")
|
||||
end start_up
|
||||
26
Task/Smith-numbers/Clojure/smith-numbers.clj
Normal file
26
Task/Smith-numbers/Clojure/smith-numbers.clj
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
(defn divisible? [a b]
|
||||
(zero? (mod a b)))
|
||||
|
||||
(defn prime? [n]
|
||||
(and (> n 1) (not-any? (partial divisible? n) (range 2 n))))
|
||||
|
||||
(defn prime-factors
|
||||
([n] (prime-factors n 2 '()))
|
||||
([n candidate acc]
|
||||
(cond
|
||||
(<= n 1) (reverse acc)
|
||||
(zero? (rem n candidate)) (recur
|
||||
(/ n candidate)
|
||||
candidate
|
||||
(cons candidate acc))
|
||||
:else (recur n (inc candidate) acc))))
|
||||
|
||||
(defn sum-digits [n]
|
||||
(reduce + (map #(- (int %) (int \0)) (str n))))
|
||||
|
||||
(defn smith-number? [n]
|
||||
(and (not (prime? n))
|
||||
(= (sum-digits n)
|
||||
(sum-digits (clojure.string/join "" (prime-factors n))))))
|
||||
|
||||
(filter smith-number? (range 1 10000))
|
||||
82
Task/Smith-numbers/Cowgol/smith-numbers.cowgol
Normal file
82
Task/Smith-numbers/Cowgol/smith-numbers.cowgol
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
include "cowgol.coh";
|
||||
typedef N is uint16; # 16-bit math is good enough
|
||||
|
||||
# Print a value right-justified in a field of length N
|
||||
sub print_right(n: N, width: uint8) is
|
||||
var arr: uint8[16];
|
||||
var buf := &arr[0];
|
||||
var nxt := UIToA(n as uint32, 10, buf);
|
||||
var len := (nxt - buf) as uint8;
|
||||
while len < width loop
|
||||
print_char(' ');
|
||||
len := len + 1;
|
||||
end loop;
|
||||
print(buf);
|
||||
end sub;
|
||||
|
||||
# Find the sum of the digits of a number
|
||||
sub digit_sum(n: N): (sum: N) is
|
||||
sum := 0;
|
||||
while n > 0 loop
|
||||
sum := sum + n % 10;
|
||||
n := n / 10;
|
||||
end loop;
|
||||
end sub;
|
||||
|
||||
# Factorize a number, write the factors into the buffer,
|
||||
# return the amount of factors.
|
||||
sub factorize(n: N, buf: [N]): (count: N) is
|
||||
count := 0;
|
||||
# Take care of the factors of 2 first
|
||||
while n>0 and n & 1 == 0 loop
|
||||
n := n >> 1;
|
||||
count := count + 1;
|
||||
[buf] := 2;
|
||||
buf := @next buf;
|
||||
end loop;
|
||||
# Then do the odd factors
|
||||
var fac: N := 3;
|
||||
while n >= fac loop
|
||||
while n % fac == 0 loop
|
||||
n := n / fac;
|
||||
count := count + 1;
|
||||
[buf] := fac;
|
||||
buf := @next buf;
|
||||
end loop;
|
||||
fac := fac + 2;
|
||||
end loop;
|
||||
end sub;
|
||||
|
||||
# See if a number is a Smith number
|
||||
sub smith(n: N): (rslt: uint8) is
|
||||
rslt := 0;
|
||||
var facs: N[16];
|
||||
var n_facs := factorize(n, &facs[0]) as @indexof facs;
|
||||
if n_facs > 1 then
|
||||
# Only composite numbers are Smith numbers
|
||||
var dsum := digit_sum(n);
|
||||
var facsum: N := 0;
|
||||
var i: @indexof facs := 0;
|
||||
while i < n_facs loop
|
||||
facsum := facsum + digit_sum(facs[i]);
|
||||
i := i + 1;
|
||||
end loop;
|
||||
if facsum == dsum then rslt := 1; end if;
|
||||
end if;
|
||||
end sub;
|
||||
|
||||
# Display all Smith numbers below 10000
|
||||
var i: N := 2;
|
||||
var count: N := 0;
|
||||
while i < 10000 loop
|
||||
if smith(i) != 0 then
|
||||
count := count + 1;
|
||||
print_right(i, 5);
|
||||
if count & 0xF == 0 then print_nl(); end if;
|
||||
end if;
|
||||
i := i + 1;
|
||||
end loop;
|
||||
print_nl();
|
||||
print("Found ");
|
||||
print_i32(count as uint32);
|
||||
print(" Smith numbers.\n");
|
||||
53
Task/Smith-numbers/D/smith-numbers.d
Normal file
53
Task/Smith-numbers/D/smith-numbers.d
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import std.stdio;
|
||||
|
||||
void main() {
|
||||
int cnt;
|
||||
for (int n=1; n<10_000; n++) {
|
||||
auto factors = primeFactors(n);
|
||||
if (factors.length > 1) {
|
||||
int sum = sumDigits(n);
|
||||
foreach (f; factors) {
|
||||
sum -= sumDigits(f);
|
||||
}
|
||||
if (sum==0) {
|
||||
writef("%4s ", n);
|
||||
cnt++;
|
||||
}
|
||||
if (cnt==10) {
|
||||
cnt = 0;
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto primeFactors(int n) {
|
||||
import std.array : appender;
|
||||
auto result = appender!(int[]);
|
||||
|
||||
for (int i=2; n%i==0; n/=i) {
|
||||
result.put(i);
|
||||
}
|
||||
|
||||
for (int i=3; i*i<=n; i+=2) {
|
||||
while (n%i==0) {
|
||||
result.put(i);
|
||||
n/=i;
|
||||
}
|
||||
}
|
||||
|
||||
if (n!=1) {
|
||||
result.put(n);
|
||||
}
|
||||
|
||||
return result.data;
|
||||
}
|
||||
|
||||
int sumDigits(int n) {
|
||||
int sum;
|
||||
while (n > 0) {
|
||||
sum += (n%10);
|
||||
n /= 10;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
70
Task/Smith-numbers/Draco/smith-numbers.draco
Normal file
70
Task/Smith-numbers/Draco/smith-numbers.draco
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/* Find the sum of the digits of a number */
|
||||
proc nonrec digitsum(word n) word:
|
||||
word sum;
|
||||
sum := 0;
|
||||
while n ~= 0 do
|
||||
sum := sum + n % 10;
|
||||
n := n / 10
|
||||
od;
|
||||
sum
|
||||
corp
|
||||
|
||||
/* Find all prime factors and write them into the given array
|
||||
(which is assumed to be big enough); return the amount of
|
||||
factors. */
|
||||
proc nonrec factors(word n; [*] word facs) word:
|
||||
word count, fac;
|
||||
count := 0;
|
||||
|
||||
/* take out factors of 2 */
|
||||
while n > 0 and n & 1 = 0 do
|
||||
n := n >> 1;
|
||||
facs[count] := 2;
|
||||
count := count + 1
|
||||
od;
|
||||
|
||||
/* take out odd factors */
|
||||
fac := 3;
|
||||
while n >= fac do
|
||||
while n % fac = 0 do
|
||||
n := n / fac;
|
||||
facs[count] := fac;
|
||||
count := count + 1;
|
||||
od;
|
||||
fac := fac + 2
|
||||
od;
|
||||
count
|
||||
corp
|
||||
|
||||
/* See if a number is a Smith number */
|
||||
proc nonrec smith(word n) bool:
|
||||
[32] word facs; /* 32 factors ought to be enough for everyone */
|
||||
word dsum, facsum, nfacs, i;
|
||||
|
||||
nfacs := factors(n, facs);
|
||||
if nfacs = 1 then
|
||||
false /* primes are not Smith numbers */
|
||||
else
|
||||
dsum := digitsum(n);
|
||||
facsum := 0;
|
||||
for i from 0 upto nfacs-1 do
|
||||
facsum := facsum + digitsum(facs[i])
|
||||
od;
|
||||
dsum = facsum
|
||||
fi
|
||||
corp
|
||||
|
||||
/* Find all Smith numbers below 10000 */
|
||||
proc nonrec main() void:
|
||||
word i, count;
|
||||
count := 0;
|
||||
for i from 2 upto 9999 do
|
||||
if smith(i) then
|
||||
write(i:5);
|
||||
count := count + 1;
|
||||
if count & 0xF = 0 then writeln() fi
|
||||
fi
|
||||
od;
|
||||
writeln();
|
||||
writeln("Found ", count, " Smith numbers.")
|
||||
corp
|
||||
21
Task/Smith-numbers/Elixir/smith-numbers.elixir
Normal file
21
Task/Smith-numbers/Elixir/smith-numbers.elixir
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
defmodule Smith do
|
||||
def number?(n) do
|
||||
d = decomposition(n)
|
||||
length(d)>1 and sum_digits(n) == Enum.map(d, &sum_digits/1) |> Enum.sum
|
||||
end
|
||||
|
||||
defp sum_digits(n) do
|
||||
Integer.digits(n) |> Enum.sum
|
||||
end
|
||||
|
||||
defp decomposition(n, k\\2, acc\\[])
|
||||
defp decomposition(n, k, acc) when n < k*k, do: [n | acc]
|
||||
defp decomposition(n, k, acc) when rem(n, k) == 0, do: decomposition(div(n, k), k, [k | acc])
|
||||
defp decomposition(n, k, acc), do: decomposition(n, k+1, acc)
|
||||
end
|
||||
|
||||
m = 10000
|
||||
smith = Enum.filter(1..m, &Smith.number?/1)
|
||||
IO.puts "#{length(smith)} smith numbers below #{m}:"
|
||||
IO.puts "First 10: #{Enum.take(smith,10) |> Enum.join(", ")}"
|
||||
IO.puts "Last 10: #{Enum.take(smith,-10) |> Enum.join(", ")}"
|
||||
6
Task/Smith-numbers/F-Sharp/smith-numbers.fs
Normal file
6
Task/Smith-numbers/F-Sharp/smith-numbers.fs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// Generate Smith Numbers. Nigel Galloway: November 6th., 2020
|
||||
let fN g=Seq.unfold(fun n->match n with 0->None |_->Some(n%10,n/10)) g |> Seq.sum
|
||||
let rec fG(n,g) p=match g%p with 0->fG (n+fN p,g/p) p |_->(n,g)
|
||||
primes32()|>Seq.pairwise|>Seq.collect(fun(n,g)->[n+1..g-1])|>Seq.takeWhile(fun n->n<10000)
|
||||
|>Seq.filter(fun g->fN g=fst(primes32()|>Seq.scan(fun n g->fG n g)(0,g)|>Seq.find(fun(_,n)->n=1)))
|
||||
|>Seq.chunkBySize 20|>Seq.iter(fun n->Seq.iter(printf "%4d ") n; printfn "")
|
||||
12
Task/Smith-numbers/Factor/smith-numbers.factor
Normal file
12
Task/Smith-numbers/Factor/smith-numbers.factor
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
USING: formatting grouping io kernel math.primes.factors
|
||||
math.ranges math.text.utils sequences sequences.deep ;
|
||||
|
||||
: (smith?) ( n factors -- ? )
|
||||
[ 1 digit-groups sum ]
|
||||
[ [ 1 digit-groups ] map flatten sum = ] bi* ; inline
|
||||
|
||||
: smith? ( n -- ? )
|
||||
dup factors dup length 1 = [ 2drop f ] [ (smith?) ] if ;
|
||||
|
||||
10,000 [1,b] [ smith? ] filter 10 group
|
||||
[ [ "%4d " printf ] each nl ] each
|
||||
125
Task/Smith-numbers/Fortran/smith-numbers.f
Normal file
125
Task/Smith-numbers/Fortran/smith-numbers.f
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
MODULE FACTORISE !Produce a little list...
|
||||
USE PRIMEBAG !This is a common need.
|
||||
INTEGER LASTP !Some size allowances.
|
||||
PARAMETER (LASTP = 9) !2*3*5*7*11*13*17*19*23*29 = 6,469,693,230, > 2,147,483,647.
|
||||
TYPE FACTORED !Represent a number fully factored.
|
||||
INTEGER PVAL(0:LASTP) !As a list of prime number indices with PVAL(0) the count.
|
||||
INTEGER PPOW(LASTP) !And the powers. for the fingered primes.
|
||||
END TYPE FACTORED !Rather than as a simple number multiplied out.
|
||||
|
||||
CONTAINS !Now for the details.
|
||||
SUBROUTINE SHOWFACTORS(N) !First, to show an internal data structure.
|
||||
TYPE(FACTORED) N !It is supplied as a list of prime factors.
|
||||
INTEGER I !A stepper.
|
||||
DO I = 1,N.PVAL(0) !Step along the list.
|
||||
IF (I.GT.1) WRITE (MSG,"('x',$)") !Append a glyph for "multiply".
|
||||
WRITE (MSG,"(I0,$)") N.PVAL(I) !The prime number's value.
|
||||
IF (N.PPOW(I).GT.1) WRITE (MSG,"('^',I0,$)") N.PPOW(I) !With an interesting power?
|
||||
END DO !On to the next element in the list.
|
||||
WRITE (MSG,1) N.PVAL(0) !End the line
|
||||
1 FORMAT (": Factor count ",I0) !With a count of prime factors.
|
||||
END SUBROUTINE SHOWFACTORS !Hopefully, this will not be needed often.
|
||||
|
||||
TYPE(FACTORED) FUNCTION FACTOR(IT) !Into a list of primes and their powers.
|
||||
Careful! 1 is not a factor of N, but if N is prime, N is. N = product of its prime factors.
|
||||
INTEGER IT,N !The number and a similar style copy to damage.
|
||||
INTEGER F,FP !A factor and a power.
|
||||
IF (IT.LE.0) STOP "Factor only positive numbers!" !Or else...
|
||||
FACTOR.PVAL(0) = 0 !No prime factors have been found. One need not apply.
|
||||
F = 0 !NEXTPRIME(F) will return 2, the first factor to try.
|
||||
N = IT !A copy I can damage.
|
||||
Collapse N into its prime factors.
|
||||
10 DO WHILE(N.GT.1) !Carthaga delenda est?
|
||||
IF (ISPRIME(N)) THEN!If the remnant is a prime number,
|
||||
F = N !Then it is the last factor.
|
||||
FP = 1 !Its power is one.
|
||||
N = 1 !And the reduction is finished.
|
||||
ELSE !Otherwise, continue trying larger factors.
|
||||
FP = 0 !It has no power yet.
|
||||
11 F = NEXTPRIME(F) !Go for the next possible factor.
|
||||
DO WHILE(MOD(N,F).EQ.0) !Well?
|
||||
FP = FP + 1 !Count a factor..
|
||||
N = N/F !Reduce the number.
|
||||
END DO !Until F's multiplicity is exhausted.
|
||||
IF (FP.LE.0) GO TO 11 !No presence? Try the next factor: N has some...
|
||||
END IF !One way or another, F is a prime factor and FP its power.
|
||||
IF (FACTOR.PVAL(0).GE.LASTP) THEN !Have I room in the list?
|
||||
WRITE (MSG,1) IT,LASTP !Alas.
|
||||
1 FORMAT ("Factoring ",I0," but with provision for only ", !This shouldn't happen,
|
||||
1 I0," distinct prime factors!") !If LASTP is correct for the current INTEGER size.
|
||||
CALL SHOWFACTORS(FACTOR) !Show what has been found so far.
|
||||
STOP "Not enough storage!" !Quite.
|
||||
END IF !But normally,
|
||||
FACTOR.PVAL(0) = FACTOR.PVAL(0) + 1 !Admit another factor.
|
||||
FACTOR.PVAL(FACTOR.PVAL(0)) = F !The prime number found to be a factor.
|
||||
FACTOR.PPOW(FACTOR.PVAL(0)) = FP !Place its power.
|
||||
END DO !Now seee what has survived.
|
||||
END FUNCTION FACTOR !Thus, a list of primes and their powers.
|
||||
END MODULE FACTORISE !Careful! PVAL(0) is the number of prime factors.
|
||||
|
||||
MODULE SMITHSTUFF !Now for the strange stuff.
|
||||
CONTAINS !The two special workers.
|
||||
INTEGER FUNCTION DIGITSUM(N,BASE) !Sums the digits of N.
|
||||
INTEGER N,IT !The number, and a copy I can damage.
|
||||
INTEGER BASE !The base for arithmetic,
|
||||
IF (N.LT.0) STOP "DigitSum: negative numbers need not apply!"
|
||||
DIGITSUM = 0 !Here we go.
|
||||
IT = N !This value will be damaged.
|
||||
DO WHILE(IT.GT.0) !Something remains?
|
||||
DIGITSUM = MOD(IT,BASE) + DIGITSUM !Yes. Grap the low-order digit.
|
||||
IT = IT/BASE !And descend a power.
|
||||
END DO !Perhaps something still remains.
|
||||
END FUNCTION DIGITSUM !Numerology.
|
||||
|
||||
LOGICAL FUNCTION SMITHNUM(N,BASE) !Worse numerology.
|
||||
USE FACTORISE !To find the prime factord of N.
|
||||
INTEGER N !The number of interest.
|
||||
INTEGER BASE !The base of the numerology.
|
||||
TYPE(FACTORED) F !A list.
|
||||
INTEGER I,FD !Assistants.
|
||||
F = FACTOR(N) !Hopefully, LASTP is large enough for N.
|
||||
c write (6,"(a,I0,1x)",advance="no") "N=",N
|
||||
c call ShowFactors(F)
|
||||
FD = 0 !Attempts via the SUM facility involved too many requirements.
|
||||
DO I = 1,F.PVAL(0) !For each of the prime factors found...
|
||||
FD = DIGITSUM(F.PVAL(I),BASE)*F.PPOW(I) + FD !Not forgetting the multiplicity.
|
||||
END DO !On to the next prime factor in the list.
|
||||
SMITHNUM = FD.EQ.DIGITSUM(N,BASE) !This is the rule.
|
||||
END FUNCTION SMITHNUM !So, is N a joker?
|
||||
END MODULE SMITHSTUFF !Simple enough.
|
||||
|
||||
USE PRIMEBAG !Gain access to GRASPPRIMEBAG.
|
||||
USE SMITHSTUFF !The special stuff.
|
||||
INTEGER LAST !Might as well document this.
|
||||
PARAMETER (LAST = 9999) !The specification is BELOW 10000...
|
||||
INTEGER I,N,BASE !Workers.
|
||||
INTEGER NB,BAG(20) !Prepare a line's worth of results.
|
||||
MSG = 6 !Standard output.
|
||||
|
||||
WRITE (MSG,1) LAST !Hello.
|
||||
1 FORMAT ('To find the "Smith" numbers up to ',I0)
|
||||
IF (.NOT.GRASPPRIMEBAG(66)) STOP "Gan't grab my file!" !Attempt in hope.
|
||||
|
||||
10 DO BASE = 2,12 !Flexible numerology.
|
||||
WRITE (MSG,11) BASE !Here we go again.
|
||||
11 FORMAT (/,"Working in base ",I0)
|
||||
N = 0 !None found.
|
||||
NB = 0 !So, none are bagged.
|
||||
DO I = 1,LAST !Step through the span.
|
||||
IF (ISPRIME(I)) CYCLE !Prime numbers are boring Smith numbers. Skip them.
|
||||
IF (SMITHNUM(I,BASE)) THEN !So?
|
||||
N = N + 1 !Count one in.
|
||||
IF (NB.GE.20) THEN !A full line's worth with another to come?
|
||||
WRITE (MSG,12) BAG !Yep. Roll the line to make space.
|
||||
12 FORMAT (20I6) !This will do for a nice table.
|
||||
NB = 0 !The line is now ready.
|
||||
END IF !So much for a line buffer.
|
||||
NB = NB + 1 !Count another entry.
|
||||
BAG(NB) = I !Place it.
|
||||
END IF !So much for a Smith style number.
|
||||
END DO !On to the next candidate number.
|
||||
WRITE (MSG,12) BAG(1:NB)!Wave the tail end.
|
||||
WRITE (MSG,13) N !Save the human some counting.
|
||||
13 FORMAT (I9," found.") !Just in case.
|
||||
END DO !On to the next base.
|
||||
END !That was strange.
|
||||
55
Task/Smith-numbers/FreeBASIC/smith-numbers.basic
Normal file
55
Task/Smith-numbers/FreeBASIC/smith-numbers.basic
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
' FB 1.05.0 Win64
|
||||
|
||||
Sub getPrimeFactors(factors() As UInteger, n As UInteger)
|
||||
If n < 2 Then Return
|
||||
Dim factor As UInteger = 2
|
||||
Do
|
||||
If n Mod factor = 0 Then
|
||||
Redim Preserve factors(0 To UBound(factors) + 1)
|
||||
factors(UBound(factors)) = factor
|
||||
n \= factor
|
||||
If n = 1 Then Return
|
||||
Else
|
||||
' non-prime factors will always give a remainder > 0 as their own factors have already been removed
|
||||
' so it's not worth checking that the next potential factor is prime
|
||||
factor += 1
|
||||
End If
|
||||
Loop
|
||||
End Sub
|
||||
|
||||
Function sumDigits(n As UInteger) As UInteger
|
||||
If n < 10 Then Return n
|
||||
Dim sum As UInteger = 0
|
||||
While n > 0
|
||||
sum += n Mod 10
|
||||
n \= 10
|
||||
Wend
|
||||
Return sum
|
||||
End Function
|
||||
|
||||
Function isSmith(n As UInteger) As Boolean
|
||||
If n < 2 Then Return False
|
||||
Dim factors() As UInteger
|
||||
getPrimeFactors factors(), n
|
||||
If UBound(factors) = 0 Then Return False '' n must be prime if there's only one factor
|
||||
Dim primeSum As UInteger = 0
|
||||
For i As UInteger = 0 To UBound(factors)
|
||||
primeSum += sumDigits(factors(i))
|
||||
Next
|
||||
Return sumDigits(n) = primeSum
|
||||
End Function
|
||||
|
||||
Print "The Smith numbers below 10000 are : "
|
||||
Print
|
||||
Dim count As UInteger = 0
|
||||
For i As UInteger = 2 To 9999
|
||||
If isSmith(i) Then
|
||||
Print Using "#####"; i;
|
||||
count += 1
|
||||
End If
|
||||
Next
|
||||
Print : Print
|
||||
Print count; " numbers found"
|
||||
Print
|
||||
Print "Press any key to quit"
|
||||
Sleep
|
||||
83
Task/Smith-numbers/Go/smith-numbers.go
Normal file
83
Task/Smith-numbers/Go/smith-numbers.go
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func numPrimeFactors(x uint) int {
|
||||
var p uint = 2
|
||||
var pf int
|
||||
if x == 1 {
|
||||
return 1
|
||||
}
|
||||
for {
|
||||
if (x % p) == 0 {
|
||||
pf++
|
||||
x /= p
|
||||
if x == 1 {
|
||||
return pf
|
||||
}
|
||||
} else {
|
||||
p++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func primeFactors(x uint, arr []uint) {
|
||||
var p uint = 2
|
||||
var pf int
|
||||
if x == 1 {
|
||||
arr[pf] = 1
|
||||
return
|
||||
}
|
||||
for {
|
||||
if (x % p) == 0 {
|
||||
arr[pf] = p
|
||||
pf++
|
||||
x /= p
|
||||
if x == 1 {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
p++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sumDigits(x uint) uint {
|
||||
var sum uint
|
||||
for x != 0 {
|
||||
sum += x % 10
|
||||
x /= 10
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func sumFactors(arr []uint, size int) uint {
|
||||
var sum uint
|
||||
for a := 0; a < size; a++ {
|
||||
sum += sumDigits(arr[a])
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func listAllSmithNumbers(maxSmith uint) {
|
||||
var arr []uint
|
||||
var a uint
|
||||
for a = 4; a < maxSmith; a++ {
|
||||
numfactors := numPrimeFactors(a)
|
||||
arr = make([]uint, numfactors)
|
||||
if numfactors < 2 {
|
||||
continue
|
||||
}
|
||||
primeFactors(a, arr)
|
||||
if sumDigits(a) == sumFactors(arr, numfactors) {
|
||||
fmt.Printf("%4d ", a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
const maxSmith = 10000
|
||||
fmt.Printf("All the Smith Numbers less than %d are:\n", maxSmith)
|
||||
listAllSmithNumbers(maxSmith)
|
||||
fmt.Println()
|
||||
}
|
||||
34
Task/Smith-numbers/Haskell/smith-numbers.hs
Normal file
34
Task/Smith-numbers/Haskell/smith-numbers.hs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import Data.Numbers.Primes (primeFactors)
|
||||
import Data.List (unfoldr)
|
||||
import Data.Tuple (swap)
|
||||
import Data.Bool (bool)
|
||||
|
||||
isSmith :: Int -> Bool
|
||||
isSmith n = pfs /= [n] && sumDigits n == foldr ((+) . sumDigits) 0 pfs
|
||||
where
|
||||
sumDigits = sum . baseDigits 10
|
||||
pfs = primeFactors n
|
||||
|
||||
baseDigits :: Int -> Int -> [Int]
|
||||
baseDigits base = unfoldr remQuot
|
||||
where
|
||||
remQuot 0 = Nothing
|
||||
remQuot x = Just (swap (quotRem x base))
|
||||
|
||||
lowSmiths :: [Int]
|
||||
lowSmiths = filter isSmith [2 .. 9999]
|
||||
|
||||
lowSmithCount :: Int
|
||||
lowSmithCount = length lowSmiths
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
mapM_
|
||||
putStrLn
|
||||
[ "Count of Smith Numbers below 10k:"
|
||||
, show lowSmithCount
|
||||
, "\nFirst 15 Smith Numbers:"
|
||||
, unwords (show <$> take 15 lowSmiths)
|
||||
, "\nLast 12 Smith Numbers below 10k:"
|
||||
, unwords (show <$> drop (lowSmithCount - 12) lowSmiths)
|
||||
]
|
||||
4
Task/Smith-numbers/J/smith-numbers-1.j
Normal file
4
Task/Smith-numbers/J/smith-numbers-1.j
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
digits=: 10&#.inv
|
||||
sumdig=: +/@,@digits
|
||||
notprime=: -.@(1&p:)
|
||||
smith=: #~ notprime * (=&sumdig q:)every
|
||||
52
Task/Smith-numbers/J/smith-numbers-2.j
Normal file
52
Task/Smith-numbers/J/smith-numbers-2.j
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#smith }.i.10000
|
||||
376
|
||||
q:376
|
||||
2 2 2 47
|
||||
47 8$smith }.i.10000
|
||||
4 22 27 58 85 94 121 166
|
||||
202 265 274 319 346 355 378 382
|
||||
391 438 454 483 517 526 535 562
|
||||
576 588 627 634 636 645 648 654
|
||||
663 666 690 706 728 729 762 778
|
||||
825 852 861 895 913 915 922 958
|
||||
985 1086 1111 1165 1219 1255 1282 1284
|
||||
1376 1449 1507 1581 1626 1633 1642 1678
|
||||
1736 1755 1776 1795 1822 1842 1858 1872
|
||||
1881 1894 1903 1908 1921 1935 1952 1962
|
||||
1966 2038 2067 2079 2155 2173 2182 2218
|
||||
2227 2265 2286 2326 2362 2366 2373 2409
|
||||
2434 2461 2475 2484 2515 2556 2576 2578
|
||||
2583 2605 2614 2679 2688 2722 2745 2751
|
||||
2785 2839 2888 2902 2911 2934 2944 2958
|
||||
2964 2965 2970 2974 3046 3091 3138 3168
|
||||
3174 3226 3246 3258 3294 3345 3366 3390
|
||||
3442 3505 3564 3595 3615 3622 3649 3663
|
||||
3690 3694 3802 3852 3864 3865 3930 3946
|
||||
3973 4054 4126 4162 4173 4185 4189 4191
|
||||
4198 4209 4279 4306 4369 4414 4428 4464
|
||||
4472 4557 4592 4594 4702 4743 4765 4788
|
||||
4794 4832 4855 4880 4918 4954 4959 4960
|
||||
4974 4981 5062 5071 5088 5098 5172 5242
|
||||
5248 5253 5269 5298 5305 5386 5388 5397
|
||||
5422 5458 5485 5526 5539 5602 5638 5642
|
||||
5674 5772 5818 5854 5874 5915 5926 5935
|
||||
5936 5946 5998 6036 6054 6084 6096 6115
|
||||
6171 6178 6187 6188 6252 6259 6295 6315
|
||||
6344 6385 6439 6457 6502 6531 6567 6583
|
||||
6585 6603 6684 6693 6702 6718 6760 6816
|
||||
6835 6855 6880 6934 6981 7026 7051 7062
|
||||
7068 7078 7089 7119 7136 7186 7195 7227
|
||||
7249 7287 7339 7402 7438 7447 7465 7503
|
||||
7627 7674 7683 7695 7712 7726 7762 7764
|
||||
7782 7784 7809 7824 7834 7915 7952 7978
|
||||
8005 8014 8023 8073 8077 8095 8149 8154
|
||||
8158 8185 8196 8253 8257 8277 8307 8347
|
||||
8372 8412 8421 8466 8518 8545 8568 8628
|
||||
8653 8680 8736 8754 8766 8790 8792 8851
|
||||
8864 8874 8883 8901 8914 9015 9031 9036
|
||||
9094 9166 9184 9193 9229 9274 9276 9285
|
||||
9294 9296 9301 9330 9346 9355 9382 9386
|
||||
9387 9396 9414 9427 9483 9522 9535 9571
|
||||
9598 9633 9634 9639 9648 9657 9684 9708
|
||||
9717 9735 9742 9760 9778 9840 9843 9849
|
||||
9861 9880 9895 9924 9942 9968 9975 9985
|
||||
45
Task/Smith-numbers/Java/smith-numbers.java
Normal file
45
Task/Smith-numbers/Java/smith-numbers.java
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import java.util.*;
|
||||
|
||||
public class SmithNumbers {
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (int n = 1; n < 10_000; n++) {
|
||||
List<Integer> factors = primeFactors(n);
|
||||
if (factors.size() > 1) {
|
||||
int sum = sumDigits(n);
|
||||
for (int f : factors)
|
||||
sum -= sumDigits(f);
|
||||
if (sum == 0)
|
||||
System.out.println(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static List<Integer> primeFactors(int n) {
|
||||
List<Integer> result = new ArrayList<>();
|
||||
|
||||
for (int i = 2; n % i == 0; n /= i)
|
||||
result.add(i);
|
||||
|
||||
for (int i = 3; i * i <= n; i += 2) {
|
||||
while (n % i == 0) {
|
||||
result.add(i);
|
||||
n /= i;
|
||||
}
|
||||
}
|
||||
|
||||
if (n != 1)
|
||||
result.add(n);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int sumDigits(int n) {
|
||||
int sum = 0;
|
||||
while (n > 0) {
|
||||
sum += (n % 10);
|
||||
n /= 10;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
170
Task/Smith-numbers/JavaScript/smith-numbers.js
Normal file
170
Task/Smith-numbers/JavaScript/smith-numbers.js
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// isSmith :: Int -> Bool
|
||||
const isSmith = n => {
|
||||
const pfs = primeFactors(n);
|
||||
return (1 < pfs.length || n !== pfs[0]) && (
|
||||
sumDigits(n) === pfs.reduce(
|
||||
(a, x) => a + sumDigits(x),
|
||||
0
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
// TEST -----------------------------------------------
|
||||
|
||||
// main :: IO ()
|
||||
const main = () => {
|
||||
|
||||
// lowSmiths :: [Int]
|
||||
const lowSmiths = enumFromTo(2)(9999)
|
||||
.filter(isSmith);
|
||||
|
||||
// lowSmithCount :: Int
|
||||
const lowSmithCount = lowSmiths.length;
|
||||
return [
|
||||
"Count of Smith Numbers below 10k:",
|
||||
show(lowSmithCount),
|
||||
"\nFirst 15 Smith Numbers:",
|
||||
unwords(take(15)(lowSmiths)),
|
||||
"\nLast 12 Smith Numbers below 10000:",
|
||||
unwords(drop(lowSmithCount - 12)(lowSmiths))
|
||||
].join('\n');
|
||||
};
|
||||
|
||||
// SMITH ----------------------------------------------
|
||||
|
||||
// primeFactors :: Int -> [Int]
|
||||
const primeFactors = x => {
|
||||
const go = n => {
|
||||
const fs = take(1)(
|
||||
dropWhile(x => 0 != n % x)(
|
||||
enumFromTo(2)(
|
||||
floor(sqrt(n))
|
||||
)
|
||||
)
|
||||
);
|
||||
return 0 === fs.length ? [n] : fs.concat(
|
||||
go(floor(n / fs[0]))
|
||||
);
|
||||
};
|
||||
return go(x);
|
||||
};
|
||||
|
||||
// sumDigits :: Int -> Int
|
||||
const sumDigits = n =>
|
||||
unfoldl(
|
||||
x => 0 === x ? (
|
||||
Nothing()
|
||||
) : Just(quotRem(x)(10))
|
||||
)(n).reduce((a, x) => a + x, 0);
|
||||
|
||||
|
||||
// GENERIC --------------------------------------------
|
||||
|
||||
// Nothing :: Maybe a
|
||||
const Nothing = () => ({
|
||||
type: 'Maybe',
|
||||
Nothing: true,
|
||||
});
|
||||
|
||||
// Just :: a -> Maybe a
|
||||
const Just = x => ({
|
||||
type: 'Maybe',
|
||||
Nothing: false,
|
||||
Just: x
|
||||
});
|
||||
|
||||
// Tuple (,) :: a -> b -> (a, b)
|
||||
const Tuple = a => b => ({
|
||||
type: 'Tuple',
|
||||
'0': a,
|
||||
'1': b,
|
||||
length: 2
|
||||
});
|
||||
|
||||
// drop :: Int -> [a] -> [a]
|
||||
// drop :: Int -> String -> String
|
||||
const drop = n => xs =>
|
||||
xs.slice(n)
|
||||
|
||||
|
||||
// dropWhile :: (a -> Bool) -> [a] -> [a]
|
||||
// dropWhile :: (Char -> Bool) -> String -> String
|
||||
const dropWhile = p => xs => {
|
||||
const lng = xs.length;
|
||||
return 0 < lng ? xs.slice(
|
||||
until(i => i === lng || !p(xs[i]))(
|
||||
i => 1 + i
|
||||
)(0)
|
||||
) : [];
|
||||
};
|
||||
|
||||
// enumFromTo :: Int -> Int -> [Int]
|
||||
const enumFromTo = m => n =>
|
||||
Array.from({
|
||||
length: 1 + n - m
|
||||
}, (_, i) => m + i);
|
||||
|
||||
// floor :: Num -> Int
|
||||
const floor = Math.floor;
|
||||
|
||||
|
||||
// quotRem :: Int -> Int -> (Int, Int)
|
||||
const quotRem = m => n =>
|
||||
Tuple(Math.floor(m / n))(
|
||||
m % n
|
||||
);
|
||||
|
||||
// show :: a -> String
|
||||
const show = x => JSON.stringify(x, null, 2);
|
||||
|
||||
// sqrt :: Num -> Num
|
||||
const sqrt = n =>
|
||||
(0 <= n) ? Math.sqrt(n) : undefined;
|
||||
|
||||
// sum :: [Num] -> Num
|
||||
const sum = xs => xs.reduce((a, x) => a + x, 0);
|
||||
|
||||
// take :: Int -> [a] -> [a]
|
||||
// take :: Int -> String -> String
|
||||
const take = n => xs =>
|
||||
'GeneratorFunction' !== xs.constructor.constructor.name ? (
|
||||
xs.slice(0, n)
|
||||
) : [].concat.apply([], Array.from({
|
||||
length: n
|
||||
}, () => {
|
||||
const x = xs.next();
|
||||
return x.done ? [] : [x.value];
|
||||
}));
|
||||
|
||||
|
||||
// unfoldl :: (b -> Maybe (b, a)) -> b -> [a]
|
||||
const unfoldl = f => v => {
|
||||
let
|
||||
xr = [v, v],
|
||||
xs = [];
|
||||
while (true) {
|
||||
const mb = f(xr[0]);
|
||||
if (mb.Nothing) {
|
||||
return xs
|
||||
} else {
|
||||
xr = mb.Just;
|
||||
xs = [xr[1]].concat(xs);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// until :: (a -> Bool) -> (a -> a) -> a -> a
|
||||
const until = p => f => x => {
|
||||
let v = x;
|
||||
while (!p(v)) v = f(v);
|
||||
return v;
|
||||
};
|
||||
|
||||
// unwords :: [String] -> String
|
||||
const unwords = xs => xs.join(' ');
|
||||
|
||||
return main();
|
||||
})();
|
||||
28
Task/Smith-numbers/Jq/smith-numbers-1.jq
Normal file
28
Task/Smith-numbers/Jq/smith-numbers-1.jq
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
def is_prime:
|
||||
. as $n
|
||||
| if ($n < 2) then false
|
||||
elif ($n % 2 == 0) then $n == 2
|
||||
elif ($n % 3 == 0) then $n == 3
|
||||
elif ($n % 5 == 0) then $n == 5
|
||||
elif ($n % 7 == 0) then $n == 7
|
||||
elif ($n % 11 == 0) then $n == 11
|
||||
elif ($n % 13 == 0) then $n == 13
|
||||
elif ($n % 17 == 0) then $n == 17
|
||||
elif ($n % 19 == 0) then $n == 19
|
||||
else {i:23}
|
||||
| until( (.i * .i) > $n or ($n % .i == 0); .i += 2)
|
||||
| .i * .i > $n
|
||||
end;
|
||||
|
||||
def sum(s): reduce s as $x (null; . + $x);
|
||||
|
||||
# emit a stream of the prime factors as per prime factorization
|
||||
def prime_factors:
|
||||
. as $num
|
||||
| def m($p): # emit $p with appropriate multiplicity
|
||||
$num | while( . % $p == 0; . / $p )
|
||||
| $p ;
|
||||
if (. % 2) == 0 then m(2) else empty end,
|
||||
(range(3; 1 + (./2); 2)
|
||||
| select(($num % .) == 0 and is_prime)
|
||||
| m(.));
|
||||
9
Task/Smith-numbers/Jq/smith-numbers-2.jq
Normal file
9
Task/Smith-numbers/Jq/smith-numbers-2.jq
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# input should be an integer
|
||||
def is_smith:
|
||||
def sumdigits:
|
||||
tostring|explode|map([.]|implode|tonumber)| add;
|
||||
(is_prime|not) and
|
||||
(sumdigits == sum(prime_factors|sumdigits));
|
||||
|
||||
"Smith numbers up to 10000:\n",
|
||||
(range(1; 10000) | select(is_smith))
|
||||
16
Task/Smith-numbers/Julia/smith-numbers.julia
Normal file
16
Task/Smith-numbers/Julia/smith-numbers.julia
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# v0.6
|
||||
|
||||
function sumdigits(n::Integer)
|
||||
sum = 0
|
||||
while n > 0
|
||||
sum += n % 10
|
||||
n = div(n, 10)
|
||||
end
|
||||
return sum
|
||||
end
|
||||
|
||||
using Primes
|
||||
issmith(n::Integer) = !isprime(n) && sumdigits(n) == sum(sumdigits(f) for f in factor(Vector, n))
|
||||
|
||||
smithnumbers = collect(n for n in 2:10000 if issmith(n))
|
||||
println("Smith numbers up to 10000:\n$smithnumbers")
|
||||
50
Task/Smith-numbers/Kotlin/smith-numbers.kotlin
Normal file
50
Task/Smith-numbers/Kotlin/smith-numbers.kotlin
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
// version 1.0.6
|
||||
|
||||
fun getPrimeFactors(n: Int): MutableList<Int> {
|
||||
val factors = mutableListOf<Int>()
|
||||
if (n < 2) return factors
|
||||
var factor = 2
|
||||
var nn = n
|
||||
while (true) {
|
||||
if (nn % factor == 0) {
|
||||
factors.add(factor)
|
||||
nn /= factor
|
||||
if (nn == 1) return factors
|
||||
}
|
||||
else if (factor >= 3) factor += 2
|
||||
else factor = 3
|
||||
}
|
||||
}
|
||||
|
||||
fun sumDigits(n: Int): Int = when {
|
||||
n < 10 -> n
|
||||
else -> {
|
||||
var sum = 0
|
||||
var nn = n
|
||||
while (nn > 0) {
|
||||
sum += (nn % 10)
|
||||
nn /= 10
|
||||
}
|
||||
sum
|
||||
}
|
||||
}
|
||||
|
||||
fun isSmith(n: Int): Boolean {
|
||||
if (n < 2) return false
|
||||
val factors = getPrimeFactors(n)
|
||||
if (factors.size == 1) return false
|
||||
val primeSum = factors.sumBy { sumDigits(it) }
|
||||
return sumDigits(n) == primeSum
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println("The Smith numbers below 10000 are:\n")
|
||||
var count = 0
|
||||
for (i in 2 until 10000) {
|
||||
if (isSmith(i)) {
|
||||
print("%5d".format(i))
|
||||
count++
|
||||
}
|
||||
}
|
||||
println("\n\n$count numbers found")
|
||||
}
|
||||
51
Task/Smith-numbers/Lua/smith-numbers.lua
Normal file
51
Task/Smith-numbers/Lua/smith-numbers.lua
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
-- Returns a boolean indicating whether n is prime
|
||||
function isPrime (n)
|
||||
if n < 2 then return false end
|
||||
if n < 4 then return true end
|
||||
if n % 2 == 0 then return false end
|
||||
for d = 3, math.sqrt(n), 2 do
|
||||
if n % d == 0 then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- Returns a table of the prime factors of n
|
||||
function primeFactors (n)
|
||||
local pfacs, divisor = {}, 1
|
||||
if n < 1 then return pfacs end
|
||||
while not isPrime(n) do
|
||||
while not isPrime(divisor) do divisor = divisor + 1 end
|
||||
while n % divisor == 0 do
|
||||
n = n / divisor
|
||||
table.insert(pfacs, divisor)
|
||||
end
|
||||
divisor = divisor + 1
|
||||
if n == 1 then return pfacs end
|
||||
end
|
||||
table.insert(pfacs, n)
|
||||
return pfacs
|
||||
end
|
||||
|
||||
-- Returns the sum of the digits of n
|
||||
function sumDigits (n)
|
||||
local sum, nStr = 0, tostring(n)
|
||||
for digit = 1, nStr:len() do
|
||||
sum = sum + tonumber(nStr:sub(digit, digit))
|
||||
end
|
||||
return sum
|
||||
end
|
||||
|
||||
-- Returns a boolean indicating whether n is a Smith number
|
||||
function isSmith (n)
|
||||
if isPrime(n) then return false end
|
||||
local sumFacs = 0
|
||||
for _, v in ipairs(primeFactors(n)) do
|
||||
sumFacs = sumFacs + sumDigits(v)
|
||||
end
|
||||
return sumFacs == sumDigits(n)
|
||||
end
|
||||
|
||||
-- Main procedure
|
||||
for n = 1, 10000 do
|
||||
if isSmith(n) then io.write(n .. "\t") end
|
||||
end
|
||||
57
Task/Smith-numbers/M2000-Interpreter/smith-numbers.m2000
Normal file
57
Task/Smith-numbers/M2000-Interpreter/smith-numbers.m2000
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
Module Checkit {
|
||||
Set Fast !
|
||||
Form 80, 40
|
||||
Refresh
|
||||
Function Smith(max=10000) {
|
||||
Function SumDigit(a$) {
|
||||
def long sum
|
||||
For i=1 to len(a$) {sum+=val(mid$(a$,i, 1)) }
|
||||
=sum
|
||||
}
|
||||
x=max
|
||||
\\ Euler's Sieve
|
||||
Dim r(x+1)=1
|
||||
k=2
|
||||
k2=k**2
|
||||
While k2<x {
|
||||
For m=k2 to x step k {r(m)=0}
|
||||
Repeat {
|
||||
k++ : k2=k**2
|
||||
} Until r(k)=1 or k2>x
|
||||
}
|
||||
r(0)=0
|
||||
smith=0
|
||||
smith2=0
|
||||
lastI=0
|
||||
inventory smithnumbers
|
||||
Top=max div 100
|
||||
c=4
|
||||
For i=4 to max {
|
||||
if c> top then print over $(0,6), ceil(i/max*100);"%" : Refresh : c=1
|
||||
c++
|
||||
if r(i)=0 then {
|
||||
smith=sumdigit(str$(i)) : lastI=i
|
||||
smith2=0
|
||||
do {
|
||||
ii=int(sqrt(i))+1
|
||||
do { ii-- : while r(ii)<>1 {ii--} } until i mod ii=0
|
||||
if ii<2 then smith2+=sumdigit(str$(i)):exit
|
||||
smith3=sumdigit(str$(ii))
|
||||
do {
|
||||
smith2+=smith3
|
||||
i=i div ii : if ii<2 or i<2 then exit
|
||||
} until i mod ii<>0 or smith2>smith
|
||||
} until i<2 or smith2>smith
|
||||
If smith=smith2 then Append smithnumbers, lastI
|
||||
}
|
||||
}
|
||||
=smithnumbers
|
||||
}
|
||||
const MaxNumbers=10000
|
||||
numbers= Smith(MaxNumbers)
|
||||
Print
|
||||
Print $(,5), numbers
|
||||
Print
|
||||
Print format$(" {0} smith numbers found <= {1}", Len(numbers), MaxNumbers)
|
||||
}
|
||||
Checkit
|
||||
52
Task/Smith-numbers/MAD/smith-numbers.mad
Normal file
52
Task/Smith-numbers/MAD/smith-numbers.mad
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
NORMAL MODE IS INTEGER
|
||||
PRINT COMMENT$ SMITH NUMBERS$
|
||||
|
||||
R GENERATE PRIMES UP TO 10,000 USING SIEVE METHOD
|
||||
BOOLEAN SIEVE
|
||||
DIMENSION SIEVE(10000)
|
||||
DIMENSION PRIMES(1500)
|
||||
|
||||
THROUGH SET, FOR I=2, 1, I.G.10000
|
||||
SET SIEVE(I) = 1B
|
||||
|
||||
THROUGH NXPRIM, FOR P=2, 1, P.G.100
|
||||
WHENEVER SIEVE(P)
|
||||
THROUGH MARK, FOR I=P*P, P, I.G.10000
|
||||
MARK SIEVE(I) = 0B
|
||||
NXPRIM END OF CONDITIONAL
|
||||
|
||||
NPRIMS = 0
|
||||
THROUGH CNTPRM, FOR P=2, 1, P.G.10000
|
||||
WHENEVER SIEVE(P)
|
||||
PRIMES(NPRIMS) = P
|
||||
NPRIMS = NPRIMS + 1
|
||||
CNTPRM END OF CONDITIONAL
|
||||
|
||||
R CHECK SMITH NUMBERS
|
||||
THROUGH SMITH, FOR I=4, 1, I.GE.10000
|
||||
WHENEVER .NOT. SIEVE(I)
|
||||
K = I
|
||||
PFSUM = 0
|
||||
THROUGH FACSUM, FOR P=0, 1, P.GE.NPRIMS .OR. K.E.0
|
||||
L = PRIMES(P)
|
||||
FACDIV WHENEVER K/L*L.E.K .AND. K.NE.0
|
||||
PFSUM = PFSUM + DGTSUM.(L)
|
||||
K = K/L
|
||||
TRANSFER TO FACDIV
|
||||
FACSUM END OF CONDITIONAL
|
||||
WHENEVER PFSUM.E.DGTSUM.(I), PRINT FORMAT NUMFMT,I
|
||||
SMITH END OF CONDITIONAL
|
||||
|
||||
VECTOR VALUES NUMFMT = $I5*$
|
||||
|
||||
R GET SUM OF DIGITS OF N
|
||||
INTERNAL FUNCTION(N)
|
||||
ENTRY TO DGTSUM.
|
||||
DSUM = 0
|
||||
DNUM = N
|
||||
LOOP WHENEVER DNUM.E.0, FUNCTION RETURN DSUM
|
||||
DSUM = DSUM + DNUM-DNUM/10*10
|
||||
DNUM = DNUM/10
|
||||
TRANSFER TO LOOP
|
||||
END OF FUNCTION
|
||||
END OF PROGRAM
|
||||
16
Task/Smith-numbers/Maple/smith-numbers.maple
Normal file
16
Task/Smith-numbers/Maple/smith-numbers.maple
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
isSmith := proc(n::posint)
|
||||
local factors, sumofDigits, sumofFactorDigits, x;
|
||||
if isprime(n) then
|
||||
return false;
|
||||
else
|
||||
sumofDigits := add(x, x = convert(n, base, 10));
|
||||
sumofFactorDigits := add(map(x -> op(convert(x, base, 10)), [op(NumberTheory:-PrimeFactors(n))]));
|
||||
return evalb(sumofDigits = sumofFactorDigits);
|
||||
end if;
|
||||
end proc:
|
||||
|
||||
findSmith := proc(n::posint)
|
||||
return select(isSmith, [seq(1 .. n - 1)]);
|
||||
end proc:
|
||||
|
||||
findSmith(10000);
|
||||
3
Task/Smith-numbers/Mathematica/smith-numbers.math
Normal file
3
Task/Smith-numbers/Mathematica/smith-numbers.math
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
smithQ[n_] := Not[PrimeQ[n]] &&
|
||||
Total[IntegerDigits[n]] == Total[IntegerDigits /@ Flatten[ConstantArray @@@ FactorInteger[n]],2];
|
||||
Select[Range[2, 10000], smithQ]
|
||||
28
Task/Smith-numbers/Miranda/smith-numbers.miranda
Normal file
28
Task/Smith-numbers/Miranda/smith-numbers.miranda
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
main :: [sys_message]
|
||||
main = [Stdout (table 5 16 taskOutput),
|
||||
Stdout ("Found " ++ show (#taskOutput) ++ " Smith numbers.\n")]
|
||||
where taskOutput = takewhile (<= 10000) smiths
|
||||
|
||||
table :: num->num->[num]->[char]
|
||||
table cw w ns = lay (map concat (split (map fmt ns)))
|
||||
where split [] = []
|
||||
split ls = take w ls : split (drop w ls)
|
||||
fmt n = reverse (take cw ((reverse (shownum n)) ++ repeat ' '))
|
||||
|
||||
smiths :: [num]
|
||||
smiths = filter smith [1..]
|
||||
|
||||
smith :: num->bool
|
||||
smith n = (~ prime) & digsum n = sum (map digsum facs)
|
||||
where facs = factors n
|
||||
prime = #facs <= 1
|
||||
|
||||
digsum :: num->num
|
||||
digsum 0 = 0
|
||||
digsum n = n mod 10 + digsum (n div 10)
|
||||
|
||||
factors :: num->[num]
|
||||
factors = f [] 2
|
||||
where f acc d n = acc, if d>n
|
||||
= f (d:acc) d (n div d), if n mod d = 0
|
||||
= f acc (d+1) n, otherwise
|
||||
60
Task/Smith-numbers/Modula-2/smith-numbers.mod2
Normal file
60
Task/Smith-numbers/Modula-2/smith-numbers.mod2
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
MODULE SmithNumbers;
|
||||
FROM FormatString IMPORT FormatString;
|
||||
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
|
||||
|
||||
PROCEDURE SumDigits(n : INTEGER) : INTEGER;
|
||||
VAR sum : INTEGER;
|
||||
BEGIN
|
||||
sum := 0;
|
||||
WHILE n > 0 DO
|
||||
sum := sum + (n MOD 10);
|
||||
n := n DIV 10;
|
||||
END;
|
||||
RETURN sum;
|
||||
END SumDigits;
|
||||
|
||||
VAR
|
||||
n,i,j,fc,sum,rc : INTEGER;
|
||||
buf : ARRAY[0..63] OF CHAR;
|
||||
BEGIN
|
||||
rc := 0;
|
||||
FOR i:=1 TO 10000 DO
|
||||
n := i;
|
||||
fc := 0;
|
||||
sum := SumDigits(n);
|
||||
|
||||
j := 2;
|
||||
WHILE n MOD j = 0 DO
|
||||
INC(fc);
|
||||
sum := sum - SumDigits(j);
|
||||
n := n DIV j;
|
||||
END;
|
||||
|
||||
j := 3;
|
||||
WHILE j*j<=n DO
|
||||
WHILE n MOD j = 0 DO
|
||||
INC(fc);
|
||||
sum := sum - SumDigits(j);
|
||||
n := n DIV j;
|
||||
END;
|
||||
INC(j,2);
|
||||
END;
|
||||
|
||||
IF n#1 THEN
|
||||
INC(fc);
|
||||
sum := sum - SumDigits(n);
|
||||
END;
|
||||
|
||||
IF (fc>1) AND (sum=0) THEN
|
||||
FormatString("%4i ", buf, i);
|
||||
WriteString(buf);
|
||||
INC(rc);
|
||||
IF rc=10 THEN
|
||||
rc := 0;
|
||||
WriteLn;
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
|
||||
ReadChar;
|
||||
END SmithNumbers.
|
||||
40
Task/Smith-numbers/Nim/smith-numbers.nim
Normal file
40
Task/Smith-numbers/Nim/smith-numbers.nim
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import strformat
|
||||
|
||||
func primeFactors(n: int): seq[int] =
|
||||
result = newSeq[int]()
|
||||
var n = n
|
||||
var i = 2
|
||||
while n mod i == 0:
|
||||
result.add(i)
|
||||
n = n div i
|
||||
i = 3
|
||||
while i * i <= n:
|
||||
while n mod i == 0:
|
||||
result.add(i)
|
||||
n = n div i
|
||||
inc i, 2
|
||||
if n != 1:
|
||||
result.add(n)
|
||||
|
||||
func sumDigits(n: int): int =
|
||||
var n = n
|
||||
var sum = 0
|
||||
while n > 0:
|
||||
inc sum, n mod 10
|
||||
n = n div 10
|
||||
sum
|
||||
|
||||
var cnt = 0
|
||||
for n in 1..10_000:
|
||||
var factors = primeFactors(n)
|
||||
if factors.len > 1:
|
||||
var sum = sumDigits(n)
|
||||
for f in factors:
|
||||
dec sum, sumDigits(f)
|
||||
if sum == 0:
|
||||
stdout.write(&"{n:4} ")
|
||||
inc cnt
|
||||
if cnt == 10:
|
||||
cnt = 0
|
||||
stdout.write("\n")
|
||||
echo()
|
||||
50
Task/Smith-numbers/Objeck/smith-numbers.objeck
Normal file
50
Task/Smith-numbers/Objeck/smith-numbers.objeck
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
use Collection;
|
||||
|
||||
class Test {
|
||||
function : Main(args : String[]) ~ Nil {
|
||||
for(n := 1; n < 10000; n+=1;) {
|
||||
factors := PrimeFactors(n);
|
||||
if(factors->Size() > 1) {
|
||||
sum := SumDigits(n);
|
||||
each(i : factors) {
|
||||
sum -= SumDigits(factors->Get(i));
|
||||
};
|
||||
|
||||
if(sum = 0) {
|
||||
n->PrintLine();
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function : PrimeFactors(n : Int) ~ IntVector {
|
||||
result := IntVector->New();
|
||||
|
||||
for(i := 2; n % i = 0; n /= i;) {
|
||||
result->AddBack(i);
|
||||
};
|
||||
|
||||
for(i := 3; i * i <= n; i += 2;) {
|
||||
while(n % i = 0) {
|
||||
result->AddBack(i);
|
||||
n /= i;
|
||||
};
|
||||
};
|
||||
|
||||
if(n <> 1) {
|
||||
result->AddBack(n);
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function : SumDigits(n : Int) ~ Int {
|
||||
sum := 0;
|
||||
while(n > 0) {
|
||||
sum += (n % 10);
|
||||
n /= 10;
|
||||
};
|
||||
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
2
Task/Smith-numbers/PARI-GP/smith-numbers-1.parigp
Normal file
2
Task/Smith-numbers/PARI-GP/smith-numbers-1.parigp
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
isSmith(n)=my(f=factor(n)); if(#f~==1 && f[1,2]==1, return(0)); sum(i=1, #f~, sumdigits(f[i, 1])*f[i, 2]) == sumdigits(n);
|
||||
select(isSmith, [1..9999])
|
||||
1
Task/Smith-numbers/PARI-GP/smith-numbers-2.parigp
Normal file
1
Task/Smith-numbers/PARI-GP/smith-numbers-2.parigp
Normal file
|
|
@ -0,0 +1 @@
|
|||
forcomposite(n=4,9999, f=factor(n); if(#f~==1 && f[1,2]==1, next); if(sum(i=1, #f~, sumdigits(f[i, 1])*f[i, 2]) == sumdigits(n), print1(n" ")))
|
||||
1
Task/Smith-numbers/PARI-GP/smith-numbers-3.parigp
Normal file
1
Task/Smith-numbers/PARI-GP/smith-numbers-3.parigp
Normal file
|
|
@ -0,0 +1 @@
|
|||
forfactored(n=4,9999, f=n[2]; if(#f~==1 && f[1,2]==1, next); if(sum(i=1, #f~, sumdigits(f[i, 1])*f[i, 2]) == sumdigits(n[1]), print1(n[1]" ")))
|
||||
60
Task/Smith-numbers/PL-I/smith-numbers.pli
Normal file
60
Task/Smith-numbers/PL-I/smith-numbers.pli
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
smith: procedure options(main);
|
||||
/* find the digit sum of N */
|
||||
digitSum: procedure(nn) returns(fixed);
|
||||
declare (n, nn, s) fixed;
|
||||
s = 0;
|
||||
do n=nn repeat(n/10) while(n>0);
|
||||
s = s + mod(n,10);
|
||||
end;
|
||||
return(s);
|
||||
end digitSum;
|
||||
|
||||
/* find and count factors of N */
|
||||
factors: procedure(nn, facs) returns(fixed);
|
||||
declare (n, nn, cnt, fac, facs(16)) fixed;
|
||||
cnt = 0;
|
||||
if nn<=1 then return(0);
|
||||
|
||||
/* factors of two */
|
||||
do n=nn repeat(n/2) while(mod(n,2)=0);
|
||||
cnt = cnt + 1;
|
||||
facs(cnt) = 2;
|
||||
end;
|
||||
|
||||
/* take out odd factors */
|
||||
do fac=3 repeat(fac+2) while(fac <= n);
|
||||
do n=n repeat(n/fac) while(mod(n,fac) = 0);
|
||||
cnt = cnt + 1;
|
||||
facs(cnt) = fac;
|
||||
end;
|
||||
end;
|
||||
|
||||
return(cnt);
|
||||
end factors;
|
||||
|
||||
/* see if a number is a Smith number */
|
||||
smith: procedure(n) returns(bit);
|
||||
declare (n, nfacs, facsum, i, facs(16)) fixed;
|
||||
nfacs = factors(n, facs);
|
||||
if nfacs <= 1 then
|
||||
return('0'b); /* primes are not Smith numbers */
|
||||
|
||||
facsum = 0;
|
||||
do i=1 to nfacs;
|
||||
facsum = facsum + digitSum(facs(i));
|
||||
end;
|
||||
return(facsum = digitSum(n));
|
||||
end smith;
|
||||
|
||||
/* print all Smith numbers up to 10000 */
|
||||
declare (i, cnt) fixed;
|
||||
cnt = 0;
|
||||
do i=2 to 9999;
|
||||
if smith(i) then do;
|
||||
put edit(i) (F(5));
|
||||
cnt = cnt + 1;
|
||||
if mod(cnt,16) = 0 then put skip;
|
||||
end;
|
||||
end;
|
||||
put skip list('Found', cnt, 'Smith numbers.');
|
||||
end smith;
|
||||
90
Task/Smith-numbers/PL-M/smith-numbers.plm
Normal file
90
Task/Smith-numbers/PL-M/smith-numbers.plm
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
100H:
|
||||
|
||||
/* CP/M BDOS FUNCTIONS */
|
||||
BDOS: PROCEDURE (F,A); DECLARE F BYTE, A ADDRESS; GO TO 5; END BDOS;
|
||||
EXIT: PROCEDURE; GO TO 0; END EXIT;
|
||||
PRINT: PROCEDURE (S); DECLARE S ADDRESS; CALL BDOS(9,S); END PRINT;
|
||||
|
||||
/* PRINT NUMBER */
|
||||
PR$NUM: PROCEDURE (N);
|
||||
DECLARE S (6) BYTE INITIAL (' $');
|
||||
DECLARE N ADDRESS, I BYTE;
|
||||
I = 5;
|
||||
DIGIT: S(I := I-1) = '0' + N MOD 10;
|
||||
IF (N := N / 10) > 0 THEN GO TO DIGIT;
|
||||
DO WHILE I>0;
|
||||
S(I := I-1) =' ';
|
||||
END;
|
||||
CALL PRINT(.S);
|
||||
END PR$NUM;
|
||||
|
||||
/* SUM OF DIGITS OF N */
|
||||
DIGIT$SUM: PROCEDURE (N) BYTE;
|
||||
DECLARE N ADDRESS, SUM BYTE;
|
||||
SUM = 0;
|
||||
DO WHILE N > 0;
|
||||
SUM = SUM + N MOD 10;
|
||||
N = N / 10;
|
||||
END;
|
||||
RETURN SUM;
|
||||
END DIGIT$SUM;
|
||||
|
||||
/* FIND AND COUNT FACTORS OF N */
|
||||
FACTORS: PROCEDURE (N, FACBUF) BYTE;
|
||||
DECLARE (N, FACBUF, FAC, FACS BASED FACBUF) ADDRESS;
|
||||
DECLARE COUNT BYTE;
|
||||
COUNT = 0;
|
||||
IF N <= 1 THEN RETURN 0;
|
||||
|
||||
/* TAKE OUT FACTORS OF TWO */
|
||||
DO WHILE NOT N;
|
||||
FACS(COUNT) = 2;
|
||||
COUNT = COUNT + 1;
|
||||
N = SHR(N, 1);
|
||||
END;
|
||||
|
||||
/* TAKE OUT ODD FACTORS */
|
||||
FAC = 3;
|
||||
DO WHILE FAC <= N;
|
||||
DO WHILE N MOD FAC = 0;
|
||||
N = N / FAC;
|
||||
FACS(COUNT) = FAC;
|
||||
COUNT = COUNT + 1;
|
||||
END;
|
||||
FAC = FAC + 2;
|
||||
END;
|
||||
|
||||
RETURN COUNT;
|
||||
END FACTORS;
|
||||
|
||||
/* SEE IF A NUMBER IS A SMITH NUMBER */
|
||||
SMITH: PROCEDURE (N) BYTE;
|
||||
DECLARE FACS (16) ADDRESS;
|
||||
DECLARE N ADDRESS, (F, NFACS, FACSUM) BYTE;
|
||||
IF (NFACS := FACTORS(N, .FACS)) <= 1 THEN
|
||||
RETURN 0; /* PRIMES ARE NOT SMITH NUMBERS */
|
||||
|
||||
FACSUM = 0;
|
||||
DO F = 0 TO NFACS-1;
|
||||
FACSUM = FACSUM + DIGIT$SUM(FACS(F));
|
||||
END;
|
||||
|
||||
RETURN FACSUM = DIGIT$SUM(N);
|
||||
END SMITH;
|
||||
|
||||
/* PRINT ALL SMITH NUMBERS UP TO 10.000 */
|
||||
DECLARE (I, COUNT) ADDRESS;
|
||||
COUNT = 0;
|
||||
DO I = 2 TO 9$999;
|
||||
IF SMITH(I) THEN DO;
|
||||
CALL PR$NUM(I);
|
||||
COUNT = COUNT + 1;
|
||||
IF (COUNT AND 0FH) = 0 THEN
|
||||
CALL PRINT(.(13,10,'$'));
|
||||
END;
|
||||
END;
|
||||
CALL PRINT(.(13,10,'FOUND $'));
|
||||
CALL PR$NUM(COUNT);
|
||||
CALL PRINT(.' SMITH NUMBERS.$');
|
||||
CALL EXIT;
|
||||
EOF
|
||||
282
Task/Smith-numbers/Pascal/smith-numbers.pas
Normal file
282
Task/Smith-numbers/Pascal/smith-numbers.pas
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
program SmithNum;
|
||||
{$IFDEF FPC}
|
||||
{$MODE objFPC} //result and useful for x64
|
||||
{$CODEALIGN PROC=64}
|
||||
{$ENDIF}
|
||||
uses
|
||||
sysutils;
|
||||
type
|
||||
tdigit = byte;
|
||||
tSum = LongInt;
|
||||
const
|
||||
base = 10;
|
||||
//maxDigitCnt *(base-1) <= High(tSum)
|
||||
//maxDigitCnt <= High(tSum) DIV (base-1);
|
||||
maxDigitCnt = 16;
|
||||
|
||||
StartPrimNo = 6;
|
||||
csegsieveSIze = 2*3*5*7*11*13;//prime 0..5
|
||||
type
|
||||
tDgtSum = record
|
||||
dgtNum : LongInt;
|
||||
dgtSum : tSum;
|
||||
dgts : array[0..maxDigitCnt-1] of tdigit;
|
||||
end;
|
||||
tNumFactype = word;
|
||||
tnumFactor = record
|
||||
numfacCnt: tNumFactype;
|
||||
numfacts : array[1..15] of tNumFactype;
|
||||
end;
|
||||
tpnumFactor= ^tnumFactor;
|
||||
|
||||
tsieveprim = record
|
||||
spPrim : Word;
|
||||
spDgtsum : Word;
|
||||
spOffset : LongWord;
|
||||
end;
|
||||
tpsieveprim = ^tsieveprim;
|
||||
|
||||
tsievePrimarr = array[0..6542-1] of tsieveprim;
|
||||
tsegmSieve = array[1..csegsieveSIze] of tnumFactor;
|
||||
|
||||
var
|
||||
Primarr:tsievePrimarr;
|
||||
copySieve,
|
||||
actSieve : tsegmSieve;
|
||||
PrimDgtSum :tDgtSum;
|
||||
PrimCnt : NativeInt;
|
||||
|
||||
function IncDgtSum(var ds:tDgtSum):boolean;
|
||||
//add 1 to dgts and corrects sum of Digits
|
||||
//return if overflow happens
|
||||
var
|
||||
i : NativeInt;
|
||||
Begin
|
||||
i := High(ds.dgts);
|
||||
inc(ds.dgtNum);
|
||||
repeat
|
||||
IF ds.dgts[i] < Base-1 then
|
||||
//add one and done
|
||||
Begin
|
||||
inc(ds.dgts[i]);
|
||||
inc(ds.dgtSum);
|
||||
BREAK;
|
||||
end
|
||||
else
|
||||
Begin
|
||||
ds.dgts[i] := 0;
|
||||
dec(ds.dgtSum,Base-1);
|
||||
end;
|
||||
dec(i);
|
||||
until i < Low(ds.dgts);
|
||||
result := i < Low(ds.dgts)
|
||||
end;
|
||||
|
||||
procedure OutDgtSum(const ds:tDgtSum);
|
||||
var
|
||||
i : NativeInt;
|
||||
Begin
|
||||
i := Low(ds.dgts);
|
||||
repeat
|
||||
write(ds.dgts[i]:3);
|
||||
inc(i);
|
||||
until i > High(ds.dgts);
|
||||
writeln(' sum of digits : ',ds.dgtSum:3);
|
||||
end;
|
||||
|
||||
procedure OutSieve(var s:tsegmSieve);
|
||||
var
|
||||
i,j : NativeInt;
|
||||
Begin
|
||||
For i := Low(s) to High(s) do
|
||||
with s[i] do
|
||||
Begin
|
||||
write(i:6,numfacCnt:4);
|
||||
For j := 1 to numfacCnt do
|
||||
write(numFacts[j]:5);
|
||||
writeln;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SieveForPrimes;
|
||||
// sieve for all primes < High(Word)
|
||||
var
|
||||
sieve : array of byte;
|
||||
pS : pByte;
|
||||
p,i : NativeInt;
|
||||
Begin
|
||||
setlength(sieve,High(Word));
|
||||
Fillchar(sieve[Low(sieve)],length(sieve),#0);
|
||||
pS:= @sieve[0]; //zero based
|
||||
dec(pS);// make it one based
|
||||
//sieve
|
||||
p := 2;
|
||||
repeat
|
||||
i := p*p;
|
||||
IF i> High(Word) then
|
||||
BREAK;
|
||||
repeat pS[i] := 1; inc(i,p); until i > High(Word);
|
||||
repeat inc(p) until pS[p] = 0;
|
||||
until false;
|
||||
//now fill array of primes
|
||||
fillchar(PrimDgtSum,SizeOf(PrimDgtSum),#0);
|
||||
IncDgtSum(PrimDgtSum);//1
|
||||
i := 0;
|
||||
For p := 2 to High(Word) do
|
||||
Begin
|
||||
IncDgtSum(PrimDgtSum);
|
||||
if pS[p] = 0 then
|
||||
Begin
|
||||
with PrimArr[i] do
|
||||
Begin
|
||||
spOffset := 2*p;//start at 2*prime
|
||||
spPrim := p;
|
||||
spDgtsum := PrimDgtSum.dgtSum;
|
||||
end;
|
||||
inc(i);
|
||||
end;
|
||||
end;
|
||||
PrimCnt := i-1;
|
||||
end;
|
||||
|
||||
procedure MarkWithPrime(SpIdx:NativeInt;var sf:tsegmSieve);
|
||||
var
|
||||
i : NativeInt;
|
||||
pSf :^tnumFactor;
|
||||
MarkPrime : NativeInt;
|
||||
Begin
|
||||
with Primarr[SpIdx] do
|
||||
Begin
|
||||
MarkPrime := spPrim;
|
||||
i := spOffSet;
|
||||
IF i <= csegsieveSize then
|
||||
Begin
|
||||
pSf := @sf[i];
|
||||
repeat
|
||||
pSf^.numFacts[pSf^.numfacCnt+1] := SpIdx;
|
||||
inc(pSf^.numfacCnt);
|
||||
inc(pSf,MarkPrime);
|
||||
inc(i,MarkPrime);
|
||||
until i > csegsieveSize;
|
||||
end;
|
||||
spOffset := i-csegsieveSize;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure InitcopySieve(var cs:tsegmSieve);
|
||||
var
|
||||
pr: NativeInt;
|
||||
Begin
|
||||
fillchar(cs[Low(cs)],sizeOf(cs),#0);
|
||||
For Pr := 0 to 5 do
|
||||
Begin
|
||||
with Primarr[pr] do
|
||||
spOffset := spPrim;//mark the prime too
|
||||
MarkWithPrime(pr,cs);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure MarkNextSieve(var s:tsegmSieve);
|
||||
var
|
||||
idx: NativeInt;
|
||||
Begin
|
||||
s:= copySieve;
|
||||
For idx := StartPrimNo to PrimCnt do
|
||||
MarkWithPrime(idx,s);
|
||||
end;
|
||||
|
||||
function DgtSumInt(n: NativeUInt):NativeUInt;
|
||||
var
|
||||
r : NativeUInt;
|
||||
Begin
|
||||
result := 0;
|
||||
repeat
|
||||
r := n div base;
|
||||
inc(result,n-base*r);
|
||||
n := r
|
||||
until r = 0;
|
||||
end;
|
||||
|
||||
{function DgtSumOfFac(pN: tpnumFactor;dgtNo:tDgtSum):boolean;}
|
||||
function TestSmithNum(pN: tpnumFactor;dgtNo:tDgtSum):boolean;
|
||||
var
|
||||
i,k,r,dgtSumI,dgtSumTarget : NativeUInt;
|
||||
pSp:tpsieveprim;
|
||||
pNumFact : ^tNumFactype;
|
||||
Begin
|
||||
i := dgtNo.dgtNum;
|
||||
dgtSumTarget :=dgtNo.dgtSum;
|
||||
|
||||
dgtSumI := 0;
|
||||
with pN^ do
|
||||
Begin
|
||||
k := numfacCnt;
|
||||
pNumFact := @numfacts[k];
|
||||
end;
|
||||
|
||||
For k := k-1 downto 0 do
|
||||
Begin
|
||||
pSp := @PrimArr[pNumFact^];
|
||||
r := i DIV pSp^.spPrim;
|
||||
repeat
|
||||
i := r;
|
||||
r := r DIV pSp^.spPrim;
|
||||
inc(dgtSumI,pSp^.spDgtsum);
|
||||
until (i - r* pSp^.spPrim) <> 0;
|
||||
IF dgtSumI > dgtSumTarget then
|
||||
Begin
|
||||
result := false;
|
||||
EXIT;
|
||||
end;
|
||||
dec(pNumFact);
|
||||
end;
|
||||
If i <> 1 then
|
||||
inc(dgtSumI,DgtSumInt(i));
|
||||
result := dgtSumI = dgtSumTarget
|
||||
end;
|
||||
|
||||
function CheckSmithNo(var s:tsegmSieve;var dgtNo:tDgtSum;Lmt:NativeInt=csegsieveSIze):NativeUInt;
|
||||
var
|
||||
pNumFac : tpNumFactor;
|
||||
i : NativeInt;
|
||||
Begin
|
||||
result := 0;
|
||||
i := low(s);
|
||||
pNumFac := @s[i];
|
||||
For i := i to lmt do
|
||||
Begin
|
||||
incDgtSum(dgtNo);
|
||||
IF pNumFac^.numfacCnt<> 0 then
|
||||
IF TestSmithNum(pNumFac,dgtNo) then
|
||||
Begin
|
||||
inc(result);
|
||||
//Mark as smith number
|
||||
inc(pNumFac^.numfacCnt,1 shl 15);
|
||||
end;
|
||||
inc(pNumFac);
|
||||
end;
|
||||
end;
|
||||
|
||||
const
|
||||
limit = 100*1000*1000;
|
||||
var
|
||||
actualNo :tDgtSum;
|
||||
i,s : NativeInt;
|
||||
Begin
|
||||
SieveForPrimes;
|
||||
InitcopySieve(copySieve);
|
||||
i := 1;
|
||||
s:= -6;//- 2,3,5,7,11,13
|
||||
|
||||
fillchar(actualNo,SizeOf(actualNo),#0);
|
||||
while i < Limit-csegsieveSize do
|
||||
Begin
|
||||
MarkNextSieve(actSieve);
|
||||
inc(s,CheckSmithNo(actSieve,actualNo));
|
||||
inc(i, csegsieveSize);
|
||||
end;
|
||||
//check the rest
|
||||
MarkNextSieve(actSieve);
|
||||
inc(s,CheckSmithNo(actSieve,actualNo,Limit-i+1));
|
||||
write(s:8,' smith-numbers up to ',actualNo.dgtnum:10);
|
||||
end.
|
||||
7
Task/Smith-numbers/Perl/smith-numbers-1.pl
Normal file
7
Task/Smith-numbers/Perl/smith-numbers-1.pl
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
use ntheory qw/:all/;
|
||||
my @smith;
|
||||
forcomposites {
|
||||
push @smith, $_ if sumdigits($_) == sumdigits(join("",factor($_)));
|
||||
} 10000-1;
|
||||
say scalar(@smith), " Smith numbers below 10000.";
|
||||
say "@smith";
|
||||
4
Task/Smith-numbers/Perl/smith-numbers-2.pl
Normal file
4
Task/Smith-numbers/Perl/smith-numbers-2.pl
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
use ntheory ":all";
|
||||
my $t=0;
|
||||
forfactored { $t++ if @_ > 1 && sumdigits($_) == sumdigits(join "",@_); } 10**8;
|
||||
say $t;
|
||||
22
Task/Smith-numbers/Phix/smith-numbers.phix
Normal file
22
Task/Smith-numbers/Phix/smith-numbers.phix
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">sum_digits</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">=</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">base</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">base</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">smith</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">prime_factors</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">sp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sum_digits</span><span style="color: #0000FF;">)),</span>
|
||||
<span style="color: #000000;">sn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sum_digits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">sn</span><span style="color: #0000FF;">=</span><span style="color: #000000;">sp</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">filter</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10000</span><span style="color: #0000FF;">),</span><span style="color: #000000;">smith</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d smith numbers found: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">),</span><span style="color: #008000;">", "</span><span style="color: #0000FF;">)})</span>
|
||||
<!--
|
||||
22
Task/Smith-numbers/PicoLisp/smith-numbers.l
Normal file
22
Task/Smith-numbers/PicoLisp/smith-numbers.l
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
(de factor (N)
|
||||
(make
|
||||
(let (D 2 L (1 2 2 . (4 2 4 2 4 6 2 6 .)) M (sqrt N))
|
||||
(while (>= M D)
|
||||
(if (=0 (% N D))
|
||||
(setq M (sqrt (setq N (/ N (link D)))))
|
||||
(inc 'D (pop 'L)) ) )
|
||||
(link N) ) ) )
|
||||
(de sumdigits (N)
|
||||
(sum format (chop N)) )
|
||||
(de smith (X)
|
||||
(make
|
||||
(for N X
|
||||
(let R (factor N)
|
||||
(and
|
||||
(cdr R)
|
||||
(= (sum sumdigits R) (sumdigits N))
|
||||
(link N) ) ) ) ) )
|
||||
(let L (smith 10000)
|
||||
(println 'first-10 (head 10 L))
|
||||
(println 'last-10 (tail 10 L))
|
||||
(println 'all (length L)) )
|
||||
81
Task/Smith-numbers/PureBasic/smith-numbers.basic
Normal file
81
Task/Smith-numbers/PureBasic/smith-numbers.basic
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
DisableDebugger
|
||||
#ECHO=#True ; #True: Print all results
|
||||
Global NewList f.i()
|
||||
|
||||
Procedure.i ePotenz(Wert.i)
|
||||
Define.i var=Wert, i
|
||||
While var
|
||||
i+1
|
||||
var/10
|
||||
Wend
|
||||
ProcedureReturn i
|
||||
EndProcedure
|
||||
|
||||
Procedure.i n_Element(Wert.i,Stelle.i=1)
|
||||
If Stelle>0
|
||||
ProcedureReturn (Wert%Int(Pow(10,Stelle))-Wert%Int(Pow(10,Stelle-1)))/Int(Pow(10,Stelle-1))
|
||||
Else
|
||||
ProcedureReturn 0
|
||||
EndIf
|
||||
EndProcedure
|
||||
|
||||
Procedure.i qSumma(Wert.i)
|
||||
Define.i sum, pos
|
||||
For pos=1 To ePotenz(Wert)
|
||||
sum+ n_Element(Wert,pos)
|
||||
Next pos
|
||||
ProcedureReturn sum
|
||||
EndProcedure
|
||||
|
||||
Procedure.b IsPrime(n.i)
|
||||
Define.i i=5
|
||||
If n<2 : ProcedureReturn #False : EndIf
|
||||
If n%2=0 : ProcedureReturn Bool(n=2) : EndIf
|
||||
If n%3=0 : ProcedureReturn Bool(n=3) : EndIf
|
||||
While i*i<=n
|
||||
If n%i=0 : ProcedureReturn #False : EndIf
|
||||
i+2
|
||||
If n%i=0 : ProcedureReturn #False : EndIf
|
||||
i+4
|
||||
Wend
|
||||
ProcedureReturn #True
|
||||
EndProcedure
|
||||
|
||||
Procedure PFZ(n.i,pf.i=2)
|
||||
If n>1 And n<>pf
|
||||
If n%pf=0
|
||||
AddElement(f()) : f()=pf
|
||||
PFZ(n/pf,pf)
|
||||
Else
|
||||
While Not IsPrime(pf+1) : pf+1 : Wend
|
||||
PFZ(n,pf+1)
|
||||
EndIf
|
||||
ElseIf n=pf
|
||||
AddElement(f()) : f()=pf
|
||||
EndIf
|
||||
EndProcedure
|
||||
|
||||
OpenConsole("Smith numbers")
|
||||
;upto=100 : sn=0 : Gosub Smith_loop
|
||||
;upto=1000 : sn=0 : Gosub Smith_loop
|
||||
upto=10000 : sn=0 : Gosub Smith_loop
|
||||
Input()
|
||||
End
|
||||
|
||||
Smith_loop:
|
||||
For i=2 To upto
|
||||
ClearList(f()) : qs=0
|
||||
PFZ(i)
|
||||
CompilerIf #ECHO : Print(Str(i)+~": \t") : CompilerEndIf
|
||||
ForEach f()
|
||||
CompilerIf #ECHO : Print(Str(F())+~"\t") : CompilerEndIf
|
||||
qs+qSumma(f())
|
||||
Next
|
||||
If ListSize(f())>1 And qSumma(i)=qs
|
||||
CompilerIf #ECHO : Print("SMITH-NUMBER") : CompilerEndIf
|
||||
sn+1
|
||||
EndIf
|
||||
CompilerIf #ECHO : PrintN("") : CompilerEndIf
|
||||
Next
|
||||
Print(~"\n"+Str(sn)+" Smith number up to "+Str(upto))
|
||||
Return
|
||||
48
Task/Smith-numbers/Python/smith-numbers-1.py
Normal file
48
Task/Smith-numbers/Python/smith-numbers-1.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
from sys import stdout
|
||||
|
||||
|
||||
def factors(n):
|
||||
rt = []
|
||||
f = 2
|
||||
if n == 1:
|
||||
rt.append(1);
|
||||
else:
|
||||
while 1:
|
||||
if 0 == ( n % f ):
|
||||
rt.append(f);
|
||||
n //= f
|
||||
if n == 1:
|
||||
return rt
|
||||
else:
|
||||
f += 1
|
||||
return rt
|
||||
|
||||
|
||||
def sum_digits(n):
|
||||
sum = 0
|
||||
while n > 0:
|
||||
m = n % 10
|
||||
sum += m
|
||||
n -= m
|
||||
n //= 10
|
||||
|
||||
return sum
|
||||
|
||||
|
||||
def add_all_digits(lst):
|
||||
sum = 0
|
||||
for i in range (len(lst)):
|
||||
sum += sum_digits(lst[i])
|
||||
|
||||
return sum
|
||||
|
||||
|
||||
def list_smith_numbers(cnt):
|
||||
for i in range(4, cnt):
|
||||
fac = factors(i)
|
||||
if len(fac) > 1:
|
||||
if sum_digits(i) == add_all_digits(fac):
|
||||
stdout.write("{0} ".format(i) )
|
||||
|
||||
# entry point
|
||||
list_smith_numbers(10_000)
|
||||
111
Task/Smith-numbers/Python/smith-numbers-2.py
Normal file
111
Task/Smith-numbers/Python/smith-numbers-2.py
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
'''Smith numbers'''
|
||||
|
||||
from itertools import dropwhile
|
||||
from functools import reduce
|
||||
from math import floor, sqrt
|
||||
|
||||
|
||||
# isSmith :: Int -> Bool
|
||||
def isSmith(n):
|
||||
'''True if n is a Smith number.'''
|
||||
pfs = primeFactors(n)
|
||||
return (1 < len(pfs) or n != pfs[0]) and (
|
||||
sumDigits(n) == reduce(
|
||||
lambda a, x: a + sumDigits(x),
|
||||
pfs, 0
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# primeFactors :: Int -> [Int]
|
||||
def primeFactors(x):
|
||||
'''List of prime factors of x'''
|
||||
def go(n):
|
||||
fs = list(dropwhile(
|
||||
mod(n),
|
||||
range(2, 1 + floor(sqrt(n)))
|
||||
))[0:1]
|
||||
|
||||
return fs + go(floor(n / fs[0])) if fs else [n]
|
||||
return go(x)
|
||||
|
||||
|
||||
# sumDigits :: Int -> Int
|
||||
def sumDigits(n):
|
||||
'''The sum of the decimal digits of n'''
|
||||
def f(x):
|
||||
return Just(divmod(x, 10)) if x else Nothing()
|
||||
return sum(unfoldl(f)(n))
|
||||
|
||||
|
||||
# TEST ----------------------------------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''Count and samples of Smith numbers below 10k'''
|
||||
|
||||
lowSmiths = [x for x in range(2, 10000) if isSmith(x)]
|
||||
lowSmithCount = len(lowSmiths)
|
||||
|
||||
print('\n'.join([
|
||||
'Count of Smith Numbers below 10k:',
|
||||
str(lowSmithCount),
|
||||
'\nFirst 15 Smith Numbers:',
|
||||
' '.join(str(x) for x in lowSmiths[0:15]),
|
||||
'\nLast 12 Smith Numbers below 10000:',
|
||||
' '.join(str(x) for x in lowSmiths[lowSmithCount - 12:])
|
||||
]))
|
||||
|
||||
|
||||
# GENERIC -------------------------------------------------
|
||||
|
||||
# Just :: a -> Maybe a
|
||||
def Just(x):
|
||||
'''Constructor for an inhabited Maybe (option type) value.
|
||||
Wrapper containing the result of a computation.
|
||||
'''
|
||||
return {'type': 'Maybe', 'Nothing': False, 'Just': x}
|
||||
|
||||
|
||||
# Nothing :: Maybe a
|
||||
def Nothing():
|
||||
'''Constructor for an empty Maybe (option type) value.
|
||||
Empty wrapper returned where a computation is not possible.
|
||||
'''
|
||||
return {'type': 'Maybe', 'Nothing': True}
|
||||
|
||||
|
||||
# mod :: Int -> Int -> Int
|
||||
def mod(n):
|
||||
'''n modulo d'''
|
||||
return lambda d: n % d
|
||||
|
||||
|
||||
# unfoldl(lambda x: Just(((x - 1), x)) if 0 != x else Nothing())(10)
|
||||
# -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
# unfoldl :: (b -> Maybe (b, a)) -> b -> [a]
|
||||
def unfoldl(f):
|
||||
'''Dual to reduce or foldl.
|
||||
Where these reduce a list to a summary value, unfoldl
|
||||
builds a list from a seed value.
|
||||
Where f returns Just(a, b), a is appended to the list,
|
||||
and the residual b is used as the argument for the next
|
||||
application of f.
|
||||
When f returns Nothing, the completed list is returned.
|
||||
'''
|
||||
def go(v):
|
||||
x, r = v, v
|
||||
xs = []
|
||||
while True:
|
||||
mb = f(x)
|
||||
if mb.get('Nothing'):
|
||||
return xs
|
||||
else:
|
||||
x, r = mb.get('Just')
|
||||
xs.insert(0, r)
|
||||
return xs
|
||||
return lambda x: go(x)
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
31
Task/Smith-numbers/REXX/smith-numbers-1.rexx
Normal file
31
Task/Smith-numbers/REXX/smith-numbers-1.rexx
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*REXX program finds (and maybe displays) Smith (or joke) numbers up to a given N.*/
|
||||
parse arg N . /*obtain optional argument from the CL.*/
|
||||
if N=='' | N=="," then N=10000 /*Not specified? Then use the default.*/
|
||||
tell= (N>0); N=abs(N) - 1 /*use the │N│ for computing (below).*/
|
||||
w=length(N) /*W: used for aligning Smith numbers. */
|
||||
#=0 /*#: Smith numbers found (so far). */
|
||||
@=; do j=4 to N; /*process almost all numbers up to N. */
|
||||
if sumD(j) \== sumfactr(j) then iterate /*Not a Smith number? Then ignore it.*/
|
||||
#=#+1 /*bump the Smith number counter. */
|
||||
if \tell then iterate /*Not showing the numbers? Keep looking*/
|
||||
@=@ right(j, w); if length(@)>199 then do; say substr(@, 2); @=; end
|
||||
end /*j*/ /* [↑] if N>0, then display Smith #s.*/
|
||||
|
||||
if @\=='' then say substr(@, 2) /*if any residual Smith #s, display 'em*/
|
||||
say /* [↓] display the number of Smith #s.*/
|
||||
say # ' Smith numbers found ≤ ' N"." /*display number of Smith numbers found*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
sumD: parse arg x 1 s 2; do d=2 for length(x)-1; s=s+substr(x,d,1); end; return s
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
sumFactr: procedure; parse arg z; $=0; f=0 /*obtain the Z number. */
|
||||
do while z//2==0; $=$+2; f=f+1; z=z% 2; end /*maybe add factor of 2*/
|
||||
do while z//3==0; $=$+3; f=f+1; z=z% 3; end /* " " " " 3*/
|
||||
/* ___*/
|
||||
do j=5 by 2 while j<=z & j*j<=n /*minimum of Z or √ N */
|
||||
if j//3==0 then iterate /*skip factors that ÷ 3*/
|
||||
do while z//j==0; f=f+1; $=$+sumD(j); z=z%j; end /*maybe reduce Z by J */
|
||||
end /*j*/ /* [↓] Z: what's left*/
|
||||
if z\==1 then do; f=f+1; $=$+sumD(z); end /*Residual? Then add Z*/
|
||||
if f<2 then return 0 /*Prime? Not a Smith#*/
|
||||
return $ /*else return sum digs.*/
|
||||
38
Task/Smith-numbers/REXX/smith-numbers-2.rexx
Normal file
38
Task/Smith-numbers/REXX/smith-numbers-2.rexx
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*REXX program finds (and maybe displays) Smith (or joke) numbers up to a given N.*/
|
||||
parse arg N . /*obtain optional argument from the CL.*/
|
||||
if N=='' | N=="," then N=10000 /*Not specified? Then use the default.*/
|
||||
tell= (N>0); N=abs(N) - 1 /*use the │N│ for computing (below).*/
|
||||
#=0 /*the number of Smith numbers (so far).*/
|
||||
w=length(N) /*W: used for aligning Smith numbers. */
|
||||
@=; do j=4 for max(0, N-3) /*process almost all numbers up to N. */
|
||||
if sumD(j) \== sumFactr(j) then iterate /*Not a Smith number? Then ignore it.*/
|
||||
#=#+1 /*bump the Smith number counter. */
|
||||
if \tell then iterate /*Not showing the numbers? Keep looking*/
|
||||
@=@ right(j, w); if length(@)>199 then do; say substr(@, 2); @=; end
|
||||
end /*j*/ /* [↑] if N>0, then display Smith #s.*/
|
||||
|
||||
if @\=='' then say substr(@, 2) /*if any residual Smith #s, display 'em*/
|
||||
say /* [↓] display the number of Smith #s.*/
|
||||
say # ' Smith numbers found ≤ ' max(0,N)"." /*display number of Smith numbers found*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
sumD: parse arg x 1 s 2; do d=2 for length(x)-1; s=s+substr(x,d,1); end; return s
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
sumFactr: procedure; parse arg z; $=0; f=0 /*obtain Z number (arg1).*/
|
||||
do while z// 2==0; $=$+ 2; f=f+1; z=z% 2; end /*maybe add factor of 2. */
|
||||
do while z// 3==0; $=$+ 3; f=f+1; z=z% 3; end /* " " " " 3. */
|
||||
do while z// 5==0; $=$+ 5; f=f+1; z=z% 5; end /* " " " " 5. */
|
||||
do while z// 7==0; $=$+ 7; f=f+1; z=z% 7; end /* " " " " 7. */
|
||||
t=z; r=0; q=1; do while q<=t; q=q*4; end /*R: will be the iSqrt(Z).*/
|
||||
do while q>1; q=q%4; _=t-r-q; r=r%2; if _>=0 then do; t=_; r=r+q; end
|
||||
end /*while q>1*/ /* [↑] compute int. SQRT(Z)*/
|
||||
|
||||
do j=11 by 6 to r while j<=z /*skip factors that are ÷ 3*/
|
||||
parse var j '' -1 _; if _\==5 then, /*is last dec. digit ¬a 5 ?*/
|
||||
do while z//j==0; f=f+1; $=$+sumD(j); z=z%j; end /*maybe reduce Z by J*/
|
||||
if _==3 then iterate; y=j+2
|
||||
do while z//y==0; f=f+1; $=$+sumD(y); z=z%y; end /*maybe reduce Z by Y*/
|
||||
end /*j*/ /* [↓] Z is what's left. */
|
||||
if z\==1 then do; f=f+1; $=$+sumD(z); end /*if a residual, then add Z*/
|
||||
if f<2 then return 0 /*Is prime? It's not Smith#*/
|
||||
return $ /*else, return sum of digs.*/
|
||||
27
Task/Smith-numbers/Racket/smith-numbers.rkt
Normal file
27
Task/Smith-numbers/Racket/smith-numbers.rkt
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#lang racket
|
||||
(require math/number-theory)
|
||||
|
||||
(define (sum-of-digits n)
|
||||
(let inr ((n n) (s 0))
|
||||
(if (zero? n) s (let-values (([q r] (quotient/remainder n 10))) (inr q (+ s r))))))
|
||||
|
||||
(define (smith-number? n)
|
||||
(and (not (prime? n))
|
||||
(= (sum-of-digits n)
|
||||
(for/sum ((pe (in-list (factorize n))))
|
||||
(* (cadr pe) (sum-of-digits (car pe)))))))
|
||||
|
||||
(module+ test
|
||||
(require rackunit)
|
||||
(check-equal? (sum-of-digits 0) 0)
|
||||
(check-equal? (sum-of-digits 33) 6)
|
||||
(check-equal? (sum-of-digits 30) 3)
|
||||
|
||||
(check-true (smith-number? 166)))
|
||||
|
||||
(module+ main
|
||||
(let loop ((ns (filter smith-number? (range 1 (add1 10000)))))
|
||||
(unless (null? ns)
|
||||
(let-values (([l r] (split-at ns (min (length ns) 15))))
|
||||
(displayln l)
|
||||
(loop r)))))
|
||||
29
Task/Smith-numbers/Raku/smith-numbers.raku
Normal file
29
Task/Smith-numbers/Raku/smith-numbers.raku
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
constant @primes = 2, |(3, 5, 7 ... *).grep: *.is-prime;
|
||||
|
||||
multi factors ( 1 ) { 1 }
|
||||
multi factors ( Int $remainder is copy ) {
|
||||
gather for @primes -> $factor {
|
||||
|
||||
# if remainder < factor², we're done
|
||||
if $factor * $factor > $remainder {
|
||||
take $remainder if $remainder > 1;
|
||||
last;
|
||||
}
|
||||
|
||||
# How many times can we divide by this prime?
|
||||
while $remainder %% $factor {
|
||||
take $factor;
|
||||
last if ($remainder div= $factor) === 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
# Code above here is verbatim from RC:Count_in_factors#Raku
|
||||
|
||||
sub is_smith_number ( Int $n ) {
|
||||
(!$n.is-prime) and ( [+] $n.comb ) == ( [+] factors($n).join.comb );
|
||||
}
|
||||
|
||||
my @s = grep &is_smith_number, 2 ..^ 10_000;
|
||||
say "{@s.elems} Smith numbers below 10_000";
|
||||
say 'First 10: ', @s[ ^10 ];
|
||||
say 'Last 10: ', @s[ *-10 .. * ];
|
||||
55
Task/Smith-numbers/Ring/smith-numbers.ring
Normal file
55
Task/Smith-numbers/Ring/smith-numbers.ring
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Project : Smith numbers
|
||||
|
||||
see "All the Smith Numbers < 1000 are:" + nl
|
||||
|
||||
for prime = 1 to 1000
|
||||
decmp = []
|
||||
sum1 = sumDigits(prime)
|
||||
decomp(prime)
|
||||
sum2 = 0
|
||||
if len(decmp)>1
|
||||
for n=1 to len(decmp)
|
||||
cstr = string(decmp[n])
|
||||
for m= 1 to len(cstr)
|
||||
sum2 = sum2 + number(cstr[m])
|
||||
next
|
||||
next
|
||||
ok
|
||||
if sum1 = sum2
|
||||
see "" + prime + " "
|
||||
ok
|
||||
next
|
||||
|
||||
func decomp nr
|
||||
for i = 1 to nr
|
||||
if isPrime(i) and nr % i = 0
|
||||
add(decmp, i)
|
||||
pr = i
|
||||
while true
|
||||
pr = pr * i
|
||||
if nr%pr = 0
|
||||
add(decmp, i)
|
||||
else
|
||||
exit
|
||||
ok
|
||||
end
|
||||
ok
|
||||
next
|
||||
|
||||
func isPrime num
|
||||
if (num <= 1) return 0 ok
|
||||
if (num % 2 = 0 and num != 2) return 0 ok
|
||||
for i = 3 to floor(num / 2) -1 step 2
|
||||
if (num % i = 0) return 0 ok
|
||||
next
|
||||
return 1
|
||||
|
||||
func sumDigits n
|
||||
sum = 0
|
||||
while n > 0.5
|
||||
m = floor(n / 10)
|
||||
digit = n - m * 10
|
||||
sum = sum + digit
|
||||
n = m
|
||||
end
|
||||
return sum
|
||||
16
Task/Smith-numbers/Ruby/smith-numbers.rb
Normal file
16
Task/Smith-numbers/Ruby/smith-numbers.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
require "prime"
|
||||
|
||||
class Integer
|
||||
|
||||
def smith?
|
||||
return false if prime?
|
||||
digits.sum == prime_division.map{|pr,n| pr.digits.sum * n}.sum
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
n = 10_000
|
||||
res = 1.upto(n).select(&:smith?)
|
||||
|
||||
puts "#{res.size} smith numbers below #{n}:
|
||||
#{res.first(5).join(", ")},... #{res.last(5).join(", ")}"
|
||||
28
Task/Smith-numbers/Rust/smith-numbers.rust
Normal file
28
Task/Smith-numbers/Rust/smith-numbers.rust
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
fn main () {
|
||||
//We just need the primes below 100
|
||||
let primes = vec![2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97];
|
||||
let mut solution = Vec::new();
|
||||
let mut number;
|
||||
for i in 4..10000 {
|
||||
//Factorize each number below 10.000
|
||||
let mut prime_factors = Vec::new();
|
||||
number = i;
|
||||
for j in &primes {
|
||||
while number % j == 0 {
|
||||
number = number / j;
|
||||
prime_factors.push(j);
|
||||
}
|
||||
if number == 1 { break; }
|
||||
}
|
||||
//Number is 1 (not a prime factor) if the factorization is complete or a prime bigger than 100
|
||||
if number != 1 { prime_factors.push(&number); }
|
||||
//Avoid the prime numbers
|
||||
if prime_factors.len() < 2 { continue; }
|
||||
//Check the smith number definition
|
||||
if prime_factors.iter().fold(0, |n,x| n + x.to_string().chars().map(|d| d.to_digit(10).unwrap()).fold(0, |n,x| n + x))
|
||||
== i.to_string().chars().map(|d| d.to_digit(10).unwrap()).fold(0, |n,x| n + x) {
|
||||
solution.push(i);
|
||||
}
|
||||
}
|
||||
println!("Smith numbers below 10000 ({}) : {:?}",solution.len(), solution);
|
||||
}
|
||||
42
Task/Smith-numbers/Scala/smith-numbers.scala
Normal file
42
Task/Smith-numbers/Scala/smith-numbers.scala
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
object SmithNumbers extends App {
|
||||
|
||||
def sumDigits(_n: Int): Int = {
|
||||
var n = _n
|
||||
var sum = 0
|
||||
while (n > 0) {
|
||||
sum += (n % 10)
|
||||
n /= 10
|
||||
}
|
||||
sum
|
||||
}
|
||||
|
||||
def primeFactors(_n: Int): List[Int] = {
|
||||
var n = _n
|
||||
val result = new collection.mutable.ListBuffer[Int]
|
||||
val i = 2
|
||||
while (n % i == 0) {
|
||||
result += i
|
||||
n /= i
|
||||
}
|
||||
var j = 3
|
||||
while (j * j <= n) {
|
||||
while (n % j == 0) {
|
||||
result += i
|
||||
n /= j
|
||||
}
|
||||
j += 2
|
||||
}
|
||||
if (n != 1) result += n
|
||||
result.toList
|
||||
}
|
||||
|
||||
for (n <- 1 until 10000) {
|
||||
val factors = primeFactors(n)
|
||||
if (factors.size > 1) {
|
||||
var sum = sumDigits(n)
|
||||
for (f <- factors) sum -= sumDigits(f)
|
||||
if (sum == 0) println(n)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
36
Task/Smith-numbers/Sidef/smith-numbers.sidef
Normal file
36
Task/Smith-numbers/Sidef/smith-numbers.sidef
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
var primes = Enumerator({ |callback|
|
||||
static primes = Hash()
|
||||
var p = 2
|
||||
loop {
|
||||
callback(p)
|
||||
p = (primes{p} := p.next_prime)
|
||||
}
|
||||
})
|
||||
|
||||
func factors(remainder) {
|
||||
|
||||
remainder == 1 && return([remainder])
|
||||
|
||||
gather {
|
||||
primes.each { |factor|
|
||||
if (factor*factor > remainder) {
|
||||
take(remainder) if (remainder > 1)
|
||||
break
|
||||
}
|
||||
|
||||
while (factor.divides(remainder)) {
|
||||
take(factor)
|
||||
break if ((remainder /= factor) == 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func is_smith_number(n) {
|
||||
!n.is_prime && (n.digits.sum == factors(n).join.to_i.digits.sum)
|
||||
}
|
||||
|
||||
var s = range(2, 10_000).grep { is_smith_number(_) }
|
||||
say "#{s.len} Smith numbers below 10_000"
|
||||
say "First 10: #{s.first(10)}"
|
||||
say "Last 10: #{s.last(10)}"
|
||||
73
Task/Smith-numbers/Stata/smith-numbers.stata
Normal file
73
Task/Smith-numbers/Stata/smith-numbers.stata
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
function factor(_n) {
|
||||
n = _n
|
||||
a = J(14, 2, .)
|
||||
i = 0
|
||||
if (mod(n, 2)==0) {
|
||||
j = 0
|
||||
while (mod(n, 2)==0) {
|
||||
j++
|
||||
n = n/2
|
||||
}
|
||||
i++
|
||||
a[i,1] = 2
|
||||
a[i,2] = j
|
||||
}
|
||||
for (k=3; k*k<=n; k=k+2) {
|
||||
if (mod(n, k)==0) {
|
||||
j = 0
|
||||
while (mod(n, k)==0) {
|
||||
j++
|
||||
n = n/k
|
||||
}
|
||||
i++
|
||||
a[i,1] = k
|
||||
a[i,2] = j
|
||||
}
|
||||
}
|
||||
if (n>1) {
|
||||
i++
|
||||
a[i,1] = n
|
||||
a[i,2] = 1
|
||||
}
|
||||
return(a[1::i,.])
|
||||
}
|
||||
|
||||
function sumdigits(_n) {
|
||||
n = _n
|
||||
for (s=0; n>0; n=floor(n/10)) s = s+mod(n,10)
|
||||
return(s)
|
||||
}
|
||||
|
||||
function smith(n) {
|
||||
a = J(n, 1, .)
|
||||
i = 0
|
||||
for (j=2; j<=n; j++) {
|
||||
f = factor(j)
|
||||
m = rows(f)
|
||||
if (m>1 | f[1,2]>1) {
|
||||
s = 0
|
||||
for (k=1; k<=m; k++) s = s+sumdigits(f[k,1])*f[k,2]
|
||||
if (s==sumdigits(j)) a[++i] = j
|
||||
}
|
||||
}
|
||||
return(a[1::i])
|
||||
}
|
||||
|
||||
a = smith(10000)
|
||||
n = rows(a)
|
||||
n
|
||||
376
|
||||
|
||||
a[1::10]'
|
||||
|
||||
1 2 3 4 5 6 7 8 9 10
|
||||
+-------------------------------------------------------------+
|
||||
1 | 4 22 27 58 85 94 121 166 202 265 |
|
||||
+-------------------------------------------------------------+
|
||||
|
||||
a[n-9::n]'
|
||||
|
||||
1 2 3 4 5 6 7 8 9 10
|
||||
+-----------------------------------------------------------------------+
|
||||
1 | 9843 9849 9861 9880 9895 9924 9942 9968 9975 9985 |
|
||||
+-----------------------------------------------------------------------+
|
||||
47
Task/Smith-numbers/Swift/smith-numbers.swift
Normal file
47
Task/Smith-numbers/Swift/smith-numbers.swift
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
extension BinaryInteger {
|
||||
@inlinable
|
||||
public var isSmith: Bool {
|
||||
guard self > 3 else {
|
||||
return false
|
||||
}
|
||||
|
||||
let primeFactors = primeDecomposition()
|
||||
|
||||
guard primeFactors.count != 1 else {
|
||||
return false
|
||||
}
|
||||
|
||||
return primeFactors.map({ $0.sumDigits() }).reduce(0, +) == sumDigits()
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func primeDecomposition() -> [Self] {
|
||||
guard self > 1 else { return [] }
|
||||
|
||||
func step(_ x: Self) -> Self {
|
||||
return 1 + (x << 2) - ((x >> 1) << 1)
|
||||
}
|
||||
|
||||
let maxQ = Self(Double(self).squareRoot())
|
||||
var d: Self = 1
|
||||
var q: Self = self & 1 == 0 ? 2 : 3
|
||||
|
||||
while q <= maxQ && self % q != 0 {
|
||||
q = step(d)
|
||||
d += 1
|
||||
}
|
||||
|
||||
return q <= maxQ ? [q] + (self / q).primeDecomposition() : [self]
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func sumDigits() -> Self {
|
||||
return String(self).lazy.map({ Self(Int(String($0))!) }).reduce(0, +)
|
||||
}
|
||||
}
|
||||
|
||||
let smiths = (0..<10_000).filter({ $0.isSmith })
|
||||
|
||||
print("Num Smith numbers below 10,000: \(smiths.count)")
|
||||
print("First 10 smith numbers: \(Array(smiths.prefix(10)))")
|
||||
print("Last 10 smith numbers below 10,000: \(Array(smiths.suffix(10)))")
|
||||
41
Task/Smith-numbers/Tcl/smith-numbers.tcl
Normal file
41
Task/Smith-numbers/Tcl/smith-numbers.tcl
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
proc factors {x} {
|
||||
# list the prime factors of x in ascending order
|
||||
set result [list]
|
||||
while {$x % 2 == 0} {
|
||||
lappend result 2
|
||||
set x [expr {$x / 2}]
|
||||
}
|
||||
for {set i 3} {$i*$i <= $x} {incr i 2} {
|
||||
while {$x % $i == 0} {
|
||||
lappend result $i
|
||||
set x [expr {$x / $i}]
|
||||
}
|
||||
}
|
||||
if {$x != 1} {lappend result $x}
|
||||
return $result
|
||||
}
|
||||
|
||||
proc digitsum {n} {
|
||||
::tcl::mathop::+ {*}[split $n ""]
|
||||
}
|
||||
|
||||
proc smith? {n} {
|
||||
set fs [factors $n]
|
||||
if {[llength $fs] == 1} {
|
||||
return false ;# $n is prime
|
||||
}
|
||||
expr {[digitsum $n] == [digitsum [join $fs ""]]}
|
||||
}
|
||||
proc range {n} {
|
||||
for {set i 1} {$i < $n} {incr i} {lappend result $i}
|
||||
return $result
|
||||
}
|
||||
|
||||
set smiths [lmap i [range 10000] {
|
||||
if {![smith? $i]} continue
|
||||
set i
|
||||
}]
|
||||
|
||||
puts [lrange $smiths 0 12]...
|
||||
puts ...[lrange $smiths end-12 end]
|
||||
puts "([llength $smiths] total)"
|
||||
83
Task/Smith-numbers/V-(Vlang)/smith-numbers.v
Normal file
83
Task/Smith-numbers/V-(Vlang)/smith-numbers.v
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
fn num_prime_factors(xx int) int {
|
||||
mut p := 2
|
||||
mut pf := 0
|
||||
mut x := xx
|
||||
if x == 1 {
|
||||
return 1
|
||||
}
|
||||
for {
|
||||
if (x % p) == 0 {
|
||||
pf++
|
||||
x /= p
|
||||
if x == 1 {
|
||||
return pf
|
||||
}
|
||||
} else {
|
||||
p++
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
fn prime_factors(xx int, mut arr []int) {
|
||||
mut p := 2
|
||||
mut pf := 0
|
||||
mut x := xx
|
||||
if x == 1 {
|
||||
arr[pf] = 1
|
||||
return
|
||||
}
|
||||
for {
|
||||
if (x % p) == 0 {
|
||||
arr[pf] = p
|
||||
pf++
|
||||
x /= p
|
||||
if x == 1 {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
p++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sum_digits(xx int) int {
|
||||
mut x := xx
|
||||
mut sum := 0
|
||||
for x != 0 {
|
||||
sum += x % 10
|
||||
x /= 10
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fn sum_factors(arr []int, size int) int {
|
||||
mut sum := 0
|
||||
for a := 0; a < size; a++ {
|
||||
sum += sum_digits(arr[a])
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fn list_all_smith_numbers(max_smith int) {
|
||||
mut arr := []int{}
|
||||
mut a := 0
|
||||
for a = 4; a < max_smith; a++ {
|
||||
numfactors := num_prime_factors(a)
|
||||
arr = []int{len: numfactors}
|
||||
if numfactors < 2 {
|
||||
continue
|
||||
}
|
||||
prime_factors(a, mut arr)
|
||||
if sum_digits(a) == sum_factors(arr, numfactors) {
|
||||
print("${a:4} ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
max_smith := 10000
|
||||
println("All the Smith Numbers less than $max_smith are:")
|
||||
list_all_smith_numbers(max_smith)
|
||||
println('')
|
||||
}
|
||||
24
Task/Smith-numbers/Wren/smith-numbers.wren
Normal file
24
Task/Smith-numbers/Wren/smith-numbers.wren
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import "/math" for Int
|
||||
import "/fmt" for Fmt
|
||||
import "/seq" for Lst
|
||||
|
||||
var sumDigits = Fn.new { |n|
|
||||
var sum = 0
|
||||
while (n > 0) {
|
||||
sum = sum + n%10
|
||||
n = (n/10).floor
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
var smiths = []
|
||||
System.print("The Smith numbers below 10,000 are:")
|
||||
for (i in 2...10000) {
|
||||
if (!Int.isPrime(i)) {
|
||||
var thisSum = sumDigits.call(i)
|
||||
var factors = Int.primeFactors(i)
|
||||
var factSum = factors.reduce(0) { |acc, f| acc + sumDigits.call(f) }
|
||||
if (thisSum == factSum) smiths.add(i)
|
||||
}
|
||||
}
|
||||
for (chunk in Lst.chunks(smiths, 16)) Fmt.print("$4d", chunk)
|
||||
32
Task/Smith-numbers/XPL0/smith-numbers.xpl0
Normal file
32
Task/Smith-numbers/XPL0/smith-numbers.xpl0
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
func SumDigits(N); \Return sum of digits in N
|
||||
int N, S;
|
||||
[S:= 0;
|
||||
repeat N:= N/10;
|
||||
S:= S+rem(0);
|
||||
until N=0;
|
||||
return S;
|
||||
];
|
||||
|
||||
func SumFactor(N); \Return sum of digits of factors of N
|
||||
int N0, N, F, S;
|
||||
[N:= N0; F:= 2; S:= 0;
|
||||
repeat if rem(N/F) = 0 then \found a factor
|
||||
[S:= S + SumDigits(F);
|
||||
N:= N/F;
|
||||
]
|
||||
else F:= F+1;
|
||||
until F > N;
|
||||
if F = N0 then return 0; \is prime
|
||||
return S;
|
||||
];
|
||||
|
||||
int C, N;
|
||||
[C:= 0;
|
||||
Format(5, 0);
|
||||
for N:= 0 to 10_000-1 do
|
||||
if SumDigits(N) = SumFactor(N) then
|
||||
[RlOut(0, float(N));
|
||||
C:= C+1;
|
||||
if rem(C/20) = 0 then CrLf(0);
|
||||
];
|
||||
]
|
||||
6
Task/Smith-numbers/Zkl/smith-numbers-1.zkl
Normal file
6
Task/Smith-numbers/Zkl/smith-numbers-1.zkl
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
fcn smithNumbers(N=0d10_000){ // -->(Smith numbers to N)
|
||||
[2..N].filter(fcn(n){
|
||||
(pfs:=primeFactors(n)).len()>1 and
|
||||
n.split().sum(0)==primeFactors(n).apply("split").flatten().sum(0)
|
||||
})
|
||||
}
|
||||
2
Task/Smith-numbers/Zkl/smith-numbers-2.zkl
Normal file
2
Task/Smith-numbers/Zkl/smith-numbers-2.zkl
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
sns:=smithNumbers();
|
||||
sns.toString(*).println(" ",sns.len()," numbers");
|
||||
Loading…
Add table
Add a link
Reference in a new issue