Skip to content

Instantly share code, notes, and snippets.

@lordmatt
Created April 3, 2019 18:09
Show Gist options
  • Save lordmatt/4fe63f545a2421035ac75efc0fe22c0b to your computer and use it in GitHub Desktop.
Save lordmatt/4fe63f545a2421035ac75efc0fe22c0b to your computer and use it in GitHub Desktop.
<?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