Vinnaren i pepparkakshustävlingen!
2019-11-10, 19:01
  #25
Medlem
Citat:
Ursprungligen postat av Baseband
Jag förstår kvadratrots-principen men blir det inte problem med lägre primtal typ < 10? 7 är ju ett primtal, och kvadratroten ur 7 är mindre än 3, så då kommer loopen inte köras alls, eller? Samma princip med 3 och 5. Först när X är 11 så överskrider kvadratroten av X iteratorn.
Märkte en till bugg i koden. Så som den är skriven så kollar den aldrig om 2 är en faktor. Lägg till raden if(x%2==0) return false efter raden som kollar om x är 2.

Vad det gäller kvadratroten så får du helt enkelt avrunda uppåt.
Citera
2019-11-10, 20:10
  #26
Medlem
Citat:
Ursprungligen postat av Baseband
Jag förstår kvadratrots-principen men blir det inte problem med lägre primtal typ < 10? 7 är ju ett primtal, och kvadratroten ur 7 är mindre än 3, så då kommer loopen inte köras alls, eller? Samma princip med 3 och 5. Först när X är 11 så överskrider kvadratroten av X iteratorn.
Och nej, det spelar ingen roll att den inte går in i loopen.
Citera
2019-11-10, 22:52
  #27
Moderator
Protons avatar
Citat:
Ursprungligen postat av Baseband
Jag registrerade mig på Project Euler idag, en sida där man presenteras för diverse matematiska problem som enklast löses med hjälp av programmering. Efter att ha gjort de två första uppgifterna så höjdes svårighetsgraden en smula på uppgift nr 3, och en avgörande faktor för att lösa uppgiften innefattar att kunna identifiera huruvida ett tal är ett primtal eller inte.

Tanken med denna tråd är inte att diskutera uppgiften i sig utan snarare olika tillvägagångssätt för att fastställa primtalsstatus med PHP-kod, och lite längre fram när detta har redogjorts för så skulle det även vara intressant att utveckla diskursen mot ytterligare primtalsrelaterad kod, exempelvis något script som primtalsfaktoriserar valfritt tal eller något liknande

Jag är medveten om att PHP inte i första hand används till sådana här saker, utan främst inom webbutveckling som backend-språk, men det är så tyst i PHP-forumet så jag tänkte att det vore kul med lite aktivitet!

Jag har skrivit ett script som har som uppgift att avgöra om ett tal är ett primtal eller inte. Om vi vill kontrollera talet 12 till exempel, så är tanken att en loop genererar talen 2-11, för att i nästa steg se om 12 är delbart med något av dessa tal. Om 12 är delbart med något av talen, vilket det är, så är det inget primtal då ett sådant bara är delbart med talet 1 och sig självt, vilka båda utelämnas i loopen.

Kod:
<?php

$number 
12;
$potentialFactors = array();
$numIsDivisibleWithThese = array();

for(
$i 2$i $number$i++) {
    
array_push($potentialFactors$i);
}

foreach(
$potentialFactors as $value) {
    if(
$number $value == 0) {
        
array_push($numIsDivisibleWithThese$value);
    }
}

if(empty(
$numIsDivisibleWithThese)) {
    echo 
$number " is a prime number.";
}

else {
    echo 
$number " is NOT a prime number.";
}

?>

Detta verkar visserligen fungera, dock känns det som en väldigt klumpig lösning. Som ni ser så är det huruvida den andra array:en är tom/innehåller tal som avgör om talet är ett primtal eller inte.

Kom gärna med tips angående hur jag kan optimera min kod, ge förslag på alternativa metoder och underrätta mig om det är så att min kod inte skulle fungera (hittills verkar programmet ange korrekt primtalsstatus men kontroll med ytterligare tal krävs för att säkerställa detta).
Finns ju till och med en namngiven algoritm för att finna alla primtal upp till ett godtycligt tal:

https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
Citera
2019-11-11, 12:46
  #28
Medlem
Basebands avatar
Citat:
Ursprungligen postat av Sugminstorasalta
Märkte en till bugg i koden. Så som den är skriven så kollar den aldrig om 2 är en faktor. Lägg till raden if(x%2==0) return false efter raden som kollar om x är 2.

