সুপার দ্রুত গতি সম্পন্ন কাজ


22

লক্ষ্যটি সহজ: আপনি 10 সেকেন্ডে যত সংখ্যক সংখ্যক সংখ্যার জন্য মোট ফাংশন গণনা করুন এবং সংখ্যার যোগফল দিন।

আপনাকে অবশ্যই আপনার ফলাফলটি প্রিন্ট করতে হবে এবং আপনাকে অবশ্যই এটি গণনা করতে হবে। কোনও স্বয়ংক্রিয় টোটিনেন্ট ফাংশন অনুমোদিত নয় তবে বিগনাম লাইব্রেরি রয়েছে। আপনাকে 1 এ শুরু করতে হবে এবং সমস্ত সংখ্যার একটানা গণনা করতে হবে। তুমি না সংখ্যার এড়িয়ে যেতে অনুমতি দেওয়া হয়েছে।

আপনার স্কোরটি হল আপনার প্রোগ্রামটি আপনার মেশিনে কতগুলি সংখ্যা গণনা করতে পারে / আমার প্রোগ্রামটি আপনার মেশিনে কয়টি গণনা করতে পারে । আমার কোডটি সি ++ (অপ্টিমাইজেশন বন্ধ) এর একটি সাধারণ প্রোগ্রাম, আশা করি আপনি এটি চালাতে পারবেন।

আপনি ব্যবহার করতে পারেন গুরুত্বপূর্ণ বৈশিষ্ট্য!

  • যদি gcd(m,n) = 1, phi(mn) = phi(m) * phi(n)
  • যদি pপ্রধান হয়, phi(p) = p - 1(জন্য p < 10^20)
  • nএমনকি যদি হয়,phi(2n) = 2 phi(n)
  • অন্যরা প্রথম লিঙ্কে তালিকাভুক্ত

আমার কোড

#include <iostream>
using namespace std;

int gcd(int a, int b)
{
    while (b != 0)
    {
        int c = a % b;
        a = b;
        b = c;
    }
    return a;
}

int phi(int n)
{
    int x = 0;
    for (int i=1; i<=n; i++)
    {
        if (gcd(n, i) == 1)
            x++;
    }
    return x;
}

int main()
{
    unsigned int sum = 0;
    for (int i=1; i<19000; i++) // Change this so it runs in 10 seconds
    {
        sum += phi(i);
    }
        cout << sum << endl;
        return 0;
}

2
হতে পারে আপনি যুক্ত করতে চাইতে পারেন যে ইনপুট নম্বরগুলি পরপর পূর্ণসংখ্যার হওয়া উচিত। অন্যথায় আমি কেবল 2 টির শক্তির জন্য সামগ্রিক ফাংশন গণনা করতে প্ররোচিত হতে পারি।
হাওয়ার্ড

আমি কি করতে পারি 1, 3, 5, 2, 4বা পছন্দ করতে পারি ?
লিকি নুন

উত্তর:


14

নিমরোড: ~ 38,667 (580,000,000 / 15,000)

এই উত্তরটি বেশ সহজ পদ্ধতির ব্যবহার করে। কোডটি একটি সাধারণ মৌলিক সংখ্যা চালনী নিযুক্ত করে যা সংমিশ্রিত সংখ্যার জন্য প্রতিটি স্লটে ক্ষুদ্রতম প্রধান শক্তিগুলির মৌলিক সঞ্চয় করে (প্রাইমগুলির জন্য শূন্য), তারপরে একই পরিসরের উপরে মোট কর্ম সঞ্চালনের জন্য গতিশীল প্রোগ্রামিং ব্যবহার করে, তারপরে ফলাফলগুলি যোগ করে। প্রোগ্রামটি চালুনিটি তৈরির জন্য কার্যত তার সমস্ত সময় ব্যয় করে, তারপরে সময়ের একটি ভগ্নাংশের মোট কার্যফল গণনা করে। দেখে মনে হচ্ছে এটি একটি দক্ষ চালনী তৈরির জন্য নেমে এসেছে (সামান্য মোচড় দিয়ে যে ফলাফলটি সংশ্লেষ সংখ্যার জন্য একটি মৌলিক গুণককে বের করতে সক্ষম হতে হবে এবং মেমরির ব্যবহারকে যুক্তিসঙ্গত স্তরে রাখতে হবে)।

আপডেট: মেমরি পদচিহ্ন হ্রাস এবং ক্যাশে আচরণ উন্নত করে কর্মক্ষমতা উন্নত। 5% -10% বেশি পারফরম্যান্স আটকানো সম্ভব, তবে কোড জটিলতা বৃদ্ধি লাভজনক নয়। শেষ পর্যন্ত, এই অ্যালগরিদমটি মূলত একটি সিপিইউ'র ভন নিউমান বোতল ব্যায়াম অনুশীলন করে এবং খুব কম অ্যালগরিদমিক টুইট রয়েছে যা এটির কাছাকাছি আসতে পারে।

সি ++ কোডটি সমস্ত অপ্টিমাইজেশনের সাথে সংকলিত হওয়ার উদ্দেশ্যে নয় এবং অন্য কেউ তা করেনি বলে পারফরম্যান্স ডিভায়ারটিকেও আপডেট করেছে। :)

আপডেট 2: উন্নত মেমরি অ্যাক্সেসের জন্য অনুকূলিতকরণ চালনা অপারেশন। বড় আকারের প্রাইমগুলি (~ 10% স্পিডআপ) সিভ করার সময় এখন মেমকিপি () (~ 5% স্পিডআপ) এর মাধ্যমে বাল্কে ছোট ছোট প্রাইমগুলি পরিচালনা করা এবং 2, 3 এবং 5 এর বহুগুণ এড়িয়ে যাওয়া।

সি ++ কোড: ৯.৯ সেকেন্ড (জি ++ ৪.৯ সহ)

নিম্রড কোড: 9.9 সেকেন্ড (-ড: রিলিজ, জিসিসি 4.9 ব্যাকএন্ড সহ)

proc handleSmallPrimes(sieve: var openarray[int32], m: int) =
  # Small primes are handled as a special case through what is ideally
  # the system's highly optimized memcpy() routine.
  let k = 2*3*5*7*11*13*17
  var sp = newSeq[int32](k div 2)
  for i in [3,5,7,11,13,17]:
    for j in countup(i, k, 2*i):
      sp[j div 2] = int32(i)
  for i in countup(0, sieve.high, len(sp)):
    if i + len(sp) <= len(sieve):
      copyMem(addr(sieve[i]), addr(sp[0]), sizeof(int32)*len(sp))
    else:
      copyMem(addr(sieve[i]), addr(sp[0]), sizeof(int32)*(len(sieve)-i))
  # Fixing up the numbers for values that are actually prime.
  for i in [3,5,7,11,13,17]:
    sieve[i div 2] = 0

proc constructSieve(m: int): seq[int32] =
  result = newSeq[int32](m div 2 + 1)
  handleSmallPrimes(result, m)
  var i = 19
  # Having handled small primes, we only consider candidates for
  # composite numbers that are relatively prime with 31. This cuts
  # their number almost in half.
  let steps = [ 1, 7, 11, 13, 17, 19, 23, 29, 31 ]
  var isteps: array[8, int]
  while i * i <= m:
    if result[i div 2] == 0:
      for j in 0..7: isteps[j] = i*(steps[j+1]-steps[j])
      var k = 1 # second entry in "steps mod 30" list.
      var j = 7*i
      while j <= m:
        result[j div 2] = int32(i)
        j += isteps[k]
        k = (k + 1) and 7 # "mod 30" list has eight elements.
    i += 2

