Goldtiger997 wrote:How can zfind be modified so that when the depth limit is reached, it prints out the partial it already has as usual, but then continues the search for more spaceships?

It sounds like you want to use the 'm' command, which sets a max length for the search. Setting an 'm' value will cause the search to back up whenever the specified max length is reached. Note that the 'm' command should not be used if you are trying to prove that no spaceships exist at a certain width.

Goldtiger997 wrote:How can zfind be modified so that when the depth limit is reached, it prints out the partial it already has as usual, but then continues the search for more spaceships?

It sounds like you want to use the 'm' command, which sets a max length for the search. Setting an 'm' value will cause the search to back up whenever the specified max length is reached. Note that the 'm' command should not be used if you are trying to prove that no spaceships exist at a certain width.

Thanks, I tried it and it's close but not quite what I want. I was thinking of something that works just like the m parameter, but prints out what it has at the max length before backing up.

Goldtiger997 wrote:Thanks, I tried it and it's close but not quite what I want. I was thinking of something that works just like the m parameter, but prints out what it has at the max length before backing up.

wildmyron wrote:
I think this is working as expected. You can see from the "Known spaceships by width" table at http://www.conwaylife.com/wiki/User:Codeholic/Sandbox that there is no even symmetric ship below width 18, so if you take a partial from a width 12 search (w6 in zfind) it is not surprising that there is no completion for it at widths up to 18 (w9 in zfind)

So does that mean that there will be an official width-extended zfind programme release sometime?

The output will be redirected to a file named 'file.txt' located in the current working directory.
The dump files produced by the /d option will also be saved to the current working directory.

One disadvantage of the redirection operator is that the output is no longer displayed on the screen. As you have MinGW installed you could use the 'tee' command provided by MinGW (may need to be installed). This will show the output on-screen and save it to file. Use a pipe ( '|' character) to send output from zfind to the tee command instead of redirection.

and exits on my Mac when compiled with clang and extending a partial at width 10. Does not happen at width 9 or when not extending a partial. It occurred while trying to find loafer tagalongs. I recompiled using gcc and it works fine.

and exits on my Mac when compiled with clang and extending a partial at width 10. Does not happen at width 9 or when not extending a partial. It occurred while trying to find loafer tagalongs. I recompiled using gcc and it works fine.

Well, I guess zfind doesn't like trap music. What does that mean, anyway? Trap?

Just a quick question - I had a few modifications I wanted to try implementing, but the comment on the MAX_WIDTH line makes me wonder - Aside from the assumption that there is enough memory (when there will almost definitely not be) to construct the required, are there any assumptions in the code about the maximum allowable width that will cause width 11 search attempts to error regardless of how much memory is actually available?

Sphenocorona wrote:Just a quick question - I had a few modifications I wanted to try implementing, but the comment on the MAX_WIDTH line makes me wonder - Aside from the assumption that there is enough memory (when there will almost definitely not be) to construct the required, are there any assumptions in the code about the maximum allowable width that will cause width 11 search attempts to error regardless of how much memory is actually available?

I'm pretty sure it's because of the use of 32-bit integers in the lookup table to store the bits of three separate rows; with a width-11 search, this would take up 33 bits, unfortunately. I had wondered the same thing myself, as a hypothetical question about running a width-11 or 12 search hooked up to a couple hundred gigabytes of advanced memristor-based RAM analogue.

Okay, good to know. I'm unfortunately still not sure how I'm going to implement the honestly fairly simple idea I had, since it will require rewriting the structure of the lookup table itself and the way the code is written makes it difficult for me to understand how it works well enough to recreate it with a mildly different structuring. For example, I don't fully understand why there are lookup tables returning three rows at a time rather than, say, just the result for the middle row. Understanding that might help me to figure out how to best implement the ideas I had in mind.

Sphenocorona wrote:Okay, good to know. I'm unfortunately still not sure how I'm going to implement the honestly fairly simple idea I had, since it will require rewriting the structure of the lookup table itself and the way the code is written makes it difficult for me to understand how it works well enough to recreate it with a mildly different structuring. For example, I don't fully understand why there are lookup tables returning three rows at a time rather than, say, just the result for the middle row. Understanding that might help me to figure out how to best implement the ideas I had in mind.

