ConwayLife.com - A community for Conway's Game of Life and related cellular automata
Home  •  LifeWiki  •  Forums  •  Download Golly

apgsearch v3.1

For general discussion about Conway's Game of Life.

Re: apgsearch v3.1

Postby Apple Bottom » August 10th, 2017, 5:59 am

A for awesome wrote:Maybe the glider-producing switch engine? The Python and C++ versions might run the offending soups for different periods of time, resulting in different quantities of debris, consisting of the most common Life objects, which are indeed the ones that show discrepancies.

Maybe try the test again with a different seed that doesn't produce any switch engines, and see if that accounts for it.


Good idea! I've tried that, using the seed "testseed0000" -- the results are even more closely aligned now, but there's some discrepancies left. Here's the logs:

apgsearch 0.54+0.31i:

@VERSION v0.54+0.31i
@MD5 4a96744472652acc9116e2c8d6d5b79f
@ROOT testseed0000
@RULE B3S23
@SYMMETRY 4x64
@NUM_SOUPS 10000
@NUM_OBJECTS 336560

@CENSUS TABLE
xs4_33 103943
xp2_7 97692
xs6_696 56959
xq4_153 26694
xs7_2596 16475
xs5_253 15274
xs6_356 9615
xs4_252 3391
xs8_6996 3224
xs7_25ac 1027
xp2_7e 744
xs12_g8o653z11 524
xs6_25a4 219
xp2_318c 215
xs14_g88m952z121 182
xs8_69ic 78
xs7_178c 64
xq4_6frc 43
xp3_co9nas0san9oczgoldlo0oldlogz1047210127401 33
xs8_25ak8 28
xs6_39c 21
xq4_27dee6 16
xs8_35ac 12
xs9_31ego 11
xs14_69bqic 11
xs8_3pm 9
xs16_g88m996z1221 7
xq4_27deee6 6
xs14_g88b96z123 6
xs11_g8o652z11 5
xs6_bd 5
xs10_g8o652z01 5
xs10_35ako 3
xs12_raar 3
xs8_312ko 3
xs9_4aar 2
xs9_178ko 2
xs18_rhe0ehr 2
xs9_25ako 2
xs11_2560ui 1
xs16_69egmiczx1 1
xs14_6970796 1
xp2_2a54 1
xs7_3lo 1

@TOP 100
7394 16
4832 14
4880 14
9418 12
9443 12
1303 12
2407 12
7023 12
3547 12
9739 8
3603 8
27 8
7206 8
2611 8
6720 8
1094 8
5711 8
2643 8
4708 8
9321 8
3691 8
8306 8
8821 8
632 8
8829 8
2177 8
3714 8
1156 8
4374 8
3227 8
8864 8
8355 8
4773 8
3751 8
5295 8
2748 8
2751 8
8949 8
4350 8
9985 8
7964 8
4893 8
801 8
1828 8
5421 8
6973 8
7002 8
4461 8
7033 8
6548 8
6561 8
3491 8
4540 8
7618 8
4035 8
970 8
2057 6
8714 6
541 6
9248 6
8741 6
9769 6
2613 6
9225 6
3656 6
4231 6
4745 6
9155 6
6298 6
8873 6
1708 6
696 6
4794 6
1221 6
7893 6
41 6
7958 6
1323 6
1340 6
4491 6
1893 6
7022 6
3440 6
6534 6
3467 6
8604 6
6058 6
9391 6
8110 6
968 6
5147 6
7636 6
5077 6
4058 6
7143 6
6636 6
7666 6
499 6
5888 2
8052 1

@SAMPLE_SOUPIDS
xs4_33 75 75 64 64 49 49 49 49 49 49
xs6_696 102 93 81 270 270 348 400 563 661 712
xs7_2596 75 80 80 79 75 78 79 73 72 80
xs5_253 79 80 76 78 72 74 80 75 75 64
xs6_356 78 75 79 73 75 72 77 64 67 71
xs4_252 80 76 73 66 66 64 59 47 46 39
xs8_6996 75 73 72 64 64 59 51 50 45 39
xs7_25ac 77 75 66 69 59 41 36 23 81 102
xp2_7e 80 73 71 60 49 11 14 5 100 135
xs12_g8o653z11 40 11 11 144 144 157 248 248 287 287
xs6_25a4 60 105 193 209 221 249 268 370 597 612
xp2_318c 79 171 150 115 118 217 243 249 308 388
xs14_g88m952z121 10 92 92 391 497 497 792 792 821 821
xs8_69ic 546 504 735 986 1155 1661 1802 1871 1922 2062
xs7_178c 107 456 916 1041 1114 1320 1381 1419 1540 1552
xq4_6frc 41 541 499 696 968 1221 1340 1323 1708 1893
xp3_co9nas0san9oczgoldlo0oldlogz1047210127401 27 632 801 970 1094 2748 2751 3227 3491 3603
xs8_25ak8 722 804 1264 1297 1558 1614 1680 2257 2444 3163
xs6_39c 192 915 1075 1285 2543 2795 2942 3068 3683 4113
xq4_27dee6 1156 1828 2177 2643 2611 3691 3751 3714 4035 4461
xs8_35ac 813 2330 3298 3485 3724 3827 4425 6485 7043 7916
xs9_31ego 474 449 1406 2821 2908 3230 4082 4130 8149 8736
xs14_69bqic 53 1295 3074 4625 5141 6040 6170 6653 7511 7815
xs8_3pm 1528 3438 4187 6193 6643 7409 9068 9344 9821
xs16_g88m996z1221 3218 3218 4290 4951 6219 7388 9244
xq4_27deee6 1303 2407 3547 7023 9418 9443
xs14_g88b96z123 1352 2278 3389 4328 9348 9506
xs11_g8o652z11 1632 3936 6467 8084 8629
xs6_bd 465 832 1781 2417 4968
xs10_g8o652z01 23 1979 5668 6318 6639
xs10_35ako 6949 9876 9905
xs12_raar 4951 5436 8270
xs8_312ko 2434 6181 7010
xs9_4aar 5197 6741
xs9_178ko 130 5263
xs18_rhe0ehr 814 1273
xs9_25ako 500 5091
xs11_2560ui 9248
xs16_69egmiczx1 8052
xs14_6970796 5908
xp2_2a54 7394
xs7_3lo 5888


Modified apgmera 3.28:

@VERSION v3.28
@MD5 4a96744472652acc9116e2c8d6d5b79f
@ROOT testseed0000
@RULE b3s23
@SYMMETRY AB_4x64_Test
@NUM_SOUPS 10000
@NUM_OBJECTS 336560

@CENSUS TABLE
xs4_33 103941
xp2_7 97694
xs6_696 56959
xq4_153 26695
xs7_2596 16475
xs5_253 15274
xs6_356 9613
xs4_252 3391
xs8_6996 3225
xs7_25ac 1027
xp2_7e 744
xs12_g8o653z11 524
xs6_25a4 219
xp2_318c 215
xs14_g88m952z121 182
xs8_69ic 78
xs7_178c 64
xq4_6frc 43
xp3_co9nas0san9oczgoldlo0oldlogz1047210127401 33
xs8_25ak8 28
xs6_39c 21
xq4_27dee6 16
xs8_35ac 12
xs9_31ego 11
xs14_69bqic 11
xs8_3pm 9
xs16_g88m996z1221 7
xs14_g88b96z123 6
xq4_27deee6 6
xs6_bd 5
xs11_g8o652z11 5
xs10_g8o652z01 5
xs8_312ko 3
xs12_raar 3
xs10_35ako 3
xs9_4aar 2
xs9_25ako 2
xs9_178ko 2
xs18_rhe0ehr 2
xs7_3lo 1
xs16_69egmiczx1 1
xs14_6970796 1
xs11_2560ui 1
xp2_2a54 1

@SAMPLE_SOUPIDS
xs4_33 0 1 2 5 7 10 11 14 16 18
xp2_7 0 1 2 4 5 6 8 9 10 11
xs6_696 0 1 2 3 4 5 7 8 9 10
xq4_153 1580 1669 2903 4323
xs7_2596 0 1 2 3 4 5 7 8 10 11
xs5_253 40 79 170 201 221 312 320 370 383 386
xs6_356 1 2 3 4 5 7 10 11 13 14
xs4_252 0 11 17 20 21 23 37 39 40 46
xs8_6996 11 19 23 25 27 28 35 37 39 41
xs7_25ac 23 36 41 59 66 69 75 77 81 102
xp2_7e 5 11 14 49 60 71 73 80 100 135
xs12_g8o653z11 11 40 144 157 248 287 334 349 356 376
xs6_25a4 60 105 193 209 221 249 268 370 597 612
xp2_318c 79 115 118 150 171 217 243 249 308 388
xs14_g88m952z121 10 92 391 497 792 821 885 973 1155 1321
xs8_69ic 504 546 735 986 1155 1661 1802 1871 1922 2062
xs7_178c 107 456 916 1041 1114 1320 1381 1419 1540 1552
xq4_6frc 41 499 541 696 968 1221 1323 1340 1708 1893
xp3_co9nas0san9oczgoldlo0oldlogz1047210127401 27 632 801 970 1094 2748 2751 3227 3491 3603
xs8_25ak8 722 804 1264 1297 1558 1614 1680 2257 2444 3163
xs6_39c 192 915 1075 1285 2543 2795 2942 3068 3683 4113
xq4_27dee6 1156 1828 2177 2611 2643 3691 3714 3751 4035 4461
xs8_35ac 813 2330 3298 3485 3724 3827 4425 6485 7043 7916
xs9_31ego 449 474 1406 2821 2908 3230 4082 4130 8149 8736
xs14_69bqic 53 1295 3074 4625 5141 6040 6170 6653 7511 7815
xs8_3pm 1528 3438 4187 6193 6643 7409 9068 9344 9821
xs16_g88m996z1221 3218 4290 4951 6219 7388 9244
xs14_g88b96z123 1352 2278 3389 4328 9348 9506
xq4_27deee6 1303 2407 3547 7023 9418 9443
xs6_bd 465 832 1781 2417 4968
xs11_g8o652z11 1632 3936 6467 8084 8629
xs10_g8o652z01 23 1979 5668 6318 6639
xs8_312ko 2434 6181 7010
xs12_raar 4951 5436 8270
xs10_35ako 6949 9876 9905
xs9_4aar 5197 6741
xs9_25ako 500 5091
xs9_178ko 130 5263
xs18_rhe0ehr 814 1273
xs7_3lo 5888
xs16_69egmiczx1 8052
xs14_6970796 5908
xs11_2560ui 9248
xp2_2a54 7394


The totals match up, but there's an extra two blinkers, one glider, and one pond, while two blocks and two ships are missing; very strange. I'll investigate some more.

EDIT: although I haven't been able to reproduce this in C1, it did happen in 8x32. Logs:

apgsearch 0.54+0.31i:

@VERSION v0.54+0.31i
@MD5 4a96744472652acc9116e2c8d6d5b79f
@ROOT testseed0000
@RULE B3S23
@SYMMETRY 8x32
@NUM_SOUPS 10000
@NUM_OBJECTS 246507

@CENSUS TABLE
xs4_33 76144
xp2_7 71038
xs6_696 40453
xq4_153 21514
xs7_2596 11789
xs5_253 11004
xs6_356 7439
xs4_252 2342
xs8_6996 2334
xs7_25ac 783
xp2_7e 559
xs12_g8o653z11 402
xs6_25a4 179
xp2_318c 169
xs14_g88m952z121 100
xs8_69ic 70
xs7_178c 33
xs8_25ak8 26
xs6_39c 24
xq4_6frc 20
xp3_co9nas0san9oczgoldlo0oldlogz1047210127401 14
xs16_g88m996z1221 10
xs14_69bqic 8
xs8_35ac 8
xs8_3pm 7
xq4_27dee6 7
xs9_31ego 3
xs14_g88b96z123 3
xs11_g8o652z11 2
xs9_4aar 2
xs9_178ko 2
xs6_bd 2
xs9_25ako 2
xs10_32qr 1
xs14_6is079c 1
xs15_354cgc453 1
xs10_35ako 1
xs14_39e0e93 1
xs10_178kk8 1
xs16_0ca952z6513 1
xs14_6970796 1
xs10_3542ac 1
xs18_rhe0ehr 1
xs12_330f96 1
xs14_3hu0696 1
xs10_g8o652z01 1
xs7_3lo 1
xs8_312ko 1

@TOP 100
2085 12
2024 9
7323 8
2590 8
6816 8
8354 8
1563 8
807 8
7083 8
6713 8
5953 8
9541 8
2249 8
972 8
57 8
5976 8
3805 8
2915 8
7526 8
6631 8
2410 8
3451 8
7032 7
620 6
8845 6
2455 6
2629 6
2472 6
3628 6
9394 6
9396 6
2877 6
5365 6
1482 6
9173 6
4315 6
222 6
230 6
5484 6
2173 6
6773 6
1270 6
6122 6
7129 3
261 2
8982 2
8011 2
4101 1
2744 1

@SAMPLE_SOUPIDS
xs4_33 78 78 69 69 4 91 91 121 121 144
xs6_696 4 138 362 393 387 698 752 1097 1128 1133
xs7_2596 79 72 72 75 79 78 78 78 78 66
xs5_253 78 78 80 78 72 79 78 70 70 66
xs6_356 80 79 77 79 78 74 78 74 79 78
xs4_252 78 75 70 57 57 57 54 57 53 53
xs8_6996 77 78 68 67 70 57 54 54 57 54
xs7_25ac 78 63 69 66 23 19 0 90 94 123
xp2_7e 36 33 22 127 135 164 256 265 295 272
xs12_g8o653z11 78 78 65 65 55 55 28 28 89 89
xs6_25a4 72 26 96 312 423 609 609 802 802 864
xp2_318c 79 70 41 184 248 217 436 468 427 797
xs14_g88m952z121 63 419 419 496 496 802 802 922 1228 1287
xs8_69ic 57 53 122 191 230 330 428 464 516 645
xs7_178c 153 327 567 1908 2395 2918 3285 3752 3844 3887
xs8_25ak8 57 362 743 921 1420 3762 3822 3904 4136 4514
xs6_39c 509 1096 1247 1693 1949 2083 2611 2754 2763 2831
xq4_6frc 230 222 620 1270 1482 2173 2472 2455 2629 2877
xp3_co9nas0san9oczgoldlo0oldlogz1047210127401 807 972 1563 2085 2249 2915 3805 5976 5953 6631
xs16_g88m996z1221 790 1359 2347 3884 5829 6489 6707 7204 9366 9553
xs14_69bqic 358 1567 4682 4835 4836 5538 8772 9885
xs8_35ac 1385 2456 3399 3939 4343 4725 8209 9225
xs8_3pm 839 1697 2304 6412 7244 7480 9727
xq4_27dee6 57 2410 2590 3451 6713 7526 8354
xs9_31ego 4594 9139 9205
xs14_g88b96z123 1424 3385 9988
xs11_g8o652z11 61 5718
xs9_4aar 30 9632
xs9_178ko 1962 4290
xs6_bd 5114 5055
xs9_25ako 1376 7642
xs10_32qr 2744
xs14_6is079c 261
xs15_354cgc453 140
xs10_35ako 9708
xs14_39e0e93 8011
xs10_178kk8 4101
xs16_0ca952z6513 2024
xs14_6970796 7530
xs10_3542ac 2085
xs18_rhe0ehr 5526
xs12_330f96 7129
xs14_3hu0696 7032
xs10_g8o652z01 4373
xs7_3lo 8982
xs8_312ko 5389


Modified apgmera 3.28:

@VERSION v3.28
@MD5 4a96744472652acc9116e2c8d6d5b79f
@ROOT testseed0000
@RULE b3s23
@SYMMETRY AB_8x32_Test
@NUM_SOUPS 10000
@NUM_OBJECTS 246509

@CENSUS TABLE
xs4_33 76145
xp2_7 71038
xs6_696 40453
xq4_153 21515
xs7_2596 11789
xs5_253 11004
xs6_356 7439
xs4_252 2342
xs8_6996 2334
xs7_25ac 783
xp2_7e 559
xs12_g8o653z11 402
xs6_25a4 179
xp2_318c 169
xs14_g88m952z121 100
xs8_69ic 70
xs7_178c 33
xs8_25ak8 26
xs6_39c 24
xq4_6frc 20
xp3_co9nas0san9oczgoldlo0oldlogz1047210127401 14
xs16_g88m996z1221 10
xs8_35ac 8
xs14_69bqic 8
xs8_3pm 7
xq4_27dee6 7
xs9_31ego 3
xs14_g88b96z123 3
xs9_4aar 2
xs9_25ako 2
xs9_178ko 2
xs6_bd 2
xs11_g8o652z11 2
xs8_312ko 1
xs7_3lo 1
xs18_rhe0ehr 1
xs16_0ca952z6513 1
xs15_354cgc453 1
xs14_6is079c 1
xs14_6970796 1
xs14_3hu0696 1
xs14_39e0e93 1
xs12_330f96 1
xs10_g8o652z01 1
xs10_35ako 1
xs10_3542ac 1
xs10_32qr 1
xs10_178kk8 1

@SAMPLE_SOUPIDS
xs4_33 0 1 4 5 7 8 10 11 12 13
xp2_7 0 1 2 5 6 7 8 9 12 15
xs6_696 0 1 2 4 5 6 7 10 11 12
xq4_153 1950 4550 4866 5685 9258
xs7_2596 1 5 8 12 13 17 19 23 24 28
xs5_253 1 168 264 448 515 532 534 601 684 711
xs6_356 0 1 3 4 5 7 12 19 24 26
xs4_252 7 19 24 30 38 41 43 44 50 53
xs8_6996 4 11 19 20 33 53 54 57 67 68
xs7_25ac 0 19 23 63 66 69 78 90 94 123
xp2_7e 22 33 36 127 135 164 196 226 256 265
xs12_g8o653z11 28 55 65 78 89 135 207 215 292 349
xs6_25a4 26 72 96 312 423 609 802 864 921 1000
xp2_318c 41 70 79 184 217 248 427 436 468 797
xs14_g88m952z121 63 419 496 802 922 1228 1287 1380 1701 1726
xs8_69ic 53 57 122 191 230 330 428 464 516 645
xs7_178c 153 327 567 1908 2395 2918 3285 3752 3844 3887
xs8_25ak8 57 362 743 921 1420 3762 3822 3904 4136 4514
xs6_39c 509 1096 1247 1693 1949 2083 2611 2754 2763 2831
xq4_6frc 222 230 620 1270 1482 2173 2455 2472 2629 2877
xp3_co9nas0san9oczgoldlo0oldlogz1047210127401 807 972 1563 2085 2249 2915 3805 5953 5976 6631
xs16_g88m996z1221 790 1359 2347 3884 5829 6489 6707 7204 9366 9553
xs8_35ac 1385 2456 3399 3939 4343 4725 8209 9225
xs14_69bqic 358 1567 4682 4835 4836 5538 8772 9885
xs8_3pm 839 1697 2304 6412 7244 7480 9727
xq4_27dee6 57 2410 2590 3451 6713 7526 8354
xs9_31ego 4594 9139 9205
xs14_g88b96z123 1424 3385 9988
xs9_4aar 30 9632
xs9_25ako 1376 7642
xs9_178ko 1962 4290
xs6_bd 5055 5114
xs11_g8o652z11 61 5718
xs8_312ko 5389
xs7_3lo 8982
xs18_rhe0ehr 5526
xs16_0ca952z6513 2024
xs15_354cgc453 140
xs14_6is079c 261
xs14_6970796 7530
xs14_3hu0696 7032
xs14_39e0e93 8011
xs12_330f96 7129
xs10_g8o652z01 4373
xs10_35ako 9708
xs10_3542ac 2085
xs10_32qr 2744
xs10_178kk8 4101


This time the number of total objects does not match up either (must have been coincidence above with 4x64); apgmera 3.28 identified an extra block and an extra glider.

I tried to find out which versions the different results came from. It turns out that both Aidan's apgsearch 0.54+0.21i (which has previously been used for a long time) and Calcyman's own apgsearch v1.1 (2015-05-25) produce the same results as 0.54+0.31i above, and a vanilla version of apmera 3.28 produces the same results as the modified apgmera above.

In particular, the results generated for the same seed by (vanilla) apgsearch 1.1 and (vanilla) apgmera 3.28 do NOT (generally) match.

This may be a) known and b) expected (based on improvements to the object censusing code); and it may also be c) not a big deal, insofar as that for very common objects, we're more interested in their relative commonness rather than perfectly accurate numbers. (To wit: is it really important if there are exactly 177040592980 gliders in 8x32, or is it OK if the number is off by a few?) It may also not be a big deal insofar as that I haven't seen it affect C1.

In any case, I feel confident to start doing 4x64 hauls in a designated "testing" symmetry (AB_4x64_Test); I do not feel confident yet to submit to the regular 4x64 census using the modified apgmera 3.28. Even though this issue issue is also present in 8x32 at the very least, I'd like to either get it sorted, or otherwise get an OK from the Powers That Be that submitting to the main 4x64 census is OK.

Thanks. :)

EDIT 2: I've wrapped this up as 3.28-ab8.

Incremental diff against 3.28-ab7 (may also apply to vanilla 3.28 if you don't care about the other changes in -ab7):

diff -Niru apgmera-cffe-ab7/includes/hashsoup.h playingaround-cffe/includes/hashsoup.h
--- apgmera-cffe-ab7/includes/hashsoup.h   2016-04-01 22:45:45.000000000 +0200
+++ playingaround-cffe/includes/hashsoup.h   2017-08-10 13:05:13.764241900 +0200
@@ -85,6 +85,16 @@
                 sqt->d[(ROWS / 2) + j - 4] = (digest[4*j+2] << 22) + (digest[4*j+3] << 14);
                 sqt2->d[(ROWS / 2) + j - 4] = (digest[4*j+1] << 2) + (digest[4*j] << 10);
             }
+        } else if (symmetry == "AB_4x64_Test") {
+            VersaTile* sqt3 = &(imp->tiles[std::make_pair(1, 0)]);
+            sqt3->updateflags = 288;
+            sqt->updateflags = 292;
+            for (int j = 0; j < 4; j++) {
+                sqt2->d[(ROWS / 2) + j - 2] = (digest[8*j] << 12) + (digest[8*j+1] << 4) + ((digest[8*j+2] & 0xc0) >> 4);
+                sqt->d[(ROWS / 2) + j - 2] = ((digest[8*j+2] & 0x3f) << 24) + (digest[8*j+3] << 16) + (digest[8*j+4] << 8) + (digest[8*j+5] & 0xfc);
+                sqt3->d[(ROWS / 2) + j - 2] = ((digest[8*j+5] & 3) << 28) + (digest[8*j+6] << 20) + (digest[8*j+7] << 12);
+            }
+            imp->modified.push_back(sqt3);
         } else if (symmetry == "D4_+4") {
             for (int j = 0; j < 16; j++) {
                 sqt->d[(ROWS / 2) + j] = (digest[2*j] << 22) + (digest[2*j+1] << 14);
diff -Niru apgmera-cffe-ab7/main.cpp playingaround-cffe/main.cpp
--- apgmera-cffe-ab7/main.cpp   2017-08-10 13:02:22.582450900 +0200
+++ playingaround-cffe/main.cpp   2017-08-10 13:06:24.612294200 +0200
@@ -27,7 +27,7 @@
#include "includes/hashsoup.h"

#define APG_VERSION "v3.28"
-#define APG_VERSION_EXTRA "-ab7"
+#define APG_VERSION_EXTRA "-ab8"

#define EXIT_USERQUIT   1
#define EXIT_HAULSDONE   2
@@ -1900,6 +1900,7 @@
         } else if (strcmp(argv[i], "-q") == 0) {
             quietLevel = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "-t") == 0) {
+            std::cout << "Testing mode enabled." << std::endl;
             testing = true;
         } else if (strcmp(argv[i], "-no") == 0) {   
             newObjects = atoi(argv[i+1]);
diff -Niru apgmera-cffe-ab7/rule2asm.py playingaround-cffe/rule2asm.py
--- apgmera-cffe-ab7/rule2asm.py   2017-08-10 13:02:22.586451100 +0200
+++ playingaround-cffe/rule2asm.py   2017-08-10 13:08:45.755367100 +0200
@@ -489,6 +489,8 @@
         cellrows = 32
     elif (symmetry == "8x32"):
         cellrows = 32
+    elif (symmetry == "AB_4x64_Test"):
+        cellrows = 32
     elif (symmetry == "C2_4"):
         cellrows = 40
     elif (symmetry == "C2_2"):
@@ -521,7 +523,7 @@
         cellrows = 40
     else:
         print("Invalid symmetry: \033[1;31m"+symmetry+"\033[0m is not one of the supported symmetries:")
-        print("    C1, C2_4, C2_2, C2_1, C4_4, C4_1, 8x32,")
+        print("    C1, C2_4, C2_2, C2_1, C4_4, C4_1, 8x32, AB_4x64_Test,")
         print("    D2_+2, D2_+1, D2_x, D4_+4, D4_+2, D4_+1, D4_x4, D4_x1, D8_4, D8_1")
         exit(1)



Full diff against vanilla 3.28, including all changes up to -ab7:

diff -Niru apgmera-cffe/compilerule.sh playingaround-cffe/compilerule.sh
--- apgmera-cffe/compilerule.sh   1970-01-01 01:00:00.000000000 +0100
+++ playingaround-cffe/compilerule.sh   2016-06-30 13:07:05.400386900 +0200
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+function makebinary() {
+   RULE=$1
+   SYM=$2
+   
+   python rule2asm.py $RULE $SYM
+   make
+   mv -v apgmera.exe apgmera-${RULE}-${SYM}.exe
+}
+
+if [[ $# -eq 1 ]]; then
+   RULE=$1
+
+   makebinary $RULE C1
+   makebinary $RULE C2_1
+   makebinary $RULE C2_2
+   makebinary $RULE C2_4
+   makebinary $RULE C4_1
+   makebinary $RULE C4_4
+   makebinary $RULE D2_+1
+   makebinary $RULE D2_+2
+   makebinary $RULE D2_x
+   makebinary $RULE D4_+1
+   makebinary $RULE D4_+2
+   makebinary $RULE D4_+4
+   makebinary $RULE D4_x1
+   makebinary $RULE D4_x4
+   makebinary $RULE D8_1
+   makebinary $RULE D8_4
+   makebinary $RULE 8x32
+   
+elif [[ $# -eq 2 ]]; then
+   RULE=$1
+   SYM=$2
+
+   makebinary $RULE $SYM
+
+else
+   echo "Usage: $0 <rulestring> [<symmetry>]"
+
+fi
diff -Niru apgmera-cffe/includes/hashsoup.h playingaround-cffe/includes/hashsoup.h
--- apgmera-cffe/includes/hashsoup.h   2016-04-01 22:45:45.000000000 +0200
+++ playingaround-cffe/includes/hashsoup.h   2017-08-10 13:05:13.764241900 +0200
@@ -85,6 +85,16 @@
                 sqt->d[(ROWS / 2) + j - 4] = (digest[4*j+2] << 22) + (digest[4*j+3] << 14);
                 sqt2->d[(ROWS / 2) + j - 4] = (digest[4*j+1] << 2) + (digest[4*j] << 10);
             }
+        } else if (symmetry == "AB_4x64_Test") {
+            VersaTile* sqt3 = &(imp->tiles[std::make_pair(1, 0)]);
+            sqt3->updateflags = 288;
+            sqt->updateflags = 292;
+            for (int j = 0; j < 4; j++) {
+                sqt2->d[(ROWS / 2) + j - 2] = (digest[8*j] << 12) + (digest[8*j+1] << 4) + ((digest[8*j+2] & 0xc0) >> 4);
+                sqt->d[(ROWS / 2) + j - 2] = ((digest[8*j+2] & 0x3f) << 24) + (digest[8*j+3] << 16) + (digest[8*j+4] << 8) + (digest[8*j+5] & 0xfc);
+                sqt3->d[(ROWS / 2) + j - 2] = ((digest[8*j+5] & 3) << 28) + (digest[8*j+6] << 20) + (digest[8*j+7] << 12);
+            }
+            imp->modified.push_back(sqt3);
         } else if (symmetry == "D4_+4") {
             for (int j = 0; j < 16; j++) {
                 sqt->d[(ROWS / 2) + j] = (digest[2*j] << 22) + (digest[2*j+1] << 14);
diff -Niru apgmera-cffe/main.cpp playingaround-cffe/main.cpp
--- apgmera-cffe/main.cpp   2016-06-30 18:32:21.542207300 +0200
+++ playingaround-cffe/main.cpp   2017-08-10 13:06:24.612294200 +0200
@@ -1,4 +1,3 @@
-
#include <iostream>
#include <vector>
#include <sstream>
@@ -8,6 +7,9 @@
#include <ctime>
#include <cmath>
#include <unistd.h>
+#include <sys/select.h>
+#include <termios.h>
+#include <stdio.h>

#ifdef USE_OPEN_MP
#include <omp.h>
@@ -25,6 +27,31 @@
#include "includes/hashsoup.h"

#define APG_VERSION "v3.28"
+#define APG_VERSION_EXTRA "-ab8"
+
+#define EXIT_USERQUIT   1
+#define EXIT_HAULSDONE   2
+#define EXIT_TIMESUP   3
+
+clock_t programStartupTime;
+int quietLevel = 0;
+bool newObjects = false;
+
+// determine whether there's a keystroke waiting
+int keyWaiting() {
+    struct timeval tv;
+    fd_set fds;
+   
+    tv.tv_sec = 0;
+    tv.tv_usec = 0;
+   
+    FD_ZERO(&fds);
+    FD_SET(STDIN_FILENO, &fds); // STDIN_FILENO is 0
+   
+    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
+   
+    return FD_ISSET(STDIN_FILENO, &fds);
+}

/*
  * Produce a new seed based on the original seed, current time and PID:
@@ -1315,6 +1342,19 @@
             }
         }

+        if(newObjects) {
+            if(nBlocks && !census["xs4_33"])
+                std::cout << "New object: \033[1;37mxs4_33\033[0m" << std::endl;
+            if(nBlinkers && !census["xp2_7"])
+                std::cout << "New object: \033[1;31mxp2_7\033[0m" << std::endl;
+            if(nBeehives && !census["xs6_696"])
+                std::cout << "New object: \033[1;37mxs6_696\033[0m" << std::endl;
+            if(nGliders && !census["xq4_153"])
+                std::cout << "New object: \033[1;34mxq4_153\033[0m" << std::endl;
+            if(nBoats && !census["xs5_253"])
+                std::cout << "New object: \033[1;37mxs5_253\033[0m" << std::endl;
+        }
+           
         census["xs4_33"] += nBlocks;
         census["xp2_7"] += nBlinkers;
         census["xs6_696"] += nBeehives;
@@ -1324,6 +1364,22 @@
         for (unsigned int i = 0; i < objlist.size(); i++) {
             std::string apgcode = objlist[i];
             if ((ignorePathologicals == false) || (apgcode.compare("PATHOLOGICAL") != 0)) {
+                if(newObjects && !census[apgcode]) {
+                    std::cout << "New object: ";
+                   
+                    if(!apgcode.find("xp"))
+                        std::cout << "\033[1;31m";
+                    else if(!apgcode.find("xq"))
+                        std::cout << "\033[1;34m";
+                    else if(!apgcode.find("yl"))
+                        std::cout << "\033[1;32m";
+                    else if(!apgcode.find("zz"))
+                        std::cout << "\033[1;32m";
+                    else
+                        std::cout << "\033[1;37m";
+                       
+                    std::cout << apgcode << "\033[0m" << std::endl;
+                }
                 census[apgcode] += 1;
                 if (alloccur[apgcode].size() == 0 || alloccur[apgcode].back().compare(suffix) != 0) {
                     if (alloccur[apgcode].size() < 10) {
@@ -1333,30 +1389,32 @@
             }

             // Mention object in terminal:
+            if(!quietLevel) {
             #ifdef STANDARD_LIFE
-            if ((apgcode[0] == 'x') && (apgcode[1] == 'p')) {
-                if ((apgcode[2] != '2') || (apgcode[3] != '_')) {
-                    if (apgcode.compare("xp3_co9nas0san9oczgoldlo0oldlogz1047210127401") != 0 && apgcode.compare("xp15_4r4z4r4") != 0) {
-                        // Interesting oscillator:
-                        std::cout << "Rare oscillator detected: \033[1;31m" << apgcode << "\033[0m" << std::endl;
+                if ((apgcode[0] == 'x') && (apgcode[1] == 'p')) {
+                    if ((apgcode[2] != '2') || (apgcode[3] != '_')) {
+                        if (apgcode.compare("xp3_co9nas0san9oczgoldlo0oldlogz1047210127401") != 0 && apgcode.compare("xp15_4r4z4r4") != 0) {
+                            // Interesting oscillator:
+                            std::cout << "Rare oscillator detected: \033[1;31m" << apgcode << "\033[0m" << std::endl;
+                        }
+                    }
+                } else if ((apgcode[0] == 'x') && (apgcode[1] == 'q')) {
+                    if (apgcode.compare("xq4_153") != 0 && apgcode.compare("xq4_6frc") != 0 && apgcode.compare("xq4_27dee6") != 0 && apgcode.compare("xq4_27deee6") != 0) {
+                        std::cout << "Rare spaceship detected: \033[1;34m" << apgcode << "\033[0m" << std::endl;
                     }
+                } else if ((apgcode[0] == 'y') && (apgcode[1] == 'l')) {
+                    std::cout << "Linear-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
+                } else if ((apgcode[0] == 'z') && (apgcode[1] == 'z')) {
+                    std::cout << "Chaotic-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
                 }
-            } else if ((apgcode[0] == 'x') && (apgcode[1] == 'q')) {
-                if (apgcode.compare("xq4_153") != 0 && apgcode.compare("xq4_6frc") != 0 && apgcode.compare("xq4_27dee6") != 0 && apgcode.compare("xq4_27deee6") != 0) {
-                    std::cout << "Rare spaceship detected: \033[1;34m" << apgcode << "\033[0m" << std::endl;
-                }
-            } else if ((apgcode[0] == 'y') && (apgcode[1] == 'l')) {
-                std::cout << "Linear-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
-            } else if ((apgcode[0] == 'z') && (apgcode[1] == 'z')) {
-                std::cout << "Chaotic-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
-            }
             #else
-            if ((apgcode[0] == 'y') && (apgcode[1] == 'l')) {
-                std::cout << "Linear-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
-            } else if ((apgcode[0] == 'z') && (apgcode[1] == 'z')) {
-                std::cout << "Chaotic-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
-            }
+                if ((apgcode[0] == 'y') && (apgcode[1] == 'l')) {
+                    std::cout << "Linear-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
+                } else if ((apgcode[0] == 'z') && (apgcode[1] == 'z')) {
+                    std::cout << "Chaotic-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
+                }
             #endif
+            }
         }

         return false;
@@ -1547,6 +1605,10 @@
         return;
     }

+    // temporarily turn off reporting of new objects
+    bool oldNewObjects = newObjects;
+    newObjects = false;
+   
     std::ostringstream ss;
     ss << authstring << "\n";
     ss << "@MD5 " << stringlist[2] << "\n";
@@ -1582,12 +1644,15 @@
     }

     catagolueRequest(ss.str().c_str(), "/verify");
+   
+    // reenable reporting of new objects   
+    newObjects = oldNewObjects;

}

#ifdef USE_OPEN_MP

-void parallelSearch(int n, int m, std::string payoshaKey, std::string seed, int local_log) {
+int parallelSearch(int n, int m, std::string payoshaKey, std::string seed, int local_log, int soups_per_line, int hauls, int seconds) {

     SoupSearcher globalSoup;

@@ -1616,7 +1681,7 @@
             for (long long i = offset; i < offset + n; i++) {
                 long long pseudoElapsed = offset + elapsed * m + threadNumber;
                 elapsed += 1;
-                if (pseudoElapsed % 10000 == 0) {
+                if (pseudoElapsed % soups_per_line == 0) {
                     std::cout << pseudoElapsed << " soups processed..." << std::endl;
                 }
                 std::ostringstream ss;
@@ -1646,13 +1711,15 @@
         }
         std::cout << "----------------------------------------------------------------------" << std::endl;
     }
+   
+    return 0;

}

#endif


-void runSearch(int n, std::string payoshaKey, std::string seed, int local_log, bool testing) {
+int runSearch(int n, std::string payoshaKey, std::string seed, int local_log, int soups_per_line, int hauls, int seconds, bool testing, int *currentHauls) {

     // Create an empty QuickLife universe:
     lifealgo *imp2 = createUniverse("QuickLife");
@@ -1661,15 +1728,17 @@

     SoupSearcher soup;

-    clock_t start = clock();
+    clock_t start_clock = clock();
+    clock_t prev_clock  = clock();

     std::cout << "Running " << n << " soups per haul:" << std::endl;


     long long i = 0;
     bool finishedSearch = false;
+    int quit = 0;

-    while (finishedSearch == false) {
+    while ((finishedSearch == false) && !quit) {

         std::ostringstream ss;
         ss << i;
@@ -1678,15 +1747,59 @@

         i += 1;

-        if (i % 10000 == 0) {
-            clock_t end = clock();
+        if (i % soups_per_line == 0) {
+            clock_t curr_clock = clock();
+
+            if(!(quietLevel > 1)) {
+                std::cout << RULESTRING << "/" << SYMMETRY << ": " << i << " soups done (soups/s: " << (int) ((double) (soups_per_line) / ((double) (curr_clock - prev_clock) / CLOCKS_PER_SEC)) << " current, ";
+                std::cout << (int) (((double) i) / ((double) (curr_clock - start_clock) / CLOCKS_PER_SEC)) << " overall)";
+                std::cout << std::endl;
+           
+                prev_clock = clock();
+            }
+           
+            if(keyWaiting()) {
+                char c = fgetc(stdin);
+                if ((c == 'q') || (c == 'Q'))
+                    quit = EXIT_USERQUIT;
+                else if ((c == 's') || (c == 'S')) {
+                    long long totobjs = 0;
+
+                    std::vector<std::pair<long long, std::string> > censusList = soup.getSortedList(totobjs);
+
+                    std::cout << "----------------------------------------------------------------------" << std::endl;
+                    std::cout << "Current census:" << std::endl;
+                    std::cout << "----------------------------------------------------------------------" << std::endl;
+
+                    for (int i = censusList.size() - 1; i >= 0; i--) {
+                        if(!censusList[i].second.find("xp"))
+                            std::cout << "\033[1;31m";
+                        else if(!censusList[i].second.find("xq"))
+                            std::cout << "\033[1;34m";
+                        else if(!censusList[i].second.find("yl"))
+                            std::cout << "\033[1;32m";
+                        else if(!censusList[i].second.find("zz"))
+                            std::cout << "\033[1;32m";
+                        else
+                            std::cout << "\033[1;37m";
+                        std::cout << censusList[i].second << "\033[0m " << censusList[i].first << std::endl;
+                    }
+                   

-            std::cout << i << " soups completed (" << (int) (10000.0 / ((double) (end-start) / CLOCKS_PER_SEC)) << " soups per second)." << std::endl;
+                    std::cout << "----------------------------------------------------------------------" << std::endl;
+                    std::cout << "Total: " << totobjs << " objects (" << censusList.size() << " distinct)" << std::endl;
+                    std::cout << "----------------------------------------------------------------------" << std::endl;

-            start = clock();
+                }
+                   
+            }
+           
+            if(seconds)
+                if(((double) (curr_clock - programStartupTime) / CLOCKS_PER_SEC) > seconds)
+                    quit = EXIT_TIMESUP;
         }

-        if (i % n == 0) {
+        if ((i % n == 0) || quit) {
             if (testing) {
                 finishedSearch = true;
             } else {
@@ -1702,9 +1815,13 @@
             }
             std::cout << "----------------------------------------------------------------------" << std::endl;
             }
+            if(hauls && (++(*currentHauls) >= hauls) && !quit)
+                quit = EXIT_HAULSDONE;
         }

     }
+   
+    return quit;

}

@@ -1736,6 +1853,11 @@

     // Default values:
     int soups_per_haul = 10000000;
+    int soups_per_line = 10000;
+    int hauls = 0;
+    int currentHauls = 0;
+    int *currentHaulsPointer = &currentHauls;
+    int seconds = 0;
     std::string payoshaKey = "#anon";
     std::string seed = reseed("original seed");
     int verifications = -1;
@@ -1743,6 +1865,8 @@
     int local_log = 0;
     bool testing = false;
     int nullargs = 1;
+    int quit = 0;
+    struct termios ttystate;

     // Extract options:
     for (int i = 1; i < argc - 1; i++) {
@@ -1759,19 +1883,33 @@
                 soups_per_haul = 100000000;
             }
             */
+        } else if (strcmp(argv[i], "-S") == 0) {
+            soups_per_line = atoi(argv[i+1]);
+        } else if (strcmp(argv[i], "-h") == 0) {
+            hauls = atoi(argv[i+1]);
+            if(hauls)
+                std::cout << "Notice: running for at most " << hauls << " hauls." << std::endl;
+        } else if (strcmp(argv[i], "-t") == 0) {
+            seconds = atoi(argv[i+1]);
+            if(seconds)
+                std::cout << "Notice: running for at most " << seconds << " seconds." << std::endl;
         } else if (strcmp(argv[i], "-v") == 0) {
             verifications = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "-L") == 0) {
             local_log = atoi(argv[i+1]);
+        } else if (strcmp(argv[i], "-q") == 0) {
+            quietLevel = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "-t") == 0) {
+            std::cout << "Testing mode enabled." << std::endl;
             testing = true;
+        } else if (strcmp(argv[i], "-no") == 0) {   
+            newObjects = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "-p") == 0) {
             parallelisation = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "--rule") == 0) {
-            std::cout << "\033[1;33mapgmera " << APG_VERSION << "\033[0m: ";
+            std::cout << "\033[1;33mapgmera " << APG_VERSION << APG_VERSION_EXTRA << "\033[0m: ";
             std::string desired_rulestring = argv[i+1];
             if (strcmp(RULESTRING, argv[i+1]) == 0) {
-                std::cout << "Rule \033[1;34m" << RULESTRING << "\033[0m is correctly configured." << std::endl;
                 nullargs += 2;
             } else {
                 std::cout << "Rule \033[1;34m" << RULESTRING << "\033[0m does not match desired rule \033[1;34m" << desired_rulestring << "\033[0m." << std::endl;
@@ -1779,7 +1917,7 @@
                 return 1;
             }
         } else if (strcmp(argv[i], "--symmetry") == 0) {
-            std::cout << "\033[1;33mapgmera " << APG_VERSION << "\033[0m: ";
+            std::cout << "\033[1;33mapgmera " << APG_VERSION << APG_VERSION_EXTRA << "\033[0m: ";
             std::string desired_symmetry = argv[i+1];
             if (strcmp(SYMMETRY, argv[i+1]) == 0) {
                 std::cout << "Symmetry \033[1;34m" << SYMMETRY << "\033[0m is correctly configured." << std::endl;
@@ -1800,12 +1938,21 @@
         verifications = (parallelisation <= 4) ? 3 : 0;
     }

-    std::cout << "\nGreetings, this is \033[1;33mapgmera " << APG_VERSION << "\033[0m, configured for \033[1;34m" << RULESTRING << "/" << SYMMETRY << "\033[0m.\n" << std::endl;
-
+    // turn on non-blocking reads
+    tcgetattr(STDIN_FILENO, &ttystate);
+    ttystate.c_lflag &= ~ICANON;
+    ttystate.c_cc[VMIN] = 1;
+    tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
+   
+    // take note of when we started searching
+    programStartupTime = clock();
+   
+    std::cout << "\nHowdy, this is \033[1;33mapgmera " << APG_VERSION << APG_VERSION_EXTRA << "\033[0m, configured for \033[1;34m" << RULESTRING_SLASHED << "/" << SYMMETRY << "\033[0m.\n" << std::endl;
+   
     // Initialise QuickLife:
     qlifealgo::doInitializeAlgoInfo(staticAlgoInfo::tick());

-    while (true) {
+    while (!quit) {
         if (verifications > 0) {
             std::cout << "Peer-reviewing hauls:\n" << std::endl;
             // Verify some hauls:
@@ -1819,17 +1966,25 @@
         std::cout << "Using seed " << seed << std::endl;
         if (parallelisation > 0) {
             #ifdef USE_OPEN_MP
-            parallelSearch(soups_per_haul, parallelisation, payoshaKey, seed, local_log);
+            quit = parallelSearch(soups_per_haul, parallelisation, payoshaKey, seed, local_log, soups_per_line, hauls, seconds);
             #else
-            runSearch(soups_per_haul, payoshaKey, seed, local_log, false);
+            quit = runSearch(soups_per_haul, payoshaKey, seed, local_log, soups_per_line, hauls, seconds, false, currentHaulsPointer);
             #endif
         } else {
-            runSearch(soups_per_haul, payoshaKey, seed, local_log, testing);
+            quit = runSearch(soups_per_haul, payoshaKey, seed, local_log, soups_per_line, hauls, seconds, testing, currentHaulsPointer);
         }
         seed = reseed(seed);

+/*        if(hauls && (++currentHauls >= hauls) && !quit)
+            quit = EXIT_HAULSDONE; */
+               
         if (testing) { break; }
     }

-    return 0;
+    // turn on blocking reads   
+    tcgetattr(STDIN_FILENO, &ttystate);
+    ttystate.c_lflag |= ICANON;
+    tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
+   
+    exit(quit);
}
diff -Niru apgmera-cffe/makefile playingaround-cffe/makefile
--- apgmera-cffe/makefile   2016-06-30 18:32:21.542207300 +0200
+++ playingaround-cffe/makefile   2016-07-11 00:07:51.884658100 +0200
@@ -8,13 +8,22 @@
         MACOSX_109_OR_LATER=1
     endif
endif
+ifeq "$(shell uname)" "MINGW32_NT-6.1"
+    # we're on Windows, using MinGW
+    WIN32=1
+endif
ifdef MACOSX_109_OR_LATER
     # g++ is really clang++ and there is currently no OpenMP support
     CFLAGS=-c -Wall -O3 -march=native
else
-    # assume we're using gcc with OpenMP support
-    CFLAGS=-c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP
-    LDFLAGS=-fopenmp
+    ifdef WIN32
+        CFLAGS=-c -Wall -O3 -march=native
+        EXTRALIBS=-lws2_32
+    else
+        # assume we're using gcc with OpenMP support
+        CFLAGS=-c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP
+        LDFLAGS=-fopenmp
+    endif
endif

SOURCES=main.cpp includes/sha256.cpp includes/md5.cpp includes/happyhttp.cpp \
@@ -23,7 +32,16 @@
gollybase/readpattern.cpp gollybase/qlifedraw.cpp

OBJECTS=$(SOURCES:.cpp=.o)
-EXECUTABLE=apgmera
+
+GENHEADERS=includes/lifeasm-sse2.h includes/lifeasm-avx1.h includes/lifeasm-avx2.h \
+includes/lifelogic-sse2.h includes/lifelogic-avx1.h includes/lifelogic-avx2.h \
+includes/params.h
+
+ifeq "$(shell uname -o)" "Cygwin"
+        EXECUTABLE=apgmera.exe
+else
+        EXECUTABLE=apgmera
+endif

# Compile:
all: $(SOURCES) $(EXECUTABLE)
@@ -36,10 +54,22 @@
   true                                                 o o
   true                                                  o

+depend: .depend
+
+.depend: $(SOURCES)
+   rm -f ./.depend
+   $(CC) $(CFLAGS) -MM $^>>./.depend;
+
+
# Clean the build environment by deleting any object files:
clean:
   rm -f $(OBJECTS)
+   rm -f ./.depend
   echo Clean done
+   
+distclean:
+   rm -f $(GENHEADERS) $(OBJECTS) $(EXECUTABLE) ./.depend
+   echo Distclean done

$(EXECUTABLE): $(OBJECTS)
   $(CC) $(LDFLAGS) $(OBJECTS) -o $@
@@ -47,3 +77,4 @@
.cpp.o:
   $(CC) $(CFLAGS) $< -o $@

+include .depend
diff -Niru apgmera-cffe/rule2asm.py playingaround-cffe/rule2asm.py
--- apgmera-cffe/rule2asm.py   2016-06-30 18:32:21.557807300 +0200
+++ playingaround-cffe/rule2asm.py   2017-08-10 13:08:45.755367100 +0200
@@ -489,6 +489,8 @@
         cellrows = 32
     elif (symmetry == "8x32"):
         cellrows = 32
+    elif (symmetry == "AB_4x64_Test"):
+        cellrows = 32
     elif (symmetry == "C2_4"):
         cellrows = 40
     elif (symmetry == "C2_2"):
@@ -521,7 +523,7 @@
         cellrows = 40
     else:
         print("Invalid symmetry: \033[1;31m"+symmetry+"\033[0m is not one of the supported symmetries:")
-        print("    C1, C2_4, C2_2, C2_1, C4_4, C4_1, 8x32,")
+        print("    C1, C2_4, C2_2, C2_1, C4_4, C4_1, 8x32, AB_4x64_Test,")
         print("    D2_+2, D2_+1, D2_x, D4_+4, D4_+2, D4_+1, D4_x4, D4_x1, D8_4, D8_1")
         exit(1)

@@ -558,6 +560,7 @@
         g.write('#define MIDDLE28 0x3ffffffcu\n')
         g.write('#define BIRTHS '+str(bee)+'\n')
         g.write('#define SURVIVALS '+str(ess)+'\n')
+        g.write('#define ' + rulestring.upper() + ' ' + rulestring + '\n')
         if (symmetry == 'C1'):
             g.write('#define C1_SYMMETRY 1\n')
         if (rulestring == 'b3s23'):
Living proof that a little knowledge is a dangerous thing.

Catagolue: Apple Bottom • Life Wiki: Apple Bottom • Twitter: @_AppleBottom_

Proud member of the Pattern Raiders!
User avatar
Apple Bottom
 
Posts: 743
Joined: July 27th, 2015, 2:06 pm

Re: apgsearch v3.1

Postby Apple Bottom » August 12th, 2017, 8:36 am

Apologies for double-posting -- I'm running into the forum software's 60,000-characters-per-post limit here.

I've implemented 2x128 soups as well, in -ab9; as object counts for these also do not precisely match those generated by 0.54+0.31i I've also left them as a test symmetry, AB_2x128_Test for now, until I get the green light to submit to the main 2x128 census instead.

The code also contains some debug output (commented out; I'll change this to #ifdef guards in -ab10).

Incremental patch against against -ab8:

diff -Niru apgmera-cffe-ab8/includes/hashsoup.h playingaround-cffe/includes/hashsoup.h
--- apgmera-cffe-ab8/includes/hashsoup.h   2017-08-11 15:41:09.946865600 +0200
+++ playingaround-cffe/includes/hashsoup.h   2017-08-11 15:41:58.557646000 +0200
@@ -1,3 +1,4 @@
+#include <bitset>

// Reverse each byte in an integer:
uint32_t reverse_uint8(uint32_t x) {
@@ -89,12 +90,51 @@
             VersaTile* sqt3 = &(imp->tiles[std::make_pair(1, 0)]);
             sqt3->updateflags = 288;
             sqt->updateflags = 292;
+            sqt2->tx = -1;
+            sqt3->tx = 1;
             for (int j = 0; j < 4; j++) {
                 sqt2->d[(ROWS / 2) + j - 2] = (digest[8*j] << 12) + (digest[8*j+1] << 4) + ((digest[8*j+2] & 0xc0) >> 4);
                 sqt->d[(ROWS / 2) + j - 2] = ((digest[8*j+2] & 0x3f) << 24) + (digest[8*j+3] << 16) + (digest[8*j+4] << 8) + (digest[8*j+5] & 0xfc);
                 sqt3->d[(ROWS / 2) + j - 2] = ((digest[8*j+5] & 3) << 28) + (digest[8*j+6] << 20) + (digest[8*j+7] << 12);
             }
             imp->modified.push_back(sqt3);
+        } else if (symmetry == "AB_2x128_Test") {
+            VersaTile* sqt3 = &(imp->tiles[std::make_pair(1, 0)]);
+            VersaTile* sqt4 = &(imp->tiles[std::make_pair(-2, 0)]);
+            VersaTile* sqt5 = &(imp->tiles[std::make_pair(2, 0)]);
+           
+            sqt->tx = 0;
+            sqt2->tx = -1;
+            sqt4->tx = -2;
+            sqt3->tx = 1;
+            sqt5->tx = 2;
+           
+            sqt->updateflags = 292;
+            sqt2->updateflags = 292;
+            sqt3->updateflags = 292;
+            sqt4->updateflags = 260;
+            sqt5->updateflags = 288;
+           
+//            std::cout << "Soup:" << std::endl;
+           
+            for (int j = 0; j < 2; j++) {
+                sqt4->d[(ROWS / 2) + j - 1] = (digest[16*j] << 16) + (digest[16*j+1] << 8) + (digest[16*j+2] & 0xfc);
+                sqt2->d[(ROWS / 2) + j - 1] = ((digest[16*j+2] & 3) << 28) + (digest[16*j+3] << 20) + (digest[16*j+4] << 12) + (digest[16*j+5] << 4) + ((digest[16*j+6] & 0xc0) >> 4);
+                sqt->d[(ROWS / 2) + j - 1] = ((digest[16*j+6] & 0x3f) << 24) + (digest[16*j+7] << 16) + (digest[16*j+8] << 8) + (digest[16*j+9] & 0xfc);
+                sqt3->d[(ROWS / 2) + j - 1] = ((digest[16*j+9] & 3) << 28) + (digest[16*j+10] << 20) + (digest[16*j+11] << 12) + (digest[16*j+12] << 4) + ((digest[16*j+13] & 0xc0) >> 4);
+                sqt5->d[(ROWS / 2) + j - 1] = ((digest[16*j+13] & 0x3f) << 24) + (digest[16*j+14] << 16) + (digest[16*j+15] << 8);
+
+//                std::cout << std::bitset< 32 >( sqt4->d[(ROWS / 2) + j - 1]) << ' ';
+//                std::cout << std::bitset< 32 >( sqt2->d[(ROWS / 2) + j - 1]) << ' ';
+//                std::cout << std::bitset< 32 >( sqt->d[(ROWS / 2) + j - 1]) << ' ';
+//                std::cout << std::bitset< 32 >( sqt3->d[(ROWS / 2) + j - 1]) << ' ';
+//                std::cout << std::bitset< 32 >( sqt5->d[(ROWS / 2) + j - 1]) << ' ';
+//                std::cout << std::endl;
+               
+            }
+            imp->modified.push_back(sqt3);
+            imp->modified.push_back(sqt4);
+            imp->modified.push_back(sqt5);
         } else if (symmetry == "D4_+4") {
             for (int j = 0; j < 16; j++) {
                 sqt->d[(ROWS / 2) + j] = (digest[2*j] << 22) + (digest[2*j+1] << 14);
diff -Niru apgmera-cffe-ab8/includes/vlife.h playingaround-cffe/includes/vlife.h
--- apgmera-cffe-ab8/includes/vlife.h   2016-04-01 22:45:45.000000000 +0200
+++ playingaround-cffe/includes/vlife.h   2017-08-11 15:27:50.423135500 +0200
@@ -8,6 +8,7 @@
#include <cstring>
#include <utility>
#include <cpuid.h>
+#include <bitset>

#include "params.h"

@@ -133,7 +134,14 @@
     }

     void updateBoundary(VersaTile* sqt) {
+   
+//        std::cout << "Updating boundary on tile tx=" << sqt->tx << ", tw=" << sqt->tw << std::endl;

+//        std::cout << "Tile before: " << std::endl;
+//        for(int j = 0; j < ROWS; j++) {       
+//            std::cout << std::bitset< 32 >( sqt->d[j] ) << std::endl;
+//        }
+   
         const uint32_t right30  = 0x3fffffffu;
         const uint32_t left30   = 0xfffffffcu;
         const uint32_t right16  = 0x0000ffffu;
@@ -178,6 +186,11 @@
             }
         }

+//        std::cout << "Tile after: " << std::endl;
+//        for(int j = 0; j < ROWS; j++) {       
+//            std::cout << std::bitset< 32 >( sqt->d[j] ) << std::endl;
+//        }
+   
         sqt->updateflags = 0;
         temp_modified.push_back(sqt);
     }
@@ -207,6 +220,8 @@
      * Advance the entire universe by two generations.
      */
     void run2gens(bool history) {
+//        std::cout << "Advancing two generations, history=" << history << std::endl;
+   
         while (!modified.empty()) {
             updateBoundary(modified.back());
             modified.pop_back();
@@ -584,7 +599,7 @@

     clock_t start = clock();

-    // Do this twenty times so that we can accurately measure the time.
+    // Do this fifty times so that we can accurately measure the time.
     for (int i = 0; i < 50; i++) {
         vlife universe;
         universe.tilesProcessed = 0;
diff -Niru apgmera-cffe-ab8/main.cpp playingaround-cffe/main.cpp
--- apgmera-cffe-ab8/main.cpp   2017-08-11 15:41:09.948865700 +0200
+++ playingaround-cffe/main.cpp   2017-08-11 15:42:46.453385500 +0200
@@ -27,7 +27,7 @@
#include "includes/hashsoup.h"

#define APG_VERSION "v3.28"
-#define APG_VERSION_EXTRA "-ab8"
+#define APG_VERSION_EXTRA "-ab9"

#define EXIT_USERQUIT   1
#define EXIT_HAULSDONE   2
diff -Niru apgmera-cffe-ab8/rule2asm.py playingaround-cffe/rule2asm.py
--- apgmera-cffe-ab8/rule2asm.py   2017-08-11 15:41:09.950865800 +0200
+++ playingaround-cffe/rule2asm.py   2017-08-11 14:34:31.424163200 +0200
@@ -491,6 +491,8 @@
         cellrows = 32
     elif (symmetry == "AB_4x64_Test"):
         cellrows = 32
+    elif (symmetry == "AB_2x128_Test"):
+        cellrows = 32
     elif (symmetry == "C2_4"):
         cellrows = 40
     elif (symmetry == "C2_2"):
@@ -523,7 +525,7 @@
         cellrows = 40
     else:
         print("Invalid symmetry: \033[1;31m"+symmetry+"\033[0m is not one of the supported symmetries:")
-        print("    C1, C2_4, C2_2, C2_1, C4_4, C4_1, 8x32, AB_4x64_Test,")
+        print("    C1, C2_4, C2_2, C2_1, C4_4, C4_1, 8x32, AB_4x64_Test, AB_2x128_Test")
         print("    D2_+2, D2_+1, D2_x, D4_+4, D4_+2, D4_+1, D4_x4, D4_x1, D8_4, D8_1")
         exit(1)



Full patch against vanilla 3.28:

diff -Niru apgmera-cffe/compilerule.sh playingaround-cffe/compilerule.sh
--- apgmera-cffe/compilerule.sh   1970-01-01 01:00:00.000000000 +0100
+++ playingaround-cffe/compilerule.sh   2016-06-30 13:07:05.400386900 +0200
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+function makebinary() {
+   RULE=$1
+   SYM=$2
+   
+   python rule2asm.py $RULE $SYM
+   make
+   mv -v apgmera.exe apgmera-${RULE}-${SYM}.exe
+}
+
+if [[ $# -eq 1 ]]; then
+   RULE=$1
+
+   makebinary $RULE C1
+   makebinary $RULE C2_1
+   makebinary $RULE C2_2
+   makebinary $RULE C2_4
+   makebinary $RULE C4_1
+   makebinary $RULE C4_4
+   makebinary $RULE D2_+1
+   makebinary $RULE D2_+2
+   makebinary $RULE D2_x
+   makebinary $RULE D4_+1
+   makebinary $RULE D4_+2
+   makebinary $RULE D4_+4
+   makebinary $RULE D4_x1
+   makebinary $RULE D4_x4
+   makebinary $RULE D8_1
+   makebinary $RULE D8_4
+   makebinary $RULE 8x32
+   
+elif [[ $# -eq 2 ]]; then
+   RULE=$1
+   SYM=$2
+
+   makebinary $RULE $SYM
+
+else
+   echo "Usage: $0 <rulestring> [<symmetry>]"
+
+fi
diff -Niru apgmera-cffe/includes/hashsoup.h playingaround-cffe/includes/hashsoup.h
--- apgmera-cffe/includes/hashsoup.h   2016-04-01 22:45:45.000000000 +0200
+++ playingaround-cffe/includes/hashsoup.h   2017-08-11 15:41:58.557646000 +0200
@@ -1,3 +1,4 @@
+#include <bitset>

// Reverse each byte in an integer:
uint32_t reverse_uint8(uint32_t x) {
@@ -85,6 +86,55 @@
                 sqt->d[(ROWS / 2) + j - 4] = (digest[4*j+2] << 22) + (digest[4*j+3] << 14);
                 sqt2->d[(ROWS / 2) + j - 4] = (digest[4*j+1] << 2) + (digest[4*j] << 10);
             }
+        } else if (symmetry == "AB_4x64_Test") {
+            VersaTile* sqt3 = &(imp->tiles[std::make_pair(1, 0)]);
+            sqt3->updateflags = 288;
+            sqt->updateflags = 292;
+            sqt2->tx = -1;
+            sqt3->tx = 1;
+            for (int j = 0; j < 4; j++) {
+                sqt2->d[(ROWS / 2) + j - 2] = (digest[8*j] << 12) + (digest[8*j+1] << 4) + ((digest[8*j+2] & 0xc0) >> 4);
+                sqt->d[(ROWS / 2) + j - 2] = ((digest[8*j+2] & 0x3f) << 24) + (digest[8*j+3] << 16) + (digest[8*j+4] << 8) + (digest[8*j+5] & 0xfc);
+                sqt3->d[(ROWS / 2) + j - 2] = ((digest[8*j+5] & 3) << 28) + (digest[8*j+6] << 20) + (digest[8*j+7] << 12);
+            }
+            imp->modified.push_back(sqt3);
+        } else if (symmetry == "AB_2x128_Test") {
+            VersaTile* sqt3 = &(imp->tiles[std::make_pair(1, 0)]);
+            VersaTile* sqt4 = &(imp->tiles[std::make_pair(-2, 0)]);
+            VersaTile* sqt5 = &(imp->tiles[std::make_pair(2, 0)]);
+           
+            sqt->tx = 0;
+            sqt2->tx = -1;
+            sqt4->tx = -2;
+            sqt3->tx = 1;
+            sqt5->tx = 2;
+           
+            sqt->updateflags = 292;
+            sqt2->updateflags = 292;
+            sqt3->updateflags = 292;
+            sqt4->updateflags = 260;
+            sqt5->updateflags = 288;
+           
+//            std::cout << "Soup:" << std::endl;
+           
+            for (int j = 0; j < 2; j++) {
+                sqt4->d[(ROWS / 2) + j - 1] = (digest[16*j] << 16) + (digest[16*j+1] << 8) + (digest[16*j+2] & 0xfc);
+                sqt2->d[(ROWS / 2) + j - 1] = ((digest[16*j+2] & 3) << 28) + (digest[16*j+3] << 20) + (digest[16*j+4] << 12) + (digest[16*j+5] << 4) + ((digest[16*j+6] & 0xc0) >> 4);
+                sqt->d[(ROWS / 2) + j - 1] = ((digest[16*j+6] & 0x3f) << 24) + (digest[16*j+7] << 16) + (digest[16*j+8] << 8) + (digest[16*j+9] & 0xfc);
+                sqt3->d[(ROWS / 2) + j - 1] = ((digest[16*j+9] & 3) << 28) + (digest[16*j+10] << 20) + (digest[16*j+11] << 12) + (digest[16*j+12] << 4) + ((digest[16*j+13] & 0xc0) >> 4);
+                sqt5->d[(ROWS / 2) + j - 1] = ((digest[16*j+13] & 0x3f) << 24) + (digest[16*j+14] << 16) + (digest[16*j+15] << 8);
+
+//                std::cout << std::bitset< 32 >( sqt4->d[(ROWS / 2) + j - 1]) << ' ';
+//                std::cout << std::bitset< 32 >( sqt2->d[(ROWS / 2) + j - 1]) << ' ';
+//                std::cout << std::bitset< 32 >( sqt->d[(ROWS / 2) + j - 1]) << ' ';
+//                std::cout << std::bitset< 32 >( sqt3->d[(ROWS / 2) + j - 1]) << ' ';
+//                std::cout << std::bitset< 32 >( sqt5->d[(ROWS / 2) + j - 1]) << ' ';
+//                std::cout << std::endl;
+               
+            }
+            imp->modified.push_back(sqt3);
+            imp->modified.push_back(sqt4);
+            imp->modified.push_back(sqt5);
         } else if (symmetry == "D4_+4") {
             for (int j = 0; j < 16; j++) {
                 sqt->d[(ROWS / 2) + j] = (digest[2*j] << 22) + (digest[2*j+1] << 14);
diff -Niru apgmera-cffe/includes/vlife.h playingaround-cffe/includes/vlife.h
--- apgmera-cffe/includes/vlife.h   2016-04-01 22:45:45.000000000 +0200
+++ playingaround-cffe/includes/vlife.h   2017-08-11 15:27:50.423135500 +0200
@@ -8,6 +8,7 @@
#include <cstring>
#include <utility>
#include <cpuid.h>
+#include <bitset>

#include "params.h"

@@ -133,7 +134,14 @@
     }

     void updateBoundary(VersaTile* sqt) {
+   
+//        std::cout << "Updating boundary on tile tx=" << sqt->tx << ", tw=" << sqt->tw << std::endl;

+//        std::cout << "Tile before: " << std::endl;
+//        for(int j = 0; j < ROWS; j++) {       
+//            std::cout << std::bitset< 32 >( sqt->d[j] ) << std::endl;
+//        }
+   
         const uint32_t right30  = 0x3fffffffu;
         const uint32_t left30   = 0xfffffffcu;
         const uint32_t right16  = 0x0000ffffu;
@@ -178,6 +186,11 @@
             }
         }

+//        std::cout << "Tile after: " << std::endl;
+//        for(int j = 0; j < ROWS; j++) {       
+//            std::cout << std::bitset< 32 >( sqt->d[j] ) << std::endl;
+//        }
+   
         sqt->updateflags = 0;
         temp_modified.push_back(sqt);
     }
@@ -207,6 +220,8 @@
      * Advance the entire universe by two generations.
      */
     void run2gens(bool history) {
+//        std::cout << "Advancing two generations, history=" << history << std::endl;
+   
         while (!modified.empty()) {
             updateBoundary(modified.back());
             modified.pop_back();
@@ -584,7 +599,7 @@

     clock_t start = clock();

-    // Do this twenty times so that we can accurately measure the time.
+    // Do this fifty times so that we can accurately measure the time.
     for (int i = 0; i < 50; i++) {
         vlife universe;
         universe.tilesProcessed = 0;
diff -Niru apgmera-cffe/main.cpp playingaround-cffe/main.cpp
--- apgmera-cffe/main.cpp   2016-06-30 18:32:21.542207300 +0200
+++ playingaround-cffe/main.cpp   2017-08-11 15:42:46.453385500 +0200
@@ -1,4 +1,3 @@
-
#include <iostream>
#include <vector>
#include <sstream>
@@ -8,6 +7,9 @@
#include <ctime>
#include <cmath>
#include <unistd.h>
+#include <sys/select.h>
+#include <termios.h>
+#include <stdio.h>

#ifdef USE_OPEN_MP
#include <omp.h>
@@ -25,6 +27,31 @@
#include "includes/hashsoup.h"

#define APG_VERSION "v3.28"
+#define APG_VERSION_EXTRA "-ab9"
+
+#define EXIT_USERQUIT   1
+#define EXIT_HAULSDONE   2
+#define EXIT_TIMESUP   3
+
+clock_t programStartupTime;
+int quietLevel = 0;
+bool newObjects = false;
+
+// determine whether there's a keystroke waiting
+int keyWaiting() {
+    struct timeval tv;
+    fd_set fds;
+   
+    tv.tv_sec = 0;
+    tv.tv_usec = 0;
+   
+    FD_ZERO(&fds);
+    FD_SET(STDIN_FILENO, &fds); // STDIN_FILENO is 0
+   
+    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
+   
+    return FD_ISSET(STDIN_FILENO, &fds);
+}

/*
  * Produce a new seed based on the original seed, current time and PID:
@@ -1315,6 +1342,19 @@
             }
         }

+        if(newObjects) {
+            if(nBlocks && !census["xs4_33"])
+                std::cout << "New object: \033[1;37mxs4_33\033[0m" << std::endl;
+            if(nBlinkers && !census["xp2_7"])
+                std::cout << "New object: \033[1;31mxp2_7\033[0m" << std::endl;
+            if(nBeehives && !census["xs6_696"])
+                std::cout << "New object: \033[1;37mxs6_696\033[0m" << std::endl;
+            if(nGliders && !census["xq4_153"])
+                std::cout << "New object: \033[1;34mxq4_153\033[0m" << std::endl;
+            if(nBoats && !census["xs5_253"])
+                std::cout << "New object: \033[1;37mxs5_253\033[0m" << std::endl;
+        }
+           
         census["xs4_33"] += nBlocks;
         census["xp2_7"] += nBlinkers;
         census["xs6_696"] += nBeehives;
@@ -1324,6 +1364,22 @@
         for (unsigned int i = 0; i < objlist.size(); i++) {
             std::string apgcode = objlist[i];
             if ((ignorePathologicals == false) || (apgcode.compare("PATHOLOGICAL") != 0)) {
+                if(newObjects && !census[apgcode]) {
+                    std::cout << "New object: ";
+                   
+                    if(!apgcode.find("xp"))
+                        std::cout << "\033[1;31m";
+                    else if(!apgcode.find("xq"))
+                        std::cout << "\033[1;34m";
+                    else if(!apgcode.find("yl"))
+                        std::cout << "\033[1;32m";
+                    else if(!apgcode.find("zz"))
+                        std::cout << "\033[1;32m";
+                    else
+                        std::cout << "\033[1;37m";
+                       
+                    std::cout << apgcode << "\033[0m" << std::endl;
+                }
                 census[apgcode] += 1;
                 if (alloccur[apgcode].size() == 0 || alloccur[apgcode].back().compare(suffix) != 0) {
                     if (alloccur[apgcode].size() < 10) {
@@ -1333,30 +1389,32 @@
             }

             // Mention object in terminal:
+            if(!quietLevel) {
             #ifdef STANDARD_LIFE
-            if ((apgcode[0] == 'x') && (apgcode[1] == 'p')) {
-                if ((apgcode[2] != '2') || (apgcode[3] != '_')) {
-                    if (apgcode.compare("xp3_co9nas0san9oczgoldlo0oldlogz1047210127401") != 0 && apgcode.compare("xp15_4r4z4r4") != 0) {
-                        // Interesting oscillator:
-                        std::cout << "Rare oscillator detected: \033[1;31m" << apgcode << "\033[0m" << std::endl;
+                if ((apgcode[0] == 'x') && (apgcode[1] == 'p')) {
+                    if ((apgcode[2] != '2') || (apgcode[3] != '_')) {
+                        if (apgcode.compare("xp3_co9nas0san9oczgoldlo0oldlogz1047210127401") != 0 && apgcode.compare("xp15_4r4z4r4") != 0) {
+                            // Interesting oscillator:
+                            std::cout << "Rare oscillator detected: \033[1;31m" << apgcode << "\033[0m" << std::endl;
+                        }
+                    }
+                } else if ((apgcode[0] == 'x') && (apgcode[1] == 'q')) {
+                    if (apgcode.compare("xq4_153") != 0 && apgcode.compare("xq4_6frc") != 0 && apgcode.compare("xq4_27dee6") != 0 && apgcode.compare("xq4_27deee6") != 0) {
+                        std::cout << "Rare spaceship detected: \033[1;34m" << apgcode << "\033[0m" << std::endl;
                     }
+                } else if ((apgcode[0] == 'y') && (apgcode[1] == 'l')) {
+                    std::cout << "Linear-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
+                } else if ((apgcode[0] == 'z') && (apgcode[1] == 'z')) {
+                    std::cout << "Chaotic-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
                 }
-            } else if ((apgcode[0] == 'x') && (apgcode[1] == 'q')) {
-                if (apgcode.compare("xq4_153") != 0 && apgcode.compare("xq4_6frc") != 0 && apgcode.compare("xq4_27dee6") != 0 && apgcode.compare("xq4_27deee6") != 0) {
-                    std::cout << "Rare spaceship detected: \033[1;34m" << apgcode << "\033[0m" << std::endl;
-                }
-            } else if ((apgcode[0] == 'y') && (apgcode[1] == 'l')) {
-                std::cout << "Linear-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
-            } else if ((apgcode[0] == 'z') && (apgcode[1] == 'z')) {
-                std::cout << "Chaotic-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
-            }
             #else
-            if ((apgcode[0] == 'y') && (apgcode[1] == 'l')) {
-                std::cout << "Linear-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
-            } else if ((apgcode[0] == 'z') && (apgcode[1] == 'z')) {
-                std::cout << "Chaotic-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
-            }
+                if ((apgcode[0] == 'y') && (apgcode[1] == 'l')) {
+                    std::cout << "Linear-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
+                } else if ((apgcode[0] == 'z') && (apgcode[1] == 'z')) {
+                    std::cout << "Chaotic-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
+                }
             #endif
+            }
         }

         return false;
@@ -1547,6 +1605,10 @@
         return;
     }

+    // temporarily turn off reporting of new objects
+    bool oldNewObjects = newObjects;
+    newObjects = false;
+   
     std::ostringstream ss;
     ss << authstring << "\n";
     ss << "@MD5 " << stringlist[2] << "\n";
@@ -1582,12 +1644,15 @@
     }

     catagolueRequest(ss.str().c_str(), "/verify");
+   
+    // reenable reporting of new objects   
+    newObjects = oldNewObjects;

}

#ifdef USE_OPEN_MP

-void parallelSearch(int n, int m, std::string payoshaKey, std::string seed, int local_log) {
+int parallelSearch(int n, int m, std::string payoshaKey, std::string seed, int local_log, int soups_per_line, int hauls, int seconds) {

     SoupSearcher globalSoup;

@@ -1616,7 +1681,7 @@
             for (long long i = offset; i < offset + n; i++) {
                 long long pseudoElapsed = offset + elapsed * m + threadNumber;
                 elapsed += 1;
-                if (pseudoElapsed % 10000 == 0) {
+                if (pseudoElapsed % soups_per_line == 0) {
                     std::cout << pseudoElapsed << " soups processed..." << std::endl;
                 }
                 std::ostringstream ss;
@@ -1646,13 +1711,15 @@
         }
         std::cout << "----------------------------------------------------------------------" << std::endl;
     }
+   
+    return 0;

}

#endif


-void runSearch(int n, std::string payoshaKey, std::string seed, int local_log, bool testing) {
+int runSearch(int n, std::string payoshaKey, std::string seed, int local_log, int soups_per_line, int hauls, int seconds, bool testing, int *currentHauls) {

     // Create an empty QuickLife universe:
     lifealgo *imp2 = createUniverse("QuickLife");
@@ -1661,15 +1728,17 @@

     SoupSearcher soup;

-    clock_t start = clock();
+    clock_t start_clock = clock();
+    clock_t prev_clock  = clock();

     std::cout << "Running " << n << " soups per haul:" << std::endl;


     long long i = 0;
     bool finishedSearch = false;
+    int quit = 0;

-    while (finishedSearch == false) {
+    while ((finishedSearch == false) && !quit) {

         std::ostringstream ss;
         ss << i;
@@ -1678,15 +1747,59 @@

         i += 1;

-        if (i % 10000 == 0) {
-            clock_t end = clock();
+        if (i % soups_per_line == 0) {
+            clock_t curr_clock = clock();
+
+            if(!(quietLevel > 1)) {
+                std::cout << RULESTRING << "/" << SYMMETRY << ": " << i << " soups done (soups/s: " << (int) ((double) (soups_per_line) / ((double) (curr_clock - prev_clock) / CLOCKS_PER_SEC)) << " current, ";
+                std::cout << (int) (((double) i) / ((double) (curr_clock - start_clock) / CLOCKS_PER_SEC)) << " overall)";
+                std::cout << std::endl;
+           
+                prev_clock = clock();
+            }
+           
+            if(keyWaiting()) {
+                char c = fgetc(stdin);
+                if ((c == 'q') || (c == 'Q'))
+                    quit = EXIT_USERQUIT;
+                else if ((c == 's') || (c == 'S')) {
+                    long long totobjs = 0;
+
+                    std::vector<std::pair<long long, std::string> > censusList = soup.getSortedList(totobjs);
+
+                    std::cout << "----------------------------------------------------------------------" << std::endl;
+                    std::cout << "Current census:" << std::endl;
+                    std::cout << "----------------------------------------------------------------------" << std::endl;
+
+                    for (int i = censusList.size() - 1; i >= 0; i--) {
+                        if(!censusList[i].second.find("xp"))
+                            std::cout << "\033[1;31m";
+                        else if(!censusList[i].second.find("xq"))
+                            std::cout << "\033[1;34m";
+                        else if(!censusList[i].second.find("yl"))
+                            std::cout << "\033[1;32m";
+                        else if(!censusList[i].second.find("zz"))
+                            std::cout << "\033[1;32m";
+                        else
+                            std::cout << "\033[1;37m";
+                        std::cout << censusList[i].second << "\033[0m " << censusList[i].first << std::endl;
+                    }
+                   

-            std::cout << i << " soups completed (" << (int) (10000.0 / ((double) (end-start) / CLOCKS_PER_SEC)) << " soups per second)." << std::endl;
+                    std::cout << "----------------------------------------------------------------------" << std::endl;
+                    std::cout << "Total: " << totobjs << " objects (" << censusList.size() << " distinct)" << std::endl;
+                    std::cout << "----------------------------------------------------------------------" << std::endl;

-            start = clock();
+                }
+                   
+            }
+           
+            if(seconds)
+                if(((double) (curr_clock - programStartupTime) / CLOCKS_PER_SEC) > seconds)
+                    quit = EXIT_TIMESUP;
         }

-        if (i % n == 0) {
+        if ((i % n == 0) || quit) {
             if (testing) {
                 finishedSearch = true;
             } else {
@@ -1702,9 +1815,13 @@
             }
             std::cout << "----------------------------------------------------------------------" << std::endl;
             }
+            if(hauls && (++(*currentHauls) >= hauls) && !quit)
+                quit = EXIT_HAULSDONE;
         }

     }
+   
+    return quit;

}

@@ -1736,6 +1853,11 @@

     // Default values:
     int soups_per_haul = 10000000;
+    int soups_per_line = 10000;
+    int hauls = 0;
+    int currentHauls = 0;
+    int *currentHaulsPointer = &currentHauls;
+    int seconds = 0;
     std::string payoshaKey = "#anon";
     std::string seed = reseed("original seed");
     int verifications = -1;
@@ -1743,6 +1865,8 @@
     int local_log = 0;
     bool testing = false;
     int nullargs = 1;
+    int quit = 0;
+    struct termios ttystate;

     // Extract options:
     for (int i = 1; i < argc - 1; i++) {
@@ -1759,19 +1883,33 @@
                 soups_per_haul = 100000000;
             }
             */
+        } else if (strcmp(argv[i], "-S") == 0) {
+            soups_per_line = atoi(argv[i+1]);
+        } else if (strcmp(argv[i], "-h") == 0) {
+            hauls = atoi(argv[i+1]);
+            if(hauls)
+                std::cout << "Notice: running for at most " << hauls << " hauls." << std::endl;
+        } else if (strcmp(argv[i], "-t") == 0) {
+            seconds = atoi(argv[i+1]);
+            if(seconds)
+                std::cout << "Notice: running for at most " << seconds << " seconds." << std::endl;
         } else if (strcmp(argv[i], "-v") == 0) {
             verifications = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "-L") == 0) {
             local_log = atoi(argv[i+1]);
+        } else if (strcmp(argv[i], "-q") == 0) {
+            quietLevel = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "-t") == 0) {
+            std::cout << "Testing mode enabled." << std::endl;
             testing = true;
+        } else if (strcmp(argv[i], "-no") == 0) {   
+            newObjects = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "-p") == 0) {
             parallelisation = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "--rule") == 0) {
-            std::cout << "\033[1;33mapgmera " << APG_VERSION << "\033[0m: ";
+            std::cout << "\033[1;33mapgmera " << APG_VERSION << APG_VERSION_EXTRA << "\033[0m: ";
             std::string desired_rulestring = argv[i+1];
             if (strcmp(RULESTRING, argv[i+1]) == 0) {
-                std::cout << "Rule \033[1;34m" << RULESTRING << "\033[0m is correctly configured." << std::endl;
                 nullargs += 2;
             } else {
                 std::cout << "Rule \033[1;34m" << RULESTRING << "\033[0m does not match desired rule \033[1;34m" << desired_rulestring << "\033[0m." << std::endl;
@@ -1779,7 +1917,7 @@
                 return 1;
             }
         } else if (strcmp(argv[i], "--symmetry") == 0) {
-            std::cout << "\033[1;33mapgmera " << APG_VERSION << "\033[0m: ";
+            std::cout << "\033[1;33mapgmera " << APG_VERSION << APG_VERSION_EXTRA << "\033[0m: ";
             std::string desired_symmetry = argv[i+1];
             if (strcmp(SYMMETRY, argv[i+1]) == 0) {
                 std::cout << "Symmetry \033[1;34m" << SYMMETRY << "\033[0m is correctly configured." << std::endl;
@@ -1800,12 +1938,21 @@
         verifications = (parallelisation <= 4) ? 3 : 0;
     }

-    std::cout << "\nGreetings, this is \033[1;33mapgmera " << APG_VERSION << "\033[0m, configured for \033[1;34m" << RULESTRING << "/" << SYMMETRY << "\033[0m.\n" << std::endl;
-
+    // turn on non-blocking reads
+    tcgetattr(STDIN_FILENO, &ttystate);
+    ttystate.c_lflag &= ~ICANON;
+    ttystate.c_cc[VMIN] = 1;
+    tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
+   
+    // take note of when we started searching
+    programStartupTime = clock();
+   
+    std::cout << "\nHowdy, this is \033[1;33mapgmera " << APG_VERSION << APG_VERSION_EXTRA << "\033[0m, configured for \033[1;34m" << RULESTRING_SLASHED << "/" << SYMMETRY << "\033[0m.\n" << std::endl;
+   
     // Initialise QuickLife:
     qlifealgo::doInitializeAlgoInfo(staticAlgoInfo::tick());

-    while (true) {
+    while (!quit) {
         if (verifications > 0) {
             std::cout << "Peer-reviewing hauls:\n" << std::endl;
             // Verify some hauls:
@@ -1819,17 +1966,25 @@
         std::cout << "Using seed " << seed << std::endl;
         if (parallelisation > 0) {
             #ifdef USE_OPEN_MP
-            parallelSearch(soups_per_haul, parallelisation, payoshaKey, seed, local_log);
+            quit = parallelSearch(soups_per_haul, parallelisation, payoshaKey, seed, local_log, soups_per_line, hauls, seconds);
             #else
-            runSearch(soups_per_haul, payoshaKey, seed, local_log, false);
+            quit = runSearch(soups_per_haul, payoshaKey, seed, local_log, soups_per_line, hauls, seconds, false, currentHaulsPointer);
             #endif
         } else {
-            runSearch(soups_per_haul, payoshaKey, seed, local_log, testing);
+            quit = runSearch(soups_per_haul, payoshaKey, seed, local_log, soups_per_line, hauls, seconds, testing, currentHaulsPointer);
         }
         seed = reseed(seed);

+/*        if(hauls && (++currentHauls >= hauls) && !quit)
+            quit = EXIT_HAULSDONE; */
+               
         if (testing) { break; }
     }

-    return 0;
+    // turn on blocking reads   
+    tcgetattr(STDIN_FILENO, &ttystate);
+    ttystate.c_lflag |= ICANON;
+    tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
+   
+    exit(quit);
}
diff -Niru apgmera-cffe/makefile playingaround-cffe/makefile
--- apgmera-cffe/makefile   2016-06-30 18:32:21.542207300 +0200
+++ playingaround-cffe/makefile   2016-07-11 00:07:51.884658100 +0200
@@ -8,13 +8,22 @@
         MACOSX_109_OR_LATER=1
     endif
endif
+ifeq "$(shell uname)" "MINGW32_NT-6.1"
+    # we're on Windows, using MinGW
+    WIN32=1
+endif
ifdef MACOSX_109_OR_LATER
     # g++ is really clang++ and there is currently no OpenMP support
     CFLAGS=-c -Wall -O3 -march=native
else
-    # assume we're using gcc with OpenMP support
-    CFLAGS=-c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP
-    LDFLAGS=-fopenmp
+    ifdef WIN32
+        CFLAGS=-c -Wall -O3 -march=native
+        EXTRALIBS=-lws2_32
+    else
+        # assume we're using gcc with OpenMP support
+        CFLAGS=-c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP
+        LDFLAGS=-fopenmp
+    endif
endif

SOURCES=main.cpp includes/sha256.cpp includes/md5.cpp includes/happyhttp.cpp \
@@ -23,7 +32,16 @@
gollybase/readpattern.cpp gollybase/qlifedraw.cpp

OBJECTS=$(SOURCES:.cpp=.o)
-EXECUTABLE=apgmera
+
+GENHEADERS=includes/lifeasm-sse2.h includes/lifeasm-avx1.h includes/lifeasm-avx2.h \
+includes/lifelogic-sse2.h includes/lifelogic-avx1.h includes/lifelogic-avx2.h \
+includes/params.h
+
+ifeq "$(shell uname -o)" "Cygwin"
+        EXECUTABLE=apgmera.exe
+else
+        EXECUTABLE=apgmera
+endif

# Compile:
all: $(SOURCES) $(EXECUTABLE)
@@ -36,10 +54,22 @@
   true                                                 o o
   true                                                  o

+depend: .depend
+
+.depend: $(SOURCES)
+   rm -f ./.depend
+   $(CC) $(CFLAGS) -MM $^>>./.depend;
+
+
# Clean the build environment by deleting any object files:
clean:
   rm -f $(OBJECTS)
+   rm -f ./.depend
   echo Clean done
+   
+distclean:
+   rm -f $(GENHEADERS) $(OBJECTS) $(EXECUTABLE) ./.depend
+   echo Distclean done

$(EXECUTABLE): $(OBJECTS)
   $(CC) $(LDFLAGS) $(OBJECTS) -o $@
@@ -47,3 +77,4 @@
.cpp.o:
   $(CC) $(CFLAGS) $< -o $@

+include .depend
diff -Niru apgmera-cffe/rule2asm.py playingaround-cffe/rule2asm.py
--- apgmera-cffe/rule2asm.py   2016-06-30 18:32:21.557807300 +0200
+++ playingaround-cffe/rule2asm.py   2017-08-11 14:34:31.424163200 +0200
@@ -489,6 +489,10 @@
         cellrows = 32
     elif (symmetry == "8x32"):
         cellrows = 32
+    elif (symmetry == "AB_4x64_Test"):
+        cellrows = 32
+    elif (symmetry == "AB_2x128_Test"):
+        cellrows = 32
     elif (symmetry == "C2_4"):
         cellrows = 40
     elif (symmetry == "C2_2"):
@@ -521,7 +525,7 @@
         cellrows = 40
     else:
         print("Invalid symmetry: \033[1;31m"+symmetry+"\033[0m is not one of the supported symmetries:")
-        print("    C1, C2_4, C2_2, C2_1, C4_4, C4_1, 8x32,")
+        print("    C1, C2_4, C2_2, C2_1, C4_4, C4_1, 8x32, AB_4x64_Test, AB_2x128_Test")
         print("    D2_+2, D2_+1, D2_x, D4_+4, D4_+2, D4_+1, D4_x4, D4_x1, D8_4, D8_1")
         exit(1)

@@ -558,6 +562,7 @@
         g.write('#define MIDDLE28 0x3ffffffcu\n')
         g.write('#define BIRTHS '+str(bee)+'\n')
         g.write('#define SURVIVALS '+str(ess)+'\n')
+        g.write('#define ' + rulestring.upper() + ' ' + rulestring + '\n')
         if (symmetry == 'C1'):
             g.write('#define C1_SYMMETRY 1\n')
         if (rulestring == 'b3s23'):
Living proof that a little knowledge is a dangerous thing.

Catagolue: Apple Bottom • Life Wiki: Apple Bottom • Twitter: @_AppleBottom_

Proud member of the Pattern Raiders!
User avatar
Apple Bottom
 
Posts: 743
Joined: July 27th, 2015, 2:06 pm

Re: apgsearch v3.1

Postby muzik » August 15th, 2017, 9:46 am

Will larger nxn soups be supported in 4.x? I feel like the current 16x16 soup size might be too small for a lot of higher-range rules.
2c/n spaceships project

Current priorities: see here
muzik
 
Posts: 2595
Joined: January 28th, 2016, 2:47 pm
Location: Scotland

Re: apgsearch v3.1

Postby muzik » August 18th, 2017, 3:36 pm

Judging by the wiki page, it seems that all currently apgsearchable rules with rule integers < 1025 have now been investigated.
2c/n spaceships project

Current priorities: see here
muzik
 
Posts: 2595
Joined: January 28th, 2016, 2:47 pm
Location: Scotland

Re: apgsearch v3.1

Postby Saka » August 19th, 2017, 9:29 am

Just tested a few things with Saka_Test. Apparently a haul can't have everything be diehards :(
Everyone, please stop posting B/S about CA
x = 17, y = 10, rule = B3/S23
b2ob2obo5b2o$11b4obo$2bob3o2bo2b3o$bo3b2o4b2o$o2bo2bob2o3b4o$bob2obo5b
o2b2o$2b2o4bobo2b3o$bo3b5ob2obobo$2bo5bob2o$4bob2o2bobobo!

(Check gen 2)
User avatar
Saka
 
Posts: 2184
Joined: June 19th, 2015, 8:50 pm
Location: In the kingdom of Sultan Hamengkubuwono X

Re: apgsearch v3.1

Postby muzik » August 19th, 2017, 10:42 am

Saka wrote:Just tested a few things with Saka_Test. Apparently a haul can't have everything be diehards :(

Should be pretty obvious to anyone who's tried searching b3s/C1.
2c/n spaceships project

Current priorities: see here
muzik
 
Posts: 2595
Joined: January 28th, 2016, 2:47 pm
Location: Scotland

Previous

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 3 guests