proc calculateAndSumTotients(sieve: var openarray[int32], n: int): int =
  result = 1
  for i in 2'i32..int32(n):
    var tot: int32
    if (i and 1) == 0:
      var m = i div 2
      var pp: int32 = 2
      while (m and 1) == 0:
        pp *= 2
        m = m div 2
      if m == 1:
        tot = pp div 2
      else:
        tot = (pp div 2) * sieve[m div 2]
    elif sieve[i div 2] == 0: # prime?
      tot = i - 1
      sieve[i div 2] = tot
    else:
      # find and extract the first prime power pp.
      # It's relatively prime with i/pp.
      var p = sieve[i div 2]
      var m = i div p
      var pp = p
      while m mod p == 0 and m != p:
        pp *= p
        m = m div p
      if m == p: # is i a prime power?
        tot = pp*(p-1)
      else:
        tot = sieve[pp div 2] * sieve[m div 2]
      sieve[i div 2] = tot
    result += tot

proc main(n: int) =
  var sieve = constructSieve(n)
  let totSum = calculateAndSumTotients(sieve, n)
  echo totSum

main(580_000_000)

এপিক! +1 টি। নিম্রোদ আরও বেশি জনপ্রিয় হতে শুরু করেছেন; 3
সিজেফুরে

অপেক্ষা করুন। ওহো। আমি আপনার অন্যান্য উত্তর upvoting করছি। : পি
সিজেফুরে

1
নিম্রড কি পাইথন এবং সি এর মধ্যে একটি ক্রস?
mbomb007

নিমরোদ সম্প্রতি নাম বদলে দেওয়া হয়েছিল নিম; পাইথনের সিনট্যাকটিক স্টাইল ধার করার সময়, শব্দার্থবিজ্ঞানগুলি পৃথক, এবং সি এর বিপরীতে, এটি মেমরি-নিরাপদ (যদি আপনি অনিরাপদ বৈশিষ্ট্যগুলি ব্যবহার না করেন) এবং আবর্জনা সংগ্রহ না করে।
রিমারের বেহরেন্ডস

9

জাভা, স্কোর ~ 24,000 (360,000,000 / 15,000)

নীচের জাভা কোডটি টোটেন্টিয়েন্ট ফাংশন এবং প্রাইম চালনী একসাথে গণনা করে। নোট করুন যে আপনার মেশিনের উপর নির্ভর করে আপনাকে প্রাথমিক / সর্বাধিক হিপ আকার বাড়াতে হবে (আমার বরং ধীর গতির ল্যাপটপে আমাকে যেতে হবে -Xmx3g -Xms3g)।

public class Totient {

    final static int size = 360000000;
    final static int[] phi = new int[size];

    public static void main(String[] args) {
        long time = System.currentTimeMillis();
        long sum = 0;

        phi[1] = 1;
        for (int i = 2; i < size; i++) {
            if (phi[i] == 0) {
                phi[i] = i - 1;
                for (int j = 2; i * j < size; j++) {
                    if (phi[j] == 0)
                        continue;

                    int q = j;
                    int f = i - 1;
                    while (q % i == 0) {
                        f *= i;
                        q /= i;
                    }
                    phi[i * j] = f * phi[q];
                }
            }
            sum += phi[i];
        }
        System.out.println(System.currentTimeMillis() - time);
        System.out.println(sum);
    }
}

9

নিমরোড: ~ 2,333,333 (42,000,000,000 / 18,000)

এটি আমার আগের উত্তর থেকে সম্পূর্ণ ভিন্ন পদ্ধতির ব্যবহার করে। বিশদ জন্য মন্তব্য দেখুন। longintমডিউল পাওয়া যাবে এখানে

import longint

const max = 500_000_000

var ts_mem: array[1..max, int]

# ts(n, d) is defined as the number of pairs (a,b)
# such that 1 <= a <= b <= n and gcd(a,b) = d.
#
# The following equations hold:
#
# ts(n, d) = ts(n div d, 1)
# sum for i in 1..n of ts(n, i) = n*(n+1)/2
#
# This leads to the recurrence:
# ts(n, 1) = n*(n+1)/2 - sum for i in 2..n of ts(n, i)
#
# or, where ts(n) = ts(n, 1):
# ts(n) = n*(n+1)/2 - sum for i in 2..n of ts(n div i)
#
# Note that the large numbers that we deal with can
# overflow 64-bit integers.

proc ts(n, gcd: int): int =
  if n == 0:
    result = 0
  elif n == 1 and gcd == 1:
    result = 1
  elif gcd == 1:
    result = n*(n+1) div 2
    for i in 2..n:
      result -= ts(n, i)
  else:
    result = ts(n div gcd, 1)

# Below is the optimized version of the same algorithm.

proc ts(n: int): int =
  if n == 0:
    result = 0
  elif n == 1:
    result = 1
  else:
    if n <= max and ts_mem[n] > 0:
      return ts_mem[n]
    result = n*(n+1) div 2
    var p = n
    var k = 2
    while k < n div k:
      let pold = p
      p = n div k
      k += 1
      let t = ts(n div pold)
      result -= t * (pold-p)
    while p >= 2:
      result -= ts(n div p)
      p -= 1
    if n <= max:
      ts_mem[n] = result

proc ts(n: int128): int128 =
  if n <= 2_000_000_000:
    result = ts(n.toInt)
  else:
    result = n*(n+1) div 2
    var p = n
    var k = 2
    while k < n div k:
      let pold = p
      p = n div k
      k += 1
      let t = ts(n div pold)
      result = result - t * (pold-p)
    while p >= 2:
      result = result - ts(n div p)
      p = p - 1

echo ts(42_000_000_000.toInt128)

মহিলা ও ভদ্রলোক, আমি এটাকে যাদুকর বলি।
আন্না জোকেলা

2
সরাসরি যোগফল গণনা করার জন্য দুর্দান্ত পদ্ধতির, তবে দুর্ভাগ্যক্রমে এটি যতটা সংখ্যক সংখ্যার জন্য মোট ফাংশন গণনা করে না যা উপরে বর্ণিত চ্যালেঞ্জ। আপনার কোডটি আসলে কয়েক হাজার সংখ্যার (আনুমানিক) জন্য ফলাফলগুলি (মোটামুটি ফাংশনটির ফলাফল নয়) গণনা করে 2*sqrt(n)যা অনেক কম স্কোর তৈরি করে।
হাওয়ার্ড

7

সি #: 49,000 (980,000,000 / 20,000)

/codegolf//a/26800 "হাওয়ার্ডের কোড"।
তবে পরিবর্তিত, ফাই মানগুলি বিজোড় পূর্ণসংখ্যার জন্য গণনা করা হয়।

using System;
using sw = System.Diagnostics.Stopwatch;
class Program
{
    static void Main()
    {
        sw sw = sw.StartNew();
        Console.Write(sumPhi(980000000) + " " + sw.Elapsed);
        sw.Stop(); Console.Read();
    }

    static long sumPhi(int n)  // sum phi[i] , 1 <= i <= n
    {
        long s = 0; int[] phi;
        if (n < 1) return 0; phi = buildPhi(n + 1);
        for (int i = 1; i <= n; i++) s += getPhi(i, phi);
        return s;
    }

    static int getPhi(int i, int[] phi)
    {
        if ((i & 1) > 0) return phi[i >> 1];
        if ((i & 3) > 0) return phi[i >> 2];
        int z = ntz(i); return phi[i >> z >> 1] << z - 1;
    }

    static int[] buildPhi(int n)  // phi[i >> 1] , i odd , i < n
    {
        int i, j, y, x, q, r, f; int[] phi;
        if (n < 2) return new int[] { 0 };
        phi = new int[n / 2]; phi[0] = 1;
        for (j = 2, i = 3; i < n; i *= 3, j *= 3) phi[i >> 1] = j;
        for (x = 4, i = 5; i <= n >> 1; i += x ^= 6)
        {
            if (phi[i >> 1] > 0) continue; phi[i >> 1] = i ^ 1;
            for (j = 3, y = 3 * i; y < n; y += i << 1, j += 2)
            {
                if (phi[j >> 1] == 0) continue; q = j; f = i ^ 1;
                while ((r = q) == i * (q /= i)) f *= i;
                phi[y >> 1] = f * phi[r >> 1];
            }
        }
        for (; i < n; i += x ^= 6)  // primes > n / 2 
            if (phi[i >> 1] == 0)
                phi[i >> 1] = i ^ 1;
        return phi;
    }

    static int ntz(int i)  // number of trailing zeros
    {
        int z = 1;
        if ((i & 0xffff) == 0) { z += 16; i >>= 16; }
        if ((i & 0x00ff) == 0) { z += 08; i >>= 08; }
        if ((i & 0x000f) == 0) { z += 04; i >>= 04; }
        if ((i & 0x0003) == 0) { z += 02; i >>= 02; }
        return z - (i & 1);
    }
}

নতুন স্কোর: 61,000 (1,220,000,000 / 20,000)
"App.config" এ আমাকে "gcAllowVeryLargeObjects সক্ষম = সত্য" যোগ করতে হয়েছিল।

    static long sumPhi(int n)
    {
        int i1, i2, i3, i4, z; long s1, s2, s3, s4; int[] phi;
        if (n < 1) return 0; phi = buildPhi(n + 1); n -= 4; z = 2;
        i1 = 1; i2 = 2; i3 = 3; i4 = 4; s1 = s2 = s3 = s4 = 0;
        if (n > 0)
            for (; ; )
            {
                s1 += phi[i1 >> 1];
                s2 += phi[i2 >> 2];
                s3 += phi[i3 >> 1];
                s4 += phi[i4 >> z >> 1] << z - 1;
                i1 += 4; i2 += 4; i3 += 4; i4 += 4;
                n -= 4; if (n < 0) break;
                if (z == 2)
                {
                    z = 3; i4 >>= 3;
                    while ((i4 & 3) == 0) { i4 >>= 2; z += 2; }
                    z += i4 & 1 ^ 1;
                    i4 = i3 + 1;
                }
                else z = 2;
            }
        if (n > -4) s1 += phi[i1 >> 1];
        if (n > -3) s2 += phi[i2 >> 2];
        if (n > -2) s3 += phi[i3 >> 1];
        if (n > -1) s4 += phi[i4 >> z >> 1] << z - 1;
        return s1 + s2 + s3 + s4;
    }

    static int[] buildPhi(int n)
    {
        int i, j, y, x, q0, q1, f; int[] phi;
        if (n < 2) return new int[] { 0 };
        phi = new int[n / 2]; phi[0] = 1;
        for (uint u = 2, v = 3; v < n; v *= 3, u *= 3) phi[v >> 1] = (int)u;
        for (x = 4, i = 5; i <= n >> 1; i += x ^= 6)
        {
            if (phi[i >> 1] > 0) continue; phi[i >> 1] = i ^ 1;
            for (j = 3, y = 3 * i; y < n; y += i << 1, j += 2)
            {
                if (phi[j >> 1] == 0) continue; q0 = j; f = i ^ 1;
                while ((q1 = q0) == i * (q0 /= i)) f *= i;
                phi[y >> 1] = f * phi[q1 >> 1];
            }
        }
        for (; i < n; i += x ^= 6)
            if (phi[i >> 1] == 0)
                phi[i >> 1] = i ^ 1;
        return phi;
    }

4

পাইথন 3: 000 24000 (335,000,000 / 14,000)

আমার সংস্করণটি হাওয়ার্ডের অ্যালগরিদমের পাইথন বন্দর । আমার আসল ফাংশনটি এই ব্লগপোস্টে প্রবর্তিত একটি অ্যালগরিদমের একটি পরিবর্তন ছিল ।

