simsim314 wrote:... to improve designs in Life we need some small "technological solutions". So I suggest we post here what we need (preferably for what purpose). And hopefully with time also solve at least partially some of the challenges.
1. A cross signal adjuster (needed for multiple channels replicators): ...
simsim314 wrote:2. A better G->H converter. The current spartan G->H converter is of about 500 ticks, this slows down all current replicators designs.
simsim314 wrote:3. A simple gate mechanism (or a flip-flop - needed for computational designs).
#C permanent Herschel-circuit switch from the "Demonoid",
#C guarded with semi-Snarks to produce a safe toggle
x = 191, y = 128, rule = LifeHistory
70.A$70.3A$73.A$72.2A6.2A$79.A.A$80.A2$74.2D$67.2A5.2D$67.2A6.2C$75.
2C2$84.2A$84.2A2$69.2A$68.A.A$68.A$67.2A2$114.A$114.3A$117.A$32.A83.
2A$30.3A$17.A11.A67.A$17.3A9.2A50.A15.3A$20.A58.3A18.A$7.2A10.2A57.A
20.2A11.2A11.E$8.A69.2A32.2A9.3E$8.A.A112.E.E$9.2A112.E$32.2A100.A$
32.2A99.A.A$53.2A78.A.A$53.2A26.2A51.A$81.2A2$9.E$9.E.E$9.3E$11.E11.
2A$23.A27.2A$24.3A23.A.A38.2A$26.A23.A41.A20.2A$49.2A25.2A11.3A21.A.A
$2.2A72.2A11.A25.A$3.A111.2A$3A$A61.2A$63.A$60.3A$13.2A8.A36.A$13.2A
6.3A48.2A$20.A51.A$5.2A13.2A51.3A$6.A68.A$6.A.A$7.2A$12.2C$12.2C2D$
14.2D3$9.A$8.A.A$8.2A3$17.2A$17.2A26$82.2A$82.A$80.A.A$80.2A2$113.2A
14.A$88.2A24.A14.3A$89.A13.2A6.3A18.A$89.A.A11.2A6.A19.2A$67.E22.2A$
65.3E87.A$65.E.E85.3A$65.E86.A$152.2A2$121.2A$121.2A2$79.2A$66.2A11.
2A99.E$67.A110.3E$64.3A94.2A15.E.D$64.A53.2A41.2A15.E$118.A19.2A49.A$
83.2A14.2A3.2A13.3A15.A.A48.A.A$84.A15.A3.A16.A15.A50.A.A$81.3A13.3A
5.3A28.2A10.2A39.A$81.A15.A9.A41.A$146.3A9.2A$146.A11.A$159.3A$161.A!
dvgrn wrote: G1@(X1, Y1, T1) and G2@(X2, Y2, T2), how do you get G1 AND G2 = G3@(X3, Y3, T3)?
x = 25, y = 20, rule = LifeHistory
3.2A19.A$4.A17.3A$4.A.A14.A$5.2A13.A.A$21.A3$4.2A13.2A$4.2A13.2A5$17.
2A$17.A.A$17.A2$.2A$A.A$2.A!
x = 95, y = 67, rule = S23/B3
55boo$55bo$53bobo$53boo20$81bo$79b3o$28boo48bo$27b3oboo45boo$28boob3ob
oo$27b3oboobboo$27boo3$88bo$59boo25b3o$59boo24bo$33boo50boo$32bobo28b
oo$32bo30boo$31boo26boo$59boo$45boo$44bobo$44bo$43boo8boo20boo$53bo21b
oo$54b3o$56bo5$93bo$92bobo$boo90bo$obo$bbo$$83boo3boo$83boo3boo3$75bob
oo$73b3oboo$72bo11boo$73b3oboo5bo$75bobobbo4b3o$79boo6bo!
dvgrn wrote:I think this would take some creative use of multiple regulators...
dvgrn wrote:Even minimal constraints would make this problem much easier...
dvgrn wrote:Distributed search, anyone?
dvgrn wrote:Here's a first effort in that direction.
towerator wrote:DNA-like spiral replicator
simsim314 wrote:dvgrn wrote: G1@(X1, Y1, T1) and G2@(X2, Y2, T2), how do you get G1 AND G2 = G3@(X3, Y3, T3)?
Hmm isn't this one from calcyman is a nice AND gate?
#C Sample ETMs (Exact-Timing Merges, i.e., OR gates)
x = 476, y = 202, rule = LifeHistory
76.2D8.2D3.2D3.2D252.2D8.2D3.2D3.2D$76.D.D6.D2.D.D2.D.D2.D251.D.D6.D
2.D.D2.D.D2.D$76.D8.D2.D.D2.D.D2.D251.D8.D2.D.D2.D.D2.D$86.2D2.D2.D.D
2.D261.2D2.D2.D.D2.D$85.D2.D.D2.D.D2.D260.D2.D.D2.D.D2.D$85.D2.D.D2.D
.D2.D260.D2.D.D2.D.D2.D$86.2D3.2D3.2D262.2D3.2D3.2D$398.A$398.3A$401.
A$400.2A5$422.A20.A$364.2D2.D2.D.3D44.3A11.A7.A.A$363.D2.D.D2.D2.D44.
A14.3A6.A$135.A227.D2.D.D2.D2.D44.2A16.A16.2A$135.3A225.D2.D.D2.D2.D
20.2A39.2A16.A$138.A224.D2.D.D2.D2.D20.2A55.A.A$137.2A225.2D3.2D3.D
77.2A$385.A$385.3A$388.A$387.2A40.2A25.2A$159.A269.2A25.A$101.2D2.D2.
D.3D44.3A11.A282.A.A$100.D2.D.D2.D2.D44.A14.3A280.2A$100.D2.D.D2.D2.D
44.2A16.A14.A$100.D2.D.D2.D2.D20.2A39.2A12.3A$100.D2.D.D2.D2.D20.2A
52.A254.2A$101.2D3.2D3.D74.2A244.2A6.A.A$122.A289.2A19.A6.A$122.3A
287.A.A15.3A6.2A$125.A59.2A227.A15.A$124.2A40.2A17.2A227.2A$166.2A$
408.2A$408.2A$443.2A$442.A.A$442.A$169.2A270.2A$149.2A19.A$149.A.A15.
3A$151.A15.A234.2A$151.2A19.2A228.A$173.A200.D.D3.D22.3A53.2A$145.2A
23.3A201.D.2D2.D24.A53.A.A$145.2A23.A203.D.D.D.D80.A$374.D.D2.2D2.C
27.A49.2A$374.D.D3.D3.C8.2A14.5A$374.D.D3.D.3C9.A13.A5.A$103.D.D3.D
78.2A204.A.A12.3A2.A$103.D.2D2.D78.A.A204.2A15.A.2A$103.D.D.D.D35.2A
43.A218.4A2.A$103.D.D2.2D2.C32.A44.2A212.2A3.A3.2A$103.D.D3.D3.C26.2A
4.A257.2A4.3A38.2A$103.D.D3.D.3C26.A4.2A265.A29.2A7.2A$141.3A268.A.2A
27.A$128.2A14.5A262.2A.2A27.A.A$129.A13.A5.A294.2A$129.A.A12.3A2.A
310.2A$130.2A15.A.2A29.2A221.2A55.A$144.4A2.A20.2A7.2A221.A54.A.A$
139.2A3.A3.2A22.A231.3A51.2A$139.2A4.3A24.A.A231.A$147.A25.2A268.A$
147.A.2A38.2A252.3A$146.2A.2A38.A244.A11.A$187.A.A218.A9.A15.3A8.2A
14.A$187.2A219.3A5.3A18.A22.A.A$138.2A271.A3.A20.2A23.A$138.A33.A237.
2A3.2A$139.3A30.3A291.A$141.A21.A11.A196.D.D3.D85.3A$137.A9.A15.3A8.
2A14.A174.A6.D.2D2.D84.A$137.3A5.3A18.A22.A.A173.3A4.D.D.D.D84.2A$
140.A3.A20.2A23.A177.A3.D.D2.2D$139.2A3.2A221.2A3.D.D3.D$195.A176.D.D
3.D92.2A.2A$101.D.D3.D85.3A228.2A46.A.2A$101.D.2D2.D84.A231.2A23.2A
21.A$101.D.D.D.D84.2A218.2A35.A14.2A4.3A$101.D.D2.2D303.A2.A35.3A11.
2A3.A3.2A$101.D.D3.D256.2A40.2A4.2A38.A16.4A2.A$101.D.D3.D92.2A.2A
159.2A39.A.A47.2A15.A.2A$153.2A46.A.2A200.A48.A.A12.3A2.A$153.2A23.2A
21.A202.2A48.A13.A5.A$141.2A35.A14.2A4.3A212.2A37.2A14.5A$140.A2.A35.
3A11.2A3.A3.2A210.A56.A$135.2A4.2A38.A16.4A2.A210.3A$134.A.A47.2A15.A
.2A212.A$134.A48.A.A12.3A2.A$133.2A48.A13.A5.A$143.2A37.2A14.5A$143.A
56.A$144.3A294.A$146.A294.3A$444.A$443.2A3$170.A229.A$170.3A227.3A$
133.A39.A229.A$133.3A36.2A228.2A$136.A316.2A$135.2A309.2A5.A.A$446.2A
7.A$455.2A2$442.A$182.2A228.2A27.A.A.2A$175.2A5.A.A220.2A5.A.A26.A.A.
A.A$145.2A28.2A7.A220.2A7.A25.2A.A.A.A2.A$138.2A5.A.A36.2A228.2A25.A
2.2A.4A$138.2A7.A293.A4.A$147.2A22.A229.A40.3A.A2.2A$170.A.A.2A224.A.
A.2A38.2A3.2A$134.A35.A.A.A.A223.A.A.A.A$133.A.A.2A30.2A.A.A.A2.A219.
2A.A.A.A2.A$133.A.A.A.A30.A2.2A.4A220.A2.2A.4A$132.2A.A.A.A2.A27.A4.A
224.A4.A$133.A2.2A.4A28.3A.A2.2A221.3A.A2.2A$133.A4.A34.2A3.2A223.2A
3.2A$134.3A.A2.2A$136.2A3.2A71$.2C254.2C$C.C253.C.C$2.C255.C!
simsim314 wrote:dvgrn wrote:Distributed search, anyone?
Well the problem is not the search, but the search space. How or with what "parameters" do you suggest to make this search? Just bouncing glider into random SLs hoping for H without destroying the SLs is kinda lost cause. We need a better and more "limited space", which will yield result with much bigger probability.
dvgrn wrote:These are 0 mod 8 and 4 mod 8, so I just need six more of these to make a complete set, to be able to merge any two same-color glider signals...
dvgrn wrote:Existing tools are mostly command-line C++ code...
simsim314 wrote:OK now I get it (you don't want to depend on glider inner state). This sounds like another technological challenge. For what purpose would it be useful?
simsim314 wrote:dvgrn wrote:Existing tools are mostly command-line C++ code...
Do you know the general algorithmic approach those search utils have used?
x = 69, y = 114, rule = LifeHistory
24.2A$23.A2.A$24.2A8$28.D2C$29.C$27.3C6$35.2A$35.A.A$10.2A25.A$11.A
25.2A$11.A.A15.2A$12.2A15.2A11$13.2A.2C$12.A.A.C.C11.2A$12.A4.C12.A.A
$11.2A19.A$32.2A5$14.2A$13.A.A$13.A25.2A$12.2A25.A$20.2A15.A.A$20.2A
15.2A12$19.2A7.3A19.A8.2A$18.A.A8.A20.3A6.2A$18.A8.3A23.A$17.2A33.2A
13.2A$67.A$65.A.A$65.2A$60.2A$35.2A21.2D2A$35.A.A20.2D$37.A$37.2A$64.
A$63.A.A$64.2A3$55.2A$27.2A14.A11.2A$27.2A14.2A$42.A.A$18.2A.A$18.A.
2A6$19.A$19.3A$10.A11.A$10.3A8.2A14.A$13.A22.A.A$12.2A23.A4$34.2A$34.
A.A$36.A$11.C24.2A$11.C.C18.2A$11.3C18.A$13.C11.2A6.3A$25.A9.A$26.3A$
28.A4$2.2A$3.A$3A$A!
#C Herschel signal blocked unless a glider comes in
x = 162, y = 114, rule = LifeHistory
140.A$140.A.A$140.2A$138.A4$123.2A$124.A$124.A.A$125.2A4$156.2A$156.A
$154.A.A$112.A37.2A2.2A$112.3A35.2A$115.A$114.2A11.2A11.D$127.2A9.3D$
138.D.D$138.D4$113.C$113.C.C$113.3C40.2A$115.C22.2A16.A.A$137.A.A18.A
$137.A20.2A$136.2A4.2A$141.A.A$141.A$140.2A7.2A$127.2A20.2A$127.A$
128.3A$130.A4$159.2A$159.A$157.A.A$157.2A5$139.2A$140.A$140.A.A$141.
2A12$142.2A$142.2A14.2A$134.2A22.A$135.A23.3A$135.A.A23.A$136.2A$152.
A$150.3A$149.A$149.2A4$117.2A$118.A$118.A.A$45.A73.2A$45.3A$21.A26.A
22.A14.2A$19.3A25.2A20.3A14.A24.2A$18.A49.A18.3A6.2A13.A44.2A$18.2A
48.2A19.A6.2A11.A.A44.2A$109.2A$38.A$36.3A$35.A115.2A$10.D11.2A11.2A
114.2A$10.3D9.2A131.2A$10.D.D65.2A75.2A$12.D65.2A$.A$A.A117.2A27.2A$A
.A117.2A11.2A14.2A$.A131.A$134.3A$47.2A32.2A53.A$47.2A11.2A20.A$60.A
18.3A13.2A3.2A14.2A$35.D25.3A15.A16.A3.A15.A$34.D.D26.A29.3A5.3A13.3A
$34.2D57.A9.A15.A$43.2A$34.2A7.A$22.2A10.A9.3A$23.A11.3A8.A$20.3A14.A
$20.A!
#C Brice Due's demultiplexer, 22 August 2006
x = 83, y = 40, rule = B3/S23
34bo47bo$32b2o46b2o$33b2o46b2o13$3bo47bo$3b3o45b3o$6bo47bo$5b2o46b2o$o
47bo$3o45b3o$3bo47bo$2b2o46b2o13$50b3o$12b2o37bo8b2o$12bo38b3o6bo$13b
3o45b3o$15bo47bo!
dvgrn wrote:- drop every possible catalyst into every possible position and orientation near an active reaction, run the resulting patterns, and just save the few exceptional cases where the catalyst survives
simsim314 wrote:dvgrn wrote:- drop every possible catalyst into every possible position and orientation near an active reaction, run the resulting patterns, and just save the few exceptional cases where the catalyst survives
I was thinking in this direction, the interesting question would be how much catalysts would there be after 3-4 iterations of say glider+block->pi interaction? thousand? hundreds? millions?
simsim314 wrote:And how explored this topic is? I mean were there some massive search attempts, that run for thousands of hours?
#C maybe-Spartan Herschel splitter based on Guam's Herschel transceiver.
#C The three input gliders are fairly adjustable -- just need two on the
#C same lane, and another one (of either color) a safe distance away.
#C Repeat time is 319 ticks, limited by the Herschel transmitter.
x = 160, y = 212, rule = LifeHistory
77.2A$76.A.A$76.2A3$71.A$70.A.A$70.A.A$71.A10$92.A$91.A.A$91.A.A$92.A
$81.D$57.2A22.D.D$57.2A22.3D$83.D7$62.2A$61.A.A$61.A$60.2A2$80.A$79.A
.A$80.2A8$145.2A$144.A2.A$145.2A4$56.2A$56.2A$60.2A$60.2A$74.2A73.3D$
74.2A74.D$148.3D4$77.A$76.A.A7.2A$76.A.A7.2A68.2A$64.2A11.A78.A.A$65.
A92.A$62.3A93.2A$62.A$66.2A$66.2A4$148.2A$139.2A7.2A$140.A$140.A.A$
141.2A$157.2A$157.A$155.A.A$155.2A5$158.A$157.A.A$158.A3$115.A8.2A$
115.3A6.2A$118.A$117.2A13.2A22.2A$132.A5.2A16.2A$130.A.A5.2A$130.2A2$
123.2A$123.2A24.2A$149.2A$107.A$105.3A21.A$104.A23.A.A21.2A$104.2A23.
2A22.A$76.A76.A.A$74.3A77.2A$29.A20.A22.A46.2A$21.A6.A.A19.3A20.2A45.
2A$21.3A5.A23.A$17.2A5.A27.2A38.A53.2A$18.A4.2A67.3A51.2A$18.A.A62.A
11.A$19.2A62.3A8.2A14.A$86.A22.A.A$85.2A23.A2$15.2A25.2A$16.A25.2A$
16.A.A88.2A$17.2A88.A.A$109.A$109.2A$30.2A73.2A$30.A.A6.2A32.2A30.A$
32.A6.A20.2A11.2A23.2A6.3A$32.2A6.3A18.A36.A9.A$42.A15.3A38.3A$58.A
42.A2$77.2A$78.A$28.2A45.3A$28.A.A44.A$30.A$30.2A5$12.2A$11.A.A$11.A
25.2A$10.2A25.A$18.2A15.A.A$18.2A15.2A12$17.2A$16.A.A$16.A$15.2A5$33.
2A$33.A.A$35.A$35.2A7$25.2A$16.2A7.2A$17.A$17.A.A$18.2A6$17.A$17.3A$
8.A11.A$8.3A8.2A14.A$11.A22.A.A$10.2A23.A4$32.2A$32.A.A$34.A$9.C24.2A
$9.C.C18.2A$9.3C18.A$11.C11.2A6.3A$23.A9.A$24.3A$26.A2$2.2A$3.A$3A$A!
#C Everything is easier with a Snark.
#C Fetch it home by all means --
#C you may serve it with greens,
#C And it's handy for triggering a Herschel receiver.
#C Here a custom F117 extension is shown for the transmitter,
#C to allow the output Herschel to escape.
x = 155, y = 140, rule = LifeHistory
72.2A$71.A.A$71.2A3$66.A$65.A.A$65.A.A31.A$66.A30.3A$75.2A7.A11.A$75.
2A7.3A9.2A$87.A$86.2A39.A$126.A.A$126.A.A$127.A$99.2A15.D$99.2A15.D.D
$116.3D$118.D3$76.D$52.2A22.D.D$52.2A22.3D30.2A$78.D11.2A18.A$90.A16.
3A$91.3A13.A$93.A4$57.2A$56.A.A$56.A$55.2A2$75.A$74.A.A$75.2A8$140.2A
$139.A2.A$140.2A4$51.2A$51.2A$55.2A$55.2A$69.2A73.3D$69.2A74.D$143.3D
4$72.D$71.D.D7.2A$71.D.D7.2A68.2A$59.2A11.D78.A.A$60.A92.A$57.3A93.2A
$57.A$61.2A$61.2A4$143.2A$134.2A7.2A$135.A$135.A.A$136.2A$99.A52.2A$
81.2A14.5A50.A$82.A13.A5.A47.A.A$82.A.A12.3A2.A47.2A$83.2A15.A.2A$97.
4A2.A$92.2A3.A3.2A$92.2A4.3A$100.A52.A$100.A.2A48.A.A$99.2A.2A49.A3$
91.2A$91.A$92.3A$94.A56.2A$133.2A16.2A$133.2A4$144.2A$144.2A3$147.2A$
148.A$148.A.A$149.2A4$141.2A$141.2A4$35.A$35.3A$38.A$37.2A11.C$50.3C$
50.C.C$52.C3$10.D$10.3D$10.D.D15.2A$12.D15.2A$.A49.2A$A.A48.A.A$A.A
50.A$.A39.2A10.2A$41.A$31.2A9.3A$32.A11.A$29.3A$29.A!
#C Sample switchable Herschel factory using Guam's transceiver.
x = 203, y = 200, rule = LifeHistory
.A$2.A$3A51$50.A$51.A$49.3A9$86.2A$85.A.A$85.2A3$80.A$79.A.A$79.A.A
31.A$80.A30.3A$89.2A7.A11.A$89.2A7.3A9.2A$101.A$100.2A39.A$140.A.A$
140.A.A$141.A$113.2A15.D$113.2A15.D.D$130.3D$132.D4$66.2A$66.2A55.2A$
104.2A18.A$104.A16.3A$105.3A13.A$107.A4$71.2A$70.A.A$70.A$69.2A2$89.A
$88.A.A$89.2A14$65.2A$65.2A$69.2A$69.2A$83.2A$83.2A5$86.D$85.D.D7.2A$
85.D.D7.2A$73.2A11.D$74.A$71.3A$71.A$75.2A$75.2A9$113.A$95.2A14.5A$
96.A13.A5.A$96.A.A12.3A2.A$97.2A15.A.2A$111.4A2.A$106.2A3.A3.2A$106.
2A4.3A$114.A$114.A.2A$113.2A.2A3$105.2A$105.A$106.3A$108.A8$201.2A$
105.A95.A$105.3A91.A.A$108.A22.A67.2A$107.2A20.3A$128.A$128.2A2$55.A
42.A49.A36.2A$55.3A38.3A47.3A15.A20.2A$58.A36.A49.A18.3A$57.2A23.2A
11.2A35.2A11.2A20.A$82.2A48.2A32.2A4$201.2A$30.D170.2A$30.3D130.2A$
30.D.D15.2A113.2A25.2A$32.D15.2A57.2A81.2A$21.A49.2A34.2A11.2A56.2A$
20.A.A48.A.A46.A57.2A2.2A10.A$20.A.A50.A47.3A58.2A10.3A$21.A39.2A10.
2A48.A73.A$61.A108.2A24.2A$51.2A9.3A38.2A48.2A16.A12.2A$52.A11.A38.A
49.A14.3A6.A6.2A$49.3A30.2A20.3A25.2A20.3A11.A7.A.A$49.A33.A22.A26.A
22.A20.A$80.3A47.3A$80.A49.A!
x = 22, y = 11, rule = LifeHistory
20.2E$20.2E$7.2E$8.E$2E6.E.E$.E7.2E$.E.E$2.2E10.2C$14.2C2.3A$18.A$19.A!
x = 164, y = 146, rule = LifeHistory
13$153.A$152.A$152.3A86$38.E$38.3E12.2E$41.E11.2E$40.2E8$37.2E$37.2E
13$42.2E3.2E$43.E3.E$40.3E5.3E13.E$40.E9.E12.E.E$64.2E2$60.3A$60.A$
61.A!
x = 11, y = 14, rule = LifeHistory
.E$.3E$4.E$3.2E5$9.2E$9.2E2$.A$.2A$A.A!
x = 38, y = 20, rule = LifeHistory
27.E8.2E$.E25.3E6.2E$.3E26.E$4.E24.2E$3.2E4$35.2E$9.2E24.2E$9.2E$27.A
$.A25.2A$.2A23.A.A$A.A4$6.2E$6.2E!
x = 17, y = 19, rule = LifeHistory
.E8.2E$.3E6.2E$4.E$3.2E5$9.2E$9.2E2$.A$.2A12.E$A.A11.E.E$15.E3$6.2E$
6.2E!
x = 20, y = 19, rule = LifeHistory
.E8.2E$.3E6.2E$4.E$3.2E13.2E$18.E$16.E.E$16.2E2$9.2E$9.2E2$.A$.2A12.E
$A.A11.E.E$15.E3$6.2E$6.2E!
simsim314 wrote:I liked this adjustable H splitter, because as we all know it's much better to adjust, rather than redesign. The adjustable circuitry can be also placed as "prototype", before we are sure we have everything in place, it's just much more "pleasant" to work with.
x = 170, y = 155, rule = LifeHistory
33.2A$32.A.A$32.2A3$27.A$26.A.A116.2A$26.A.A115.A2.A$27.A117.2A8$149.
3D$150.D$48.A99.3D$47.A.A$47.A.A$48.A$37.D$13.2A22.D.D$13.2A22.3D116.
2A$39.D116.A.A$158.A$158.2A5$18.2A$17.A.A$17.A130.2A$16.2A121.2A7.2A$
140.A$36.A103.A.A$35.A.A103.2A$36.2A120.2A$158.2A$168.2A$168.A$166.A.
A$166.2A9$12.2A148.2A$12.2A148.A.A$16.2A146.A$16.2A146.2A$30.2A$30.2A
4$147.2A$33.A113.2A$32.A.A7.2A111.2A$32.A.A7.2A111.A$20.2A11.A122.3A$
21.A136.A$18.3A$18.A$22.2A$22.2A2$51.A8.2A$51.3A6.2A$54.A$53.2A13.2A$
68.A88.A$66.A.A86.3A$66.2A86.A$20.3A131.2A$22.A36.2A$21.A37.2A3$65.A$
64.A.A89.2A$65.A90.2A$132.2A$131.A.A$56.2A73.A$56.2A72.2A6$38.3A$40.A
$39.A6$152.2A$152.A.A$154.A$154.2A7$144.2A$135.2A7.2A$136.A$136.A.A$
137.2A$153.2A$153.A$151.A.A$151.2A5$154.A$153.A.A$154.A5$3A$2.A149.2A
$.A132.2A16.2A$134.2A4$145.2A$145.2A3$148.2A$149.A$149.A.A$150.2A4$
142.2A$142.2A!
simsim314 wrote:I've started to look for G->H, wrote some preliminary scripts, and although it's not something "drastic", just wanted to share this...
simsim314 wrote:I was also trying to "back engineer" all known G->H and I've found some "preliminary" algorithm:
1. First find all "catalysts" when catalyst is defined as something which has been influenced by interaction, and survived in it's original form for at least one generation.
2. Find all pairs and triples of "compatible" catalysts: which defined as catalyst that have at least one common generation, i.e. generation where they both were influenced but didn't die yet (and of course all of them have to be "activated")
simsim314 wrote:4. Search all stable catalysts that return the initial block/beehive to it's initial place.
simsim314 wrote:Doing some "hand search" made me realize that human can actually "guess" much better where the potential is, or "what is the actual problem". Another point is, after using 4-5 catalysts there is usually no more room for anything new. So the tree of choices is VERY wide but not that deep, making it an algorithmic challenge (in deep trees one can use some statistical analysis, to guess where to go, based on some random walking).
This algorithm also misses some depth when one of the catalyst is drastically changing the interaction, and all other catalyst stop to work. This adds some "new" options to the search, and I'm not sure either the current search engines didn't look in those directions, or this is a bad idea for some reason.
simsim314 wrote:Next the boat (or tub) is the stabilizer...
Also it's interesting to notice that all the interaction stages are within 18 ticks. I would say the semi snark was generated by trying a deeper and more "tight" search.
x = 201, y = 106, rule = LifeHistory
46.A39.A39.A$45.A39.A39.A$45.3A37.3A3.2E32.3A$91.E$89.E.E$38.E39.E10.
2E27.E$37.E.E37.E.E37.E.E$37.E.E37.E.E37.E.E$32.2E4.E39.E39.E$31.E.E
95.2E$31.E97.E.E$30.2E99.E$131.2E13$A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A
.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.
A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A
.A.A.A.A.A.A.A.A.A.A.A.A.A.A2$158.A2$158.A2$158.A2$158.A2$158.A2$158.
A2$158.A23.E$46.A49.A39.A45.3E$45.A49.A39.A22.A26.E8.A$45.3A47.3A3.2E
32.3A3.2E41.2E7.A$101.E39.E16.A34.3A$99.E.E37.E.E$38.E49.E10.2E27.E
10.2E17.A$37.E.E47.E.E37.E.E56.E$37.E.E47.E.E37.E.E28.A26.E.E$32.2E4.
E43.2E4.E39.E56.E.E$31.E.E15.2E30.E.E55.2E17.A21.2E4.E$31.E17.E.E29.E
57.E.E37.E.E$30.2E19.E28.2E59.E16.A20.E$51.2E88.2E35.2E$158.A2$158.A
2$158.A2$158.A2$158.A2$158.A$A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.
A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A
.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A3.A.A.A.A.A.A.A.A.A.A
.A.A.A.A.A.A.A.A.A.A2$158.A2$158.A2$158.A2$158.A2$158.A2$158.A2$158.A
2$158.A23.E$90.A91.3E$89.A68.A26.E8.A$89.3A3.2E87.2E7.A$95.E62.A34.3A
3.2E$93.E.E103.E$82.E10.2E63.A38.E.E$81.E.E102.E10.2E$81.E.E74.A26.E.
E$76.2E4.E102.E.E$75.E.E15.2E63.A21.2E4.E$75.E17.E.E83.E.E15.2E$74.2E
19.E62.A20.E17.E.E$95.2E81.2E19.E$158.A40.2E2$158.A2$158.A2$158.A2$
158.A2$158.A$160.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A.A!
simsim314 wrote:Another problem I'm dealing with: the space for new catalysts is shrinking as the number of the catalysts grow. Because the catalyst is working due to previous N generations, so the "cell path" of those generations is actually "taken" by those catalysts and cannot be "altered". So placing the catalyst there is illogical, as it's illogical to place a catalyst in front of the first glider. This could be a nice optimization, not wasting time on places which are already "inside the path" of already present catalyst.
simsim314 wrote:I was also thinking about something that called "evaluation function". In chess for example the tree has too many nodes, and this makes those kind of problem very common (also the problem with "same variation that get the same results in 250 ways). The solution in chess as I know it, is to "spread the search" over few branches in parallel, with most potential. When some branch is "dead end" (or when the evaluation of it dropped after searching all the leaves) the chess engine just search for new candidates, from the current "less explored" areas.
simsim314 wrote:I was wondering, how bad is it to use golly with python for this kind of searches? I don't think I can write anything better than golly that will run Life simulation. On the other hand the python-golly interface is pretty heavy, python is slow, as i understand golly "data management" (all the get-put functions) is also not the best in the world.
simsim314 wrote:How crucial is it to write the search utility in C? Do you think it's possible to make some "golly oriented" script, that will use the golly speed, that could compensate of the other slow factors?
@RULE PropogatingLife
@TABLE
n_states:7
neighborhood:Moore
symmetries:rotate8
# 1 regular live cell
# 2 trigger cell
# 3 head live
# 4 head dead
# 5 tail live
# 6 tail dead
var la1 = {1, 2, 5}
var la2 = {1, 2, 5}
var la3 = {1, 2, 5}
var a1 = {0,1, 2, 5, 6}
var a2 = {0,1, 2, 5, 6}
var a3 = {0,1, 2, 5, 6}
var a4 = {0,1, 2, 5, 6}
var a5 = {0,1, 2, 5, 6}
var a6 = {0,1, 2, 5, 6}
var a7 = {0,1, 2, 5, 6}
var a8 = {0,1, 2, 5, 6}
var hla1 = {1, 2, 3}
var hla2 = {1, 2, 3}
var hla3 = {1, 2, 3}
var ha1 = {0,1, 2, 3, 4}
var ha2 = {0,1, 2, 3, 4}
var ha3 = {0,1, 2, 3, 4}
var ha4 = {0,1, 2, 3, 4}
var ha5 = {0,1, 2, 3, 4}
var ha6 = {0,1, 2, 3, 4}
var ha7 = {0,1, 2, 3, 4}
var ha8 = {0,1, 2, 3, 4}
var ha = {1, 2, 3, 4}
var z = {0,1}
var hz = {3,4}
var v = {1,2}
var hd1 = {0,4}
var hd2 = {0,4}
var hd3 = {0,4}
var hd4 = {0,4}
var hd5 = {0,4}
var hd6 = {0,4}
var tz = {5,6}
var ta1 = {0,1, 2, 3, 4, 5, 6}
var ta2 = {0,1, 2, 3, 4, 5, 6}
var ta3 = {0,1, 2, 3, 4, 5, 6}
var ta4 = {0,1, 2, 3, 4, 5, 6}
var ta5 = {0,1, 2, 3, 4, 5, 6}
var ta6 = {0,1, 2, 3, 4, 5, 6}
var ta7 = {0,1, 2, 3, 4, 5, 6}
var ta8 = {0,1, 2, 3, 4, 5, 6}
var ta = {1, 2, 3, 4, 5, 6}
var tla1 = {1, 2, 3, 5}
var tla2 = {1, 2, 3, 5}
var tla3 = {1, 2, 3, 5}
var td1 = {0,4,6}
var td2 = {0,4,6}
var td3 = {0,4,6}
var td4 = {0,4,6}
var td5 = {0,4,6}
var td6 = {0,4,6}
var d1 = {0,6}
var d2 = {0,6}
var d3 = {0,6}
var d4 = {0,6}
var d5 = {0,6}
var d6 = {0,6}
#regular case (with neighbour tails only) three neighbours
z,la1,la2,la3,d1,d2,d3,d4,d5,1
z,la1,la2,d1,la3,d2,d3,d4,d5,1
z,la1,la2,d1,d2,la3,d3,d4,d5,1
z,la1,la2,d1,d2,d3,la3,d4,d5,1
z,la1,la2,d1,d2,d3,d4,la3,d5,1
z,la1,la2,d1,d2,d3,d4,d5,la3,1
z,la1,d1,la2,d2,la3,d3,d4,d5,1
z,la1,d1,la2,d2,d3,la3,d4,d5,1
2,la1,la2,la3,d1,d2,d3,d4,d5,2
2,la1,la2,d1,la3,d2,d3,d4,d5,2
2,la1,la2,d1,d2,la3,d3,d4,d5,2
2,la1,la2,d1,d2,d3,la3,d4,d5,2
2,la1,la2,d1,d2,d3,d4,la3,d5,2
2,la1,la2,d1,d2,d3,d4,d5,la3,2
2,la1,d1,la2,d2,la3,d3,d4,d5,2
2,la1,d1,la2,d2,d3,la3,d4,d5,2
#regular case(with neighbour tails only) two neighbors
v,la1,la3,d1,d2,d3,d4,d5,d6,v
v,la1,d1,la3,d2,d3,d4,d5,d6,v
v,la1,d1,d2,la3,d3,d4,d5,d6,v
v,la1,d1,d2,d3,la3,d4,d5,d6,v
#regular case (with neighbour tails only) death
1,a1,a2,a3,a4,a5,a6,a7,a8,0
0,a1,a2,a3,a4,a5,a6,a7,a8,0
2,a1,a2,a3,a4,a5,a6,a7,a8,4
#Neighbohr head no tails
z,hla1,hla2,hla3,hd1,hd2,hd3,hd4,hd5,3
z,hla1,hla2,hd1,hla3,hd2,hd3,hd4,hd5,3
z,hla1,hla2,hd1,hd2,hla3,hd3,hd4,hd5,3
z,hla1,hla2,hd1,hd2,hd3,hla3,hd4,hd5,3
z,hla1,hla2,hd1,hd2,hd3,hd4,hla3,hd5,3
z,hla1,hla2,hd1,hd2,hd3,hd4,hd5,hla3,3
z,hla1,hd1,hla2,hd2,hla3,hd3,hd4,hd5,3
z,hla1,hd1,hla2,hd2,hd3,hla3,hd4,hd5,3
1,hla1,hla3,hd1,hd2,hd3,hd4,hd5,hd6,3
1,hla1,hd1,hla3,hd2,hd3,hd4,hd5,hd6,3
1,hla1,hd1,hd2,hla3,hd3,hd4,hd5,hd6,3
1,hla1,hd1,hd2,hd3,hla3,hd4,hd5,hd6,3
2,hla1,hla2,hla3,hd1,hd2,hd3,hd4,hd5,2
2,hla1,hla2,hd1,hla3,hd2,hd3,hd4,hd5,2
2,hla1,hla2,hd1,hd2,hla3,hd3,hd4,hd5,2
2,hla1,hla2,hd1,hd2,hd3,hla3,hd4,hd5,2
2,hla1,hla2,hd1,hd2,hd3,hd4,hla3,hd5,2
2,hla1,hla2,hd1,hd2,hd3,hd4,hd5,hla3,2
2,hla1,hd1,hla2,hd2,hla3,hd3,hd4,hd5,2
2,hla1,hd1,hla2,hd2,hd3,hla3,hd4,hd5,2
2,hla1,hla3,hd1,hd2,hd3,hd4,hd5,hd6,2
2,hla1,hd1,hla3,hd2,hd3,hd4,hd5,hd6,2
2,hla1,hd1,hd2,hla3,hd3,hd4,hd5,hd6,2
2,hla1,hd1,hd2,hd3,hla3,hd4,hd5,hd6,2
z,ha,ha2,ha3,ha4,ha5,ha6,ha7,ha8,4
2,ha,ha2,ha3,ha4,ha5,ha6,ha7,ha8,4
hz,tla1,tla2,tla3,td1,td2,td3,td4,td5,5
hz,tla1,tla2,td1,tla3,td2,td3,td4,td5,5
hz,tla1,tla2,td1,td2,tla3,td3,td4,td5,5
hz,tla1,tla2,td1,td2,td3,tla3,td4,td5,5
hz,tla1,tla2,td1,td2,td3,td4,tla3,td5,5
hz,tla1,tla2,td1,td2,td3,td4,td5,tla3,5
hz,tla1,td1,tla2,td2,tla3,td3,td4,td5,5
hz,tla1,td1,tla2,td2,td3,tla3,td4,td5,5
3,tla1,tla3,td1,td2,td3,td4,td5,td6,5
3,tla1,td1,tla3,td2,td3,td4,td5,td6,5
3,tla1,td1,td2,tla3,td3,td4,td5,td6,5
3,tla1,td1,td2,td3,tla3,td4,td5,td6,5
2,tla1,tla2,tla3,td1,td2,td3,td4,td5,2
2,tla1,tla2,td1,tla3,td2,td3,td4,td5,2
2,tla1,tla2,td1,td2,tla3,td3,td4,td5,2
2,tla1,tla2,td1,td2,td3,tla3,td4,td5,2
2,tla1,tla2,td1,td2,td3,td4,tla3,td5,2
2,tla1,tla2,td1,td2,td3,td4,td5,tla3,2
2,tla1,td1,tla2,td2,tla3,td3,td4,td5,2
2,tla1,td1,tla2,td2,td3,tla3,td4,td5,2
2,tla1,tla3,td1,td2,td3,td4,td5,td6,2
2,tla1,td1,tla3,td2,td3,td4,td5,td6,2
2,tla1,td1,td2,tla3,td3,td4,td5,td6,2
2,tla1,td1,td2,td3,tla3,td4,td5,td6,2
hz,ta1,ta2,ta3,ta4,ta5,ta6,ta7,ta8,6
2,ta1,ta2,ta3,ta4,ta5,ta6,ta7,ta8,4
#tails
tz,tla1,tla2,tla3,td1,td2,td3,td4,td5,1
tz,tla1,tla2,td1,tla3,td2,td3,td4,td5,1
tz,tla1,tla2,td1,td2,tla3,td3,td4,td5,1
tz,tla1,tla2,td1,td2,td3,tla3,td4,td5,1
tz,tla1,tla2,td1,td2,td3,td4,tla3,td5,1
tz,tla1,tla2,td1,td2,td3,td4,td5,tla3,1
tz,tla1,td1,tla2,td2,tla3,td3,td4,td5,1
tz,tla1,td1,tla2,td2,td3,tla3,td4,td5,1
5,tla1,tla3,td1,td2,td3,td4,td5,td6,1
5,tla1,td1,tla3,td2,td3,td4,td5,td6,1
5,tla1,td1,td2,tla3,td3,td4,td5,td6,1
5,tla1,td1,td2,td3,tla3,td4,td5,td6,1
tz,ta1,ta2,ta3,ta4,ta5,ta6,ta7,ta8,0
@COLORS
0 0 0 0
1 255 255 255
2 255 0 0
3 255 255 255
4 0 0 255
5 255 255 255
6 0 0 0
x = 97, y = 120, rule = PropogatingLife
60.A.A20.A$61.2A18.3A$61.A18.A$80.BA6$90.A$88.3A$87.A$87.BA$65.AB$65.
2A6$77.2A$77.2A$91.AB$91.2A$95.2A$95.BA14$71.2A$71.A.B$72.A7$67.A.2A$
67.2A.A2$76.AB$76.2A10$62.A$60.3A$59.A$59.2A2$66.2A$67.A$67.A.A$40.A
27.AB$31.A7.A.A$31.3A6.B$34.A$33.AB6$26.2A25.2A$26.2A25.A$51.A.A6.A8.
AB15.BA$2A49.BA7.3A6.2A15.A.A$AB61.A24.A$62.2A24.2A$38.AB$29.2A6.A.A$
30.A6.A41.A$29.A6.2A39.3A$4.BA23.2A45.A$4.2A70.2A4$40.AB$39.A.A$39.A$
38.2A4$83.2A$83.2A4$78.BA$78.2A$82.2A$82.2A$41.2A$41.2A$47.AB27.2A$
47.2A27.2A3$45.2A$45.2A5.2A$52.2A!
dvgrn wrote: If you can come up with a really good evaluation function that keeps 99% of the promising reactions and throws away 99% of the "obviously useless" ones
simsim314 wrote:And as I mentioned, there is an obvious evaluation function with catalyst searches (for G->H): like the minimal distance to the original block, and number of options to place the catalyst relatively "close" to the block. You're definitely right that it can for example have some "cache of patterns" and very similar pattern that showed to be a failure can also score lower. So we can come up with "more or less" reasonable evaluation function that will cut our "brute force search" in millions or billions of times...
dvgrn wrote: There are quite a few unfinished search utilities lying around out there for every functional one -- and not too surprisingly, the simpler programs seem to be the ones that get finished more often!
/* catalyst v1.0
Released 3/21/2001
Copyright (c) 2001, Gabriel Nivasch
*/
/*
Modified By Michael Simkin
GCC compatible C code.
*/
#include <stdio.h>
#include <stdlib.h>
#define Profilea 0
#define SZ 60
#define MAXGENS 100
#define MAXCATS 10
#define NCATS 7
#define CATSZ 15
typedef struct
{
int x, y;
} cell;
typedef struct
{
char c[CATSZ][CATSZ];
int x, y, name;
} catalyst;
const catalyst cata[NCATS]=
{
{ { {' ', ' ', 'x', ':', '2', '1', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', '.', '*', 'o', ':', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'.', ':', '$', '%', '*', 'X', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{':', '*', '*', '*', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{':', '*', '$', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'.', '.', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}
},
6, 6, 'eat1'
},
{ { {' ', ' ', ' ', '.', '.', 'X', ':', '2', '1', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', '.', ':', '$', '*', '$', 'o', 'o', '2', ' ', ' ', ' ', ' ', ' ', ' '},
{'.', ':', '*', '*', '*', '$', 'o', 'o', ':', ' ', ' ', ' ', ' ', ' ', ' '},
{'.', '*', '%', '^', '$', '$', '$', '$', 'X', ' ', ' ', ' ', ' ', ' ', ' '},
{'.', ':', '*', '*', '*', '$', '*', '*', '.', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', '.', ':', '%', '*', '^', '*', '$', '.', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ':', '*', '%', '*', ':', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', '.', ':', '*', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', '.', '.', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}
},
9, 9, 'eat2'
},
{ { {'x', '.', ':', ':', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'2', '*', '$', '*', '*', ':', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'X', '*', '*', '$', '*', ':', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'x', ':', ':', ':', '.', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}
},
4, 6, 'snak'
},
{ { {'.', 'X', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{':', '*', 'o', '2', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{':', '*', 'o', '2', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'.', 'X', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}
},
4, 4, 'bloc'
},
{ { {' ', ' ', ' ', ' ', '.', ':', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ':', '*', '*', ':', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ':', 'o', 'o', ':', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', '.', ':', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', 'x', '.', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', '.', ':', 'o', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', '.', '*', '$', 'o', '1', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'.', ':', '$', '$', '*', 'X', '1', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{':', '*', '*', '*', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{':', '*', '$', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'.', '.', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}
},
11, 8, 'tubw'
},
{ { {' ', '.', 'x', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'.', ':', '*', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'1', 'o', '$', '*', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'.', ':', '*', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', '.', 'x', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}
},
5, 5, '_tub'
},
{ { {' ', 'x', '.', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'x', ':', '*', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'1', 'o', '%', '*', ':', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{'1', 'X', '*', '*', ':', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', '.', ':', ':', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}
},
5, 5, 'boat'
}
};
/* The following array contains the state of the pattern at each
generation from 0 to the current one. For each generation there are two
arrays: now[SZ][SZ] and history[SZ][SZ]. now[][] contains the state of
the pattern at that generation. The format is as follows:
If the cell is alive, then bit #9 (LiveBit) is set.
In addition, exactly one of the bits #0 to #8 is set, indicating the
number of live neighbors the cell has.
history[][] contains the superposition (inclusive "OR") of all the
states each cell has been in, in all the previous generations.
The purpose of history[][] is to know whether the cell has ever been alive,
and if it was never alive, to know all the different neighbor counts it
has had. If bit #9 is set, it means the cell has been alive at some
point, and each of the bits #0 to #8 that is set indicates a neighbor
count the cell has had at some point.
For each generation there are also four variables indicating the current
boundaries of the pattern, and the variable numcats, which indicates how
many catalysts have been placed this generation.
*/
struct board
{
int now[SZ][SZ];
int history[SZ][SZ];
int xmin, xmax, ymin, ymax;
int numcats;
} stack[MAXGENS];
//Bit values used in now[][] and history[][]:
#define LiveBit 512
#define CountBitMask 511
//This macro function is used in advance1gen():
#define WillLive(x) ((x)==8 || (x)==516 || (x)==520)
/* The following array is used to print out the patterns created.
At the beginning the initial pattern is set in it. In addition, each
time a catalyst is placed on the board at a certain generation, it is
also placed here. When the catalyst is removed from the board, it is
also removed from here.
*/
int boardgen0[SZ][SZ];
int g0minx=SZ, g0miny=SZ, g0maxx=0, g0maxy=0;
/* This array indicates which cells are fixed, i.e. if they are dead,
they are not allowed to live, and if they are alive, they are not
allowed to die. There are two sources from which fixed cells can come:
From the catalysts (cells marked 'x', 'X', and '*'), or from the input
pattern of the user. Note that cells that were set fixed dead by the
user or by a catalyst, might be set again as fixed dead by another catalyst.
Then, when the second catalyst is removed, the cell should still remain fixed
dead because of the first catalyst or the user's input. Therefore, the
procedure is as follows:
To set a cell as fixed, add 1. To unset it, substract 1. The cell is free
only if the value is 0. If the value is less than 0, it is an error.
*/
int fixed[SZ][SZ];
/* The following array contains info for each catalyst that has
been placed on the board: position, catalyst number, orientation,
generation placed, and the old values of the pattern boundaries, which
are restored when the catalyst is removed.
*/
struct catposition
{
int x, y, n, orient, gen;
int oldxmin, oldxmax, oldymin, oldymax; //Used to restore the values
//after removing the catalyst.
int g0oldminx, g0oldminy, g0oldmaxx, g0oldmaxy;
//Used to restore g0minx, etc., after removing the catalyst.
} catplaced[MAXCATS];
int catisused[NCATS]; //The user can select which catalysts to use.
int startinggen, gens, catstoplace, catspergen, catsurvive;
int currgen, currx, curry, currcatn, currorient;
int nCatsTotal=0; //Used to index catplaced[]
int callcount=0;
int advance1gen(void);
int placecatalyst(void);
int removelastcat(void);
void printgen(int);
void printboard(FILE *);
void printinfo(FILE *);
int main()
{
int initial[SZ][SZ];
int x, y, g;
int xmin=SZ, xmax=0, ymin=SZ, ymax=0;
char ch;
int tofile;
FILE *fi;
#if Profilea
if(ProfilerInit(collectDetailed, bestTimeBase, 50, 10))
{
printf("Error: ProfilerInit().\n");
return 1;
}
#endif
//Use this commented-out code to print out a catalyst and check that
//it is correct:
/*for (y=0; y<cata[6].y; y++)
{
for (x=0; x<cata[6].x; x++)
printf("%c", cata[6].c[x][y]);
printf("\n");
}
if(1)return 0;*/
for (x=0; x<SZ; x++)
for (y=0; y<SZ; y++)
{
initial[x][y]=0;
boardgen0[x][y]=0;
fixed[x][y]=0;
for (g=0; g<MAXGENS; g++)
{
stack[g].now[x][y]= 1<<0;
stack[g].history[x][y]= 1<<0;
}
}
for (x=0; x<NCATS; x++)
catisused[x]=0;
printf("Print output to file (y/n)? ");
do
{
scanf("%c", &ch);
}
while (ch!='n' && ch!='N' && ch!='y' && ch!='Y');
tofile=((ch=='Y') || (ch=='y'));
if (tofile)
fi=fopen("reactions.txt", "w");
else
fi=stdout;
printf("\nPlease enter the pattern. Use ' ' or '.' for regular dead cells,\n"
"',' for fixed dead cells, '*' for fixed live cells, and any other \n"
"character for regular live cells. Finish the pattern with '!':\n");
//Read the pattern entered by the user and store it in initial[][].
//Set the fixed cells in fixed[][]:
x=3;
y=3;
char c;
while ((c=getchar())!='!')
{
if (c == '\n')
{
x=3;
y++;
continue;
}
if (c != ' ' && c != '.')
{
if (x>=SZ-3)
{
printf("Error: Pattern too wide.\n");
return 1;
}
if (y>=SZ-3)
{
printf("Error: Pattern too tall.\n");
return 1;
}
if (c == ',')
initial[x][y]=1; //Fixed dead
else if (c == '*')
initial[x][y]=2; //Fixed live
else
initial[x][y]=3; //Live
if (x<xmin) xmin=x;
if (x>xmax) xmax=x;
if (y<ymin) ymin=y;
if (y>ymax) ymax=y;
}
x++;
}
//Initialize fixed[][], stack[0], and boardgen0[][],
//centering the pattern in the middle of the board:
int xoffset=(SZ-xmax-xmin-2)/2, yoffset=(SZ-ymax-ymin-2)/2;
for (x=xmin-1; x<=xmax+1; x++)
for (y=ymin-1; y<=ymax+1; y++)
{
stack[0].now[x+xoffset][y+yoffset]=0;
if (initial[x][y]>1) //2 or 3, which is alive
{
stack[0].now[x+xoffset][y+yoffset]=LiveBit;
//Little hack so that things work properly:
stack[0].history[x+xoffset][y+yoffset] = 1<<3;
boardgen0[x+xoffset][y+yoffset]=1;
}
if (initial[x][y]==1 || initial[x][y]==2) //Fixed
fixed[x+xoffset][y+yoffset]=1;
//Count the neighbors:
int count=(initial[x-1][y-1]>1) + (initial[x][y-1]>1) + (initial[x+1][y-1]>1)
+(initial[x-1][y ]>1) + (initial[x+1][y ]>1)
+(initial[x-1][y+1]>1) + (initial[x][y+1]>1) + (initial[x+1][y+1]>1);
if (count<0 || count>8)
{
printf("Error: count is out of range.\n");
return 1;
}
//Check for inconsistency:
if ((initial[x][y]==2 && count!=2 && count!=3) ||
(initial[x][y]==1 && count==3))
{
printf("Error: Inconsistency in the starting pattern.\n");
return 1;
}
//Set the neighbor count bit:
stack[0].now[x+xoffset][y+yoffset] |= 1<<count;
} //for for
//Set boundary variables:
stack[0].xmin= g0minx= xmin-1 + xoffset;
stack[0].xmax= g0maxx= xmax+1 + xoffset;
stack[0].ymin= g0miny= ymin-1 + yoffset;
stack[0].ymax= g0maxy= ymax+1 + yoffset;
stack[0].numcats=0;
//Repeat the initial pattern to the user:
printf("\nYou entered:\n");
if (tofile)
fprintf(fi, "Initial pattern:\n");
for (y=ymin; y<=ymax; y++)
{
for (x=xmin; x<=xmax; x++)
{
switch (initial[x][y])
{
case 0:
ch='.';
break;
case 1:
ch=',';
break;
case 2:
ch='*';
break;
case 3:
ch='o';
break;
}
printf("%c", ch);
if (tofile)
fprintf(fi, "%c", ch);
}
printf("\n");
if (tofile)
fprintf(fi, "\n");
}
printf("\nCustomize which catalysts to use (y/n)? ");
do
{
scanf("%c", &ch);
}
while (ch!='n' && ch!='N' && ch!='y' && ch!='Y');
if ((ch=='Y') || (ch=='y'))
{
printf("These are the available catalysts:\n");
for (x=0; x<NCATS; x++)
printf("%2d: %c%c%c%c\n", x+1, cata[x].name>>24, cata[x].name>>16,
cata[x].name>>8, cata[x].name);
do
{
printf("Enter a number from the above list, or 0 to finish: ");
scanf("%d", &x);
if (x==0)
break;
if (x>NCATS || x<0)
{
printf("Invalid number.\n");
continue;
}
x--;
catisused[x]=1;
printf("%c%c%c%c selected.\n", cata[x].name>>24, cata[x].name>>16,
cata[x].name>>8, cata[x].name);
}
while(1);
}
else
for (x=0; x<NCATS; x++)
catisused[x]=1;
if (tofile)
{
fprintf(fi, "\nCatalysts to use:\n");
for (x=0; x<NCATS; x++)
if (catisused[x])
fprintf(fi, "%c%c%c%c\n", cata[x].name>>24, cata[x].name>>16,
cata[x].name>>8, cata[x].name);
}
printf("\nEarliest generation for placing catalysts? ");
scanf("%d", &startinggen);
printf("Latest generation for placing catalysts? ");
scanf("%d", &gens);
if (tofile)
fprintf(fi, "\nGenerations for placing catalysts: %d through %d.\n",
startinggen, gens);
printf("How many generations must a catalyst survive? ");
scanf("%d", &catsurvive);
gens += catsurvive;
if (gens>=MAXGENS)
{
printf("Error: %d exceeds the maximum number of generations, which is %d.\n",
gens, MAXGENS-1);
return 1;
}
printf("Maximum number of catalysts? ");
scanf("%d", &catstoplace);
if (catstoplace>MAXCATS)
{
printf("Error: %d exceeds the maximum number of catalysts, which is %d.\n",
catstoplace, MAXCATS);
return 1;
}
/* The purpose of this option was to allow the user to restrict the number of
catalysts that can be placed in one generation, in order to reduce the
huge number of possibilities that occur when catstoplace has a large value.
However, searching with a large value of catstoplace is inconvenient in any
case. Therefore, I deactivated this option but still left it in the code.
To re-activate it, un-comment this code and remove the line
"catspergen=catstoplace;":
*/
/*printf("Maximum number of catalysts in one generation? ");
scanf("%d", &catspergen);*/
catspergen=catstoplace;
printf("\n");
if (tofile)
{
fprintf(fi, "Catalysts must survive %d generation%s.\n", catsurvive,
catsurvive==1?"":"s");
/*fprintf(fi, "%d catalysts maximum (%d maximum in one generation).\n\n",
catstoplace, catspergen);*/
fprintf(fi, "%d catalyst%s maximum.\n\n", catstoplace,
catstoplace==1?"":"s");
}
currgen=0;
currx=0;
curry=0;
currcatn=0;
currorient=0;
int numprinted=0;
//Main loop:
while(currgen>=0)
{
//Place another catalyst at this generation
//until you can no more.
if (currgen >= startinggen && currgen+catsurvive <= gens)
while (nCatsTotal < catstoplace &&
stack[currgen].numcats < catspergen &&
placecatalyst())
{ }
if (currgen==gens)
{
fprintf(fi, "Pattern # %d:\n", ++numprinted);
printboard(fi);
printinfo(fi);
if (removelastcat())
break; //Finished. Out of main loop.
//Increment the current position:
currx++;
continue;
}
//Advance 1 generation.
if (advance1gen())
{
if (nCatsTotal==0 ||
currgen-catplaced[nCatsTotal-1].gen>=catsurvive)
{
fprintf(fi, "Pattern # %d:\n", ++numprinted);
printboard(fi);
printinfo(fi);
}
if (removelastcat())
break; //Finished. Out of main loop.
//Increment the current position:
currx++;
}
if (callcount%1000==0)
{
printf("%d calls to advance1gen().\n", callcount);
printinfo(stdout);
if (tofile)
{
fprintf(fi, "%d calls to advance1gen().\n", callcount);
printinfo(fi);
}
}
}
printf("The end.\n%d call%s to advance1gen()\n"
"%d pattern%s printed.\n", callcount, callcount==1?"":"s",
numprinted, numprinted==1?"":"s");
if (tofile)
fprintf(fi, "The end.\n%d call%s to advance1gen()\n"
"%d pattern%s printed.\n", callcount, callcount==1?"":"s",
numprinted, numprinted==1?"":"s");
#if Profilea
ProfilerDump("\pprofile");
ProfilerTerm();
#endif
return 0;
} //main()
/* This function advances the pattern 1 generation and checks that nothing
of this occurs:
- A 'fixed' cell changes
- The pattern reaches the edge of the board
If one of these occurs the function returns 1.
*/
int advance1gen(void)
{
int x, y;
callcount++;
if (currgen==MAXGENS)
{
printf("Error in advance1gen(): Too many generations.\n");
exit(1);
}
if (stack[currgen].xmin<=1 || stack[currgen].xmax>= SZ-2 ||
stack[currgen].ymin<=1 || stack[currgen].ymax>= SZ-2)
return 1; //Edge of the board reached.
stack[currgen+1].xmin=SZ;
stack[currgen+1].xmax=0;
stack[currgen+1].ymin=SZ;
stack[currgen+1].ymax=0;
//We have to clear additional space around the pattern because it may
//contain junk from before, and the function placecatalyst() sometimes
//expands the boundaries without clearing.
int xstart=stack[currgen].xmin-1-CATSZ,
ystart=stack[currgen].ymin-1-CATSZ;
if (xstart<1) xstart=1;
if (ystart<1) ystart=1;
for (x=xstart; x<=stack[currgen].xmax+1+CATSZ && x<SZ-1; x++)
for (y=ystart; y<=stack[currgen].ymax+1+CATSZ && y<SZ-1; y++)
{
if (x<stack[currgen].xmin-1 || x>stack[currgen].xmax+1 ||
y<stack[currgen].ymin-1 || y>stack[currgen].ymax+1)
{
stack[currgen+1].now[x][y]= 1<<0;
stack[currgen+1].history[x][y]= 1<<0;
continue;
}
//Set the cell itself's next generation:
if(WillLive(stack[currgen].now[x][y]))
stack[currgen+1].now[x][y] = LiveBit;
else
stack[currgen+1].now[x][y] = 0;
//Count number of the live neighbors the cell will have the next
//generation:
int count=0;
if (WillLive(stack[currgen].now[x-1][y-1])) count++;
if (WillLive(stack[currgen].now[x-1][y ])) count++;
if (WillLive(stack[currgen].now[x-1][y+1])) count++;
if (WillLive(stack[currgen].now[x ][y-1])) count++;
if (WillLive(stack[currgen].now[x ][y+1])) count++;
if (WillLive(stack[currgen].now[x+1][y-1])) count++;
if (WillLive(stack[currgen].now[x+1][y ])) count++;
if (WillLive(stack[currgen].now[x+1][y+1])) count++;
//If it's a fixed cell, check that it will not change 2 generations
//from now. We assume that it has already been checked that it will
//not change next generation:
if (fixed[x][y] &&
(((stack[currgen].now[x][y] & LiveBit) && count!=2 && count!=3) ||
((stack[currgen].now[x][y] & LiveBit)==0 && count==3)))
return 1;
//Set the cell's count bit:
stack[currgen+1].now[x][y] |= 1<<count;
//Also set the next generation's history board:
stack[currgen+1].history[x][y] = stack[currgen].history[x][y] |
stack[currgen].now[x][y];
//Adjust next gen's boundary variables if necessary.
//Note that the pattern's boundaries will never become smaller than
//in a previous generation, because of history[][]:
if ((stack[currgen+1].now[x][y] & (~1)) ||
(stack[currgen+1].history[x][y] & (~1)))
{
if (x < stack[currgen+1].xmin) stack[currgen+1].xmin=x;
if (x > stack[currgen+1].xmax) stack[currgen+1].xmax=x;
if (y < stack[currgen+1].ymin) stack[currgen+1].ymin=y;
if (y > stack[currgen+1].ymax) stack[currgen+1].ymax=y;
}
} //for for
currgen++;
currx=curry=currcatn=currorient=0;
return 0;
} //advance1gen()
/* This function looks for a place to place a catalyst on this generation's
board, starting from the position specified by the globals currx, curry,
currorient, and currcatn, and going ahead. It makes sure that the
catalyst would not have reacted at any previous generation. It also makes
sure that the catalyst will react now, i.e. next generation.
*/
int placecatalyst()
{
int catszx, catszy;
char catcell;
while (currcatn<NCATS)
{
//Skip this catalyst if it is deactivated:
if (!catisused[currcatn])
{
currorient=0;
currcatn++;
continue;
}
while (currorient<8)
{
//Skip some orientations for symmetric patterns:
if (cata[currcatn].name=='eat2')
if (currorient>=4)
break;
if (cata[currcatn].name=='bloc' || cata[currcatn].name=='_tub')
if (currorient==1 || currorient==3 || currorient==5 || currorient==7)
{
curry=0;
currorient++;
continue;
}
if (currorient<4)
{
catszy=cata[currcatn].y;
catszx=cata[currcatn].x;
}
else
{
catszy=cata[currcatn].x;
catszx=cata[currcatn].y;
}
if (curry<stack[currgen].ymin - catszy)
curry=stack[currgen].ymin - catszy;
while (curry<SZ-catszy && curry<=stack[currgen].ymax + catszy)
{
if (currx<stack[currgen].xmin - catszx)
currx=stack[currgen].xmin - catszx;
while (currx<SZ-catszx && currx<=stack[currgen].xmax + catszx)
{
int x, y, reacts=0, isgood=1;
//Check the catalyst in this position cell by cell:
for (x=0; x<catszx && isgood; x++)
for (y=0; y<catszy && isgood; y++)
{
//Select the cell according to the orientation:
if (currorient==0) catcell=cata[currcatn].c[ x][ y];
else if (currorient==1) catcell=cata[currcatn].c[catszx-1-x][ y];
else if (currorient==2) catcell=cata[currcatn].c[ x][catszy-1-y];
else if (currorient==3) catcell=cata[currcatn].c[catszx-1-x][catszy-1-y];
else if (currorient==4) catcell=cata[currcatn].c[ y][ x];
else if (currorient==5) catcell=cata[currcatn].c[catszy-1-y][ x];
else if (currorient==6) catcell=cata[currcatn].c[ y][catszx-1-x];
else catcell=cata[currcatn].c[catszy-1-y][catszx-1-x];
if (catcell=='o' || catcell=='*')
if ((stack[currgen].history[currx+x][curry+y] != 1<<0) ||
(fixed[currx+x][curry+y] > 0))
{
isgood=0;
continue;
}
if (catcell=='.' || catcell=='1' || catcell=='x')
if (stack[currgen].history[currx+x][curry+y] &
(LiveBit | (1<<2) | (1<<3)))
{
isgood=0;
continue;
}
if (catcell=='$' || catcell=='%' || catcell=='^')
if (stack[currgen].history[currx+x][curry+y] & LiveBit)
{
isgood=0;
continue;
}
if (catcell==':' || catcell=='2' || catcell=='X')
if (stack[currgen].history[currx+x][curry+y] &
(LiveBit | (1<<1) | (1<<3)))
{
isgood=0;
continue;
}
if (catcell=='1')
if ((stack[currgen].now[currx+x][curry+y] & CountBitMask) == (1<<2))
reacts=1;
if (catcell=='2')
if ((stack[currgen].now[currx+x][curry+y] & CountBitMask) == (1<<1))
reacts=1;
if (catcell=='x')
if ((stack[currgen].now[currx+x][curry+y] & CountBitMask) == (1<<2))
{
isgood=0;
continue;
}
if (catcell=='X')
if ((stack[currgen].now[currx+x][curry+y] & CountBitMask) == (1<<1))
{
isgood=0;
continue;
}
//Reject also if the catalyst will cause a birth in a fixed cell:
if (fixed[currx+x][curry+y] && (catcell=='.' || catcell=='1') &&
(stack[currgen].now[currx+x][curry+y] & CountBitMask) == (1<<2))
{
isgood=0;
continue;
}
if (fixed[currx+x][curry+y] && (catcell==':' || catcell=='2') &&
(stack[currgen].now[currx+x][curry+y] & CountBitMask) == (1<<1))
{
isgood=0;
continue;
}
} //for for
if (isgood && reacts)
{
//Save the current values of the boundary variables:
catplaced[nCatsTotal].oldxmin=stack[currgen].xmin;
catplaced[nCatsTotal].oldxmax=stack[currgen].xmax;
catplaced[nCatsTotal].oldymin=stack[currgen].ymin;
catplaced[nCatsTotal].oldymax=stack[currgen].ymax;
//Save the current boundaries of boardgen0[][]:
catplaced[nCatsTotal].g0oldminx=g0minx;
catplaced[nCatsTotal].g0oldminy=g0miny;
catplaced[nCatsTotal].g0oldmaxx=g0maxx;
catplaced[nCatsTotal].g0oldmaxy=g0maxy;
//Place the catalyst on the board.
//Also, modify the history board as if the
//catalyst was always there.
//Also place the catalyst on boardgen0[][]:
for (x=0; x<catszx; x++)
for (y=0; y<catszy; y++)
{
if (currorient==0) catcell=cata[currcatn].c[ x][ y];
else if (currorient==1) catcell=cata[currcatn].c[catszx-1-x][ y];
else if (currorient==2) catcell=cata[currcatn].c[ x][catszy-1-y];
else if (currorient==3) catcell=cata[currcatn].c[catszx-1-x][catszy-1-y];
else if (currorient==4) catcell=cata[currcatn].c[ y][ x];
else if (currorient==5) catcell=cata[currcatn].c[catszy-1-y][ x];
else if (currorient==6) catcell=cata[currcatn].c[ y][catszx-1-x];
else catcell=cata[currcatn].c[catszy-1-y][catszx-1-x];
//Adjust now[][], history[][], and boardgen0[][]:
if (catcell=='o')
{
stack[currgen].now[currx+x][curry+y]=LiveBit+(1<<3);
stack[currgen].history[currx+x][curry+y]=LiveBit+(1<<3);
boardgen0[currx+x][curry+y]=2;
}
//It doesn't necessarily have 3 neighbors, but it doesn't matter.
if (catcell=='*')
{
stack[currgen].now[currx+x][curry+y]=LiveBit+(1<<3);
stack[currgen].history[currx+x][curry+y]=LiveBit+(1<<3);
boardgen0[currx+x][curry+y]=2;
fixed[currx+x][curry+y]++;
}
//Adjust the boundaries of boardgen0[][]:
if (catcell=='o' || catcell=='*' || catcell=='x' || catcell=='X')
{
if (currx+x < g0minx) g0minx=currx+x;
if (currx+x > g0maxx) g0maxx=currx+x;
if (curry+y < g0miny) g0miny=curry+y;
if (curry+y > g0maxy) g0maxy=curry+y;
}
if (catcell=='.' || catcell=='1' || catcell=='x')
{
stack[currgen].now[currx+x][curry+y] <<= 1;
stack[currgen].history[currx+x][curry+y] <<= 1;
}
if (catcell==':' || catcell=='2' || catcell=='X')
{
stack[currgen].now[currx+x][curry+y] <<= 2;
stack[currgen].history[currx+x][curry+y] <<= 2;
}
if (catcell=='$')
{
stack[currgen].now[currx+x][curry+y] <<= 4;
stack[currgen].history[currx+x][curry+y] <<= 4;
}
if (catcell=='%')
{
stack[currgen].now[currx+x][curry+y] <<= 5;
stack[currgen].history[currx+x][curry+y] <<= 5;
}
if (catcell=='^')
{
stack[currgen].now[currx+x][curry+y] <<= 6;
stack[currgen].history[currx+x][curry+y] <<= 6;
}
if (catcell=='x' || catcell=='X')
fixed[currx+x][curry+y]++;
//Adjust the boundary variables if necessary:
if (catcell != ' ')
{
if (currx+x < stack[currgen].xmin)
stack[currgen].xmin=currx+x;
if (currx+x > stack[currgen].xmax)
stack[currgen].xmax=currx+x;
if (curry+y < stack[currgen].ymin)
stack[currgen].ymin=curry+y;
if (curry+y > stack[currgen].ymax)
stack[currgen].ymax=curry+y;
}
} //for for
//Record the placement:
catplaced[nCatsTotal].x=currx;
catplaced[nCatsTotal].y=curry;
catplaced[nCatsTotal].n=currcatn;
catplaced[nCatsTotal].orient=currorient;
catplaced[nCatsTotal].gen=currgen;
nCatsTotal++;
stack[currgen].numcats++;
return 1;
} //isgood && reacts
currx++;
} //while currx
currx=0;
curry++;
} //while curry
curry=0;
currorient++;
} //while currorient
currorient=0;
currcatn++;
} //while currcatn
return 0; //No way to place a catalyst
} //placecatalyst()
/* This function removes the last catalyst that was placed, according to
the array catplaced[]. It backs up to the generation when that catalyst
was placed. It returns 1 if there are no catalysts to remove.
*/
int removelastcat()
{
if (nCatsTotal==0)
return 1;
nCatsTotal--;
currgen=catplaced[nCatsTotal].gen;
currx=catplaced[nCatsTotal].x;
curry=catplaced[nCatsTotal].y;
currcatn=catplaced[nCatsTotal].n;
currorient=catplaced[nCatsTotal].orient;
stack[currgen].numcats--;
int catszx, catszy, x, y;
char catcell;
if (currorient<4)
{
catszy=cata[currcatn].y;
catszx=cata[currcatn].x;
}
else
{
catszy=cata[currcatn].x;
catszx=cata[currcatn].y;
}
//Undo the placement of the catalyst, by restoring the values of
//new[][] and history[][].
//Also, remove the catalyst from boardgen0[][]:
for (x=0; x<catszx; x++)
for (y=0; y<catszy; y++)
{
int newhist=0;
if (currorient==0) catcell=cata[currcatn].c[ x][ y];
else if (currorient==1) catcell=cata[currcatn].c[catszx-1-x][ y];
else if (currorient==2) catcell=cata[currcatn].c[ x][catszy-1-y];
else if (currorient==3) catcell=cata[currcatn].c[catszx-1-x][catszy-1-y];
else if (currorient==4) catcell=cata[currcatn].c[ y][ x];
else if (currorient==5) catcell=cata[currcatn].c[catszy-1-y][ x];
else if (currorient==6) catcell=cata[currcatn].c[ y][catszx-1-x];
else catcell=cata[currcatn].c[catszy-1-y][catszx-1-x];
if (catcell=='o' || catcell=='*')
{
stack[currgen].now[currx+x][curry+y]= 1<<0;
stack[currgen].history[currx+x][curry+y]= 1<<0;
boardgen0[currx+x][curry+y]=0;
}
if (catcell=='*')
{
stack[currgen].now[currx+x][curry+y]= 1<<0;
stack[currgen].history[currx+x][curry+y]= 1<<0;
boardgen0[currx+x][curry+y]=0;
fixed[currx+x][curry+y]--;
if (fixed[currx+x][curry+y]<0)
{
printf("Error 1 in removelastcat(): fixed[%d][%d] < 0.\n",
currx+x, curry+y);
exit(1);
}
}
if (catcell=='x' || catcell=='X')
{
fixed[currx+x][curry+y]--;
if (fixed[currx+x][curry+y]<0)
{
printf("Error 2 in removelastcat(): fixed[%d][%d] < 0.\n",
currx+x, curry+y);
exit(1);
}
}
if (catcell=='.' || catcell=='1' || catcell=='x')
{
stack[currgen].now[currx+x][curry+y] >>= 1;
stack[currgen].history[currx+x][curry+y] >>= 1;
}
if (catcell==':' || catcell=='2' || catcell=='X')
{
stack[currgen].now[currx+x][curry+y] >>= 2;
stack[currgen].history[currx+x][curry+y] >>= 2;
}
if (catcell=='$')
{
stack[currgen].now[currx+x][curry+y] >>= 4;
stack[currgen].history[currx+x][curry+y] >>= 4;
}
if (catcell=='%')
{
stack[currgen].now[currx+x][curry+y] >>= 5;
stack[currgen].history[currx+x][curry+y] >>= 5;
}
if (catcell=='^')
{
stack[currgen].now[currx+x][curry+y] >>= 6;
stack[currgen].history[currx+x][curry+y] >>= 6;
}
} //for for
//Restore the boundary variables:
stack[currgen].xmin=catplaced[nCatsTotal].oldxmin;
stack[currgen].xmax=catplaced[nCatsTotal].oldxmax;
stack[currgen].ymin=catplaced[nCatsTotal].oldymin;
stack[currgen].ymax=catplaced[nCatsTotal].oldymax;
//Restore boardgen0[][]'s boundaries:
g0minx=catplaced[nCatsTotal].g0oldminx;
g0miny=catplaced[nCatsTotal].g0oldminy;
g0maxx=catplaced[nCatsTotal].g0oldmaxx;
g0maxy=catplaced[nCatsTotal].g0oldmaxy;
return 0;
} //removelastcat()
void printgen(int mode)
{
int x, y,n;
for (y=stack[currgen].ymin; y<=stack[currgen].ymax; y++)
{
for (x=stack[currgen].xmin; x<=stack[currgen].xmax; x++)
if (mode==0)
{
if (stack[currgen].now[x][y] & LiveBit)
if (fixed[x][y]) printf("*");
else printf("o");
else if (fixed[x][y]) printf(",");
else printf(".");
}
else
printf("%4d", stack[currgen].history[x][y]);
printf("\n");
}
printf("Catalysts placed at gens:");
for (n=0; n<nCatsTotal; n++)
printf(" %d", catplaced[n].gen);
printf("\nGeneration %d\n -----\n", currgen);
} //printgen()
void printboard(FILE *f)
{
int x, y;
for (y=g0miny; y<=g0maxy; y++)
{
for (x=g0minx; x<=g0maxx; x++)
//Fix this:
if (boardgen0[x][y])
if (fixed[x][y]) fprintf(f, "*");
else fprintf(f, "o");
else if (fixed[x][y]) fprintf(f, ",");
else fprintf(f, ".");
fprintf(f, "\n");
}
} //printboard()
void printinfo(FILE *f)
{
int n;
fprintf(f, "%d catalyst%s", nCatsTotal, nCatsTotal==1?"":"s");
if (nCatsTotal>0)
{
fprintf(f, ", which react%s", nCatsTotal==1 ? "s at gen." : " at gens.:");
for (n=0; n<nCatsTotal; n++)
fprintf(f, " %d", catplaced[n].gen);
}
else
fprintf(f, ".");
fprintf(f, "\nGeneration reached: %d\n -----\n", currgen);
} //printinfo()
x = 152, y = 146, rule = LifeHistory
19.2A$19.A$17.A.A$17.2A$28.2A$28.A$26.A.A$26.2A4$37.2A$37.A$2.2A31.A.
A$.A.A31.2A$.A$2A15.2A2.2A$17.2A.2A$22.A10$24.2A$24.2A8$44.2A$43.2A$
45.A3$48.A$47.2A$47.A.A19$71.A$70.2A$70.A.A4$74.2A$73.2A$75.A19$97.2A
$96.2A$98.A3$101.A$100.2A$100.A.A19$124.A$123.2A$123.A.A4$127.2A$126.
2A$128.A19$150.2A$149.2A$151.A!
simsim314 wrote:Here is a way to "slow salvo" 180 degree reflector 2G->G with 6 spartan components. This is by far the best 180 degree spartan reflector, for "high cost" 180 degree reflection purposes (i.e. where for some reason a minimalist 180 degree reflector is needed instead of heavy silver)... [Its] recovery is only 106 ticks.
#C "Glider stopper" used as a 2G->G 180-degree reflector
#C (the beehive can also stop a glider on two 90-degree lanes,
#C and the rest of the circuitry is transparent to one of those lanes)
x = 42, y = 46, rule = LifeHistory
3.C$3.3C$6.C$5.CD7$28.2A$28.A$26.A.A$26.2A4$37.2A$2.2A33.A$.A.A31.A.A
$.A33.2A$2A$17.2A2.2A$17.2A.2A$22.A10$24.2A$24.2A8$40.2A$39.2A$41.A!
dvgrn wrote:Somewhere in here, the extra 12sL for a full Silver reflector generally starts looking like a real bargain...!
simsim314 wrote:I'm not sure what is the best approach there, but this 2G+6SL looks like an option between a heavy 4G synchronizer and heavy 12SLs dried salvo.
This construction can also be used in opposite glider collision designs.It's pretty light weighted, and we need 2G->G component anyway.
#C Spartan resettable version of boojum reflector,
#C with a resettable Spartan rectifier at the right for comparison
#C The boojum reflector needs three asynchronous inputs
#C (or semi-synchronous, any timing within a fairly wide range).
x = 155, y = 78, rule = LifeHistory
2.A$A.A$.2A26$83.A$83.A.A$83.2A67.A$152.A.A$152.2A13$129.A$26.A30.2A
69.A.A$25.A.A29.2A69.A.A$26.A102.A3$31.2A$6.2A23.2A$7.A31.2A$7.A.A29.
A$8.2A27.A.A$4.2A25.2A4.2A$4.2A25.2A$50.2A$50.2A$32.2D85.2A$32.2D34.
2A49.2A$35.2C31.A.A$35.2C33.A66.2A$13.2A2.2A51.2A65.A.A$12.A.A2.2A
120.A$14.A21.2A101.2A$30.2A4.2A70.A$29.A.A27.2A46.A.A$29.A29.A.A45.A
2.A$28.2A31.A46.2A18.2A$36.2A23.2A65.A.A$36.2A92.A$103.2A25.2A$102.A.
A$42.A61.A$10.2A29.A.A$10.2A30.A!
Users browsing this forum: No registered users and 5 guests