flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > [fasmg] Lucas Prime Test

Goto page 1, 2, 3  Next
Author
Thread Post new topic Reply to topic
bitRAKE



Joined: 21 Jul 2003
Posts: 4175
Location: vpcmpistri
bitRAKE 23 Apr 2018, 22:54
Code:
; Lucas Prime Test

; fails for composites: http://oeis.org/A005845
;  705, 2465, 2737, 3745, 4181, 5777, 6721, ...
MACRO LucasCheck num
  LOCAL l0,l1,Lucas
  l0 = -1
  l1 = 2
  REPEAT num
    Lucas = l0 + l1
    l0 = l1
    l1 = Lucas
  END REPEAT
  IF (Lucas-1) MOD num = 0
    DISPLAY `num,": Lucas pseudoprime",13,10
  ELSE
    DISPLAY `num,": Composite Number",13,10
  END IF
END MACRO

LucasCheck 705
LucasCheck 1973
LucasCheck ((1 SHL 19) - 19) ; about ten seconds    
Rereading the manual - so many new features to play with. So far my favorite is continue/file of VIRTUAL - powerful!

Start with some numbers, though.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 23 Apr 2018, 22:54
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4175
Location: vpcmpistri
bitRAKE 24 Apr 2018, 04:59
Next I try to verify some data: There is list of cube sums at https://arxiv.org/abs/1604.07746v1

Seemed rather simple at first, but how to do it without altering the file?
Code:
VIRTUAL AT 0
  BLOCK::
END VIRTUAL

POSTPONE
  VIRTUAL BLOCK
    LOAD data:$@-$$ from $$
  END VIRTUAL
  EVAL data
END POSTPONE

MACRO DisplayNumber in
  LOCAL number
  number = in scale 0
    IF number < 0
      DISPLAY '-'
      number = -number
    END IF
    REPEAT 1, n:number
      DISPLAY `n
    END REPEAT
END MACRO

VIRTUAL BLOCK
  MACRO ?! line&
    MATCH =END =VIRTUAL,line
      END VIRTUAL
      PURGE ?
    ELSE MATCH =INCLUDE txt,line
      file txt
      db 10
    ELSE
      db `line,10
    END MATCH
  END MACRO

  results = 0
  MACRO ?! line&
    MATCH =EOF,line
      PURGE ?
      DISPLAY 10,"Found "
      DisplayNumber results
      DISPLAY " known cube sums.",10,10
    ELSE MATCH k= x= y= z= q,line
      ; assume header
      DISPLAY "Unknown line: ",`line,10
    ELSE MATCH k= x= y= z,line
      IF ~ defined k
        DISPLAY "Unknown line: ",`line,10
      ELSE IF k = (x)*(x)*(x) + (y)*(y)*(y) + (z)*(z)*(z)
        results = results+1
      ELSE
        DISPLAY "Unknown line: ",`line,10
       END IF
    ELSE
      DISPLAY "Unknown line: ",`line,10
    END MATCH
  END MACRO
  INCLUDE "sumofthreecubes_20160426.txt"
  EOF
END VIRTUAL    
Minimal error checking to bypass the header. Result matches what the paper says. This way I get to use FASMG to parse the lines, but I always wonder if there is an easier way?
Code:
flat assembler  version g.i4pue
Unknown line: List of solutions of x^3 + y^3 + z^3 = k for k < 1000
Unknown line: k not s^3 or 2*s^3 (s integer)
Unknown line: x, y, and z bounded up to 10^15
Unknown line: Sander G. Huisman 26-04-2016
Unknown line: Results combined with previous results.
Unknown line: ------------------------------------------------
Unknown line: k x y z
Unknown line: ------------------------------------------------

Found 15254 known cube sums.


2 passes, 0.7 seconds, 0 bytes.    

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 24 Apr 2018, 04:59
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 25 Apr 2018, 11:05
I'm glad to see someone else having fun with it! Wink

bitRAKE wrote:
This way I get to use FASMG to parse the lines, but I always wonder if there is an easier way?
If the file you want to parse may contain absolutely everything, then there may be no easier way. [EDIT] Then I found an easier way, see below. [/EDIT]
But you could make these headers help instead of just being obstacles:
Code:
MACRO DisplayNumber in
  LOCAL number 
  number = in scale 0 
    IF number < 0 
      DISPLAY '-' 
      number = -number 
    END IF 
    REPEAT 1, n:number 
      DISPLAY `n 
    END REPEAT 
END MACRO

results = 0

macro List tail&
 purge List
 macro ?! line&
    MATCH =EOF,line
      PURGE ? 
      DISPLAY 10,"Found " 
      DisplayNumber results 
      DISPLAY " known cube sums.",10,10 
    ELSE MATCH k= x= y= z= q,line 
      ; assume header 
      DISPLAY "Unknown line: ",`line,10 
    ELSE MATCH k= x= y= z,line 
      IF ~ defined k 
        DISPLAY "Unknown line: ",`line,10 
      ELSE IF k = (x)*(x)*(x) + (y)*(y)*(y) + (z)*(z)*(z) 
        results = results+1 
      ELSE 
        DISPLAY "Unknown line: ",`line,10 
       END IF 
    ELSE 
      DISPLAY "Unknown line: ",`line,10 
    END MATCH 
 end macro
end macro

INCLUDE "sumofthreecubes_20160426.txt"
EOF    
And another small trick to get rid of EOF macro:
Code:
MACRO DisplayNumber in
  LOCAL number 
  number = in scale 0 
    IF number < 0 
      DISPLAY '-' 
      number = -number 
    END IF 
    REPEAT 1, n:number 
      DISPLAY `n 
    END REPEAT 
END MACRO

results = 0

macro List tail&
 purge List
 local File
 File := __FILE__
 macro ?! line&
    if __FILE__ <> File
      PURGE ? 
      DISPLAY 10,"Found " 
      DisplayNumber results 
      DISPLAY " known cube sums.",10,10
      line
    ELSE MATCH k= x= y= z= q,line 
      ; assume header 
      DISPLAY "Unknown line: ",`line,10 
    ELSE MATCH k= x= y= z,line 
      IF ~ defined k 
        DISPLAY "Unknown line: ",`line,10 
      ELSE IF k = (x)*(x)*(x) + (y)*(y)*(y) + (z)*(z)*(z) 
        results = results+1 
      ELSE 
        DISPLAY "Unknown line: ",`line,10 
       END IF 
    ELSE 
      DISPLAY "Unknown line: ",`line,10 
    END MATCH 
 end macro
end macro

INCLUDE "sumofthreecubes_20160426.txt"    


Also, to make it a bit more universal, instead of "macro Line" you could use "macro ?" and then count on the first line of included file to not contain any unconditional directive/macro. INCLUDE is an unconditional instruction (so "macro ?" does not catch it) because it has an unconditional variant (the one when "!" modifier is used).


Last edited by Tomasz Grysztar on 25 Apr 2018, 14:17; edited 1 time in total
Post 25 Apr 2018, 11:05
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 25 Apr 2018, 11:46
On a second thought, you could use that trick which allows to switch to namespace than contains no defined instructions and then "macro ?" should catch the first line of included file universally:
Code:
MACRO DisplayNumber in 
  LOCAL number  
  number = in scale 0  
    IF number < 0  
      DISPLAY '-'  
      number = -number  
    END IF  
    REPEAT 1, n:number  
      DISPLAY `n  
    END REPEAT  
END MACRO 

results = 0 

macro ProcessLine line& 
  MATCH k= x= y= z= q,line 
    ; assume header 
    DISPLAY "Unknown line: ",`line,10 
  ELSE MATCH k= x= y= z,line 
    IF defined k & k = (x)*(x)*(x) + (y)*(y)*(y) + (z)*(z)*(z) 
      results = results+1 
    ELSE 
      DISPLAY "Unknown line: ",`line,10 
    END IF 
  ELSE 
    DISPLAY "Unknown line: ",`line,10 
  END MATCH 
end macro 

macro Finish 
  DISPLAY 10,"Found " 
  DisplayNumber results 
  DISPLAY " known cube sums.",10,10 
end macro 