আমি এক্সিকিউশন সময় দ্রুত করতে নম্পি এবং নুম্বা মডিউলগুলি ব্যবহার করছি। নোট করুন যে সাধারণত আপনার স্থানীয় ভেরিয়েবলের প্রকারগুলি ঘোষণা করতে হবে না (নুম্বা ব্যবহার করার সময়) তবে এই ক্ষেত্রে আমি যতটা সম্ভব কার্যকর করার সময়টি গ্রাস করতে চেয়েছিলাম।

সম্পাদনা করুন: একক ফাংশনে মিলিত গঠন এবং সামারাম ফাংশনগুলি।

সি ++: 9.99 এস (এন = 14,000); পাইথন 3: 9.94 সে (এন = 335,000,000)

import numba as nb
import numpy as np
import time

n = 335000000

@nb.njit("i8(i4[:])", locals=dict(
    n=nb.int32, s=nb.int64, i=nb.int32,
    j=nb.int32, q=nb.int32, f=nb.int32))

def summarum(phi):
    s = 0

    phi[1] = 1

    i = 2
    while i < n:
        if phi[i] == 0:
            phi[i] = i - 1

            j = 2

            while j * i < n:
                if phi[j] != 0:
                    q = j
                    f = i - 1

                    while q % i == 0:
                        f *= i
                        q //= i

                    phi[i * j] = f * phi[q]
                j += 1
        s += phi[i]
        i += 1
    return s

if __name__ == "__main__":
    s1 = time.time()
    a = summarum(np.zeros(n, np.int32))
    s2 = time.time()

    print(a)
    print("{}s".format(s2 - s1))

1
আপনি যখন অন্য ব্যবহারকারীর কাছ থেকে কোড অনুলিপি করেন তখন আপনার যথাযথ ক্রেডিট দেওয়া উচিত।
হাওয়ার্ড

যথাযথ ক্রেডিট সহ আপডেট!
আনা জোকেলা

3

এখানে আমার পাইথন বাস্তবায়ন যা 10 সেকেন্ডে ~ 60000 নম্বর ক্র্যাঙ্ক করতে সক্ষম বলে মনে হচ্ছে। আমি পোলার্ড rho অ্যালগরিদম ব্যবহার করে এবং রবিন মিলার প্রাথমিকতা পরীক্ষা ব্যবহার করে সংখ্যার গুণক করছি।

from Queue import Queue
import random

def gcd ( a , b ):
    while b != 0: a, b = b, a % b
    return a

def rabin_miller(p):
    if(p<2): return False
    if(p!=2 and p%2==0): return False
    s=p-1
    while(s%2==0): s>>=1
    for _ in xrange(10):
        a=random.randrange(p-1)+1
        temp=s
        mod=pow(a,temp,p)
        while(temp!=p-1 and mod!=1 and mod!=p-1):
            mod=(mod*mod)%p
            temp=temp*2
        if(mod!=p-1 and temp%2==0): return False
    return True

def pollard_rho(n):
    if(n%2==0): return 2;
    x=random.randrange(2,1000000)
    c=random.randrange(2,1000000)
    y=x
    d=1
    while(d==1):
        x=(x*x+c)%n
        y=(y*y+c)%n
        y=(y*y+c)%n
        d=gcd(x-y,n)
        if(d==n): break;
    return d;

def primeFactorization(n):
    if n <= 0: raise ValueError("Fucked up input, n <= 0")
    elif n == 1: return []
    queue = Queue()
    factors=[]
    queue.put(n)
    while(not queue.empty()):
        l=queue.get()
        if(rabin_miller(l)):
            factors.append(l)
            continue
        d=pollard_rho(l)
        if(d==l):queue.put(l)
        else:
            queue.put(d)
            queue.put(l/d)
    return factors

def phi(n):

    if rabin_miller(n): return n-1
    phi = n
    for p in set(primeFactorization(n)):
        phi -= (phi/p)
    return phi

if __name__ == '__main__':

  n = 1
  s = 0

  while n < 60000:
    n += 1
    s += phi(n)
  print(s)

2

1 (2 এন ) = 2 এন - 1
Σ φ (2 i ) = 2 আমি - 1 থেকে 1 থেকে এন পর্যন্ত