I may not be remembering properly. All I remember is that there are multiple cases where a 32-bit integer has to store w*3 bits, which fails for w>10.

A for awesome wrote:All I remember is that there are multiple cases where a 32-bit integer has to store w*3 bits, which fails for w>10.

This is correct. When zfind tries to find the next row in the spaceship sequence, it uses two tables: gInd and gRows. gInd takes as input three known rows from the current search state and outputs an index for the array gRows. gRows stores the rows which are viable extensions given the three rows input to gInd. The array gRows contains every row that can be achieved from evolving a stack of 3 rows while still staying within the specified width. For width n, this is 2^(3n)-2^(3n-3) rows, and when width=11 this is greater than 2^32. That is, when width>10, gRows has more than 2^32 entries, so the indices stored in gInd must be able to store values bigger than 32 bits.

If you have a machine with enough memory, you should be able to modify the program to work at width 11 by changing some of the malloc statements and declaring gInd and pInd as uint64_t* (and probably pRemain as well). Unfortunately, many of the malloc statements have the 32-bit assumption hard-coded. I think the following modifications for zfind 2.0 should be sufficient as long as you aren't using the dump state parameter (but you probably are if you're doing a width-11 search):

The reason this doesn't work with dumpstate is that when the state is written to/read from the file, it writes/reads the pInd and pRemain values as 32-bit instead of 64-bit. This shouldn't be hard to fix. You probably just need to change the following lines:

407, 408, 596, 597, 603, and 604.

You will need to create a new function that loads larger (probably unsigned long long) integers to replace loadUL() in lines 603 and 604. I don't intend to do all this right now (I'm extremely busy marathoning Samurai Jack), but I will fix these issues the next time I update zfind.

I'm curious about the way gInd and gRows are handled are utilized in particular, as some of the ideas I've got pertain to modifying them specifically. I had made a file with zfind-s source since I figured the lack of unnecessary code would help make it quicker and easier to implement changes to the core components.

It does this by using two lookup tables. The first table (gRows) actually gives the rows X that we are looking for (stored as unsigned 16-bit integers). The second table (gInd) gives indices into the first table (stored as unsigned 32-bit integers). The input for the second lookup table is the three rows A, B, and Y.

More precisely, let ABY be the bitwise concatenation of the integers representing rows A, B, and Y. Then gInd[ABY] gives the index in the array gRows of the first row X such that evolve(A,B,X)=Y. Now, any other row X' satisfying evolve(A,B,X')=Y has index gInd[ABY]+i in the array gRows, where gInd[ABY]+i < gInd[ABY+1]. That is, gRows[gInd[ABY]+i] gives a row X' such that evolve(A,B,X')=Y whenever gInd[ABY]+i < gInd[ABY+1] and i >= 0.

gInd and gRows are calculated inside the function makeTables(). Lines 145-152 (of zfind-s) are where the construction of gInd begins. The for loop runs through every combination of three rows, A, B, X and calculates Y:=evolve(A,B,X). It then increments gInd[ABY]. At the end of this loop, gInd[ABY] gives the number of rows X such that evolve(A,B,X)=Y.

The next for loop (line 154) simply replaces the original value of gInd[ABY] with the cumulative sum of the original gInd[n] values for all n <= ABY.

The last for loop (lines 157-164) constructs gRows and finishes the construction of gInd. It again loops through every combination of three rows, A, B, X and calculates Y:=evolve(A,B,X). The program then reduces gInd[ABY] by 1 and places the row X in the array gRows at index gInd[ABY] (that is, gRows[gInd[ABY]]:=X).

In the end, gInd[ABY] is the index in gRows of the first row X satisfying evolve(A,B,X)=Y.

muzik wrote:I cant go any higher than a width of 10 without a "Segmentation fault (core dumped)" error

There are multiple reasons why width 11 doesn't work. For now, zfind is restricted to width 10 or below. For this reason, zfind is not good for finding low-period ships. You should probably us gfind for periods below 5.