2023W-EFFPROG

Magic Hexagon.
Log | Files | Refs | README

commit 60c25832c0c7f378ed159d9bcf90ffc91075b3c0
parent efe64dea2c09f67442b71162184ee96a18370e0e
Author: Markus Hunner <26381538+markhun@users.noreply.github.com>
Date:   Sat, 30 Dec 2023 13:26:53 +0100

Globalize hexagon properties

Diffstat:
Mmagichex/src/magichex.c | 78++++++++++++++++++++++++++++++++++++++++++------------------------------------
1 file changed, 42 insertions(+), 36 deletions(-)

diff --git a/magichex/src/magichex.c b/magichex/src/magichex.c @@ -42,6 +42,12 @@ typedef struct hexagonEntry HexagonEntry; lowest value = dr - (H-1)/2 highest value = dr + (H-1)/2 */ +static long n; +static long number_hex_entries; +static long d; +static unsigned long r; +static unsigned long H; +static unsigned long M; unsigned long solutions = 0; /* counter of solutions */ unsigned long leafs = 0; /* counter of leaf nodes visited in the search tree */ @@ -104,12 +110,12 @@ CHANGE_IDENTIFIER lessthan(HexagonEntry *v1, HexagonEntry *v2) return (setlo(v2, v1->lo+1)); } -CHANGE_IDENTIFIER sum(HexagonEntry hexagon[], unsigned long nv, unsigned long stride, long sum, +CHANGE_IDENTIFIER sum(HexagonEntry hexagon[], unsigned long nv, unsigned long stride, HexagonEntry *hexagonStart, HexagonEntry *hexagonEnd) { unsigned long i; - long hi = sum; - long lo = sum; + long hi = M; + long lo = M; HexagonEntry *hexagonEntry_p; #if 0 printf("sum(hexagonStart+%ld, %lu, %lu, %ld, hexagonStart, hexagonStart+%ld) ",hexagon-hexagonStart,nv,stride,sum,hexagonEnd-hexagonStart); fflush(stdout); @@ -146,11 +152,8 @@ CHANGE_IDENTIFIER sum(HexagonEntry hexagon[], unsigned long nv, unsigned long st /* reduce the ranges of the variables as much as possible (with the constraints we use); returns 1 if all variables still have a non-empty range left, 0 if one has an empty range */ -bool solve(unsigned long n, long d, HexagonEntry hexagon[]) +bool solve(HexagonEntry hexagon[]) { - unsigned long r = 2*n-1; - unsigned long H = 3*n*n-3*n+1; - long M = d*H; long o = d*r - (H-1)/2; /* offset in occupation array */ unsigned long occupation[H]; /* if hexagon[i] has value x, occupation[x-o]==i, if no hexagon[*] has value x, occupation[x-o]==H */ @@ -159,12 +162,12 @@ bool solve(unsigned long n, long d, HexagonEntry hexagon[]) //printf("(re)start\n"); /* deal with the alldifferent constraint */ for (i=0; i<H; i++) - occupation[i] = r*r; + occupation[i] = number_hex_entries; restart: - for (i=0; i<r*r; i++) { + for (i=0; i<number_hex_entries; i++) { HexagonEntry *hexagonEntry = &hexagon[i]; if (hexagonEntry->lo == hexagonEntry->hi && occupation[hexagonEntry->lo-o] != i) { - if (occupation[hexagonEntry->lo-o] < r*r) + if (occupation[hexagonEntry->lo-o] < number_hex_entries) return false; /* another variable has the same value */ occupation[hexagonEntry->lo-o] = i; /* occupy hexagonEntry->lo */ //goto restart; @@ -172,14 +175,14 @@ bool solve(unsigned long n, long d, HexagonEntry hexagon[]) } bool k = false; /* now propagate the alldifferent results to the bounds */ - for (i=0; i<r*r; i++) { + for (i=0; i<number_hex_entries; i++) { HexagonEntry *hexagonEntry = &hexagon[i]; if (hexagonEntry->lo < hexagonEntry->hi) { - if (occupation[hexagonEntry->lo-o] < r*r) { + if (occupation[hexagonEntry->lo-o] < number_hex_entries) { hexagonEntry->lo++; k = true; } - if (occupation[hexagonEntry->hi-o] < r*r) { + if (occupation[hexagonEntry->hi-o] < number_hex_entries) { hexagonEntry->hi--; k = true; } @@ -207,25 +210,25 @@ bool solve(unsigned long n, long d, HexagonEntry hexagon[]) for (i=0; i<r; i++) { CHANGE_IDENTIFIER f; /* line */ - f = sum(hexagon+r*i+max(0,i+1-n), min(i+n,r+n-i-1), 1, M, hexagon, hexagon+r*r); + f = sum(hexagon+r*i+max(0,i+1-n), min(i+n,r+n-i-1), 1, hexagon, hexagon+number_hex_entries); if (f==NOSOLUTION) return false; if (f==CHANGED) goto restart; /* column (diagonal down-left in the hexagon) */ - f = sum(hexagon+i+max(0,i+1-n)*r, min(i+n,r+n-i-1), r, M, hexagon, hexagon+r*r); + f = sum(hexagon+i+max(0,i+1-n)*r, min(i+n,r+n-i-1), r, hexagon, hexagon+number_hex_entries); if (f==NOSOLUTION) return false; if (f==CHANGED) goto restart; /* diagonal (down-right) */ - f = sum(hexagon-n+1+i+max(0,n-i-1)*(r+1), min(i+n,r+n-i-1), r+1, M, hexagon, hexagon+r*r); + f = sum(hexagon-n+1+i+max(0,n-i-1)*(r+1), min(i+n,r+n-i-1), r+1, hexagon, hexagon+number_hex_entries); if (f==NOSOLUTION) return false; if (f==CHANGED) goto restart; } return true; // all done } -void printhexagon(unsigned long n, HexagonEntry hexagon[]) +void printhexagon(HexagonEntry hexagon[]) { unsigned long i,j; - unsigned r=2*n-1; + for (i=0; i<r; i++) { unsigned long l=0; unsigned long h=r; @@ -255,13 +258,13 @@ void printhexagon(unsigned long n, HexagonEntry hexagon[]) /* assign values to hexagon[index] and all later variables in hexagon such that the constraints hold */ -void labeling(unsigned long n, long d, HexagonEntry hexagon[], unsigned long index) +void labeling(HexagonEntry hexagon[], unsigned long index) { long i; - unsigned long r = 2*n-1; + HexagonEntry *hexagonEntry = &hexagon[index]; - if (index >= r*r) { - printhexagon(n,hexagon); + if (index >= number_hex_entries) { + printhexagon(hexagon); solutions++; leafs++; printf("leafs visited: %lu\n\n",leafs); @@ -269,11 +272,11 @@ void labeling(unsigned long n, long d, HexagonEntry hexagon[], unsigned long ind } if (hexagonEntry->id == PLACEHOLDER_ENTRY_ID) // call labeling again as we do not need to process placeholders - return labeling(n,d,hexagon,index+1); + return labeling(hexagon,index+1); for (i = hexagonEntry->lo; i <= hexagonEntry->hi; i++) { - HexagonEntry newHexagon[r*r]; + HexagonEntry newHexagon[number_hex_entries]; HexagonEntry* newHexagonEntry = &newHexagon[index]; - memmove(newHexagon,hexagon,r*r*sizeof(HexagonEntry)); + memmove(newHexagon,hexagon,number_hex_entries*sizeof(HexagonEntry)); newHexagonEntry->lo = i; newHexagonEntry->hi = i; #if 0 @@ -285,22 +288,21 @@ void labeling(unsigned long n, long d, HexagonEntry hexagon[], unsigned long ind } printf("\n"); #endif - if (solve(n,d,newHexagon)) - labeling(n,d,newHexagon,index+1); + if (solve(newHexagon)) + labeling(newHexagon,index+1); else leafs++; } } -HexagonEntry *makehexagon(unsigned long n, long d) +HexagonEntry *makehexagon() { unsigned long i,j; - unsigned long r = 2*n-1; - unsigned long H = 3*n*n-3*n+1; + - HexagonEntry *hexagon = calloc(r*r,sizeof(HexagonEntry)); + HexagonEntry *hexagon = calloc(number_hex_entries,sizeof(HexagonEntry)); unsigned long id = 0; - for (i=0; i<r*r; i++) { + for (i=0; i<number_hex_entries; i++) { hexagon[i].id = PLACEHOLDER_ENTRY_ID; hexagon[i].lo = 1; hexagon[i].hi = 0; @@ -328,8 +330,7 @@ int main(int argc, char *argv[]) { unsigned long i; unsigned long j=0; - unsigned long n; - long d; + if (argc < 3) { fprintf(stderr, "Usage: %s <order> <deviation> <value> ... <value>\n", argv[0]); exit(1); @@ -340,14 +341,19 @@ int main(int argc, char *argv[]) exit(1); } d = strtol(argv[2],NULL,10); - HexagonEntry *hexagon = makehexagon(n,d); + r = 2*n-1; + number_hex_entries = r*r; + H = 3*n*n-3*n+1; + M = d*H; + + HexagonEntry *hexagon = makehexagon(); for (i=3; i<argc; i++) { while (hexagon[j].id == PLACEHOLDER_ENTRY_ID) j++; // skip this entry as it is a placeholder hexagon[j].lo = hexagon[j].hi = strtol(argv[i],NULL,10); j++; } - labeling(n,d,hexagon,0); + labeling(hexagon,0); printf("%lu solution(s), %lu leafs visited\n",solutions, leafs); //(void)solve(n, d, hexagon); //printhexagon(n, hexagon);