<?php
function intdiv_1($a, $b){
return ($a - $a % $b) / $b;
}
function int_div($dividend, $divisor){
$res;
if (function_exists('intdiv'))
$res=intdiv($dividend, $divisor);
else // < php7
$res=intdiv_1($dividend, $divisor);
return $res;
}
class Sheet {
private $size; //1,2 or 4
private $sections=array()/* = array(4) {
"1"=>null,
"2"=>null,
"3"=>null,
"4"=>null
}*/;
public function __construct($dim, $arg) {
$this->size = $dim;
if (is_array($arg)==true && sizeof($arg)==$dim) {//building a sheet of 2 or 4
$i=1;
foreach($arg as $elem)
$this->sections[$i++]=$elem;
return;
}
else {
if (is_array($arg)==false && $dim==1) //buidling a sheet of 1
$this->sections[1]= $arg;
else
throw new Exception("Incompatible arguments");
}
}
public function __toString() {
$ret='-';
foreach($this->sections as $key=>$val)
$ret .= (string)$val;
return $ret.'-';
}
public function divide(){ //return first the left or upper section of the shhet
$ret1; //left or upper part of the sheet
$ret2; //right or lower part of the shet
switch($this->size) {
case 4: //vertical cut
$arr1=array($this->sections[1],$this->sections[3]);
$ret1=new Sheet(2,$arr1);
$arr2=array($this->sections[2],$this->sections[4]);
$ret2=new Sheet(2,$arr2);
break;
case 2: //horizontal cut
$ret1 = new Sheet(1,$this->sections[1]);
$ret2 = new Sheet(1,$this->sections[2]);
break;
default:
throw new Exception("Value must be 2 or 4");
}
$this->size /= 2;
return array($ret1,$ret2);
}
public function toArray(){
$ret=[];
foreach($this->sections as $val)
$ret[]=$val;
return $ret;
}
}
class SheetPile{
private $sheets=array();
private $sheetSize;
public function __construct($size){
$this->sheetSize=$size;
}
public function __toString() {
$ret='A stack of '.$this->sheetSize."-sized sheets:\n";
foreach($this->sheets as $val)
$ret .= (string)$val."\n";
return $ret;
}
public function add($sheet){ //sheets are stacked one below the other starting from the upper one
array_push($this->sheets, $sheet);
}
public function divide(){ //return first the left or upper section of the pile in form of SheetPiles
$pile1=new SheetPile($this->sheetSize/2);
$pile2=new SheetPile($this->sheetSize/2);
switch($this->sheetSize) {
case 2:case 4: //horizontal(2) or vertical(4) cut
foreach($this->sheets as $elem){
list($s1,$s2)= $elem->divide();
$pile1->add($s1); $pile2->add($s2);
}
break;
default:
throw new Exception("Value must be 2 or 4");
}
return array($pile1,$pile2);
}
public function stackUp(){ //left pile ($this) is placed over the right one, upper pile ($this) over the other
list($pile1,$pile2)=$this->divide();
$pile1->sheets = array_merge($pile1->sheets,$pile2->sheets);
return $pile1;
}
public function SingleSheetPile_To_Array(){
if ($this->sheetSize!=1)
throw new Exception("This function applies only to Pile of Sheets with size 1");
else {
$ret=[];
foreach($this->sheets as $elem)
$ret=array_merge($ret,$elem->toArray());
return $ret;
}
}
}
function A4toA6($num_pages) {
$n =1+int_div($num_pages-1, 4);
$arr;
$pp=1;
for($i=1;$i<=$n;$i++){
for($j=0;$j<4;$j++){
$val=$i+$j*$n;
$arr[$i][$j]=($val>$num_pages)?" ":$val; //arr[page][quarter(0-3 from left to right from top to bottom]
}
}
return $arr;
}
function verify_A4toA6($num_pages) {
$arr=A4toA6($num_pages);
$pile=new SheetPile(4);
foreach($arr as $val){ //for every page
$sheet4 = new Sheet(4,$val);
$pile->add($sheet4);
}
$pile=$pile->stackUp(); //from 4 to 2
$pile=$pile->stackUp(); //from 2 to 1
$pages=[];
for($i=1;$i<=$num_pages;$i++)
$pages[]=$i;
return $pages==$pile->SingleSheetPile_To_Array();
}
print_r(3==3);print_r(3==33);
print("SHEEEEEET\n");
$s1 = new Sheet(1,0);print($s1."\n");
$s2 = new Sheet(2,array(2,4));print($s2."\n");
list($a,$b)=$s2->divide();print("V:\n");print($a."\n");print($b);
$s4 = new Sheet(4,array(3,5,7,9));print("\n".$s4."\n");
print("sheetdiv\n");
list($a,$b)=$s4->divide();print("\nH:\n");print($a."\n");print($b);
print("PILEEEEEE\n");
$q1 = new Sheet(4,array(1,3,5,7));$q2 = new Sheet(4,array(2,4,6,8));
$p = new SheetPile(4); $p->add($q1);$p->add($q2);print($p);
$d1=new Sheet(2,array(2,4)); $d2 = new Sheet(2,array(7,8));
$pp = new SheetPile(2);$pp->add($d1);$pp->add($d2);print($pp);
$u1=new Sheet(1,4); $u2=new Sheet(1,1);
$ppp = new SheetPile(1);$ppp->add($u1);$ppp->add($u2);print($ppp);
print("pilediv\n");
print_r($p->stackUp()->stackUp()->SingleSheetPile_To_Array());
print_r(verify_A4toA6(8));