Avatar billede gulbaek Nybegynder
17. januar 2004 - 21:21 Der er 27 kommentarer og
1 løsning

Oversæt matematisk algoritme til kode, meget svær opgave

Hejsa, jeg har følgende matematiske algoritme som jeg godt kunne tænke mig oversat til C#, men den er lidt for indviklet til mine evner.

Nogen som har lyst til at give det et forsøg ?

Input: integer n > 1
1. if ( n is of the form ab, b > 1 ) output COMPOSITE;
2. r = 2;
3. while(r < n) {
4.    if ( gcd(n,r) 6= 1 ) output COMPOSITE;
5.    if (r is prime)
6.        let q be the largest prime factor of r -1;
7.        if (q &#8805; 4&#8730;r log n) and (n^((r-1)/q) &#8800; 1 (mod r))
8.              break;
9.    r r + 1;
10. }
11. for a = 1 to 2&#8730;r log n
12.    if ( (x - a)^n &#8800; (x^n - a)(mod x^r - 1,n)) output COMPOSITE;
13. output PRIME;

ps. det er en algoritme til at finde primtal og ved godt der findes meget simplere algoritmer, men denne skulle være den mest effektive.
Avatar billede gulbaek Nybegynder
17. januar 2004 - 21:27 #1
sådan noget tis, den kan ikke vise tegnene rigtigt
Avatar billede viciodk Praktikant
17. januar 2004 - 21:28 #2
Smid den ind her og poste et link:
http://www.pastebin.com/
Avatar billede arne_v Ekspert
17. januar 2004 - 21:34 #3
Avatar billede viciodk Praktikant
17. januar 2004 - 21:36 #4
Den er også her (samt analyse af problemstillingen)
http://www.eas.asu.edu/~cse450sp/projects/final_P12.doc
Avatar billede gulbaek Nybegynder
17. januar 2004 - 21:41 #5
jepper præcist arne_v, og den kunne jeg godt tænke mig at få lavet om til C# kode

viciodk, det blev de samme da jeg forsøgte at skrive på den side
Avatar billede arne_v Ekspert
17. januar 2004 - 21:43 #6
For normale int eller for vilkårligt store integers ?
Avatar billede gulbaek Nybegynder
17. januar 2004 - 21:48 #7
hmm, er det ikke nemmest at starte med normale int

og har lige uploadet algoritmen som pdf her
http://www.gulbaek.net/tmp/algoritme.pdf
Avatar billede arne_v Ekspert
17. januar 2004 - 21:53 #8
Jo

(og den er svær nok i forvejen)
Avatar billede gulbaek Nybegynder
17. januar 2004 - 21:54 #9
hehe jo tak, er også villig til at give flere point
Avatar billede arne_v Ekspert
17. januar 2004 - 22:01 #10
Du må ikke give mere end 200 point, så det kan du ikke.

Men der er jo også lidt udfording i det !

:-)
Avatar billede gulbaek Nybegynder
17. januar 2004 - 22:06 #11
hehe ja, det er en rimelig stor udfordring, men tænk på hvor mange der kan få glæde af det :-)
Avatar billede gulbaek Nybegynder
17. januar 2004 - 22:51 #12
Har lige fået lavet gcd metoden, så det er da en start

public static int gcd(int a, int b)
        {
            int x = a;
            int y = b;
            while (y != 0)
            {
                int r = x % y;
                x = y;
                y = r;
            }
            return x;
        }
Avatar billede gulbaek Nybegynder
17. januar 2004 - 23:59 #13
Her er hvad jeg har fået lavet indtil videre, umiddelbart virker den fint, men jeg mangler stadig at implementer lidt.

using System;

namespace Primtal_i_P
{
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
            prime(Convert.ToInt32(Console.ReadLine()));
            //Console.WriteLine(gcd(414,662));
            Console.ReadLine();
        }
        public static int gcd(int a, int b)
        {
            int x = a;
            int y = b;
            while (y != 0)
            {
                int r = x % y;
                x = y;
                y = r;
            }
            return x;
        }

        public static bool prime(int n)
        {
            //if(n is of the form a^b, b > 1) output COMPOSITE;
            int    r = 2;
            while( r < n)
            {
                if(gcd(n,r) != 1)
                {
                    Console.WriteLine(n +" er ikke et primtal");
                    return false;
                }
                else
                {
                    int q = 1;  // let q be the largest prime factor of r - 1
                    if(q >= 4*Math.Sqrt(r * Math.Log(n)) & (n*((r-1)/q) != 1 % r))
                        break;
                }
                r++;
            }
            int a = 1;
            if(a == 2 * Math.Sqrt( r * Math.Log(n)))
                //if( ((x-a)^n != (x^n - a)) % x^r - 1)
            {
                    Console.WriteLine(n +" er ikke et primtal");
                    return false;
            }
            Console.WriteLine(n +" er et primtal");
            return true;
        }

    }
}
Avatar billede gulbaek Nybegynder
18. januar 2004 - 00:02 #14
de udmærkerede steder er de steder hvor de driller lidt, f.eks. aner jeg ikke hvor x kommer fra i den sidste if sætning.
Avatar billede gulbaek Nybegynder
18. januar 2004 - 12:51 #15
Der er ikke nogen, der kan forklare hvad dette betyder ?

