What's going wrong here

Tried to write a simple program to churn through primes. Thought it would be very simple and am really puzzled that it doesn’t work. All the code is very simple so my best guess is that math.floor doesn’t work as I imagined.

Apologies if it’s a stupid error but I’m really confused.

Also I realise that this isn’t the best way to take advantage of processor grunt since it’s max 60 checks per second. However since I can’t even get this to work I’ve got little chance of refining it!

 Primes

-- Use this function to perform your initial setup
function setup()

end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)
    check = check or 3
    check = check + 1
    
    testPrime(check)
    font("AmericanTypewriter-Bold")
    fontSize(50)
    text(HIGHPRIME, WIDTH/2, HEIGHT/2)
    print(check.."   "..max)
    
end

function testPrime(check)
    max = math.floor(check^0.5)
    status = prime
    for i = 1, max do
        if (check / i) == math.floor(check / i) then
            status = notprime
        end
    end
    if status == prime then
        HIGHPRIME = check
    end
end

@Epicurus101 - Simple error, your loop in testPrime starts at 1, and of course all numbers are divisible by 1 :stuck_out_tongue:

Test for 2 first, then start the loop at 3 and increase by 2 at a time.

Also if you find it is not prime, don’t keep looping, use the break command to stop.

Thank you for spotting the dumb error. You may have found A bug, but you haven’t found THE bug! The problem I have is over detection of primes, not under detection! Run the new version and you’ll see what I mean. So there’s a (hopefully less dumb) error still to be found.


-- Primes


function setup()

end


function draw()

    background(40, 40, 50)
    check = check or 9
    HIGHPRIME = HIGHPRIME or 7
    testPrime(check)
    font("AmericanTypewriter-Bold")
    fontSize(50)
    text(HIGHPRIME, WIDTH/2, HEIGHT/2)
    print(check.."   "..max)
    check = check + 2
end

function testPrime(check)
    max = math.floor(check^0.5)
    status = prime
    for i = 2, max do
        if (check / i) == math.floor(check / i) then
            status = notprime
            break
        end
    end
    if status == prime then
        HIGHPRIME = check
    end
end

@epicurus prime and notprime are always nil. Did you mean not prime instead of notprime.

You don’t need the draw function at all, and the mod function does a better job

Try this

function setup()
    for i=1,100 do
        if testPrime(i) then 
            HIGHPRIME=i
            print(i)
        end
    end
end

function testPrime(check)
    if math.fmod(check,2)==0 then return end
    for i = 3,math.sqrt(check),2 do
        if math.fmod(check,i)==0 then return end
    end
    return true   
end

Maybe it helps if I share my own prime number program here :slight_smile: Just to bring some variation in here ^^

-- Prime V3

function setup()
    -- CONFIGURATION
    
    num = 1      -- Number to start the calculation with
    size = 13           -- Font size (at least 10 suggested)
    speed = 100  -- Check n numbers per frame
    
    -- END OF CONFIGURATION
    
    rectMode(CORNERS)
    textMode(CORNER)
    displayMode(FULLSCREEN)
    img = image(WIDTH, HEIGHT)
    setContext(img)
    background(30, 40, 50, 255)
    setContext()
    spriteMode(CORNER)
    
    borderDist = 3
    numPos = borderDist
    row = 1
    
    if num < 2 then num = 2 end
    if getInt(num/2) then num = num - 1 end
end

function draw()
    for i = 1, speed do
        calculationTick()
    end
    
    sprite(img, 0, 0)
end


function calculationTick()
    if getPrime(num) then printNum(num) end
    num = num + 2 -- simply skip every number devidable by two
end


function getPrime(x)
    prime = true
    for i = 2, math.sqrt(x) do
        if getInt(x/i) then
            prime = false
            break
        end
    end
    if prime then
        return true
    end
end


function getInt(x)
    if x - math.floor(x) == 0 then
        return true
    else
        return false
    end
end


function printNum(x)
    font("Courier")
    fontSize(FontSize)
    fill(255, 255, 255, 255)
    
    --table.insert(primes, x)
    
    textWidth, textHeight = textSize(x)
    rowHeight = textHeight * row
    setContext(img)
    
    textMode(CORNER)
    text(x, numPos, HEIGHT - rowHeight)
    setContext()
    numPos = numPos + textWidth + size/2
    if numPos >= WIDTH-textWidth-borderDist then
        row = row + 1
        numPos = borderDist
    end
end

The method I was using to print the numbers on screen is pretty basic. I wrote that program very early when my lua skills weren’t really advanced… Just look over it and take what you want :slight_smile: The way I search for prime numbers should be easily understandable. :slight_smile:

Thanks all for suggestions of alternative progs, but as ever I learn more by knowing where I went wrong. Dave1707 wins the bug spotting prize. I meant status to be a variable which could either be “prime” or “not prime”. Lack of quotes to denote string was dumb error number 2. Program now works!

@epicurus101 - you should try to learn from everything you can, not just from one simple bug. I showed you some useful optimisations, but I won’t bother next time if you aren’t interested in them.

Hi Ignatz, sorry didn’t mean to appear ungrateful. As I’ve said many times on the forums I owe a huge amount to your tutorials. Learning from everything I can is too much though, because the amount I don’t know is many times greater than what I do know. In practice, tackling particular puzzles is how I learn best I’ve found. If the method I use isn’t working then seeing a completely different way to do the same thing may get me out of one specific jam but won’t prevent me getting into similar jams in future. “Give a man a fish…” sort of stuff.

Bug hunting is a new skill for me, and I’m still trying to build up my armoury so I have a reasonably logical list of things to check. Sadly, both of these bugs were in the “kicking myself” territory!

Thanks for the mod tip. it’s been tucked away for future reference.

@epicurus101 Here’s a simple prime number generator that puts the numbers in a table then prints them. You could use the table of primes to plot the numbers or whatever you want instead of printing them.


function setup()
    limit=1000
    primes={}
    for z=2,limit do
        testPrime(z)
    end
    for key,value in pairs(primes) do
        print(value)
    end
    print(#primes.." prime numbers to "..limit)
end

function testPrime(check)
    for i=2,math.sqrt(check) do
        if check%i==0 then
            return  -- not a prime, exit function
        end
    end
    table.insert(primes,check)  -- put prime number in the table
end

@dave1707 - if you’re doing anything but trivial calculations, you will want to optimise a little more, eg by checking divisibility by 2, then doing a loop starting from 3 with steps of 2, which halves the time required.

@Ignatz I just looked at you’re code above and I see that’s what you’re doing. That will speed things up, but I was just keeping it simple. When I get time, I’ll add a timer and try running it both ways for primes to a million and see what the difference is.

@Ignatz Doing it you’re way runs in half the time. That is reasonable since the “for” loop increments by 2.