Python :: Aufgabe #171

1 Lösung Lösung öffentlich

Gaußsche Primzahlendecke

Fortgeschrittener - Python von hollst - 07.11.2017 um 12:18 Uhr
Die Gaußsche Primzahlendecke soll als Textilie in den 60er Jahren in den USA ein echter Verkaufsschlager gewesen sein.
Es handelt sich dabei um ein (weißes) Tuch, das entsprechend der Verteilung der Primzahlen in der (komplexen) Gaußschen
Ebene bestickt ist. Genau ein solches Muster wollen auch wir hier mittels Coding erzeugen (Abb. 1).

Während die Sache mit den "normalen" Primzahlen recht einfach zu verstehen ist (Primzahl ist eine Ganzzahl, die nur durch
sich selbst bzw. durch EINS ohne Rest teilbar ist), ist das mit den komplexen Primzahlen schon etwas schwieriger, wir haben
es hier schließlich mit einem Zahlenpaar (Real- und Imaginärteil) zu tun. Besonders interessant ist, das einige "normale"
Primzahlen (z. B. 13 = (3 + 2 * i) * (3 - 2 * i)) keine komplexen Primzahlen sind (was sag ich einige, es sind unendlich viele).

Ohne uns vertiefend mit der Zahlentheorie zu beschäftigen, hier die wesentlichen Voraussetzungen für die Programmierung:

Eine komplexe Integerzahl Z = X + i * Y (X (Realteil), Y (Imaginärteil) Ganzahlen, i * i = -1) heißt Gaußsche Primzahl,
wenn sie eine der drei folgenden Bedingungen erfüllt:

1. Wenn sowohl X als auch Y ungleich 0 sind, dann ist Z eine Gaußsche Primzahl, wenn (X * X + Y * Y) eine "normale" Primzahl ist,
2. ist X = 0, dann ist Z = i * Y Gaußsche Primzahl, wenn Y "normale" Primzahl ist und wenn |Y| = 3 (mod 4) (oder in c#: Math.Abs(Y) % 4 == 3) ist,
3. ist Y = 0, dann ist Z = X Gaußsche Primzahl, wenn X "normale" Primzahl ist und wenn |X| = 3 (mod 4) ist.

Die Programmieraufgabe bestehe nun darin, die Gaußschen Primzahlen für {|X|, |Y|} <= N (z. B. N = 50, Abb. 2 (nur erster Quadrant))
graphisch darzustellen.

Lösungen:

vote_ok
von 0 (0 Punkte) - 11.11.2017 um 15:27 Uhr
Quellcode ausblenden Python-Code
#----------------------------------------------------
# Dateiname:  gauß_primdecke.py
# Über eine Liste werden sämtliche komplexen Zahlen  {|X|, |Y|} <= N erstellt
# mithilfe paralleler Datenverarbeitung wird geprüft, ob es sich bei dem jeweiligen Paar um eine gaussprime Zahl handelt
# aus der Liste mit den komplexen Zahlen und dem entsprechenden Wahrheitswert wird die Grafik erstellt,exemplarisch für den ersten Quadranten
# da zur Darstellung ein Canvas (Tkinter) verwendet wird, erscheint die Darstellung an der x-Achse gespiegelt
# Python 3.6.1
# Nr. 171 trainyourprogrammer.de
# Mot Sonne 11.11.2017
# Vielen Dank an User hollst!
#----------------------------------------------------

from math import ceil,sqrt
from multiprocessing import Pool
from tkinter import *
def check(tupel):
    x,y,wahr=tupel
    if x!=0 and y!=0:
        z=x**2+y**2
        for i in range(2,ceil(sqrt(z))):
            if z%i==0:
                return (x,y,False)
        return (x,y,True)
    elif x==0:
        z=abs(y)
        if z%4==3:
            for i in range(2,ceil(sqrt(z))):
                if z%i==0:
                    return (x,y,False)
            return (x,y,True)
        return (x,y,False)
    elif y==0:
        z=abs(x)
        if z%4==3:
            for i in range(2,ceil(sqrt(z))):
                if z%i==0:
                    return (x,y,False)
            return (x,y,True)
        return (x,y,False)
if __name__=='__main__':
    L=[]
    #Für andere Werte von N muss das Canvas eventuell angepasst werden!
    N=50
    for x in range(0,N+1):
        for y in range(0,N+1):
            L.append((x,y,False))
    p=Pool()
    m=len(L)
    #das dritte Argument von map dient der Effizienz, Pool verwendet automatisch die maximale Anzahl der Prozessoren
    results=p.map(check,L,m)
    p.close()
    p.join()
    #Widgets
    fenster=Tk()
    fenster.title("Gaußsche Primzahlendecke")
    c=Canvas(fenster,width=12*N,height=12*N)
    c=Canvas(fenster,width=12*N,height=12*N)
    c.create_line(N,N,N,11*N,arrow=LAST)
    c.create_line(N,N,11*N,N,arrow=LAST)
    c.create_text(300,580,text='Gaußsche Primzahlen im ersten Quadranten für Real-und Imaginäranteil kleiner als 50')
    c.create_text(4*N,N//2,text='Realanteil')
    c.create_text(N//2,4*N,text='Ima-\ngin-\nära-\nnte-\nil')
    #Für andere Werte von N eventuell anpassen! Hier wurde der Maßstab N/5 verwendet
    for i in range(N+1):
        c.create_text(N+10*i,N-5,text=str(i),font=('Arial',5))
    for i in range(N+1):
        c.create_text(N-5,N+10*i,text=str(i),font=('Arial',5))
    c.pack()
    for x,y,wahr in results:
        if wahr:
            c.create_oval(N+10*x-3,N+10*y-3,N+10*x+3,N+y*10+3,fill='red')
        #Hier können alternativ andersfarbige Objekte eingefügt werden, vorsicht, das geht manchmal auf die Augen :-P
        else:
            c.create_rectangle(N+10*x-3,N+10*y-3,N+10*x+3,N+y*10+3,fill='black')
    fenster.mainloop()

1810124

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.