if(n is of the form a^b, b > 1) output COMPOSITE;
Avatar billede arne_v Ekspert
18. januar 2004 - 12:54 #16
Forklare det er nemt. Kode det ...

2^2 = 4
2^3 = 8
2^4 = 16
...
3^2 = 9
3^3 = 27
3^4 = 81
...
...

Er ikke primtal.
Avatar billede gulbaek Nybegynder
18. januar 2004 - 13:06 #17
Hmm, ja det blir jo lidt svært at kode, men det må være muligt
Avatar billede arne_v Ekspert
18. januar 2004 - 13:16 #18
public static bool isAB(int n)
    {
        for(int a = 2; a <= (int)Math.Sqrt(n); a++)   
        {
            for(int b = 2; b <= (int)(Math.Log(n)/Math.Log(a)); b++)
            {
                if(Math.Pow(a, b) == n)
                {
                    return true;
                }
            }
        }
        return false;
    }

ligner en ide !
Avatar billede gulbaek Nybegynder
18. januar 2004 - 13:31 #19
hmm, har lige kørt nogle tests med og uden din kode, hvis jeg skal finde alle primtal fra 1 -> 1000 så er det en del hurtigere med din kode, men hvis jeg forsøger mig med 1 -> 10000 så blir det faktisk langsommere
Avatar billede arne_v Ekspert
18. januar 2004 - 13:38 #20
Den skal nok omkodes en del, så man helt undgår de meget dyre Sqrt/Log/Pow.
Avatar billede gulbaek Nybegynder
18. januar 2004 - 13:50 #21
hmm,ja det ville nok være en god ide
Avatar billede gulbaek Nybegynder
18. januar 2004 - 13:51 #22
Men hvad så med denne linie.

if( ((x-a)^n != (x^n - a)) % x^r - 1)

aner ikke lige hvor x kommer fra.
Avatar billede arne_v Ekspert
18. januar 2004 - 14:03 #23
Et af stederne bruger de 3 vandrette streger, hvilket antyder at x er
"for enhver x".
Avatar billede arne_v Ekspert
18. januar 2004 - 20:53 #24
Ja.

using System;

class MainClass
{
    private const int N = 200000;
    public static bool isAB1(int n)
    {
        for(int a = 2; a <= (int)Math.Sqrt(n); a++)   
        {
            for(int b = 2; b <= (int)(Math.Log(n)/Math.Log(a) + 0.01); b++)
            {
                if(Math.Pow(a, b) == n)
                {
                    return true;
                }
            }
        }
        return false;
    }
    public static bool isAB2(int n)
    {
        int a = 2;
        while(a*a <= n)
        {
            int apowb = a * a;
            while(apowb <= n)
            {
                if(apowb == n)
                {
                    return true;
                }
                apowb *= a;
            }
            a++;
        }
        return false;
    }
    public static void Main(string[] args)
    {
        for(int i = 2; i <= 1000; i++)
        {
            if(isAB1(i) != isAB2(i))
            {
                Console.WriteLine(i + " " + isAB1(i) + " " + isAB2(i));
            }
        }
        long t1 = DateTime.Now.Ticks;
        for(int i = 2; i < N; i++)
        {
            isAB1(i);
        }
        long t2 = DateTime.Now.Ticks;
        long t3 = DateTime.Now.Ticks;
        for(int i = 2; i < N; i++)
        {
            isAB2(i);
        }
        long t4 = DateTime.Now.Ticks;
        Console.WriteLine("1: " + (t2 - t1)/1000000 + " 2: " + (t4 - t3)/1000000);
    }
}

siger at isAB2 er 80 gange hurtigere end isAB1.

(bemærk iøvrigt de +0.01 - det virkede ikke helt uden)
Avatar billede gulbaek Nybegynder
18. januar 2004 - 21:08 #25
Hehe, ja det var jo lidt af en forbedring
Avatar billede gulbaek Nybegynder
18. januar 2004 - 21:10 #26
Kunne være jeg skulle få fjernet alle de steder jeg har brugt Math.Log og Math.Sqrt
Avatar billede gulbaek Nybegynder
23. marts 2004 - 23:41 #27
Vist ved at være lukke tid :-) Fik ikke lavet en 100 % løsning, men fint nok til mit behov, takker

arne_v og viciodk kom lige med et svar
Avatar billede arne_v Ekspert
24. marts 2004 - 07:31 #28
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester