Sayfalar

5 Ocak 2017

Euler Projesi 211. Soru

Bölen Kare Toplamı

Herhangi bir n pozitif tamsayısı için, pozitif bölenlerinin kareleri toplamı σ2(n) ile gösterilsin. Örneğin,
σ2(10) = 1 + 4 + 25 + 100 = 130.
σ2(n) tamkare olmak üzere, 0 < n < 64,000,000 için tüm n sayılarının toplamını bulunuz.

Cevap: 1922364685

C++:
#include <stdio.h>
#include <math.h>


int main()  {

    int isprime[8096],primes[1028],A[8000],i,j,q,n,up,np;
    long long int S[8000],sum=0,mul,div,p,sq;
    
    for(i=0;i<8096;i++)  isprime[i]=1;
    isprime[0]=0;
    isprime[1]=0;
    np=0;
    for(i=2;i<8096;i++)  {
        if(isprime[i])  {
            for(j=i*i;j<8096;j+=i)  isprime[j]=0;
            primes[np]=i;
            np++;
        }
    }
    for(n=0;n<64000000;n+=8000)  {
        for(i=0;i<8000;i++)  A[i]=1;
        for(i=0;i<8000;i++)  S[i]=1;
        up=n+8000;
        for(i=0;primes[i]*primes[i]<=up;i++)  {
            p=primes[i];
            q=1;
            mul=1;
            while(q<=up/p)  {
                  q*=p;
                  div=mul;
                  mul=mul*p*p+1;
                  for(j=((n+q-1)/q)*q-n;j<8000;j+=q)  S[j]/=div,S[j]*=mul,A[j]*=p;
            }
        }
        for(i=(n==0);i<8000;i++)  {
            if(A[i]!=n+i)  {
               p=(n+i)/A[i];
               S[i]*=p*p+1;
            }
            sq=(long long int) sqrt(S[i]);
            if(sq*sq==S[i])  sum+=n+i;
        }
    }
    printf("%I64d\n",sum);
    return 0;
}
 
Mathematica:
sqrs = 0;
For[x = 1, x < 64000000, x++, {
   tot = DivisorSigma[2, x];
   If[Sqrt[tot] == IntegerPart[Sqrt[tot]], sqrs += x];
   }];
Print[sqrs]
 
Pascal:
program bidon;

uses minimaple;
var  t:array[1..64000000] of int64;

function longueur(n:int64):int64;
var som:int64;
begin
  som:=0;
  while n<>0 do
  begin
  som:=som+1;
  n:=n div 10;
  end;
  longueur:=som;
end;

function heron(n:int64):int64;
var x:extended;
    taille,mem,k:int64;
begin
  taille:=longueur(n);
  x:=exporapide(10,taille);
  mem:=trunc(x);
  x:=(x+n/x)/2;
  k:=trunc(x);
  while mem<>k do
  begin
    mem:=trunc(x);
    x:=(x+n/x)/2;
    k:=trunc(x);
  end;
  heron:=abs(k);
end;

function issqr(n:int64):boolean;
var k:int64;
begin
  k:=heron(n);
  if k*k=n then issqr:=true else issqr:=false;
end;

function cb(n:int64;p:int64):int64;
var som:int64;
begin
  som:=0;
  while n mod p=0 do
  begin
    som:=som+1;
    n:=n div p;
  end;
  cb:=som;
end;

function rez(n:int64):int64;
var i,som,j,k,ad,u:int64;
    flag:boolean;
begin
  som:=1;
  t[1]:=1;
  i:=2;
  while i<=n do
  begin
    if i mod 100000=0 then writeln(i);
    if isprime(i)=true then t[i]:=i*i+1
    else
    begin
      j:=1;
      flag:=false;
      while flag=false do
      begin
        j:=nextprime(j);
        if i mod j=0 then flag:=true;
      end;
      k:=cb(i,j);
      ad:=0;
      u:=0;
      while u<=k do
      begin
        ad:=ad+exporapide(j,2*u);
        u:=u+1;
      end;
      k:=t[i div exporapide(j,k)]*ad;
      if issqr(k) then som:=som+i;
      t[i]:=k;
    end;
  i:=i+1;
  end;
  rez:=som;
end;

begin
  writeln(rez(64000000));
end.
 
Java:
uses getime;
const n=64000000;
var a:array[1..n] of QWord;
 i,j:longint;
 r,i2,ii:QWord;

function issquare(n:QWord):boolean;
var r:QWord;
begin
 r:=trunc(sqrt(n));
 if r*r=n then issquare:=true else issquare:=false;
