Created
April 3, 2019 18:09
-
-
Save lordmatt/4fe63f545a2421035ac75efc0fe22c0b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* Problem | |
* ------- | |
* | |
* I needed a set of undefined size of card layouts on a 5x5 grid that were | |
* rotationally unique from each other. This data had to be as CSV lines in a | |
* file. | |
* | |
* Solution | |
* -------- | |
* | |
* Treat the two dimentions of an array as cartesian coordinates and transform | |
* the vectors to create four rotations for each additional candidate which | |
* can then be used as a string comparison against the list of accepted | |
* candidates. | |
* | |
* planning | |
* -------- | |
* | |
* 5x5 grid must have n1 to n2 filled spaces | |
* If rotated in all four positions it must be unique | |
* If it is add it to collection. | |
* Repeat until LIMIT tries fail | |
* | |
* | |
00000 | |
00000 | |
00000 | |
00000 | |
00000 | |
x2,y3 | |
00000 | |
00@00 | |
0@0@0 | |
00@00 | |
00000 | |
c=size+1 | |
x2,y3 | |
ix=c-x=4,-> ix4,y3 | |
x3,y2 (swap) | |
i: x3,y4 | |
*/ | |
// fixed information | |
define('_GRID_SIZE_',5); | |
define('_FILE_PATH_','/path/to/grid.csv'); | |
// stuff that I wanted to tweak | |
$limit = 35; // how many fails before we give up? | |
$maxSize=120; // how many to find? | |
$n = 4; // size of fills (how many filled in squares)? | |
$low_n = 2; // if we cannot find any more, what size may we drop down to? | |
mt_srand(); | |
/** | |
* Creates an array with a random grid vector | |
* @return array | |
*/ | |
function rand_xy(){ | |
return array(mt_rand(0,(_GRID_SIZE_-1)),mt_rand(0,(_GRID_SIZE_-1))); | |
} | |
/** | |
* Check for rotational uniqueness. | |
* @param array $test | |
* @param array $collection | |
* @return boolean | |
*/ | |
function is_new($test,$collection){ | |
$stringSet = array(); | |
foreach($collection as $one){ | |
$stringSet[] = grid_as_string($one); | |
} | |
$testString = grid_as_string($test); # no rotation | |
$r1 = array(); | |
$r2 = array(); | |
$r3 = array(); | |
foreach($test as $x=>$row){ | |
foreach($row as $y=>$bool){ | |
if($bool){ | |
$r1[_GRID_SIZE_-$x][$y]=TRUE; # 2nd rotation :: $invX = _GRID_SIZE_-$x; // we're already plus one!! | |
$r2[$y][$x]=TRUE; # 1st rotation :: swap X,Y | |
$r3[$y][_GRID_SIZE_-$x]=TRUE; # 3rd and final :: swap invX,Y | |
} | |
} | |
} | |
$testStringR1 = grid_as_string($r1); | |
$testStringR2 = grid_as_string($r2); | |
$testStringR3 = grid_as_string($r2); | |
if( in_array($testString, $stringSet) || | |
in_array($testStringR1, $stringSet) || | |
in_array($testStringR2, $stringSet) || | |
in_array($testStringR3, $stringSet) | |
){ return FALSE; } | |
# it must be good | |
return TRUE; | |
} | |
function size_of_collection($collection){ | |
return count($collection); // this was probably a bit pointless | |
} | |
function grid_as_string($ar,$join='',$FF='0',$TT='1'){ | |
$str=''; | |
$first=TRUE; | |
for ($i = 0; $i < (_GRID_SIZE_*_GRID_SIZE_); $i++) { | |
if(!$first){ | |
$str .= $join; | |
} | |
$str .= $FF; | |
$first=FALSE; | |
} | |
#print_r($ar); | |
foreach($ar as $x=>$row){ | |
foreach($row as $y=>$bool){ | |
#if($bool){ | |
$pos = ($x+(_GRID_SIZE_*$y))*strlen($FF); | |
$pos = $pos*(strlen($join))+$pos; | |
$str[$pos]=$TT; | |
#} | |
} | |
} | |
return $str; | |
} | |
/** | |
* Hard and slow | |
* @param array $ar | |
*/ | |
function fill_count($ar){ | |
$c=0; | |
foreach($ar as $x=>$row){ | |
foreach($row as $y=>$bool){ | |
$c++; | |
} | |
} | |
return $c; | |
} | |
function fill_with(&$ar,$n){ | |
$i=0; | |
while( (fill_count($ar)<$n) && $i<12 ){ | |
$get = rand_xy(); | |
$ar[$get[0]][$get[1]]=TRUE; | |
} | |
} | |
$collection = array(); | |
$i=0; | |
while($i<$limit){ | |
$test = array(); | |
fill_with($test, $n); | |
if(is_new($test, $collection)){ | |
$collection[]=$test;// add to collection | |
$i=0; | |
}else{ | |
++$i; | |
} | |
if(size_of_collection($collection)>=$maxSize){ | |
$i=$limit; | |
break; | |
} | |
if($i>($limit-3)){ | |
if($n>$low_n){ | |
--$n; | |
$i=0; | |
} | |
} | |
} | |
$stringSet = array(); | |
foreach($collection as $one){ | |
$stringSet[] = grid_as_string($one,',','N','Y'); | |
} | |
$str = implode("\n", $stringSet); | |
file_put_contents(_FILE_PATH_, $str); | |
#echo "<pre>"; | |
#print_r($collection); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment