aboutsummaryrefslogtreecommitdiff
path: root/cube.c
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-04-12 18:49:14 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-04-12 18:49:14 +0200
commit1cf6502c9f3d8994e5c97f90cc29392043e40f2b (patch)
tree5a0b7da5f701094c1e809ed2a3b11b5c2c29379d /cube.c
parent6e9ca0165e27bb863b25ff2d72844731f38efca7 (diff)
downloadnissy-core-1cf6502c9f3d8994e5c97f90cc29392043e40f2b.tar.gz
nissy-core-1cf6502c9f3d8994e5c97f90cc29392043e40f2b.zip
Added edge pruning table, to be tested
Diffstat (limited to '')
-rw-r--r--cube.c181
1 files changed, 169 insertions, 12 deletions
diff --git a/cube.c b/cube.c
index 1974671..e77bf9e 100644
--- a/cube.c
+++ b/cube.c
@@ -38,6 +38,8 @@ Section: mathematical constants
38#define _12c4 495U 38#define _12c4 495U
39#define _8c4 70U 39#define _8c4 70U
40 40
41#define COCSEP_CLASSES 3393U
42
41_static int64_t binomial[12][12] = { 43_static int64_t binomial[12][12] = {
42 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 44 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
43 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 45 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
@@ -1183,6 +1185,8 @@ _static void writetrans(uint8_t, char *);
1183_static cube_fast_t move(cube_fast_t, uint8_t); 1185_static cube_fast_t move(cube_fast_t, uint8_t);
1184_static cube_fast_t transform(cube_fast_t, uint8_t); 1186_static cube_fast_t transform(cube_fast_t, uint8_t);
1185 1187
1188_static_inline int64_t coord_fast_h48(cube_fast_t, uint32_t *, uint8_t);
1189
1186cube_t 1190cube_t
1187solvedcube(void) 1191solvedcube(void)
1188{ 1192{
@@ -1774,7 +1778,7 @@ move(cube_fast_t c, uint8_t m)
1774 case B3: 1778 case B3:
1775 return _move(B3, c); 1779 return _move(B3, c);
1776 default: 1780 default:
1777 DBG_LOG("mover error, unknown move\n"); 1781 DBG_LOG("move error, unknown move\n");
1778 return zero_fast; 1782 return zero_fast;
1779 } 1783 }
1780} 1784}
@@ -1885,6 +1889,31 @@ transform(cube_fast_t c, uint8_t t)
1885 } 1889 }
1886} 1890}
1887 1891
1892/* h is the number of eo bits used */
1893_static_inline int64_t
1894coord_fast_h48(cube_fast_t c, uint32_t *cocsepdata, uint8_t h)
1895{
1896 cube_fast_t d;
1897 int64_t cocsep, coclass, esep, eo, esize;
1898 uint32_t data;
1899 uint8_t ttrep;
1900
1901 DBG_ASSERT(h <= 11, -1,
1902 "coord_fast_h48: h must be between 0 and 11\n");
1903
1904 cocsep = coord_fast_cocsep(c);
1905 data = cocsepdata[cocsep];
1906 coclass = (data & (0xFFFFU << 16U)) >> 16U;
1907 ttrep = (data & (0xFFU << 8U)) >> 8U;
1908
1909 d = transform(c, ttrep); /* TODO: transform only edges */
1910 esep = coord_fast_esep(d);
1911 eo = coord_fast_eo(d);
1912
1913 esize = (_12c4 * _8c4) << h;
1914 return (coclass * esize) + (esep << h) + (eo >> (11-h));
1915}
1916
1888/****************************************************************************** 1917/******************************************************************************
1889Section: moves, move sequences and transformations 1918Section: moves, move sequences and transformations
1890 1919
@@ -1918,10 +1947,28 @@ moveaxis(uint8_t move)
1918Section: auxiliary procedures for H48 optimal solver (temporary) 1947Section: auxiliary procedures for H48 optimal solver (temporary)
1919******************************************************************************/ 1948******************************************************************************/
1920 1949
1950typedef struct {
1951 cube_fast_t cube;
1952 uint8_t nmoves;
1953 uint8_t depth;
1954 uint8_t h;
1955 uint8_t k;
1956 uint16_t *nclasses;
1957 uint32_t *cocsepdata;
1958 uint32_t *buf32;
1959 bool *visited;
1960} dfsarg_gendata_t;
1961
1921_static size_t gendata_cocsep(void *); 1962_static size_t gendata_cocsep(void *);
1922_static uint32_t dfs_cocsep( 1963_static uint32_t dfs_cocsep( /* TODO: use dfsarg */
1923 cube_fast_t, uint8_t, uint8_t, uint16_t *, uint32_t *, bool *); 1964 cube_fast_t, uint8_t, uint8_t, uint16_t *, uint32_t *, bool *);
1924 1965
1966_static size_t gendata_eoesep(uint8_t, uint8_t, void *, void *);
1967_static uint32_t dfs_eoesep(dfsarg_gendata_t *);
1968
1969_static_inline uint8_t get_h48_pval(uint32_t *, int64_t, uint8_t);
1970_static_inline void set_h48_pval(uint32_t *, int64_t, uint8_t, uint8_t);
1971
1925/* 1972/*
1926Each element of the cocsep table is a uint32_t used as follows: 1973Each element of the cocsep table is a uint32_t used as follows:
1927 - Lowest 8-bit block: pruning value 1974 - Lowest 8-bit block: pruning value
@@ -1937,35 +1984,41 @@ _static size_t
1937gendata_cocsep(void *buf) 1984gendata_cocsep(void *buf)
1938{ 1985{
1939 static size_t tablesize = _3p7 << 7U; 1986 static size_t tablesize = _3p7 << 7U;
1987 static size_t infosize = 12;
1940 1988
1941 cube_fast_t solved; 1989 cube_fast_t solved;
1942 uint32_t *buf32, cc; 1990 uint32_t *buf32, *info, cc;
1943 uint16_t n; 1991 uint16_t n;
1944 uint8_t i, j; 1992 uint8_t i, j;
1945 bool visited[tablesize]; 1993 bool visited[tablesize];
1946 1994
1947 buf32 = (uint32_t *)buf; 1995 buf32 = (uint32_t *)buf;
1996 info = buf32 + tablesize;
1948 memset(buf32, 0xFFU, 4*tablesize); 1997 memset(buf32, 0xFFU, 4*tablesize);
1949 memset(buf32 + tablesize, 0, 21*4); 1998 memset(info, 0, 4*infosize);
1950 1999
1951 solved = cubetofast(solvedcube()); 2000 solved = cubetofast(solvedcube());
1952 buf32[tablesize+1] = 9U; /* Known max pruning value */
1953 for (i = 0, n = 0, cc = 0; i < 10; i++) { 2001 for (i = 0, n = 0, cc = 0; i < 10; i++) {
1954 memset(visited, 0, tablesize); /* Set visited bit for dfs */ 2002 memset(visited, 0, tablesize * sizeof(bool));
1955 DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i); 2003 DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i);
1956 cc = dfs_cocsep(solved, 0, i, &n, buf32, visited); 2004 cc = dfs_cocsep(solved, 0, i, &n, buf32, visited);
1957 buf32[tablesize+i+2] = cc; 2005 info[i+2] = cc;
1958 DBG_LOG("found %" PRIu32 "\n", cc); 2006 DBG_LOG("found %" PRIu32 "\n", cc);
1959 } 2007 }
1960 buf32[tablesize] = (uint32_t)n; 2008 info[0] = (uint32_t)n;
2009 info[1] = 9U; /* Known max pruning value */
2010 DBG_ASSERT(n == COCSEP_CLASSES, 0,
2011 "cocsep: computed %" PRIu16 " symmetry classes, "
2012 "expected %" PRIu16 "\n", n, COCSEP_CLASSES);
1961 2013
1962 DBG_LOG("cocsep data computed, %" PRIu32 " symmetry classes\n", n); 2014 DBG_LOG("cocsep data computed\n");
1963 DBG_LOG("Maximum pruning value: %" PRIu32 "\n", buf32[tablesize+1]); 2015 DBG_LOG("Symmetry classes: %" PRIu32 "\n", info[0]);
2016 DBG_LOG("Maximum pruning value: %" PRIu32 "\n", info[1]);
1964 DBG_LOG("Pruning value distribution:\n"); 2017 DBG_LOG("Pruning value distribution:\n");
1965 for (j = 0; j < 10; j++) 2018 for (j = 0; j < 10; j++)
1966 DBG_LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, buf32[tablesize+j+2]); 2019 DBG_LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, info[j+2]);
1967 2020
1968 return 4*(tablesize + 12); 2021 return 4*(tablesize + infosize);
1969} 2022}
1970 2023
1971_static uint32_t 2024_static uint32_t
@@ -2014,6 +2067,110 @@ dfs_cocsep(
2014 return cc; 2067 return cc;
2015} 2068}
2016 2069
2070/*
2071TODO description
2072h is the number of eo bits
2073k is the compression size (4, 2 or 1 bit)
2074*/
2075_static size_t
2076gendata_eoesep(uint8_t h, uint8_t k, void *cocsepdata, void *buf)
2077{
2078 DBG_ASSERT(k == 4, 0, "eoesep: only k=4 is supported");
2079
2080 size_t tablesize = ((COCSEP_CLASSES * _12c4 * _8c4) / (8U / k)) << h;
2081 size_t infosize = 25; /* TODO unknown yet */
2082
2083 uint32_t *buf32, *info, cc;
2084 bool visited[tablesize]; /* TODO: change this, becomes too large */
2085 dfsarg_gendata_t arg;
2086
2087 buf32 = (uint32_t *)buf;
2088 info = buf32 + tablesize;
2089 memset(buf32, 0xFFU, 4*tablesize);
2090 memset(info, 0, 4*infosize);
2091
2092 arg.cube = cubetofast(solvedcube());
2093 arg.nmoves = 0;
2094 arg.cocsepdata = (uint32_t *)cocsepdata;
2095 arg.buf32 = buf32;
2096 arg.visited = visited;
2097 /* TODO loop until no more is done, not until 12! (or hardcode limits)*/
2098 for (arg.depth = 0, cc = 0; arg.depth < 12; arg.depth++) {
2099 memset(visited, 0, tablesize * sizeof(bool));
2100 DBG_LOG("gendata_eoesep: generating depth %" PRIu8 "\n",
2101 arg.depth);
2102 cc = dfs_eoesep(&arg);
2103 info[arg.depth+1] = cc;
2104 DBG_LOG("found %" PRIu32 "\n", cc);
2105 }
2106
2107 return cc;
2108}
2109
2110_static_inline uint8_t
2111get_h48_pval(uint32_t *buf32, int64_t index, uint8_t k)
2112{
2113 uint8_t mask, shift;
2114
2115 DBG_ASSERT(k == 1 || k == 2 || k == 4, 0,
2116 "h48 coordinate invalid k=%" PRIu8 "\n", k);
2117
2118 shift = (uint8_t)(k * index % (32 / k));
2119 mask = (1U << k) - 1U;
2120
2121 return (buf32[index] & (mask << shift)) >> shift;
2122}
2123
2124_static_inline void
2125set_h48_pval(uint32_t *buf32, int64_t index, uint8_t k, uint8_t val)
2126{
2127 uint8_t mask, shift;
2128
2129 DBG_ASSERT(k == 1 || k == 2 || k == 4, ,
2130 "h48 coordinate invalid k=%" PRIu8 "\n", k);
2131
2132 shift = (uint8_t)(k * index % (32 / k));
2133 mask = (1U << k) - 1U;
2134
2135 buf32[index] = (buf32[index] & (~mask)) | (val << shift);
2136}
2137
2138_static uint32_t
2139dfs_eoesep(dfsarg_gendata_t *arg)
2140{
2141 uint8_t m, olddepth;
2142 uint32_t cc;
2143 uint64_t i;
2144 dfsarg_gendata_t newarg;
2145
2146 i = coord_fast_h48(arg->cube, arg->cocsepdata, arg->h);
2147 olddepth = get_h48_pval(arg->buf32, i, arg->k);
2148 if (olddepth < arg->nmoves || arg->visited[i])
2149 return 0;
2150 arg->visited[i] = true;
2151
2152 if (arg->nmoves == arg->depth) {
2153 cc = olddepth == 0xFFU;
2154 set_h48_pval(arg->buf32, i, arg->k, arg->depth);
2155 return cc;
2156 }
2157
2158 cc = 0;
2159 newarg = *arg;
2160 newarg.nmoves = arg->nmoves + 1;
2161/*
2162 newarg.nmoves = arg->nmoves + 1;
2163 newarg.depth = arg->depth;
2164 newarg.h = arg->h;
2165 newarg.k = arg->k;
2166*/
2167 _foreach_move(m, arg->cube, newarg.cube,
2168 cc += dfs_eoesep(&newarg);
2169 )
2170
2171 return cc;
2172}
2173
2017/****************************************************************************** 2174/******************************************************************************
2018Section: solvers 2175Section: solvers
2019 2176

Generated with cgit - Back to sebastiano.tronto.net