end;

begin
 for i:=1 to n do
 begin
  ii:=i;
  i2:=ii*ii;
  for j:=1 to n DIV i do
   a[i*j]:=a[i*j]+i2;
 end;
 
 r:=1;
 for i:=2 to n do
  if issquare(a[i]) then r:=r+i;

 writeln(r);
end.
 
Matlab:
clc
clear all

tic

limit=64000000;
a=ones(limit,1);
starting=1:limit;

for flag=2:limit
    increment=flag:flag:limit;
    a(increment)=a(increment)+flag.^2;
end

b=sqrt(a);
final_answer=sum(starting(abs(b-round(b))<1e-9))

toc
 
Basic:
Private Function GetValue() As Long

        Dim sup As Long = 64000000
        Dim lstPrimes As List(Of Long) = FewFirstPrimes(CLng(Sqrt(sup)))
        Dim lstUsedPrimes As New List(Of Long)
        Dim lstLeftPrimes As New List(Of Long)
        lstLeftPrimes.AddRange(lstPrimes)

        Dim counter As Long = 1 'that's because 1 is also a square

        For Each p In lstPrimes

            For k As Long = 1 To DetermineUpperPowerLimit(p, sup)
                Dim q As Long = 0
                Dim isOver As Boolean = False

                Do Until isOver
                    q += 1

                    Dim wasUsed As Boolean = False

                    For Each up In lstUsedPrimes
                        If q Mod up = 0 Then
                            wasUsed = True
                            Exit For
                        End If
                    Next

                    If (q Mod p <> 0) AndAlso Not wasUsed Then
                        Dim d As Long = CType((q * Pow(p, k)), Long)
                        If d >= sup Then
                            isOver = True
                        Else                                                      
                            Dim sum As Long = GetSQforPrimePower(p, k)

                            '-------------------------------------------
                            Dim m As Long = q

                            For Each pInner In lstLeftPrimes

                                If m Mod pInner = 0 Then

                                    Dim isOverInner As Boolean = False
                                    Dim temp As Long = CLng(m / pInner)
                                    Dim kInner As Long = 1

                                    Do Until isOverInner
                                        If temp Mod pInner <> 0 Then
                                            isOverInner = True
                                        Else
                                            kInner += 1
                                            temp = CLng(temp / pInner)
                                        End If
                                    Loop

                                    sum *= GetSQforPrimePower(pInner, kInner)
                                    m = CLng(m / Pow(pInner, kInner))

                                End If

                                If m = 1 OrElse pInner > Sqrt(m) Then
                                    Exit For
                                End If

                            Next

                            'if m is not 1 then it is a prime
                            If m > 1 Then
                                sum *= GetSQforPrimePower(m, 1)
                            End If

                            '------------------------------------------------------

                            Dim result As Double = Math.Sqrt(sum)
                            If result Mod 1 = 0 Then                               
                                counter += d
                            End If

                        End If
                    End If
                Loop
            Next

            lstUsedPrimes.Add(p)
            lstLeftPrimes.Remove(p)

        Next

        Return counter

    End Function

    Private Function DetermineUpperPowerLimit(ByVal d As Long, ByVal sup As Long) As Long

        Dim p As Long = 0
        Dim isOver As Boolean = False

        Do Until isOver
            Dim temp As Long = CLng(Math.Pow(d, p))
            If temp >= sup Then
                isOver = True
            Else
                p = p + 1
            End If
        Loop

        Return p - 1

    End Function

    Private Function GetSQforPrimePower(ByVal p As Long, ByVal k As Long) As Long

        Return CLng((Math.Pow(p, (k + 1) * 2) - 1) / (Math.Pow(p, 2) - 1))

    End Function

    Public Function IsPrime(ByVal num As Long) As Boolean
        If num = 2 Or num = 3 Then
            Return True
        End If
        If ((num And 1) = 0) Or ((num Mod 3) = 0) Or (num < 2) Then
            Return False
        End If
        For i As Long = 6 To CInt(Math.Ceiling(Math.Sqrt(num)) + 1) Step 6
            If (num Mod (i - 1)) = 0 Then
                Return False
            End If
            If (num Mod (i + 1)) = 0 Then
                Return False
            End If
        Next
        Return True
    End Function

    Public Function FewFirstPrimes(ByVal Supremum As Long) As List(Of Long)

        Dim loPrimes As New List(Of Long)

        For i As Long = 1 To Supremum

            If IsPrime(i) Then
                loPrimes.Add(i)
            End If

        Next

        Return loPrimes

    End Function