# The Cyclically Resolvable Steiner Triple Systems of Order 57
## 3 Construction
BlockOK(j,n,cl,len) checks if block \(j\) and the blocks from its orbit under \(G_{\
icefrac{{n}}{{len}}}\) are mutually disjoint among themselves and disjoint with the already chosen \(n-1\) blocks of class \(cl\). PutBlock(j,n,cl,len) (TakeBlock(j,n,cl,len)) adds to (removes from) class \(cl\) block \(j\) and the blocks from its orbit under \(G_{\
icefrac{{n}}{{len}}}\) and makes the corresponding changes in TakenBlock. PutBlock returns the number of all the constructed blocks of class \(cl\) and assigns it to the variable all. If not all the blocks are constructed, ChooseBlock is called to choose the \(all+1\)st block of the class. If \(all=19\) the class is ready and NewRes checks if this partial solution is not isomorphic to a previously constructed one. If the solution is new, all parallel classes from the class orbit of the last class are added to the solution by PutClassOrb, and ChooseBlock is called to start constructing the next parallel class, or if all parallel classes have been constructed WriteRes is called to write the resolution in a file. By the algorithm \(A_{2}\) it would take more than a month to complete the job on a PC. That is why we used the high-performance computer Avitohol of the Bulgarian Academy of Sciences (see the acknowledgment), where a parallel implementation of the program ran on 96 cores and completed the job in 12 h.  
Advantages and disadvantages of the two algorithms:  
* Both algorithms are based on exhaustive backtrack search and therefore their complexity is exponential. This is a serious disadvantage which makes backtrack search usable only for classification of combinatorial structures with relatively small parameters. Such an algorithm can be made applicable for definite parameters by the rejection of isomorphic partial solutions of some sizes, and by the implementation of suitable restrictions which are true for the considered objects and parameters. * For the rejection of isomorphic solutions a minimality test is used in both algorithms in the function NewRes. This test is applied to some of the partial solutions and rejects partial solutions for which there exists an automorphism of the considered STS(57) that maps the current partial solution to a lexicographically smaller one. The rejection of partial solutions cuts off big branches of the search tree and makes the computation feasible. * \(A_{2}\) is applied on all the \(2,353,310\) STS(57)s, while \(A_{1}\) considers only those 156,040 designs which remain after using Corollary 1 and is therefore much faster. * \(A_{2}\) tries to construct resolutions of all possible types and structure, not only with the structure from Theorem 1 which is considered by \(A_{1}\). This makes \(A_{1}\) faster too. * \(A_{2}\) also constructs parallel classes with more than one block which is fixed under \(G_{3}\). By Theorem 1 there are no such parallel classes in a point-cyclic resolution of an STS(57) and \(A_{1}\) does not construct them. This way \(A_{1}\) saves a lot of time, while \(A_{2}\) obtains a lot of partial solutions which are not extendable to point-cyclic resolutions. Although \(A_{1}\) is much faster, we implemented the more general algorithm \(A_{2}\) too as a partial check of the correctness of the obtained results, and in particular to check that no solutions were lost by possible errors in the theoretical restrictions, or in the C++ implementations of the algorithms. Each author has implemented in C++ one of the two algorithms. The same results were obtained.