Conway’s game of life
Author | Message | ||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
Conway’s game of life has always fascinated me so when I saw the recent link to a LED display running it I decided to have a go and write it for MMBasic DOS with a view to perhaps doing a CMM version. That went well enough and it runs well and very fast on the PC. So I decided to convert it to the Micromite with TeraTerm. I was surprised how slow it was on the Micromite. With the DOS version there is a 300mS PAUSE instruction in the program between updates but with the Micromite that blew out to over 3 seconds with the pause removed! With a fair bit of tweaking and MMEdit’s crunch on load it’s working a lot better but limited a bit by the serial link to TeraTerm. The un-tweaked DOS version is more watchable. I’ll include them here if anyone wants to play and maybe tell me how to speed the Micromite version up a bit. original MMBasic DOS version Life03.zip Micromite with TeraTerm version LifeT01.zip Edit: I forgot to say: MMEdit's crunch on load helped too. Bill Edited 2020-04-25 15:42 by Turbo46 Keep safe. Live long and prosper. |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4048 |
Hey Bill, Very pretty. I don't have a Micromite, but I ported your code to the Colour Maximite (replace "Else If" with "ElseIf") and gave it a bit of a prod. Note that results with the CMM may differ from the uM as I don't know if Geoff optimised variable resolution (a significant bottleneck) in the BASIC interpreter between v4.5 and 5. The best optimisation I could find was this: Sub NextGen ' Breed the next generation into a new matrix Print Chr$(27) "[H" For y = 1 To MatY b = 0 c = CurM(1, y - 1) + CurM(1, y) + CurM(1, y + 1) s$ = Space$(MatX) For x = 1 To MatX d = CurM(x + 1, y - 1) + CurM(x + 1, y) + CurM(x + 1, y + 1) adj = b + c + d If CurM(x, y) Then Poke Var s$, x, &h4f MewM(x, y) = (adj = 3) Or (adj = 4) Else MewM(x, y) = (adj = 3) EndIf b = c c = d Next x Print s$ Next y End Sub And similarly for NextGen2. This was ~30% faster than the original code on my CMM. Basically this: 1. reduces the number of variable lookups. 2. prints the matrix a line at a time instead of a cell at a time. Shorter variable names also help, but I expect that is one of the things that "crunch on load" might be doing for you; I have no experience with MMEdit since I am using a Raspberry Pi as my serial terminal not Windoze. I believe there is a further optimisation at the expense of clarity & flexibility by using a hardcoded matrix width and using a 1D instead of 2D array but I would guess it would only get you another 10% at most. Best wishes, Tom |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4048 |
Hi Bill, I hope you don't mind but I've taken the liberty of attaching my CMM port including some graphics (which are pretty but slow): LIFE_CMM.zip And you can see a video here: Conway's Game of Life on YouTube Yellow = births Green = survivors Red = deaths Please let me know if you want either removed. Best wishes, Tom |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
Hi Tom, Thanks for that, very clever! I know you are doing something clever with the matrix with the c and d variables but I need a coffee or two to work it out. Printing a line at a time is clever too, If I'd even thought of it I would have used string functions to to do it but your POKE VAR method would have to be quicker. It does fix the character to "O" but that's OK. I have wondered whether using just 79 rather than &H4F is faster, but never tested it. I guess that CHR$(a$) would also work? But slower. Using: MewM(x, y) = (adj = 3) Is also something I never do, I would use IF THEN. Did I say I'm not a programmer? MMEdit's crunch just removes REMs, blank lines and formatting spaces I believe. I tried to keep the variable name lengths short but still have a meaning. Removing spaces within the program also helps I believe: a=b not a = b. Thanks again Tom, I'll have a play again this arvo if I get the time. Bill Keep safe. Live long and prosper. |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
Hi Tom, Thanks yet again, that's brilliant! Now I'm going to have to dust off my CMM and have a play. It may be just because it's a new concept but I find the different colours a bit confusing. I thought something like that may be interesting but take too much processing. Maybe an option to just show live cells? I'd like to see a graphics only version and/or a print only version. I expect they would both run faster than the combined version? BTW I noticed a stray PRINT in the InitM sub, I was printing the initial array in that sub as well and missed removing it. There is a crunch utility in the library, it may be worth having a look at. Bill Keep safe. Live long and prosper. |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
Hi again Tom, It took more than a couple of coffees but I think I have it worked out. b=0 represents the 3 values of (x-1,y-1) , (x-1,y) and (x-1,y+1) which are off the edge and are zero according to the rules. c is same but around x and d is the same around x+1 Adj includes the value of the current cell which you take into account when updating the new matrix. And then you maintain that moving window of 9 cells as you move along x. b=c c=d And you only need to calculate d each time around the loop. Is that correct? For a printing version the screen update could be quicker if instead of a$ being used to print one line, an array a$(x,y) could hold the whole screen which could be printed in a FOR NEXT loop? Bill Keep safe. Live long and prosper. |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4048 |
Hey Bill, Sounds like you've got it! and it saves a significant number of variable lookups - I can't stress too much how at least on the CMM these are the biggest "unexpected" performance killer. Is my code measurably faster on the Micromite? I doubt there is any significant difference between using 79 and &h4F, but if you test it then let me know. Yes, you could use CHR$(a$) but that is an extra variable lookup and function call; if you do it then at least declare a = CHR$("O") at the start instead of a$, it would save you 250 bytes of memory too. Actually you would only need a 1D array of strings, an element per line. But I don't believe this will help you because of all the additional variable lookups at the printing stage. Now if there were a PRINT (C)function that could print the entire array as a single operation it would be different. Note that printing a line at a time did not make as significant a performance improvement as I expected, and a great deal less than the variable lookup optimisation. I am a programmer but in my day job using modern PC hardware and compiled languages I wouldn't be using such aggressive hand optimisation as I applied to this subroutine. I'll leave that to automated tools, I like my whitespace the way it is when developing. An exercise for the reader You might also try different circles instead of colour. Smaller circles for births and unfilled circles for deaths. Absolutely as you wouldn't need to lookup the GRAPHICS variable all the time. So there was. I tried to avoid rewriting/reformatting all your code Thanks what we really need is a macro/preprocessor so that constant variable values get inlined on execution. Anyway I don't want to stage a "takeover" of your fun, but here are some things you could experiment with: 1. On the Micromite (not Maximite) you could see whether you get better performance using integer variables, see Micromite User Manual, p33. On most computers integer operations are faster than floating point operations ... though I don't guarantee it makes a difference in MMBasic. 2. The "duplication" of the NextGen function is undesireable but not trivially fixed because (at least in MMBasic 4.5) we can't pass an array as a parameter to a Sub/Function. However if you declare a single matrix with twice the number of rows you can then just switch between the two "halves" using offsets into that matrix, e.g. Sub NextGen ' Breed the next generation into a new matrix Print Chr$(27) "[H" For y = 1 To MatY b = 0 c = CurM(1, y - 1) + CurM(1, y) + CurM(1, y + 1) ... becomes Sub NextGen(offset) ' Breed the next generation into a new matrix Print Chr$(27) "[H" For y = 1 + offset To MatY + offset b = 0 c = CurM(1, y - 1) + CurM(1, y) + CurM(1, y + 1) ... Any resulting performance penalty should be marginal. 3. You could try making the matrix toroidal by having the right hand side consider cells on the left hand side to be adjacent, and vice-versa. Same for top and bottom. You'll lose some performance but it makes smaller matrices more interesting; I will be doing it for my 16x16 LED matrix. Best wishes, Tom |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
Hi Tom, Yes, your code is faster on the Micromite. With the Micromite using both b$ and b is a no no, so I changed b$ to e$. Yes, a 1D array of course. I was thinking of the visual appearance (?) hoping to reduce the delay between each line. I'll try it and see. Re the grapics, Maximite can use custom fonts, I haven't investigated them yet but maybe a font could be used in place of grapics. I believe that on the 'Mites that integers can even be slower because floating point calculations use the on-board floating point processor. I deliberately didn't use integers because I was aiming for a Maximite version. That's a good idea to reduce the code size, it did annoy me to have to have two almost identical subroutines. However it was quicker than the method used in the DOS version. Whoosh! that went straight over my head. Coffee won't help with that one. Thanks again Bill Edited 2020-04-27 10:19 by Turbo46 Keep safe. Live long and prosper. |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6108 |
This 'should' work on all mites with a LCD. Tested on a H7 I left all the heavy lifting alone and just updated where necessary for the uMs. The main change was RGB(colour) needed for the display routines. ' John Conway's Game of Life for Micromite MMBasic with TeraTerm ' Bill McKinley 'Mode 3 dim Bx$ dim GRAPHICS = 1 ' Set = 0 for Terminal mode, = 1 for Graphics ' NOTE: If you make the matrix too small the Glider demo will cause an error ' and the matrix will not overwrite some of the text on the screen ' Make it too big and it will not fit on the screen ' A ratio of 2 of x to 1 of y gives a better looking display dim MatX = 40 ' Matrix horizontal size dim MatY = 25 ' Matrix vertical size dim RandL = 0.3 ' For the randomizing of life less than =< RandL means there is life ' Make it high and you get a lot of cells but they die quickly dim PT = 000 ' Pause time in mS between display updates dim DIAM If GRAPHICS Then 'DIAM = 480 / MatX : MatY = 35 DIAM = mm.hres/matX MatY = int( MatX *mm.vres/mm.hres) endif ' Zero based matrix has one more cell all round than is displayed Dim CurM(MatX+1, MatY+1) ' The current matrix of life Dim NewM(MatX+1, MatY+1) ' The next generation of life ChkScr ' Print intro SetupTimer ' Randomize by waiting for a keypress ClrScr ' Clear the screen (matrix area) InitM ' Initialize the random matrix (or demo) Do ' Program loop NextGen ' Calculate the next generation Pause PT NextGen2 ' Calculate the next generation 'UpdateM ' Update the matrix with the new generation Pause PT Loop Until Inkey$ <> "" ' loop forever or until a keypres Sub ChkScr ' Print intro ClrScr Print " CONWAY'S GAME OF LIFE" Print " Press a key to start" Print " and another to stop" Print " G for a glider demo" End Sub Sub SetupTimer ' Wait for a key press to start timer Do Bx$ = Inkey$ Loop Until Bx$ <> "" 'Randomize Timer End Sub Sub ClrScr 'Clear the screen area If Not GRAPHICS Then Print Chr$(27) "[2J" Chr$(27) "[H" Else Cls End Sub Sub InitM ' Initialise the matrix of life local integer x,y If Bx$ = "g" Or bx$ = "G" Then 'Set thr glider and target CurM(4, 7) = 1 CurM(5, 7) = 1 CurM(6, 7) = 1 CurM(6, 6) = 1 CurM(5, 5) = 1 CurM(15, 15) = 1 CurM(15, 16) = 1 CurM(16, 15) = 1 CurM(16, 16) = 1 Else For y = 1 To MatY For x = 1 To MatX If Rnd() <= RandL Then CurM(x, y) = 1 Else CurM(x, y) = 0 EndIf Next x Next y EndIf End Sub Sub NextGen ' Breed the next generation into a new matrix local integer x, y, b, c, d, adj, dying, birth local s$ If Not GRAPHICS Then Print Chr$(27) "[H" For y = 1 To MatY b = 0 c = CurM(1, y - 1) + CurM(1, y) + CurM(1, y + 1) s$ = Space$(MatX) For x = 1 To MatX d = CurM(x + 1, y - 1) + CurM(x + 1, y) + CurM(x + 1, y + 1) adj = b + c + d If CurM(x, y) Then Poke Var s$, x, &h4f birth = NewM(x, y) = 0 NewM(x, y) = (adj = 3) Or (adj = 4) If GRAPHICS Then If birth Then draw_cell(x, y, rgb(Yellow)) Else draw_cell(x, y, rgb(Green)) EndIf Else dying = adj <> 3 And NewM(x, y) = 1 NewM(x, y) = (adj = 3) If GRAPHICS Then If dying Then draw_cell(x, y, rgb(red)) Else draw_cell(x, y, rgb(Black)) EndIf EndIf b = c c = d Next x If Not GRAPHICS Then Print s$ Next y End Sub Sub draw_cell(x, y, col) Circle(x - 0.5) * DIAM, (y - 0.5) * DIAM, DIAM/2 - 2, 1,,col, col End Sub Sub NextGen2 ' Breed the next generation into a new matrix local integer x, y, b, c, d, adj, dying, birth local s$ If Not GRAPHICS Then Print Chr$(27) "[H" For y = 1 To MatY b = 0 c = NewM(1, y - 1) + NewM(1, y) + NewM(1, y + 1) s$ = Space$(MatX) For x = 1 To MatX d = NewM(x + 1, y - 1) + NewM(x + 1, y) + NewM(x + 1, y + 1) adj = b + c + d If NewM(x, y) Then Poke Var s$, x, &h4f birth = CurM(x, y) = 0 CurM(x, y) = (adj = 3) Or (adj = 4) If GRAPHICS Then If birth Then draw_cell(x, y, rgb(Yellow)) Else draw_cell(x, y, rgb(Green)) EndIf Else dying = adj <> 3 And CurM(x, y) = 1 CurM(x, y) = (adj = 3) If GRAPHICS Then If dying Then draw_cell(x, y, rgb(red)) Else draw_cell(x, y, rgb(Black)) EndIf EndIf b = c c = d Next x If Not GRAPHICS Then Print s$ Next y End Sub Back when I did one on the Microbee (I think), I used an extra dimension to the one array and toggled between the two sides rather than 2 arrays. Jim VK7JH MMedit  MMBasic Help |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
Thanks Jim, That's another idea that didn't occur to me. Just so I have that right, if I use: Dim CurM(MatX+1, MatY+1, 1) That will create a 3 dimensional array consisting of two 2 dimensional arrays: CurM(MatX+1, MatY+1, 0) and CurM(MatX+1, MatY+1, 1) That would be a lot easier to handle than one large array with offsets. Bill Keep safe. Live long and prosper. |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6108 |
Yes and G1 = 1 - G1 G2 = 1 = G1 will do the toggling for each generation then use CurM(MatX+1, MatY+1, G1) CurM(MatX+1, MatY+1, G2) Jim VK7JH MMedit  MMBasic Help |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
G1 = 1 - G1 G2 = 1 = G1 I understand (eventually) I was thinking of using: NextGen 0,1 NextGen 1,0 To tell NextGen which array to use and which to update but your suggestion means that I only have to call NextGen once with no parameters. Neat! Thanks again Jim. Bill Edit: Should that be: G1 = 1 - G1 G2 = 0 = G1 Edit2: Got the TeraTerm version working with Jim's suggestion of a 3 dimensional matrix and will post it later. Edited 2020-04-27 15:05 by Turbo46 Keep safe. Live long and prosper. |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
For anyone interested here is the revised version for a Miromite with TeraTerm. LifeT03.zip and one text only version for the Maximite. LifeC01.zip The changes include: Tom's algorithm for updating the new matrix, Jim's 3 dimension array and printing the whole matrix after the whole array has been updated. Bill Keep safe. Live long and prosper. |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4048 |
I should have come up with that, I guess I literally demonstrated 2D thinking ... ... actually I was thinking of using a 1D array of floats and treating it as an array of bytes on which I could impose whatever structure I wanted with Poke & Peek. Best wishes, Tom Edited 2020-04-28 05:01 by thwill |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4048 |
Integer calculations being slower seems highly unlikely, as I understand it the reason there isn't also an on-board integer processor is you don't need one, it's only floating points that require the extra support. Aside: if I remember correctly Intel processors (386/486) came with SX and DX variants, the DX variant included the floating point support, and the SX did not. However both were manufactured as the same IC and then the FP unit on the SX versions were mechanically "damaged". A good reason. Whoosh! that went straight over my head. Coffee won't help with that one. From Wikipedia: "A more sophisticated trick is to consider the left and right edges of the field to be stitched together, and the top and bottom edges also, yielding a toroidal array. The result is that active areas that move across a field edge reappear at the opposite edge." Basically if you have this array: A B C D E F G H I J K L M N O P Q R S T Instead of treating it as having a border of dead cells: X X X X X X X X A B C D E X X F G H I J X X K L M N O X X P Q R S T X X X X X X X X You pretend you are looking at a window of a larger array that extends and repeats infinitely: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... A B C D E A B C D E ... ... F G H I J F G H I J ... ... K L M N O K L M N O ... ... P Q R S T P Q R S T ... ... A B C D E A B C D E ... ... F G H I J F G H I J ... ... K L M N O K L M N O ... ... P Q R S T P Q R S T ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Now when considering adjacencies A is considered to be next to 8 potentially "live "cells T, P, Q, E, B, J, F and G instead of 5 of the cells it is next to always being "dead". Best wishes, Tom |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4048 |
I haven't had opportunity to measure it myself, but isn't that perceptibly slower than printing as you go along? Aside: it also uses more memory but that isn't an issue for such a small program and in any case you are already using 4 bytes to store each cell where you only need 1 bit. Best wishes, Tom |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
That was my expectation but I seem to recall being corrected on that myself (by CaptainBoing?). I'll do some tests. I get it. A 'glider' going off the right of the display would then enter from the right? Yes, There is a pause while spawning the next generation but then printing the next generation is quicker. I think it looks better. Yes, unfortunately. Any packing and unpacking the data would slow it down though. Bill Keep safe. Live long and prosper. |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1619 |
It seems that integers vs floats is not that simple, see this post Bill Keep safe. Live long and prosper. |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4048 |
Hey Bill, Thanks for the link to such an interesting thread, I'm surprised but I guess that is modern hardware for you, it is more unpredicatable. A glider going off the right appears on the left, off the top appears on the bottom, and vice versa. Time for CFunctions ... but not on the Maximite :-( Regards, Tom |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6108 |
I've done some more playing. This version should run on most platforms but Maximites will need the RGB(xxx) bits tweaked. I added a timer that times the first 40 generations and displays the average On my H7, seed pattern 5 gives a time of 234mS per generation and pattern 6 gives 250mS. There are 10 starting patterns 0 to 9 Some patterns work best without the red dying cells. I haven't tried wrapping the display. The only speedup tried is flagging the dying cells to save overwriting all blank cells each generation. ' John Conway's Game of Life for Micromite MMBasic with TeraTerm ' Bill McKinley ' adapted by TassyJim DIM Bx$ DIM INTEGER MatX = 40 ' Matrix horizontal size DIM MatY = 25 ' Matrix vertical size - gets calculated later depending on screen size DIM FLOAT RandL = 0.3 ' For the randomizing of life less than =< RandL means there is life ' Make it high and you get a lot of cells but they die quickly DIM PT = 000 ' Pause time in mS between display updates DIM INTEGER initialPause = 3000 ' time to display starting pattern DIM INTEGER DIAM, a, b = 1, j DIM INTEGER dying, dyingOn = RGB(127,0,0) DIAM = MM.HRES/matX MatY = INT( MatX *MM.VRES/MM.HRES) ' Zero based matrix has one more cell all round than is displayed DIM CurM(MatX+1, MatY+1,2) ' The matrix of life DO ChkScr ' Print intro IF Bx$ = "Q" OR Bx$ = "q" THEN EXIT DO CLS InitM ' Initialize the random matrix (or demo) initial_gen PAUSE initialPause TIMER = 0 ' reset for next timer j = 0 DO ' Program loop NextGen ' Calculate the next generation PAUSE PT j = j + 1 IF j = 40 THEN PRINT TIMER /40 LOOP UNTIL INKEY$ <> "" 'or j = 40' loop forever or until a keypres LOOP SUB ChkScr ' Print intro CLS PRINT " CONWAY'S GAME OF LIFE" PRINT " Press a key to start " PRINT " and another to stop " PRINT " 0-9 for a demo" PRINT " Q to quit " DO Bx$ = INKEY$ LOOP UNTIL Bx$ <> "" END SUB SUB InitM ' Initialise the matrix of life LOCAL INTEGER x,y, n FOR y = 1 TO MatY FOR x = 1 TO MatX CurM(x, y, b) = 0 NEXT x NEXT y x = 0 SELECT CASE Bx$ CASE "1" ' glider RESTORE seed1 CASE "2" ' blinker RESTORE seed2 CASE "3" ' toad RESTORE seed3 CASE "4" ' beacon RESTORE seed4 CASE "5" 'Penta-decathlon RESTORE seed5 CASE "6" ' pulsar RESTORE seed6 CASE "7" ' RESTORE seed7 CASE "8" ' RESTORE seed8 CASE "9" ' RESTORE seed9 CASE "0" ' diehard RESTORE seed0 CASE "Q","q" ' do nothing x = -1 CASE ELSE ' random set FOR y = 1 TO MatY FOR x = 1 TO MatX IF RND() <= RandL THEN CurM(x, y, b) = 1 ELSE CurM(x, y, b) = 0 ENDIF NEXT x NEXT y END SELECT IF x = 0 THEN ' we need to read a set configuration DO READ x READ y IF x = -1 THEN EXIT DO IF y = -1 THEN PRINT "Error in Data",x,y: EXIT DO CurM(x, y, b) = 1 LOOP dying = y*dyingOn ENDIF 'Bx$="" END SUB SUB initial_gen FOR y = 1 TO MatY FOR x = 1 TO MatX IF CurM(x, y, b) = 1 THEN draw_cell(x, y, RGB(YELLOW)) ENDIF NEXT x NEXT y END SUB SUB NextGen ' Breed the next generation into a side of the matrix LOCAL INTEGER x, y, d a = 1 - a b = 1 - a FOR y = 1 TO MatY FOR x = 1 TO MatX d = CurM(x - 1, y - 1, a) + CurM(x - 1, y, a) + CurM(x - 1, y+1, a) d = d + CurM(x , y - 1, a) + CurM(x , y+1, a) d = d + CurM(x+1,y-1,a)+CurM(x+1,y,a)+CurM(x+1,y+1,a) d = d MOD 10 IF CurM(x, y , a) = 1 THEN IF d = 2 OR d = 3 THEN draw_cell(x, y, RGB(GREEN)) CurM(x, y, b) = 1 ELSE draw_cell(x, y, dying) CurM(x , y, b) = 10 ' flag this cell to be cleared next generation ENDIF ELSE IF d = 3 THEN draw_cell(x, y, RGB(YELLOW)) CurM(x, y, b) = 1 ELSE IF CurM(x, y, a) = 10 THEN draw_cell(x, y, RGB(BLACK)) CurM(x , y, b) = 0 ENDIF ENDIF NEXT x NEXT y END SUB SUB draw_cell(x, y, col) CIRCLE (x - 0.5) * DIAM, (y - 0.5) * DIAM, DIAM/2 - 2, 1,,col, col 'text x * DIAM, y * DIAM,"O","LT",1,1,col ', col END SUB ' seeds are pairs of x,y cells ending in -1 then 0 or 1 for coloured dying cells seed1: ' glider DATA 4,7,5,7,6,7,6,6,5,5,-1,0 seed2: ' blinker DATA 4,7,5,7,6,7,-1,0 seed3: ' toad DATA 5,7,6,7,7,7,4,8,5,8,6,8,-1,0 seed4: ' beacon DATA 4,7,5,7,4,8,7,9,6,10,7,10,-1,0 seed5: 'Penta-decathlon DATA 5, 7,6, 7,7, 7,5, 8,7, 8,5, 9,6, 9,7, 9 DATA 5, 10,6, 10,7, 10,5, 11,6, 11,7, 11,5, 12 DATA 6, 12,7, 12,5, 13,7, 13,5, 14,6, 14,7, 14,-1,1 seed6: ' pulsar DATA 5,3,6,3,7,3,11,3,12,3,13,3,3,5,8,5,10,5,15,5 DATA 3,6,8,6,10,6,15,6,3,7,8,7,10,7,15,7 DATA 5,8,6,8,7,8,11,8,12,8,13,8,5,10,6,10,7,10,11,10,12,10,13,10 DATA 3,11,8,11,10,11,15,11,3,12,8,12,10,12,15,12 DATA 3,13,8,13,10,13,15,13,5,15,6,15,7,15,11,15,12,15,13,15 DATA -1, 1 seed7: ' LW spaceship data 3,2,6,2,7,3,3,4,7,4,4,5,5,5,6,5,7,5,-1,1 seed8: ' MW spaceship data 5,2,3,3,7,3,8,4,3,5,8,5,4,6,5,6,6,6,7,6,8,6,-1,1 seed9: ' HW spaceship data 7,4,8,4,3,5,4,5,5,5,6,5,8,5,9,5,3,6,4,6,5,6,6,6,7,6,8,6 data 4,7,5,7,6,7,7,7,-1,1 seed0: 'diehard data 8,2,2,3,3,3,4,3,7,4,8,4,9,4,-1,1 Jim VK7JH MMedit  MMBasic Help |
||||