Permalänk
Medlem

Python 3 funktion, hjälp.

Hej, jag håller på att lära mig Python 3 på min fritid och har stött på ett litet problem. Jag ska skapa en funktion som ska värdera ifall ett nummer är ett primtal eller inte. Min första lösning ser ut så här:

def check_prime(n):
....if n > 1:
........if (n % 2) == 0:
............return False
........else:
............return True
....else:
........return False

Dold text

Jag försökte skriva om den till detta:

def check_prime(n):
....if n > 1 and (n % 2) == 0:
........return False
....else:
........return True

Dold text

Men då anser funktionen att "1" är ett primtal (detta då 1 inte är >1 och n % 2 == 0, därför "True"). Hur skulle man kunna motverka detta, då den första lösningen är lite "ful"?

Visa signatur

Dator: | i5 6600K @ 4,4GHz | Be-Quiet Pure Rock | Palit GeForce GTX 1060 Dual | Corsair Vengeance LPX Black DDR4 2133MHz 2x8GB | Gigabyte GA-Z170-Gaming K3 | Fractal Design Define S | Kingston 240GB | Corsair RM550X 550W |

Skärmar: | Asus VG248QE@144Hz | Samsung S24D340H@60Hz

Permalänk
Medlem

Testa med or istället för and i din if-sats.

Permalänk
Medlem

@stenharl:

Inte helt vaken just nu men borde inte detta räcka?

if n >= 1 and (n % 2) == 0:

(större eller Lika med 1)

Edit: borde som ovan säger också vara or

Visa signatur

13700K & GTX 3070

Permalänk
Medlem
Skrivet av backlulund:

Testa med or istället för and i din if-sats.

Tyvärr så blir det knas då tex 13 är >1 och klassas då som "False"

Skrivet av sebstr:

@stenharl:

Inte helt vaken just nu men borde inte detta räcka?

if n >= 1 and (n % 2) == 0:

(större eller Lika med 1)

Edit: borde som ovan säger också vara or

I detta fall blir 1 inkluderat som primtal också. Helst skulle jag vilja skriva "if n >!= 1 and (n % 2) == 0: " men det går inte.

Ett primtal måste vara större än ett och ha en rest på 1. Ifall jag skriver or så blir det större än 1 eller rest på 1.

Visa signatur

Dator: | i5 6600K @ 4,4GHz | Be-Quiet Pure Rock | Palit GeForce GTX 1060 Dual | Corsair Vengeance LPX Black DDR4 2133MHz 2x8GB | Gigabyte GA-Z170-Gaming K3 | Fractal Design Define S | Kingston 240GB | Corsair RM550X 550W |

Skärmar: | Asus VG248QE@144Hz | Samsung S24D340H@60Hz

Permalänk
Medlem
Skrivet av stenharl:

Ett primtal måste vara större än ett och ha en rest på 1. Ifall jag skriver or så blir det större än 1 eller rest på 1.

Fast med din funktion blir väl vartannat tal klassat som ett primtal?

Ett primtal ska väl bara vara delbart med sig själv och med 1?
Alltså du kan inte dela ett annat tal med ett primtal och få ut ett heltal.

Permalänk
Medlem
Skrivet av backlulund:

Fast med din funktion blir väl vartannat tal klassat som ett primtal?

Ett primtal ska väl bara vara delbart med sig själv och med 1?
Alltså du kan inte dela ett annat tal med ett primtal och få ut ett heltal.

Så här blir det då jag kör den andra koden:

test = check_prime(13) #True
test2 = check_prime(104537) #True
test3 = check_prime(104538) #False
test4 = check_prime(1) #True <--- Fel
test5 = check_prime(1933) #True
test6 = check_prime(1934) #False

Den första koden jag har blir resultatet: (Vilket är rätt)

test = check_prime(13) #True
test2 = check_prime(104537) #True
test3 = check_prime(104538) #False
test4 = check_prime(1) #False <---Rätt
test5 = check_prime(1933) #True
test6 = check_prime(1934) #False

Visa signatur

Dator: | i5 6600K @ 4,4GHz | Be-Quiet Pure Rock | Palit GeForce GTX 1060 Dual | Corsair Vengeance LPX Black DDR4 2133MHz 2x8GB | Gigabyte GA-Z170-Gaming K3 | Fractal Design Define S | Kingston 240GB | Corsair RM550X 550W |

Skärmar: | Asus VG248QE@144Hz | Samsung S24D340H@60Hz

Permalänk
Medlem
Skrivet av stenharl:

Så här blir det då jag kör den andra koden:

test = check_prime(13) #True
test2 = check_prime(104537) #True
test3 = check_prime(104538) #False
test4 = check_prime(1) #True <--- Fel
test5 = check_prime(1933) #True
test6 = check_prime(1934) #False

Den första koden jag har blir resultatet: (Vilket är rätt)

test = check_prime(13) #True
test2 = check_prime(104537) #True
test3 = check_prime(104538) #False
test4 = check_prime(1) #False <---Rätt
test5 = check_prime(1933) #True
test6 = check_prime(1934) #False

Testa med 15, t.ex. Som backlulund säger så fungerar inte heller den första varianten korrekt, en algoritm för att testa om något är ett primtal kräver mer än att kolla om det går att dela jämnt med 2.

Sedan är väl det extra fel som introducerats när du skrev den andra varianten att du blandat villkor som var för att den ska returnera True med villkor för att den ska returnera False.

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Medlem

@stenharl: Även om din kod råkar ge rätt svar för de där talen, så är din algoritm fel som backlulund påpekade. Ett primtal är ett tal större än ett som inte är delbart med något annat än 1 och sig själv.

T.ex. 9 är inte ett primtal, eftersom det är delbart med 3.

Om du endast vill kolla om ett tal är större än ett, och inte delbart med två (inte samma sak som primtal), så är lösningen

return n > 1 and n % 2 != 0

Permalänk
Medlem
Skrivet av evil penguin:

Testa med 15, t.ex. Som backlulund säger så fungerar inte heller den första varianten korrekt, en algoritm för att testa om något är ett primtal kräver mer än att kolla om det går att dela jämnt med 2.

Sedan är väl det extra fel som introducerats när du skrev den andra varianten att du blandat villkor som var för att den ska returnera True med villkor för att den ska returnera False.

Skrivet av Tazavoo:

@stenharl: Även om din kod råkar ge rätt svar för de där talen, så är din algoritm fel som backlulund påpekade. Ett primtal är ett tal större än ett som inte är delbart med något annat än 1 och sig själv.

T.ex. 9 är inte ett primtal, eftersom det är delbart med 3.

Om du endast vill kolla om ett tal är större än ett, och inte delbart med två (inte samma sak som primtal), så är lösningen

return n > 1 and n % 2 != 0

Det var som katten, jag hade en lista med primtal som jag på måfå hade lagt in i koden och alla tal jag testade fungerade som det skulle, men nu när jag testade 15 så fungerade ingen av koderna.

Jaja åter till ritbordet antar jag

Visa signatur

Dator: | i5 6600K @ 4,4GHz | Be-Quiet Pure Rock | Palit GeForce GTX 1060 Dual | Corsair Vengeance LPX Black DDR4 2133MHz 2x8GB | Gigabyte GA-Z170-Gaming K3 | Fractal Design Define S | Kingston 240GB | Corsair RM550X 550W |

Skärmar: | Asus VG248QE@144Hz | Samsung S24D340H@60Hz

Permalänk
Medlem

@stenharl: Prova att använda dig av range

for i in range(0,101): check_prime(i)

Så kan du testa du alla tal 0-100 direkt utan någon lista.

Visa signatur

13700K & GTX 3070

Permalänk
Medlem
Skrivet av stenharl:

Det var som katten, jag hade en lista med primtal som jag på måfå hade lagt in i koden och alla tal jag testade fungerade som det skulle, men nu när jag testade 15 så fungerade ingen av koderna.

Jaja åter till ritbordet antar jag

Ja, precis. Din nuvarande kod svarar bara på om talet är större än 1 och udda.

Om du resonerar lite kring vad själva målbilden är, så har du ju påbörjat en algoritm som genom att leta motexempel (och eventuellt då finna att det inte existerar några) avgör om något är ett primtal. Men för ett större tal så finns det många fler potentiella motexempel än talet 2.

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Hedersmedlem

Mig veterligen kan man inte hitta primtal med en enkel if-sats, hade det varit så enkelt hade det inte lagts enorm beräkningskraft för att hitta primtal till kryptering.

En trivial lösning är att testa modulus med alla tal större än 1 upp till talet som testas, inget borde ge rest 0.

Permalänk
Medlem
Skrivet av evil penguin:

Ja, precis. Din nuvarande kod svarar bara på om talet är större än 1 och udda.

Om du resonerar lite kring vad själva målbilden är, så har du ju påbörjat en algoritm som genom att leta motexempel (och eventuellt då finna att det inte existerar några) avgör om något är ett primtal. Men för ett större tal så finns det många fler potentiella motexempel än talet 2.

Skrivet av Shimonu:

Mig veterligen kan man inte hitta primtal med en enkel if-sats, hade det varit så enkelt hade det inte lagts enorm beräkningskraft för att hitta primtal till kryptering.

En trivial lösning är att testa modulus med alla tal större än 1 upp till talet som testas, inget borde ge rest 0.

Ja jag har ingen aning, tar uppgifter här ifrån https://www.practicepython.org/ och är på uppgift 11. Men jag får knåpa vidare

Visa signatur

Dator: | i5 6600K @ 4,4GHz | Be-Quiet Pure Rock | Palit GeForce GTX 1060 Dual | Corsair Vengeance LPX Black DDR4 2133MHz 2x8GB | Gigabyte GA-Z170-Gaming K3 | Fractal Design Define S | Kingston 240GB | Corsair RM550X 550W |

Skärmar: | Asus VG248QE@144Hz | Samsung S24D340H@60Hz

Permalänk
Skrivet av Shimonu:

En trivial lösning är att testa modulus med alla tal större än 1 upp till talet som testas, inget borde ge rest 0.

Sen kan man börja bygga ut lösningen och det är då det börjar bli roligt.
Hur snabbt kan man hitta alla primtal under MAXINT

Permalänk
Medlem
Skrivet av stenharl:

Ja jag har ingen aning, tar uppgifter här ifrån https://www.practicepython.org/ och är på uppgift 11. Men jag får knåpa vidare

Jo, men det finns ju egentligen två separata delproblem här...

1) Hur testar man om något är ett primtal? Detta är snarast en fråga om domänkunskap (att förstå själva problemet man står inför) och har inte egentligen med programmering att göra.

2) Hur formulerar man 1) i python-kod? Detta handlar att förstå verktygen du har i python och hur du kombinerar dessa för att implementera 1).

Jag får intryck av att du har problem med 1) vilket isf gör det omöjligt att lyckas med 2).

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Medlem
Skrivet av evil penguin:

Jo, men det finns ju egentligen två separata delproblem här...

1) Hur testar man om något är ett primtal? Detta är snarast en fråga om domänkunskap (att förstå själva problemet man står inför) och har inte egentligen med programmering att göra.

2) Hur formulerar man 1) i python-kod? Detta handlar att förstå verktygen du har i python och hur du kombinerar dessa för att implementera 1).

Jag får intryck av att du har problem med 1) vilket isf gör det omöjligt att lyckas med 2).

Helt rätt, och därför har jag börjat om nu

Visa signatur

Dator: | i5 6600K @ 4,4GHz | Be-Quiet Pure Rock | Palit GeForce GTX 1060 Dual | Corsair Vengeance LPX Black DDR4 2133MHz 2x8GB | Gigabyte GA-Z170-Gaming K3 | Fractal Design Define S | Kingston 240GB | Corsair RM550X 550W |

Skärmar: | Asus VG248QE@144Hz | Samsung S24D340H@60Hz

Permalänk
Medlem
Skrivet av evil penguin:

Jo, men det finns ju egentligen två separata delproblem här...

1) Hur testar man om något är ett primtal? Detta är snarast en fråga om domänkunskap (att förstå själva problemet man står inför) och har inte egentligen med programmering att göra.

2) Hur formulerar man 1) i python-kod? Detta handlar att förstå verktygen du har i python och hur du kombinerar dessa för att implementera 1).

Jag får intryck av att du har problem med 1) vilket isf gör det omöjligt att lyckas med 2).

ok, så här går min tankegång nu:
1. Mata in n i funktionen
2. Skapa en lista med tal från 1 - n.
3. Dela varje index i listan med n.
4. Om endast 1 och n skapar ett heltal = primtal.

Detta skulle kunna lösas med en for loop där man tar varje i / n, och kontrollerar om man fått ett heltal.
Om endast 1 och n ger detta resultat så är n ett primtal.

Är jag på rätt spår tror du, eller har jag gått in i en återvändsgränd?

Visa signatur

Dator: | i5 6600K @ 4,4GHz | Be-Quiet Pure Rock | Palit GeForce GTX 1060 Dual | Corsair Vengeance LPX Black DDR4 2133MHz 2x8GB | Gigabyte GA-Z170-Gaming K3 | Fractal Design Define S | Kingston 240GB | Corsair RM550X 550W |

Skärmar: | Asus VG248QE@144Hz | Samsung S24D340H@60Hz

Permalänk
Medlem
Skrivet av stenharl:

ok, så här går min tankegång nu:
1. Mata in n i funktionen
2. Skapa en lista med tal från 1 - n.
3. Dela varje index i listan med n.
4. Om endast 1 och n skapar ett heltal = primtal.

Detta skulle kunna lösas med en for loop där man tar varje i / n, och kontrollerar om man fått ett heltal.
Om endast 1 och n ger detta resultat så är n ett primtal.

Är jag på rätt spår tror du, eller har jag gått in i en återvändsgränd?

Jag tänker att du skulle dela n med talet i (ur listan, i ditt exempel), inte tvärt om.
I övrigt låter det väl rimligt, men du kan ju använda modulus-operatorn som i ditt första försök.

Sedan går det att optimera en del, men för att nå något som fungerar så...

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Medlem

En kul uppgift jag var tvungen att klura ut.
Fredag-em och trött på att göra ritningar nu på jobbet så slängde ihop detta:

from math import sqrt #bardbards primtalsknäckare, startar med 2 kända primtal för att komma igång knownPrime = [2,3] #Ändra värdet nedan för att bestämma hur högt du vill kolla maxNumber = 2000 def checkPrimeList(n): for prime in knownPrime: if prime <= int(sqrt(i)): #Kan fortsätta att köra if n % prime != 0: #Ser bra ut, kolla mot nästa primtal next else: #Sket sig här.... return False else: if not n in knownPrime: return True return False return False for i in range(3,maxNumber+1): #Ändra värdet här, enbart för att få en visuell feedback att något händer =) if i % 100 == 0: print("Har analyserat "+str(i)+" tal..") #ignorerar alla jämna tal if i%2 ==0: next else: if checkPrimeList(i): knownPrime.append(i) print("Nu har jag kört klart!") print("Hittade dessa primtal i intervallet:") print(knownPrime)

Gjorde lite slumpmässiga kontroller och det verkar stämma bra

Visa signatur

Bara gammalt skräp...

Permalänk
Medlem
Skrivet av evil penguin:

Jag tänker att du skulle dela n med talet i (ur listan, i ditt exempel), inte tvärt om.
I övrigt låter det väl rimligt, men du kan ju använda modulus-operatorn som i ditt första försök.

Sedan går det att optimera en del, men för att nå något som fungerar så...

Tack så mycket för hjälpen!

Nu ser den ut så här:

def check_prime(n):
....for i in range(1, n+1):
........if n % i == 0:
............print("yes")
........else:
............print("no")

Dold text

Nu går den igenom alla tal för sig i listan, och printar "yes" om den delar ett heltal, och no om den inte gör det.
Eftersom listan starar på 1 och slutar på n+1, så är det de tal som bara printat "yes" som första och sista tal , med "no" emellan primtal.

Förtydligande:
När jag matar in ett icke primtal (14) så blir output:en:

yes
yes
no
no
no
no
yes
no
no
no
no
no
no
yes

Dold text

Medans om jag tar ett primtal (17) så blir output:en:

yes
no
no
no
no
no
no
no
no
no
no
no
no
no
no
no
yes

Dold text

Nu gäller det bara att klura ut hur man kan presentera det på att finare sätt än bara en radda "yes"/"no"

Visa signatur

Dator: | i5 6600K @ 4,4GHz | Be-Quiet Pure Rock | Palit GeForce GTX 1060 Dual | Corsair Vengeance LPX Black DDR4 2133MHz 2x8GB | Gigabyte GA-Z170-Gaming K3 | Fractal Design Define S | Kingston 240GB | Corsair RM550X 550W |

Skärmar: | Asus VG248QE@144Hz | Samsung S24D340H@60Hz

Permalänk
Medlem
Skrivet av bardbard:

En kul uppgift jag var tvungen att klura ut.
Fredag-em och trött på att göra ritningar nu på jobbet så slängde ihop detta:

from math import sqrt #bardbards primtalsknäckare, startar med 2 kända primtal för att komma igång knownPrime = [2,3] #Ändra värdet nedan för att bestämma hur högt du vill kolla maxNumber = 2000 def checkPrimeList(n): for prime in knownPrime: if prime <= int(sqrt(i)): #Kan fortsätta att köra if n % prime != 0: #Ser bra ut, kolla mot nästa primtal next else: #Sket sig här.... return False else: if not n in knownPrime: return True return False return False for i in range(3,maxNumber+1): #Ändra värdet här, enbart för att få en visuell feedback att något händer =) if i % 100 == 0: print("Har analyserat "+str(i)+" tal..") #ignorerar alla jämna tal if i%2 ==0: next else: if checkPrimeList(i): knownPrime.append(i) print("Nu har jag kört klart!") print("Hittade dessa primtal i intervallet:") print(knownPrime)

Gjorde lite slumpmässiga kontroller och det verkar stämma bra

Oj, ja det ser komplexare ut an det jag knåpat ihop

(se min förra post)

Visa signatur

Dator: | i5 6600K @ 4,4GHz | Be-Quiet Pure Rock | Palit GeForce GTX 1060 Dual | Corsair Vengeance LPX Black DDR4 2133MHz 2x8GB | Gigabyte GA-Z170-Gaming K3 | Fractal Design Define S | Kingston 240GB | Corsair RM550X 550W |

Skärmar: | Asus VG248QE@144Hz | Samsung S24D340H@60Hz

Permalänk
Medlem
Skrivet av stenharl:

Tack så mycket för hjälpen!

Nu ser den ut så här:

def check_prime(n):
....for i in range(1, n+1):
........if n % i == 0:
............print("yes")
........else:
............print("no")

Dold text

Nu går den igenom alla tal för sig i listan, och printar "yes" om den delar ett heltal, och no om den inte gör det.
Eftersom listan starar på 1 och slutar på n+1, så är det de tal som bara printat "yes" som första och sista tal , med "no" emellan primtal.

Förtydligande:
När jag matar in ett icke primtal (14) så blir output:en:

yes
yes
no
no
no
no
yes
no
no
no
no
no
no
yes

Dold text

Medans om jag tar ett primtal (17) så blir output:en:

yes
no
no
no
no
no
no
no
no
no
no
no
no
no
no
no
yes

Dold text

Nu gäller det bara att klura ut hur man kan presentera det på att finare sätt än bara en radda "yes"/"no"

Anpassa vilka tal du testar med så du inte testar med första och sista? (argumenten till range)

Edit: Om du gör det, så du inte får en massa falska positiva "yes", så kan du ju returnera True/False som i ditt ursprungliga exempel.

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Datavetare

def primes_upto(n): # Lista med primtal vi hittat så här långt, vi startar med en tom # lista. primes = [] # Kolla alla tal från [2..n], range(a, b) blir [a..b[ så behovs # ett +1 för att även inkludera b, d.v.s range(a, b+1) ger [a..b] for maybePrime in range(2, n + 1): # 'maybePrime' är ett primtal om det inte är delbart med något # av de primtal vi hittat så här långt. if all(maybePrime % p != 0 for p in primes): # 'maybePrime' är ett primtal, så lägg till det till # listan primes.append(maybePrime) return primes

Detta löser inte helt ditt problem. Vidare är det som sagt ett rätt ineffektivt sätt att ta fram alla primtal upp till talet n.

Men det är en start. Några saker att fixa till.

1. skriv om "if all(...)" delen med en normal "for-sats" på ett sätt du faktiskt förstår. Kommentaren beskriver vad som logisk ska hända.

2. Lite uppenbara optimeringar. Man kanske inte behöver räkna om _alla_ primtal varje gång? Kanske spara de man redan räknat ut och bara räkna ut de extra som behövs?

3. Som redan visats i tråden, räcker ju att testa att dela med tal upp till kvadratroten ur det man vill kolla. Hur får man in den optimeringen i koden ovan?

4. Och hur går man från en lista med primtal till att lura ut om det tal man nu har är ett av primtalen i listan (och är således ett primtal) eller ej (och är då inte ett primtal)?

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av evil penguin:

Anpassa vilka tal du testar med så du inte testar med första och sista? (argumenten till range)

Edit: Om du gör det, så du inte får en massa falska positiva "yes", så kan du ju returnera True/False som i ditt ursprungliga exempel.

Skrivet av Yoshman:

def primes_upto(n): # Lista med primtal vi hittat så här långt, vi startar med en tom # lista. primes = [] # Kolla alla tal från [2..n], range(a, b) blir [a..b[ så behovs # ett +1 för att även inkludera b, d.v.s range(a, b+1) ger [a..b] for maybePrime in range(2, n + 1): # 'maybePrime' är ett primtal om det inte är delbart med något # av de primtal vi hittat så här långt. if all(maybePrime % p != 0 for p in primes): # 'maybePrime' är ett primtal, så lägg till det till # listan primes.append(maybePrime) return primes

Detta löser inte helt ditt problem. Vidare är det som sagt ett rätt ineffektivt sätt att ta fram alla primtal upp till talet n.

Men det är en start. Några saker att fixa till.

1. skriv om "if all(...)" delen med en normal "for-sats" på ett sätt du faktiskt förstår. Kommentaren beskriver vad som logisk ska hända.

2. Lite uppenbara optimeringar. Man kanske inte behöver räkna om _alla_ primtal varje gång? Kanske spara de man redan räknat ut och bara räkna ut de extra som behövs?

3. Som redan visats i tråden, räcker ju att testa att dela med tal upp till kvadratroten ur det man vill kolla. Hur får man in den optimeringen i koden ovan?

4. Och hur går man från en lista med primtal till att lura ut om det tal man nu har är ett av primtalen i listan (och är således ett primtal) eller ej (och är då inte ett primtal)?

Tack för eran input! Jag ska knåpa lite mer på detta när jag får tid över. Om jag kör fast mer så postar jag i tråden

Visa signatur

Dator: | i5 6600K @ 4,4GHz | Be-Quiet Pure Rock | Palit GeForce GTX 1060 Dual | Corsair Vengeance LPX Black DDR4 2133MHz 2x8GB | Gigabyte GA-Z170-Gaming K3 | Fractal Design Define S | Kingston 240GB | Corsair RM550X 550W |

Skärmar: | Asus VG248QE@144Hz | Samsung S24D340H@60Hz

Permalänk
Medlem

Okej, nu har jag knåpat lite mer och kört fast igen. Har googlat ett tag men kan som inte hitta någon lösning.

def check_prime(n):
....primes = [2]
# anledningen till att denna är satt som "2" och inte som tom lista, är att 2 är det enda primtal som funktionen inte kan räkna ut pga "for i in range(2, n):"

....print(primes)
# denna är där för att se om "primes" ändrats genom att printa listan, skall tas bort då allt fungerar

....if n in primes:
........return True
....else:
........for i in range(2, n):
............if n % i == 0:
................return False
............else:
................primes.append(n) # här skall den lägga till (n) ifall det är ett primtal i "primes"
................return True

test = check_prime(13)
print(test) # denna är är för att testa om funktionen fungerar eller ej.

Dold text

Problemet är att inte "primes" uppdateras så att om jag t.ex. kört 13 vilket är ett primtal så läggs den inte till i "primes" listan, utan stannar bara vid "2".

Så hur gör jag så att listan uppdateras så den "kommer ihåg" primes och kan testa mot redan uträknade tal?

Eller går inte detta i python?

Visa signatur

Dator: | i5 6600K @ 4,4GHz | Be-Quiet Pure Rock | Palit GeForce GTX 1060 Dual | Corsair Vengeance LPX Black DDR4 2133MHz 2x8GB | Gigabyte GA-Z170-Gaming K3 | Fractal Design Define S | Kingston 240GB | Corsair RM550X 550W |

Skärmar: | Asus VG248QE@144Hz | Samsung S24D340H@60Hz

Permalänk
Medlem
Skrivet av stenharl:

Så hur gör jag så att listan uppdateras så den "kommer ihåg" primes och kan testa mot redan uträknade tal?

Eller går inte detta i python?

Det går om du inte avslutar exekveringen mellan varje anrop till funktionen, alternativt skriver allt till en fil som du sedan läser in vid start.

Väljer du att inte spara varje känt primtal till fil så kan du göra din lista "global" med nyckelordet med samma namn. Se Python Global Keyword.

Visa signatur

Skoj: Ryzen 9 5900x, RTX 3080, 32 GB RAM @3200MHz CL16
Jobb: Alienware M15 R6, RTX 3080, 32 GB RAM
Privat: Macbook Pro 13" late 2016