প্রথমত, সময়গুলি সন্ধান করার জন্য কিছু:

import os
from time import perf_counter

SEARCH_LOWER = -1
SEARCH_HIGHER = 1

def integer_binary_search(start, lower=None, upper=None, big_jump=1):
    if lower is not None and lower == upper:
        raise StopIteration # ?

    result = yield start

    if result == SEARCH_LOWER:
        if lower is None:
            yield from integer_binary_search(
                start=start - big_jump,
                lower=None,
                upper=start - 1,
                big_jump=big_jump * 2)
        else:
            yield from integer_binary_search(
                start=(lower + start) // 2,
                lower=lower,
                upper=start - 1)
    elif result == SEARCH_HIGHER:
        if upper is None:
            yield from integer_binary_search(
                start=start + big_jump,
                lower=start + 1,
                upper=None,
                big_jump=big_jump * 2)
        else:
            yield from integer_binary_search(
                start=(start + upper) // 2,
                lower=start + 1,
                upper=upper)
    else:
        raise ValueError('Expected SEARCH_LOWER or SEARCH_HIGHER.')

search = integer_binary_search(start=1000, lower=1, upper=None, big_jump=2500)
n = search.send(None)

while True:
    print('Trying with %d iterations.' % (n,))

    os.spawnlp(
        os.P_WAIT,
        'g++', 'g++', '-Wall', '-Wextra', '-pedantic', '-O0', '-o', 'reference',
        '-DITERATIONS=%d' % (n,),
        'reference.cpp')

    start = perf_counter()
    os.spawnl(os.P_WAIT, './reference', './reference')
    end = perf_counter()
    t = end - start

    if t >= 10.1:
        n = search.send(SEARCH_LOWER)
    elif t <= 9.9:
        n = search.send(SEARCH_HIGHER)
    else:
        print('%d iterations in %f seconds!' % (n, t))
        break

রেফারেন্স কোডের জন্য, আমার জন্য, এটি:


14593 পুনরাবৃত্তি দিয়ে চেষ্টা করা হচ্ছে।
7.৯8774597
seconds সেকেন্ডে 64724364 14593 পুনরাবৃত্তি!

এখন, হাস্কেল:

import System.Environment (getArgs)

phiSum :: Integer -> Integer
phiSum n = 2 ^ n - 1

main :: IO ()
main = getArgs >>= print . phiSum . (2^) . read . head

এটি 0.257 সেকেন্ডের মধ্যে 2525224 সংখ্যা সহ কিছু তৈরি করে। এবং এখন আমি @ হাওয়ার্ডের মন্তব্যটি লক্ষ্য করছি।


আপনি যোগফল পরিচালিত 1 থেকে শুরু করে মোট একটানা সংখ্যার সাথে স্কোর পোস্ট করতে পারেন?
Qwr

@qwr, যে 0. হবে আপনি পরপর সংখ্যার চান, আপনি এটি আপনার প্রশ্নে উল্লেখ করা উচিত =)
Ry-

আমি করেছিলাম. আমি ইতিমধ্যে এটি সম্পাদনা করেছি, আমি আবার এটি সম্পাদনা করব।
Qwr

2

মতলব: 1464 = 26355867/18000

আমি আপনার কোডটি পরীক্ষা করতে পারছি না তাই আমি 18000 দ্বারা বিভক্ত হয়েছি কারণ এটি পরীক্ষকদের মধ্যে দ্রুততম কম্পিউটারের প্রতিনিধিত্ব করে। এই সম্পত্তিটি ব্যবহার করে আমি স্কোর এ এসেছি:

  • যদি পি প্রধান হয়, ফাই (পি) = পি - 1 (পি <10 10 20 এর জন্য)

আমি বেশিরভাগই পছন্দ করি যে এটি একটি ওলাইনার:

sum(primes(500000000)-1)

1
phi(p)সমস্ত নন-প্রাইম সম্পর্কে কী p?
জিওবিটস

2
@ জিওবিটস আমি এগুলি এড়িয়ে গেছি কারণ প্রশ্নটি উল্লেখ করে না যে আপনি কোন সংখ্যা ব্যবহার করবেন, যতক্ষণ না তারা সত্যই গণনা করা হয়।
ডেনিস জহেরুদ্দিন

আহ, শব্দটির মধ্যে এটি লক্ষ্য করেনি। খুশী হলাম।
জিওবিটস

আপনি একটি স্কোরও পোস্ট করেননি ...
qwr

1
... একই কম্পিউটারে মতলব ও সি ++ না থাকা কীভাবে সম্ভব?
কাইল কানোজ

1

পাইথন 2.7: 10.999 (165975/15090)

পাইপি ২.৩.১: ২৮.৪৯6 (430000/15090)

আমি ব্যবহার করি কিছু আকর্ষণীয় পদ্ধতি:

রবিন-মিলার স্ট্রং সিউডোপ্রাইম টেস্ট - একটি প্রাথমিক পরীক্ষা যা প্রদত্ত সংখ্যাটি প্রধান কিনা তা নির্ধারণের জন্য একটি দক্ষ সম্ভাব্য আলগোরিদম সরবরাহ করে

ইউলারের পণ্য সূত্র - পণ্যটি পৃথক পৃথক মৌলিক সংখ্যার উপরে এন ভাগ করে

ইউলারের পণ্য সূত্র

কোড:

import math
import random

#perform a Modular exponentiation
def modular_pow(base, exponent, modulus):
    result=1
    while exponent>0:
        if exponent%2==1:
           result=(result * base)%modulus
        exponent=exponent>>1
        base=(base * base)%modulus
    return result

#Miller-Rabin primality test
def checkMillerRabin(n,k):
    if n==2: return True
    if n==1 or n%2==0: return False

    #find s and d, with d odd
    s=0
    d=n-1
    while(d%2==0):
        d/=2
        s+=1
    assert (2**s*d==n-1)

    #witness loop
    composite=1
    for i in xrange(k):
        a=random.randint(2,n-1)
        x=modular_pow(a,d,n)
        if x==1 or x==n-1: continue
        for j in xrange(s-1):
            composite=1
            x=modular_pow(x,2,n)
            if x==1: return False #is composite
            if x==n-1: 
                composite=0
                break
        if composite==1:
            return False        #is composite
    return True                 #is probably prime

def findPrimes(n):              #generate a list of primes, using the sieve of eratosthenes

    primes=(n+2)*[True]

    for i in range(2,int(math.sqrt(n))+1):
        if primes[i]==True:
            for j in range(i**2,n+1,i):
                primes[j]=False

    primes=[i for i in range(2,len(primes)-1) if primes[i]==True]
    return primes

def primeFactorization(n,primes):   #find the factors of a number

    factors=[]

    i=0
    while(n!=1):
        if(n%primes[i]==0):
            factors.append(primes[i])
            n/=primes[i]
        else:
            i+=1

    return factors

def phi(n,primes):
    #some useful properties
    if (checkMillerRabin(n,10)==True):      #fast prime check
        return n-1

    factors=primeFactorization(n,primes)    #prime factors
    distinctive_prime_factors=set(factors)  

    totient=n
    for f in distinctive_prime_factors:     #phi = n * sum (1 - 1/p), p is a distinctive prime factor
        totient*=(1-1.0/f);

    return totient

if __name__ == '__main__':


    s=0
    N=165975
    # N=430000
    primes=findPrimes(N)    #upper bound for the number of primes
    for i in xrange(1,N):
        s+=phi(i,primes)

    print "Sum =",s 

ধন্যবাদ অ্যালগরিদমগুলি! এটি কেবলমাত্র আমি সহজেই বুঝতে পেরেছিলাম এবং সহ-প্রাইমদের গণনা করার জোর করে চেক নয়।
ব্যবহারকারীর
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.