Vad det gäller kvadratroten så får du helt enkelt avrunda uppåt.

Citat:
Ursprungligen postat av Sugminstorasalta
Och nej, det spelar ingen roll att den inte går in i loopen.

Okej, om det inte spelar någon roll så har jag antagligen skrivit felaktig kod. Jag får följande output:

Citat:
0 = false
1 = false
2 = true
3 = false
4 = false
5 = false
6 = false
7 = false
8 = false
9 = false
10 = false
11 = true
12 = false
13 = true
14 = false
15 = false
16 = false
17 = true
18 = false
19 = true
20 = false

Från och med 10 verkar det fungera, den anger att 11, 13, 17 och 19 är primtal vilket stämmer. Jag ska fortsätta testa högre tal för att utesluta buggar. Dock anger den felaktigt att 3, 5 och 7 inte är primtal, och det var det jag menade på när det kommer till låga tal. Visserligen skulle jag bara kunna lösa dessa tre enskilda fall med specifika if-satser men jag bifogar min kod nedan först då jag misstänker att jag kanske gjort någonting fel hehe.

Kod:
<?php
$number 
13;

function 
primeNumberDetector($number) {

    if(
$number 2) {
        return 
false;
    }

    if(
$number == 2) {
        return 
true;
    }

    if(
$number == 0) {
        return 
false;
    }

    for(
$i == 3$i sqrt($number); $i++) {

        if(
$number $i == 0) {
            return 
false;
        }

        else {
            return 
true;
        }       
    }
}
?>
Citera
2019-11-11, 12:47
  #29
Medlem
Basebands avatar
Citat:
Ursprungligen postat av Proton
Finns ju till och med en namngiven algoritm för att finna alla primtal upp till ett godtycligt tal:

https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

Okej tack, jag ska kika på det!
Citera
2019-11-11, 12:50
  #30
Medlem
Citat:
Ursprungligen postat av Baseband
Okej, om det inte spelar någon roll så har jag antagligen skrivit felaktig kod. Jag får följande output:



Från och med 10 verkar det fungera, den anger att 11, 13, 17 och 19 är primtal vilket stämmer. Jag ska fortsätta testa högre tal för att utesluta buggar. Dock anger den felaktigt att 3, 5 och 7 inte är primtal, och det var det jag menade på när det kommer till låga tal. Visserligen skulle jag bara kunna lösa dessa tre enskilda fall med specifika if-satser men jag bifogar min kod nedan först då jag misstänker att jag kanske gjort någonting fel hehe.

Kod:
<?php
$number 
13;

function 
primeNumberDetector($number) {

    if(
$number 2) {
        return 
false;
    }

    if(
$number == 2) {
        return 
true;
    }

    if(
$number == 0) {
        return 
false;
    }

    for(
$i == 3$i sqrt($number); $i++) {

        if(
$number $i == 0) {
            return 
false;
        }

        else {
            return 
true;
        }       
    }
}
?>
Ja, du har gjort fel. Det ska inte vara något else.
Citera
2019-11-11, 13:24
  #31
Medlem
Basebands avatar
Citat:
Ursprungligen postat av Sugminstorasalta
Ja, du har gjort fel. Det ska inte vara något else.

Fast jag vill ju att funktionen ska returnera true om talet är ett primtal, eller hur menar du nu?
Citera
2019-11-11, 13:25
  #32
Medlem
Citat:
Ursprungligen postat av Baseband
Fast jag vill ju att funktionen ska returnera true om talet är ett primtal, eller hur menar du nu?
Du kan ju inte returnera true innan du är klar med loopen, eller hur?
Citera
2019-11-11, 13:38
  #33
Medlem
Basebands avatar
Citat:
Ursprungligen postat av Sugminstorasalta
Du kan ju inte returnera true innan du är klar med loopen, eller hur?

Hmm men om $number är till exempel 23, så kontrolleras först om $number är mindre än 2, vilket det inte är så då körs nästa if-sats där programmet kontrollerar om $number är 2 vilket det heller inte är, och sedan kontrolleras huruvida det är ett jämnt tal i den tredje if-satsen vilket också returnerar false. Sedan påbörjas en for-loop där iteratorn börjar på 3 och villkoret är att iteratorn inte får överskrida kvadratroten ur $number, om detta condition stämmer så inkrementeras iteratorn med 1.

Om $number är 23 så kommer loopen itereras två gånger, först när $i är 3 och sedan ytterligare en gång när $i är 4. Både ($number % 3) samt ($number % 4) !== 0, vilket leder till att min else körs och returnerar true, vilket ju är helt korrekt.

Det kan hända att jag har fel, jag är själv lite osäker så du får gärna rätta mig

Däremot måste jag på något sätt signalera att talet är ett primtal om if-satsen i for-loopen inte returnerar false för några iterations, då false för samtliga iterations = inga faktorer = $number !== primtal, och detta var också anledningen till att jag i början av tråden pushade in de itererade värdena i en array då detta fick agera boolean-värde d.v.s. om array:en är tom = inga itererade värden har pushats in = $number har inga faktorer = $number är ett primtal.
__________________
Senast redigerad av Baseband 2019-11-11 kl. 13:42.
Citera
2019-11-11, 13:39
  #34
Medlem
Jag tror att loopen måste uppdateras så att den även inkluderar fallet med kvadratroten av talet.
Kod:
for($i == 3; $i <= sqrt($number); $i++)
istället för
Kod:
for($i == 3; $i < sqrt($number); $i++) 
Annars blir det nog problem med jämna kvadrater, då dessa inte kontrolleras (25, 49, 81 etc).

Om du har passerat loopen korrekt så har du inte hittat några faktorer till talet och då är det ett primtal. Så då returnerar du bara 'True' rakt av.
__________________
Senast redigerad av DieTrolle 2019-11-11 kl. 13:41.
Citera
2019-11-11, 13:43
  #35
Medlem
Citat:
Ursprungligen postat av Baseband
Hmm men om $number är till exempel 23, så kontrolleras först om $number är mindre än 2, vilket det inte är så då körs nästa if-sats där programmet kontrollerar om $number är 2 vilket det heller inte är, och sedan kontrolleras huruvida det är ett jämnt tal i den tredje if-satsen vilket också returnerar false. Sedan påbörjas en for-loop där iteratorn börjar på 3 och villkoret är att iteratorn inte får överskrida kvadratroten ur $number, om detta condition stämmer så inkrementeras iteratorn med 1.

Om $number är 23 så kommer loopen itereras två gånger, först när $i är 3 och sedan ytterligare en gång när $i är 4. Både ($number % 3) samt ($number % 4) !== 0, vilket leder till att min else körs och returnerar true, vilket ju är helt korrekt.

Det kan hända att jag har fel, jag är själv lite osäker så du får gärna rätta mig

Däremot måste jag på något sätt signalera att talet är ett primtal om if-satsen i for-loopen inte returnerar false för några iterations, då false för samtliga iterations = inga faktorer = $number !== primtal.
Precis som jag har sagt så är det inte direkt någon brist på exempel. Sök på "php isprime"

https://www.geeksforgeeks.org/php-check-number-prime/
https://gist.github.com/twaddington/...a1872786b7f9c0
https://www.w3resource.com/php-exerc...exercise-2.php
Citera
2019-11-11, 13:44
  #36
Medlem
Basebands avatar
Citat:
Ursprungligen postat av DieTrolle
Jag tror att loopen måste uppdateras så att den även inkluderar fallet med kvadratroten av talet.
Kod:
for($i == 3; $i <= sqrt($number); $i++)
istället för
Kod:
for($i == 3; $i < sqrt($number); $i++) 
Annars blir det nog problem med jämna kvadrater, då dessa inte kontrolleras (25, 49, 81 etc).

Om du har passerat loopen korrekt så har du inte hittat några faktorer till talet och då är det ett primtal. Så då returnerar du bara 'True' rakt av.

Just det, det hade jag helt glömt av, tack. Men är det som användaren Sugminstorasalta säger, att mitt else-statement är felaktigt utplacerat eller något? Enligt min egna logik är det helt i sin ordning att den är där den är.
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback