flat assembler
Message board for the users of flat assembler.
![]() Goto page 1, 2, 3 Next |
Author |
|
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 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. |
|||
![]() |
|
Tomasz Grysztar 25 Apr 2018, 11:05
I'm glad to see someone else having fun with it!
![]() bitRAKE wrote: This way I get to use FASMG to parse the lines, but I always wonder if there is an easier way? 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 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 |
|||
![]() |
|
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" |
|||
![]() |
|
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 References: http://beust.com/weblog/2008/08/28/coding-challenge-wrap-up/ http://realtimecollisiondetection.net/blog/?p=78 BSF instruction is a significant reduction. |
|||
![]() |
|
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 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. |
|||
![]() |
|
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 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. |
|||
![]() |
|
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 Code: repeat 1, dk:k, dn:n sum_#dk#_#dn := k+n end repeat 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 |
|||
![]() |
|
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 Quote: Note that while symbolic variables belong to the expression class of symbols, Last edited by bitRAKE on 26 Jan 2019, 10:53; edited 1 time in total |
|||
![]() |
|
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.
|
|||
![]() |
|
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 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 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 |
|||
![]() |
|
bitRAKE 26 Jan 2019, 11:10
Is this the recommended trickery?
Code: s_#dk#_#dn = 0 s_#dk#_#dn = k+n We have to force it variable because it's constant once it's defined. Very cryptic. ![]() Oh, you beat me to it, thank you. |
|||
![]() |
|
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. 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. |
|||
![]() |
|
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 ![]() 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 |
|||
![]() |
|
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 |
|||
![]() |
|
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. ![]() |
|||
![]() |
|
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. |
|||
![]() |
|
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. |
|||
![]() |
|
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 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. |
|||
![]() |
|
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 Last edited by bitRAKE on 17 Feb 2019, 20:51; edited 1 time in total |
|||
![]() |
|
Goto page 1, 2, 3 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.