macro _ProcessFile path, MACRO, END, INCLUDE

  local space 

  NAMESPACE space     ; enter a namespace with no instructions 

  MACRO ? first_line&
   END NAMESPACE
   purge ?
   _FILE := __FILE__
   macro ?! line&
     if __FILE__ = _FILE
       ProcessLine line
     else
       purge ?
       Finish
       line
     end if
   end macro
   first_line
  END MACRO

  INCLUDE path

end macro 

macro ProcessFile path
  _ProcessFile path, macro, end, include
end macro 

ProcessFile "sumofthreecubes_20160426.txt"    
Post 25 Apr 2018, 11:46
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4175
Location: vpcmpistri
bitRAKE 09 May 2018, 05:20
Very fast solution to unique digit sequences:
Code:
struc NextKBitNumber
  local smallest,ripple
  smallest = . and (- .)
  ripple = . + smallest
  . = ripple or ((. xor ripple) shr (2 + (bsf smallest)))
end struc

repeat 9
  ; number of digits = bits set
  n = (1 shl %) - 1
  while (bsr n) < 9
    repeat 9
      m = n and (1 shl (%-1))
      if m
        display "0"+%
      end if
    end repeat
    display 13,10
    n NextKBitNumber
  end while
end repeat    
I intentionally skipped the zero digit: it makes the output much longer and creates another test in the inner loop. Not a big deal.

References:
http://beust.com/weblog/2008/08/28/coding-challenge-wrap-up/
http://realtimecollisiondetection.net/blog/?p=78

BSF instruction is a significant reduction.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 09 May 2018, 05:20
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4175
Location: vpcmpistri
bitRAKE 10 Jan 2019, 08:00
http://www.cs.utsa.edu/~wagner/knuth/
7.1.4. Binary decision diagrams

In further exploration with fasmg:
Code:
element v:'v'
element l:'l'
element h:'h'

struc I terms&
  namespace .
  iterate term,terms
    indx 1+%%-%
    match V=?L=:H,term
      repeat 1,d:%-1
        I#d := v*V + l*L + h*H
      end repeat
    end match
  end iterate
  iterate term,terms
  nodes = %%
  break
  end iterate
  end namespace
end struc

; calculate number of solution of BDD
struc Algorithm_C BDD*
        local c
        c.0 = 0
        c.1 = 1
        repeat BDD#.nodes - 2, k:2
        repeat 1,lo:BDD#.I#k scale 2
        repeat 1,hi:BDD#.I#k scale 3
                c.#k := \
                (c.#lo shl ((BDD#.I#lo scale 1) - (BDD#.I#k scale 1) - 1)) +\
                (c.#hi shl ((BDD#.I#hi scale 1) - (BDD#.I#k scale 1) - 1))
        end repeat
        end repeat
        end repeat
        repeat 1,s:BDD#.nodes - 1
                . = c.#s shl ((BDD#.I#s scale 1)-1)
        end repeat
end struc


TT I 1?7:6,2?5:4,2?0:1,3?1:0,3?3:2,4?1:0,4?0:1,5?1:1,5?0:0
answer Algorithm_C TT

repeat 1,d:answer
  display `d," solutions to BDD.",13,10
end repeat


iSets I 1?14:13,2?12:11,2?10:0,3?9:8,3?9:0,3?7:6,4?5:4,4?5:0,4?2:3,4?2:0,5?1:2,5?1:0,5?2:0,6?1:0,7?1:1,7?0:0
answer Algorithm_C iSets

repeat 1,d:answer
  display `d," independent sets of C_6.",13,10
end repeat    
Directly from the interesting text...
http://www.cs.utsa.edu/~wagner/knuth/fasc1b.pdf
(source, but no PDF)
https://www-cs-faculty.stanford.edu/~knuth/taocp.html#vol4

Now to write some generating functions and see if the implementation needs to be tweaked.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 10 Jan 2019, 08:00
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4175
Location: vpcmpistri
bitRAKE 26 Jan 2019, 07:22
Is there a way to memorize values efficiently in fasmg?

As an example:
Code:
struc f terms&
        . = 0
        iterate t,terms
                . = . + t*t
        end iterate
end struc


struc sum k,n
        local temp
        . = 0
        repeat n
                temp f %
                . = . + k * temp
        end repeat
end struc    
I would like to save the computed values of "sum" for each set of parameters. Some languages have dictionaries - key,value pairs to expedite this. I'm just wonder how to construct this in fasmg?

Extending the above, if I had another sum which depended on the above sum. Ideally, we don't want to recompute everything for the same input values. One method I tried was creating dynamic symbols with the parameters, but couldn't get it to work.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 26 Jan 2019, 07:22
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 26 Jan 2019, 08:11
I would just do it like this:
Code:
struc sum k,n
        ; ...
        repeat 1, dk:k, dn:n
                sum.dk.dn := k+n
        end repeat
end struc    
This produces a lot of namespaces. You could try to make it use a bit less memory by using a single flat namespace:
Code:
        repeat 1, dk:k, dn:n
                sum_#dk#_#dn := k+n
        end repeat    
Probably worth checking which one works better for you.

BTW, a trick with a conversion to number allows to use any text as a key for storage:
Code:
macro put key,value
        repeat 1, dk:`key
                stored.dk = value
        end repeat
end macro

struc get key
        repeat 1, dk:`key
                . = stored.dk
        end repeat
end struc


put @:-), 2357

now get @:-)

dd now    
Post 26 Jan 2019, 08:11
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4175
Location: vpcmpistri
bitRAKE 26 Jan 2019, 10:10
How do we avoid computing the sum multiple times though? How to work around the undefined key?
Code:
                match ,s_#dk#_#dn
                        display "match "
                end match
                if defined s_#dk#_#dn
                        display "defined "
                end if
                if used s_#dk#_#dn
                        display "used "
                end if
                if s_#dk#_#dn relativeto 0
                        display "relativeto 0"
                end if
                display 13,10    
Tested these, but it's eventually defined used and relativeto 0.
Quote:
Note that while symbolic variables belong to the expression class of symbols,
their state cannot be determined with operators like "defined" or "used",
because an logical expression containing such operators is evaluated as if
every symbolic variable was replaced with the text of corresponding value.
Therefore "defined" followed by an identifier* of symbolic variable is going to
be applied to the content of this variable, whatever it is. For example if you
create a symbolic variable which is simply a link to a regular symbol, the
"defined" or "used" followed by the identifier of this symbolic variable is
going to determine the status of linked symbol.
* typo


Last edited by bitRAKE on 26 Jan 2019, 10:53; edited 1 time in total
Post 26 Jan 2019, 10:10
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 26 Jan 2019, 10:50
You need to force variable status of such symbol, so it cannot be forward-referenced and then DEFINED is going to work as you expect.
Post 26 Jan 2019, 10:50
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 26 Jan 2019, 10:59
Some examples:
Code:
struc sum k,n
        repeat 1, dk:k, dn:n
                if ~ defined sum.dk.dn
                        sum.dk.dn = k+n
                        sum.dk.dn = k+n
                end if
                . = sum.dk.dn
        end repeat
end struc    
or for the same effect:
Code:
struc sum k,n
        repeat 1, dk:k, dn:n
                if ~ defined sum.dk.dn
                        restore sum.dk.dn
                        sum.dk.dn = k+n
                end if
                . = sum.dk.dn
        end repeat
end struc    
Finally a variant that works with multi-pass and caches once computed value for all future passes:
Code:
struc sum k,n
        repeat 1, dk:k, dn:n
                if ~ defined sum.dk.dn
                        sum.dk.dn = k+n
                else
                        sum.dk.dn = sum.dk.dn
                end if
                . = sum.dk.dn
        end repeat
end struc    
Post 26 Jan 2019, 10:59
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4175
Location: vpcmpistri
bitRAKE 26 Jan 2019, 11:10
Is this the recommended trickery?
Code:
s_#dk#_#dn = 0
s_#dk#_#dn = k+n    
Wish it was just the single "=" and ":=" for constant.

We have to force it variable because it's constant once it's defined. Very cryptic. Razz

Oh, you beat me to it, thank you.
Post 26 Jan 2019, 11:10
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 26 Jan 2019, 11:31
bitRAKE wrote:
We have to force it variable because it's constant once it's defined. Very cryptic. Razz
Yeah, backward-compatibility has prevented it from being nice.

My last example is not complete - it works only if "sum" is used once (it would be more clear if I used := instead of = inside). To make it work generally, additional variable to mark the status within current pass would be needed.
Post 26 Jan 2019, 11:31
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4175
Location: vpcmpistri
bitRAKE 27 Jan 2019, 15:32
Computing the terms of https://oeis.org/A000055
Number of trees with n unlabeled nodes.
Code:
a_1 := 1
struc a: n
        repeat 1,dn:n
                if ~ defined a_#dn
                        a_#dn = 0
                        local _a,_s
                        repeat n-1
                                _a a %
                                _s s n-1,%
                                a_#dn = a_#dn + _a*_s*%
                        end repeat
                        a_#dn = a_#dn / (n-1)
                end if
                . = a_#dn
        end repeat
end struc


struc s: n*,k*
        repeat 1, dn:n, dk:k
                if ~ defined s_#dk#_#dn
                        restore s_#dk#_#dn ; force variable
                        s_#dk#_#dn a n+1-k
                        if ~ (n < 2*k)
                                local _s
                                _s s n-k,k
                                s_#dk#_#dn = s_#dk#_#dn + _s
                        end if
                end if
                . = s_#dk#_#dn
        end repeat
end struc


struc A000055 n
        repeat 1, dn:n
                if ~ defined A000055_#dn
                        restore A000055_#dn ; force variable
                        A000055_#dn a n
                        local aj,da
                        repeat n/2
                                aj a %
                                da a n-%
                                A000055_#dn = A000055_#dn - aj*da
                        end repeat
                        if ~ (n and 1)
                                A000055_#dn = A000055_#dn + da*(da+1)/2
                        end if
                end if
                . = A000055_#dn
        end repeat
end struc    
Needing "restore" on just the "s" function was really confusing. Everything else appeared to work and it wasn't clear why it was broken. Thanks again for the help. Very Happy

In under a second:
Code:
display "n",9,"bits",9,"A000055(n)",13,10
repeat 196
        DisplayNumber %
        display 9

        N A000055 %
        b = bsr N
        if N > (1 shl b)
                b = b + 1
        end if
        DisplayNumber b
        display 9

        DisplayNumber N
        display 13,10
end repeat    

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 27 Jan 2019, 15:32
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4175
Location: vpcmpistri
bitRAKE 01 Feb 2019, 19:45
Code:
struc pow?: n,e ; exponentiation, n^e
        repeat 1,dn:n,de:e
                if de > 0
                        local t
                        t pow dn,de shr 1
                        if de and 1
                                . = t * t * dn
                        else
                                . = t * t
                        end if
                else if de = 0
                        . = 1
                else
                        err
                end if
        end repeat
end struc    
Post 01 Feb 2019, 19:45
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 02 Feb 2019, 09:13
Do you use "repeat 1" as a method of sanitizing macro arguments? I never thought of this method, interesting.

PS. It fills me with joy to see that you keep playing with fasmg and having fun with it. After all, I hoped I would not be making it a toy just for myself. Smile
Post 02 Feb 2019, 09:13
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4175
Location: vpcmpistri
bitRAKE 02 Feb 2019, 19:54
The sanitizing is only needed once - haven't tested if redefining STRUC would be an optimization.

P.S. I do have notes for my own "assembler" but the underlying premise is quite different. Exploration with other languages helps me to work through the design. Still searching for the all inclusive type system - I think it might not exist.

Going back to a time without protection, security, etc. How much do we give up for these illusions? Trust itself dissolves - we don't need trust because we can fall back to our walls. To live in reality is to be adrift at sea.
Post 02 Feb 2019, 19:54
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 03 Feb 2019, 15:28
bitRAKE wrote:
P.S. I do have notes for my own "assembler" but the underlying premise is quite different. Exploration with other languages helps me to work through the design. Still searching for the all inclusive type system - I think it might not exist.
Great, and good luck! I strongly believe that we should keep exploring new possibilities. This is one of main intents that emerged behind my development of fasm and fasmg - they are like "outsiders" that complement the "mainstream" tools and languages and show how some things can be done differently. Having many different "outsiders" of this kind is, I believe, important - we should keep researching alternatives that would otherwise gone unnoticed.
Post 03 Feb 2019, 15:28
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4175
Location: vpcmpistri
bitRAKE 05 Feb 2019, 00:34
Pulling out all the stops on new features to change ";" delimiters to commas. UnicodeData.txt can be sent to MACRO or ITERATE'or, etc.
Code:
PREPROCESSOR := __FILE__
namespace PREPROCESSOR

retaincomments
isolatelines

macro ProcessLine line&
        local P
        define P line
        while 1
                match first;rest,P
                        redefine P first,rest
                else match rest;,P
                        redefine P rest,
                        break
                else match ,P
                        err 'unexpected line ',`line,13,10
                        break
                else
                        break
                end match
        end while
        match any,P
                db `any,13,10
        end match
end macro

define symlinks include:macro:purge:if:else:end:namespace:__FILE__:PREPROCESSOR
match include:macro:purge:if:else:end:namespace:__FILE__:PREPROCESSOR, symlinks
macro EMPTY
        local empty
        namespace empty
                macro ? line&
                        if __FILE__ = PREPROCESSOR
                                purge ?
                                line
                        else
                                namespace PREPROCESSOR
                                        ProcessLine line
                                end namespace
                        end if
                end macro
                include '../www.unicode.org/Public/11.0.0/ucd/UnicodeData.txt'
        end namespace
end macro
end match

EMPTY

combinelines
removecomments
end namespace    
Any language with a string split function could probably do it in a couple lines of code, but where is the fun in that, lol.

Note: commas do appear in the original data, but only between <> as codepoint range markers. So, they do not interfere with use in FASMG as a single parameter.
Post 05 Feb 2019, 00:34
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4175
Location: vpcmpistri
bitRAKE 16 Feb 2019, 04:27
Code:
macro Lucas_Lehmer_Test P*
        ; allow special case for two, otherwise P must be odd
        assert P and 1 | P = 2

        local S,M
        M := (1 shl P) - 1
        S = 4 ; A003010, A018844

        repeat P-2
                S = S * S - 2
                S = (S shr P) + (S and M)
                if S > M
                        S = S - M ; same as S = (S and M) + 1
                end if
        end repeat

        display '2^'
        DisplayNumber P
        display '-1 is '

        if S = M | P = 2
                display 'prime'
        else
                display 'composite'
        end if

        display '.',13,10
end macro


; A000043
iterate p, 2,3,5,7,13,17,19,31,61,89,107,127,521,607,1279,2203,2281,3217,4253,4423,9689,9941,11213,19937,21701,23209,44497,86243,110503,132049,216091,756839,859433,1257787,1398269,2976221,3021377,6972593,13466917,20996011,24036583,25964951,30402457,32582657,37156667,42643801,43112609,57885161,74207281,77232917,82589933
        indx 23
        Lucas_Lehmer_Test p
;       if % > 21
;               display 13,10,'Verified '
;               DisplayNumber %
;               display ' of '
;               DisplayNumber %%
;               display ' known Mersenne primes.'
                break
;       end if
end iterate    


; flat assembler version g.igd4j
; 2^11213-1 is prime.
; 1 pass, 62.7 seconds, 0 bytes.

; flat assembler version g.igd4j
; 2^19937-1 is prime.
; 1 pass, 319.3 seconds, 0 bytes.

; flat assembler version g.igd4j
; Verified 22 of 51 known Mersenne primes.
; 1 pass, 118.1 seconds, 0 bytes.

Notes: Twice as fast as "MOD M" method. Performance really suffers if numbers are allowed to grow. S(P-2) always equals M with this method! (Could move the -2 to the end of loop for zero result.)

https://rosettacode.org/wiki/Lucas-Lehmer_test

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup


Last edited by bitRAKE on 17 Feb 2019, 20:51; edited 1 time in total
Post 16 Feb 2019, 04:27
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2, 3  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.