Permalänk
Medlem
Skrivet av mmolder:

Det går om du inte avslutar exekveringen mellan varje anrop till funktionen, alternativt skriver allt till en fil som du sedan läser in vid start.

Väljer du att inte spara varje känt primtal till fil så kan du göra din lista "global" med nyckelordet med samma namn. Se Python Global Keyword.

Jag testade global nyckelordet, men jag kan inte få det att fungera. Nu kanske jag är trög men tanken är att efter varje gång jag finner ett nytt primtal så läggs det till i listan.

Så det börjar med [2], sen efter jag matat in "13" i funktionen så printas [2, 13], om jag matar in 61, så printas [2, 13, 61].

Måste jag ha en fil som funktionen läser in vid start för att uppnå detta, eller kan man åstakomma detta med "global" funktionen?

Visa signatur

Dator: | i5 6600K @ 4,4GHz | Be-Quiet Pure Rock | Palit GeForce GTX 1060 Dual | Corsair Vengeance LPX Black DDR4 2133MHz 2x8GB | Gigabyte GA-Z170-Gaming K3 | Fractal Design Define S | Kingston 240GB | Corsair RM550X 550W |

Skärmar: | Asus VG248QE@144Hz | Samsung S24D340H@60Hz

Permalänk
Medlem
Skrivet av stenharl:

Okej, nu har jag knåpat lite mer och kört fast igen. Har googlat ett tag men kan som inte hitta någon lösning.

def check_prime(n):
....primes = [2]
# anledningen till att denna är satt som "2" och inte som tom lista, är att 2 är det enda primtal som funktionen inte kan räkna ut pga "for i in range(2, n):"

....print(primes)
# denna är där för att se om "primes" ändrats genom att printa listan, skall tas bort då allt fungerar

....if n in primes:
........return True
....else:
........for i in range(2, n):
............if n % i == 0:
................return False
............else:
................primes.append(n) # här skall den lägga till (n) ifall det är ett primtal i "primes"
................return True

test = check_prime(13)
print(test) # denna är är för att testa om funktionen fungerar eller ej.

Dold text

Problemet är att inte "primes" uppdateras så att om jag t.ex. kört 13 vilket är ett primtal så läggs den inte till i "primes" listan, utan stannar bara vid "2".

Så hur gör jag så att listan uppdateras så den "kommer ihåg" primes och kan testa mot redan uträknade tal?

Eller går inte detta i python?

Flytta ut 'primes'-listan utanför funktionen så den blir global så ska du se att det går bättre:

primes = [2] def check_prime(n): # anledningen till att denna är satt som "2" och inte som tom lista, är att 2 är det enda primtal som funktionen inte kan räkna ut pga "for i in range(2, n):" ....print(primes) # denna är där för att se om "primes" ändrats genom att printa listan, skall tas bort då allt fungerar ....if n in primes: ........return True ....else: ........for i in range(2, n): ............if n % i == 0: ................return False ............else: ................primes.append(n) # här skall den lägga till (n) ifall det är ett primtal i "primes" ................return True test = check_prime(13) print(test) # denna är är för att testa om funktionen fungerar eller ej.

Visa signatur

Bara gammalt skräp...

Permalänk
Medlem

@stenharl: Exakt som ovanstående skriver så kan det enkelt lösas genom att flytta din lista för primtal utanför funktionen vilket gör den global. Följande kod testar alla tal mellan 2 och 50 för primtal och skriver till slut ut listan. Går så klart att modifiera så att det fungerar som du vill. Exempelvis genom att be om ett tal i taget som i sin tur testas.

primes = [2] def check_prime(n): if n in primes: return True else: for i in range(2, n): if n % i == 0: return False else: primes.append(n) return True for x in range(2, 50): test = check_prime(x) print x, test print(primes)

Visa signatur

Skoj: Ryzen 9 5900x, RTX 3080, 32 GB RAM @3200MHz CL16
Jobb: Alienware M15 R6, RTX 3080, 32 GB RAM
Privat: Macbook Pro 13" late 2016

Permalänk
Medlem

Sedan har du fortfarande fel i din beräkning då den kommer att returnera tal som inte är primtal.
Om man kör programmet ovan får man att dessa är primtal:

[2, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49]

Där de fetade talen är felaktiga.
Rätt rad ska vara:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

Visa signatur

Bara gammalt skräp...