├── Chapter01 └── 1.php ├── Chapter02 ├── 1.php └── 2.php ├── Chapter03 ├── 1.php ├── 2.php ├── 3.php └── 4.php ├── Chapter04 ├── 1.php ├── 10.php ├── 11.php ├── 2.php ├── 3.php ├── 4.php ├── 5.php ├── 6.php ├── 7.php ├── 8.php └── 9.php ├── Chapter05 ├── 1.php ├── 10.php ├── 2.php ├── 3.php ├── 4.php ├── 5.php ├── 6.php ├── 7.php ├── 8.php ├── 9.php └── example.sql ├── Chapter06 ├── 1.php ├── 2.php ├── 3.php ├── 4.php ├── 5.php └── 6.php ├── Chapter07 ├── 1.php ├── 10.php ├── 2.php ├── 3.php ├── 4.php ├── 5.php ├── 6.php ├── 7.php ├── 8.php └── 9.php ├── Chapter08 ├── 1.php ├── 10.php ├── 2.php ├── 3.php ├── 4.php ├── 5.php ├── 6.php ├── 7.php ├── 8.php └── 9.php ├── Chapter09 ├── 1.php ├── 2.php ├── 3.php ├── 4.php ├── 5.php ├── 6.php ├── 7.php └── 8.php ├── Chapter10 ├── 1.php ├── 2.php ├── 3.php └── 4.php ├── Chapter11 ├── 1.php ├── 10.php ├── 11.php ├── 2.php ├── 3.php ├── 4.php ├── 5.php ├── 6.php ├── 7.php ├── 8.php └── 9.php ├── Chapter12 ├── 1.php ├── 2.php └── 3.php ├── Chapter13 ├── 1.php ├── 2.php ├── 3.php ├── 4.php ├── 5.php ├── composer.json ├── composer.lock └── vendor │ ├── autoload.php │ ├── composer │ ├── ClassLoader.php │ ├── LICENSE │ ├── autoload_classmap.php │ ├── autoload_files.php │ ├── autoload_namespaces.php │ ├── autoload_psr4.php │ ├── autoload_real.php │ ├── autoload_static.php │ └── installed.json │ └── tarsana │ └── functional │ ├── build.php │ └── composer.json ├── LICENSE └── README.md /Chapter01/1.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function findABook(Array $bookList, string $bookName) { 11 | $found = FALSE; 12 | 13 | foreach($bookList as $index => $book) { 14 | if($book === $bookName) { 15 | $found = $index; 16 | break; 17 | } 18 | } 19 | return $found; 20 | } 21 | 22 | function placeAllBooks(Array $orderedBooks, Array &$bookList) { 23 | foreach ($orderedBooks as $book) { 24 | $bookFound = findABook($bookList, $book); 25 | if($bookFound !== FALSE) { 26 | array_splice($bookList, $bookFound, 1); 27 | } 28 | } 29 | } 30 | 31 | $bookList = ['PHP','MySQL','PGSQL','Oracle','Java']; 32 | $orderedBooks = ['MySQL','PGSQL','Java']; 33 | 34 | placeAllBooks($orderedBooks, $bookList); 35 | echo implode(",", $bookList); 36 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter02/1.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | 11 | $array = [1,2,3,4,5]; 12 | $mixedArray = []; 13 | $mixedArray[0] = 200; 14 | $mixedArray['name'] = "Mixed array"; 15 | $mixedArray[1] = 10.65; 16 | $mixedArray[2] = ['I', 'am', 'another', 'array']; 17 | 18 | 19 | $array = [10,20,30,40,50]; 20 | $array[] = 70; 21 | $array[] = 80; 22 | 23 | $arraySize = count($array); 24 | for($i = 0;$i<$arraySize;$i++) { 25 | echo "Position ".$i." holds the value ".$array[$i]."\n"; 26 | } 27 | 28 | $startMemory = memory_get_usage(); 29 | 30 | $array = []; 31 | $array[10] = 100; 32 | $array[21] = 200; 33 | $array[29] = 300; 34 | $array[500] = 1000; 35 | $array[1001] = 10000; 36 | $array[71] = 1971; 37 | 38 | foreach($array as $index => $value) { 39 | echo "Position ".$index." holds the value ".$value."\n"; 40 | } 41 | 42 | echo memory_get_usage() - $startMemory, " bytes\n"; 43 | 44 | 45 | $studentInfo = []; 46 | $studentInfo['Name'] = "Adiyan"; 47 | $studentInfo['Age'] = 11; 48 | $studentInfo['Class'] = 6; 49 | $studentInfo['RollNumber'] = 71; 50 | $studentInfo['Contact'] = "info@adiyan.com"; 51 | 52 | foreach($studentInfo as $key => $value) { 53 | echo $key.": ".$value."\n"; 54 | } 55 | 56 | 57 | $players = []; 58 | $players[] = ['Name' => "Ronaldo", "Age" => 31, "Country" => "Portugal", "Team" => "Real Madrid"]; 59 | $players[] = ['Name' => "Messi", "Age" => 27, "Country" => "Argentina", "Team" => "Barcelona"]; 60 | $players[] = ['Name' => "Neymar", "Age" => 24, "Country" => "Brazil", "Team" => "Barcelona"]; 61 | $players[] = ['Name' => "Rooney", "Age" => 30, "Country" => "England", "Team" => "Man United"]; 62 | 63 | foreach($players as $index => $playerInfo) { 64 | echo "Info of player # ".($index+1)."\n"; 65 | foreach($playerInfo as $key => $value) { 66 | echo $key.": ".$value."\n"; 67 | } 68 | echo "\n"; 69 | } 70 | 71 | $startTime = microtime(); 72 | $startMemory = memory_get_usage(); 73 | $array = []; // new SplFixedArray(10000); 74 | //$array = range(1, 100000); 75 | for($i = 0;$i<10000;$i++) 76 | $array[$i] = $i; 77 | echo memory_get_usage() - $startMemory, ' bytes'; 78 | echo "\n".microtime() - $startTime, ' nano second'; 79 | 80 | $graph = []; 81 | $nodes = ['A', 'B', 'C', 'D', 'E']; 82 | foreach ($nodes as $xNode) { 83 | foreach ($nodes as $yNode) { 84 | $graph[$xNode][$yNode] = 0; 85 | } 86 | } 87 | 88 | $graph["A"]["B"] = 1; 89 | $graph["B"]["A"] = 1; 90 | $graph["A"]["C"] = 1; 91 | $graph["C"]["A"] = 1; 92 | $graph["A"]["E"] = 1; 93 | $graph["E"]["A"] = 1; 94 | $graph["B"]["E"] = 1; 95 | $graph["E"]["B"] = 1; 96 | $graph["B"]["D"] = 1; 97 | $graph["D"]["B"] = 1; 98 | 99 | 100 | foreach ($nodes as $xNode) { 101 | foreach ($nodes as $yNode) { 102 | echo $graph[$xNode][$yNode] . "\t"; 103 | } 104 | echo "\n"; 105 | } 106 | -------------------------------------------------------------------------------- /Chapter02/2.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | */ 8 | 9 | 10 | $startMemory = memory_get_usage(); 11 | $array = new SplFixedArray(100); 12 | for ($i = 0; $i < 100; $i++) 13 | $array[$i] = new SplFixedArray(100); 14 | 15 | 16 | 17 | 18 | echo memory_get_usage() - $startMemory, ' bytes'; 19 | 20 | $startMemory = memory_get_usage(); 21 | $array = range(1,100000); 22 | $endMemory = memory_get_usage(); 23 | echo ($endMemory - $startMemory)." bytes"; 24 | 25 | 26 | $items = 100000; 27 | $startTime = microtime(); 28 | $startMemory = memory_get_usage(); 29 | $array = new SplFixedArray($items); 30 | for ($i = 0; $i < $items; $i++) { 31 | $array[$i] = $i; 32 | } 33 | echo array_filter($array); 34 | $endMemory = memory_get_usage(); 35 | $endTime = microtime(); 36 | $memoryConsumed = ($endMemory - $startMemory) / (1024 * 1024); 37 | $memoryConsumed = ceil($memoryConsumed); 38 | echo "memory = {$memoryConsumed} MB\n"; 39 | echo "time =".($endTime-$startTime)."\n"; 40 | 41 | $array =[1 => 10, 2 => 100, 3 => 1000, 4 => 10000]; 42 | $splArray = SplFixedArray::fromArray($array,false); 43 | unset($array); 44 | print_r($splArray); 45 | 46 | $keyArray = [1 => 10, 2 => 100, 3 => 1000, 4 => 10000]; 47 | $splArray = SplFixedArray::fromArray($keyArray, $keyArray); 48 | unset($array); 49 | print_r($splArray); 50 | 51 | 52 | $items = 5; 53 | $array = new SplFixedArray($items); 54 | for ($i = 0; $i < $items; $i++) { 55 | $array[$i] = $i * 10; 56 | } 57 | 58 | $newArray = $array->toArray(); 59 | print_r($newArray); 60 | 61 | 62 | $items = 5; 63 | $array = new SplFixedArray($items); 64 | for ($i = 0; $i < $items; $i++) { 65 | $array[$i] = $i * 10; 66 | } 67 | 68 | $array->setSize(10); 69 | $array[7] = 100; 70 | 71 | 72 | $array = []; 73 | $array['Germany'] = "Position 1"; 74 | $array['Argentina'] = "Position 2"; 75 | $array['Portugal'] = "Position 6"; 76 | $array['Fifa_World_Cup'] = "2018 Russia"; 77 | 78 | 79 | $ronaldo = [ 80 | "name" => "Ronaldo", 81 | "country" => "Portugal", 82 | "age" => 31, 83 | "currentTeam" => "Real Madrid" 84 | ]; 85 | 86 | $messi = [ 87 | "name" => "Messi", 88 | "country" => "Argentina", 89 | "age" => 27, 90 | "currentTeam" => "Barcelona" 91 | ]; 92 | 93 | $team = [ 94 | "player1" => $ronaldo, 95 | "player2" => $messi 96 | ]; 97 | 98 | 99 | 100 | Class Player { 101 | 102 | public $name; 103 | public $country; 104 | public $age; 105 | public $currentTeam; 106 | 107 | } 108 | 109 | $ronaldo = new Player; 110 | $ronaldo->name = "Ronaldo"; 111 | $ronaldo->country = "Portugal"; 112 | $ronaldo->age = 31; 113 | $ronaldo->currentTeam = "Real Madrid"; 114 | 115 | 116 | $odd = []; 117 | $odd[] = 1; 118 | $odd[] = 3; 119 | $odd[] = 5; 120 | $odd[] = 7; 121 | $odd[] = 9; 122 | 123 | $prime = []; 124 | $prime[] = 2; 125 | $prime[] = 3; 126 | $prime[] = 5; 127 | 128 | if (in_array(2, $prime)) { 129 | echo "2 is a prime"; 130 | } 131 | 132 | $union = array_merge($prime, $odd); 133 | $intersection = array_intersect($prime, $odd); 134 | $compliment = array_diff($prime, $odd); 135 | 136 | 137 | $odd = []; 138 | $odd[1] = true; 139 | $odd[3] = true; 140 | $odd[5] = true; 141 | $odd[7] = true; 142 | $odd[9] = true; 143 | 144 | $prime = []; 145 | $prime[2] = true; 146 | $prime[3] = true; 147 | $prime[5] = true; 148 | 149 | if (isset($prime[2])) { 150 | echo "2 is a prime"; 151 | } 152 | 153 | $union = $prime + $odd; 154 | $intersection = array_intersect_key($prime, $odd); 155 | $compliment = array_diff_key($prime, $odd); 156 | -------------------------------------------------------------------------------- /Chapter03/1.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class ListNode { 11 | 12 | public $data = NULL; 13 | public $next = NULL; 14 | 15 | public function __construct(string $data = NULL) { 16 | $this->data = $data; 17 | } 18 | 19 | } 20 | 21 | class LinkedList implements Iterator { 22 | 23 | private $_firstNode = NULL; 24 | private $_totalNode = 0; 25 | private $_currentNode = NULL; 26 | private $_currentPosition = 0; 27 | 28 | public function insert(string $data = NULL) { 29 | $newNode = new ListNode($data); 30 | if ($this->_firstNode === NULL) { 31 | $this->_firstNode = &$newNode; 32 | } else { 33 | $currentNode = $this->_firstNode; 34 | while ($currentNode->next !== NULL) { 35 | $currentNode = $currentNode->next; 36 | } 37 | $currentNode->next = $newNode; 38 | } 39 | $this->_totalNode++; 40 | return TRUE; 41 | } 42 | 43 | public function insertAtFirst(string $data = NULL) { 44 | $newNode = new ListNode($data); 45 | if ($this->_firstNode === NULL) { 46 | $this->_firstNode = &$newNode; 47 | } else { 48 | $currentFirstNode = $this->_firstNode; 49 | $this->_firstNode = &$newNode; 50 | $newNode->next = $currentFirstNode; 51 | } 52 | $this->_totalNode++; 53 | return TRUE; 54 | } 55 | 56 | public function search(string $data = NULL) { 57 | if ($this->_totalNode) { 58 | $currentNode = $this->_firstNode; 59 | while ($currentNode !== NULL) { 60 | if ($currentNode->data === $data) { 61 | return $currentNode; 62 | } 63 | $currentNode = $currentNode->next; 64 | } 65 | } 66 | return FALSE; 67 | } 68 | 69 | public function insertBefore(string $data = NULL, string $query = NULL) { 70 | $newNode = new ListNode($data); 71 | 72 | if ($this->_firstNode) { 73 | $previous = NULL; 74 | $currentNode = $this->_firstNode; 75 | while ($currentNode !== NULL) { 76 | if ($currentNode->data === $query) { 77 | $newNode->next = $currentNode; 78 | $previous->next = $newNode; 79 | $this->_totalNode++; 80 | break; 81 | } 82 | $previous = $currentNode; 83 | $currentNode = $currentNode->next; 84 | } 85 | } 86 | } 87 | 88 | public function insertAfter(string $data = NULL, string $query = NULL) { 89 | $newNode = new ListNode($data); 90 | 91 | if ($this->_firstNode) { 92 | $nextNode = NULL; 93 | $currentNode = $this->_firstNode; 94 | while ($currentNode !== NULL) { 95 | if ($currentNode->data === $query) { 96 | if ($nextNode !== NULL) { 97 | $newNode->next = $nextNode; 98 | } 99 | $currentNode->next = $newNode; 100 | $this->_totalNode++; 101 | break; 102 | } 103 | $currentNode = $currentNode->next; 104 | $nextNode = $currentNode->next; 105 | } 106 | } 107 | } 108 | 109 | public function deleteFirst() { 110 | if ($this->_firstNode !== NULL) { 111 | if ($this->_firstNode->next !== NULL) { 112 | $this->_firstNode = $this->_firstNode->next; 113 | } else { 114 | $this->_firstNode = NULL; 115 | } 116 | $this->_totalNode--; 117 | return TRUE; 118 | } 119 | return FALSE; 120 | } 121 | 122 | public function deleteLast() { 123 | if ($this->_firstNode !== NULL) { 124 | $currentNode = $this->_firstNode; 125 | if ($currentNode->next === NULL) { 126 | $this->_firstNode = NULL; 127 | } else { 128 | $previousNode = NULL; 129 | 130 | while ($currentNode->next !== NULL) { 131 | $previousNode = $currentNode; 132 | $currentNode = $currentNode->next; 133 | } 134 | 135 | $previousNode->next = NULL; 136 | $this->_totalNode--; 137 | return TRUE; 138 | } 139 | } 140 | return FALSE; 141 | } 142 | 143 | public function delete(string $query = NULL) { 144 | if ($this->_firstNode) { 145 | $previous = NULL; 146 | $currentNode = $this->_firstNode; 147 | while ($currentNode !== NULL) { 148 | if ($currentNode->data === $query) { 149 | if ($currentNode->next === NULL) { 150 | $previous->next = NULL; 151 | } else { 152 | $previous->next = $currentNode->next; 153 | } 154 | 155 | $this->_totalNode--; 156 | break; 157 | } 158 | $previous = $currentNode; 159 | $currentNode = $currentNode->next; 160 | } 161 | } 162 | } 163 | 164 | public function reverse() { 165 | if ($this->_firstNode !== NULL) { 166 | if ($this->_firstNode->next !== NULL) { 167 | $reversedList = NULL; 168 | $next = NULL; 169 | $currentNode = $this->_firstNode; 170 | while ($currentNode !== NULL) { 171 | $next = $currentNode->next; 172 | $currentNode->next = $reversedList; 173 | $reversedList = $currentNode; 174 | $currentNode = $next; 175 | } 176 | $this->_firstNode = $reversedList; 177 | } 178 | } 179 | } 180 | 181 | public function getNthNode(int $n = 0) { 182 | $count = 1; 183 | if ($this->_firstNode !== NULL && $n <= $this->_totalNode) { 184 | $currentNode = $this->_firstNode; 185 | while ($currentNode !== NULL) { 186 | if ($count === $n) { 187 | return $currentNode; 188 | } 189 | $count++; 190 | $currentNode = $currentNode->next; 191 | } 192 | } 193 | } 194 | 195 | public function display() { 196 | echo "Total book titles: " . $this->_totalNode . "\n"; 197 | $currentNode = $this->_firstNode; 198 | while ($currentNode !== NULL) { 199 | echo $currentNode->data . "\n"; 200 | $currentNode = $currentNode->next; 201 | } 202 | } 203 | 204 | public function getSize() { 205 | return $this->_totalNode; 206 | } 207 | 208 | public function current() { 209 | return $this->_currentNode->data; 210 | } 211 | 212 | public function next() { 213 | $this->_currentPosition++; 214 | $this->_currentNode = $this->_currentNode->next; 215 | } 216 | 217 | public function key() { 218 | return $this->_currentPosition; 219 | } 220 | 221 | public function rewind() { 222 | $this->_currentPosition = 0; 223 | $this->_currentNode = $this->_firstNode; 224 | } 225 | 226 | public function valid() { 227 | return $this->_currentNode !== NULL; 228 | } 229 | 230 | } 231 | 232 | $BookTitles = new LinkedList(); 233 | $BookTitles->insert("Introduction to Algorithm"); 234 | $BookTitles->insert("Introduction to PHP and Data structures"); 235 | $BookTitles->insert("Programming Intelligence"); 236 | $BookTitles->insertAtFirst("Mediawiki Administrative tutorial guide"); 237 | $BookTitles->insertBefore("Introduction to Calculus", "Programming Intelligence"); 238 | $BookTitles->insertAfter("Introduction to Calculus", "Programming Intelligence"); 239 | 240 | 241 | foreach ($BookTitles as $title) { 242 | echo $title . "\n"; 243 | } 244 | 245 | 246 | for ($BookTitles->rewind(); $BookTitles->valid(); $BookTitles->next()) { 247 | echo $BookTitles->current() . "\n"; 248 | } 249 | 250 | /* 251 | $BookTitles->display(); 252 | $BookTitles->deleteFirst(); 253 | $BookTitles->deleteLast(); 254 | $BookTitles->delete("Introduction to PHP and Data structures"); 255 | $BookTitles->reverse(); 256 | $BookTitles->display(); 257 | echo "2nd Item is: ".$BookTitles->getNthNode(2)->data; 258 | * 259 | */ -------------------------------------------------------------------------------- /Chapter03/2.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class ListNode { 11 | 12 | public $data = NULL; 13 | public $next = NULL; 14 | 15 | public function __construct(string $data = NULL) { 16 | $this->data = $data; 17 | } 18 | 19 | } 20 | 21 | class CircularLinkedList { 22 | 23 | private $_firstNode = NULL; 24 | private $_totalNode = 0; 25 | 26 | public function insertAtEnd(string $data = NULL) { 27 | $newNode = new ListNode($data); 28 | if ($this->_firstNode === NULL) { 29 | $this->_firstNode = &$newNode; 30 | } else { 31 | $currentNode = $this->_firstNode; 32 | while ($currentNode->next !== $this->_firstNode) { 33 | $currentNode = $currentNode->next; 34 | } 35 | $currentNode->next = $newNode; 36 | } 37 | $newNode->next = $this->_firstNode; 38 | $this->_totalNode++; 39 | return TRUE; 40 | } 41 | 42 | public function display() { 43 | echo "Total book titles: " . $this->_totalNode . "\n"; 44 | $currentNode = $this->_firstNode; 45 | while ($currentNode->next !== $this->_firstNode) { 46 | echo $currentNode->data . "\n"; 47 | $currentNode = $currentNode->next; 48 | } 49 | 50 | if ($currentNode) { 51 | echo $currentNode->data . "\n"; 52 | } 53 | } 54 | 55 | } 56 | 57 | $BookTitles = new CircularLinkedList(); 58 | $BookTitles->insertAtEnd("Introduction to Algorithm"); 59 | $BookTitles->insertAtEnd("Introduction to PHP and Data structures"); 60 | $BookTitles->insertAtEnd("Programming Intelligence"); 61 | $BookTitles->insertAtEnd("Mediawiki Administrative tutorial guide"); 62 | $BookTitles->display(); 63 | -------------------------------------------------------------------------------- /Chapter03/3.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class ListNode { 11 | 12 | public $data = NULL; 13 | public $next = NULL; 14 | public $prev = NULL; 15 | 16 | public function __construct(string $data = NULL) { 17 | $this->data = $data; 18 | } 19 | 20 | } 21 | 22 | class DoublyLinkedList { 23 | 24 | private $_firstNode = NULL; 25 | private $_lastNode = NULL; 26 | private $_totalNode = 0; 27 | 28 | public function insertAtFirst(string $data = NULL) { 29 | $newNode = new ListNode($data); 30 | if ($this->_firstNode === NULL) { 31 | $this->_firstNode = &$newNode; 32 | $this->_lastNode = $newNode; 33 | } else { 34 | $currentFirstNode = $this->_firstNode; 35 | $this->_firstNode = &$newNode; 36 | $newNode->next = $currentFirstNode; 37 | $currentFirstNode->prev = $newNode; 38 | } 39 | $this->_totalNode++; 40 | return TRUE; 41 | } 42 | 43 | public function insertAtLast(string $data = NULL) { 44 | $newNode = new ListNode($data); 45 | if ($this->_firstNode === NULL) { 46 | $this->_firstNode = &$newNode; 47 | $this->_lastNode = $newNode; 48 | } else { 49 | $currentNode = $this->_lastNode; 50 | $currentNode->next = $newNode; 51 | $newNode->prev = $currentNode; 52 | $this->_lastNode = $newNode; 53 | } 54 | $this->_totalNode++; 55 | return TRUE; 56 | } 57 | 58 | public function insertBefore(string $data = NULL, string $query = NULL) { 59 | $newNode = new ListNode($data); 60 | 61 | if ($this->_firstNode) { 62 | $previous = NULL; 63 | $currentNode = $this->_firstNode; 64 | while ($currentNode !== NULL) { 65 | if ($currentNode->data === $query) { 66 | $newNode->next = $currentNode; 67 | $currentNode->prev = $newNode; 68 | $previous->next = $newNode; 69 | $newNode->prev = $previous; 70 | $this->_totalNode++; 71 | break; 72 | } 73 | $previous = $currentNode; 74 | $currentNode = $currentNode->next; 75 | } 76 | } 77 | } 78 | 79 | public function insertAfter(string $data = NULL, string $query = NULL) { 80 | $newNode = new ListNode($data); 81 | 82 | if ($this->_firstNode) { 83 | $nextNode = NULL; 84 | $currentNode = $this->_firstNode; 85 | while ($currentNode !== NULL) { 86 | if ($currentNode->data === $query) { 87 | if ($nextNode !== NULL) { 88 | $newNode->next = $nextNode; 89 | } 90 | if ($currentNode === $this->_lastNode) { 91 | $this->_lastNode = $newNode; 92 | } 93 | $currentNode->next = $newNode; 94 | $nextNode->prev = $newNode; 95 | $newNode->prev = $currentNode; 96 | $this->_totalNode++; 97 | break; 98 | } 99 | $currentNode = $currentNode->next; 100 | $nextNode = $currentNode->next; 101 | } 102 | } 103 | } 104 | 105 | public function deleteFirst() { 106 | if ($this->_firstNode !== NULL) { 107 | if ($this->_firstNode->next !== NULL) { 108 | $this->_firstNode = $this->_firstNode->next; 109 | $this->_firstNode->prev = NULL; 110 | } else { 111 | $this->_firstNode = NULL; 112 | } 113 | $this->_totalNode--; 114 | return TRUE; 115 | } 116 | return FALSE; 117 | } 118 | 119 | public function deleteLast() { 120 | if ($this->_lastNode !== NULL) { 121 | 122 | $currentNode = $this->_lastNode; 123 | if ($currentNode->prev === NULL) { 124 | $this->_firstNode = NULL; 125 | $this->_lastNode = NULL; 126 | } else { 127 | $previousNode = $currentNode->prev; 128 | $this->_lastNode = $previousNode; 129 | $previousNode->next = NULL; 130 | $this->_totalNode--; 131 | return TRUE; 132 | } 133 | } 134 | return FALSE; 135 | } 136 | 137 | public function delete(string $query = NULL) { 138 | if ($this->_firstNode) { 139 | $previous = NULL; 140 | $currentNode = $this->_firstNode; 141 | while ($currentNode !== NULL) { 142 | if ($currentNode->data === $query) { 143 | if ($currentNode->next === NULL) { 144 | $previous->next = NULL; 145 | } else { 146 | $previous->next = $currentNode->next; 147 | $currentNode->next->prev = $previous; 148 | } 149 | 150 | $this->_totalNode--; 151 | break; 152 | } 153 | $previous = $currentNode; 154 | $currentNode = $currentNode->next; 155 | } 156 | } 157 | } 158 | 159 | public function displayForward() { 160 | echo "Total book titles: " . $this->_totalNode . "\n"; 161 | $currentNode = $this->_firstNode; 162 | while ($currentNode !== NULL) { 163 | echo $currentNode->data . "\n"; 164 | $currentNode = $currentNode->next; 165 | } 166 | } 167 | 168 | public function displayBackward() { 169 | echo "Total book titles: " . $this->_totalNode . "\n"; 170 | $currentNode = $this->_lastNode; 171 | while ($currentNode !== NULL) { 172 | echo $currentNode->data . "\n"; 173 | $currentNode = $currentNode->prev; 174 | } 175 | } 176 | 177 | public function getSize() { 178 | return $this->_totalNode; 179 | } 180 | 181 | } 182 | 183 | $BookTitles = new DoublyLinkedList(); 184 | $BookTitles->insertAtLast("Introduction to Algorithm"); 185 | $BookTitles->insertAtLast("Introduction to PHP and Data structures"); 186 | $BookTitles->insertAtLast("Programming Intelligence"); 187 | $BookTitles->insertAtFirst("Mediawiki Administrative tutorial guide"); 188 | $BookTitles->insertAfter("Introduction to Calculus", "Programming Intelligence"); 189 | $BookTitles->displayForward(); 190 | $BookTitles->displayBackward(); 191 | $BookTitles->deleteFirst(); 192 | $BookTitles->deleteLast(); 193 | $BookTitles->delete("Introduction to PHP and Data structures"); 194 | $BookTitles->displayForward(); 195 | $BookTitles->displayBackward(); 196 | //echo "2nd Item is: ".$BookTitles->getNthNode(2)->data; -------------------------------------------------------------------------------- /Chapter03/4.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | $BookTitles = new SplDoublyLinkedList(); 11 | 12 | $BookTitles->push("Introduction to Algorithm"); 13 | $BookTitles->push("Introduction to PHP and Data structures"); 14 | $BookTitles->push("Programming Intelligence"); 15 | $BookTitles->push("Mediawiki Administrative tutorial guide"); 16 | $BookTitles->add(1,"Introduction to Calculus"); 17 | $BookTitles->add(3,"Introduction to Graph Theory"); 18 | 19 | for($BookTitles->rewind();$BookTitles->valid();$BookTitles->next()){ 20 | echo $BookTitles->current()."\n"; 21 | } -------------------------------------------------------------------------------- /Chapter04/1.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | interface Stack { 11 | 12 | public function push(string $item); 13 | 14 | public function pop(); 15 | 16 | public function top(); 17 | 18 | public function isEmpty(); 19 | } 20 | 21 | class Books implements Stack { 22 | 23 | private $limit; 24 | private $stack; 25 | 26 | public function __construct(int $limit = 20) { 27 | $this->limit = $limit; 28 | $this->stack = []; 29 | } 30 | 31 | public function pop(): string { 32 | 33 | if ($this->isEmpty()) { 34 | throw new UnderflowException('Stack is empty'); 35 | } else { 36 | return array_pop($this->stack); 37 | } 38 | } 39 | 40 | public function push(string $newItem) { 41 | 42 | if (count($this->stack) < $this->limit) { 43 | array_push($this->stack, $newItem); 44 | } else { 45 | throw new OverflowException('Stack is full'); 46 | } 47 | } 48 | 49 | public function top(): string { 50 | return end($this->stack); 51 | } 52 | 53 | public function isEmpty(): bool { 54 | return empty($this->stack); 55 | } 56 | 57 | } 58 | 59 | 60 | try { 61 | $programmingBooks = new Books(10); 62 | $programmingBooks->push("Introduction to PHP7"); 63 | $programmingBooks->push("Mastering JavaScript"); 64 | $programmingBooks->push("MySQL Workbench tutorial"); 65 | echo $programmingBooks->pop()."\n"; 66 | echo $programmingBooks->top()."\n"; 67 | } catch (Exception $e) { 68 | echo $e->getMessage(); 69 | } -------------------------------------------------------------------------------- /Chapter04/10.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | interface Queue { 11 | 12 | public function enqueue(string $item); 13 | 14 | public function dequeue(); 15 | 16 | public function peek(); 17 | 18 | public function isEmpty(); 19 | } 20 | 21 | class CircularQueue implements Queue { 22 | 23 | private $queue; 24 | private $limit; 25 | private $front = 0; 26 | private $rear = 0; 27 | 28 | public function __construct(int $limit = 5) { 29 | $this->limit = $limit; 30 | $this->queue = []; 31 | } 32 | 33 | public function size() { 34 | if ($this->rear > $this->front) 35 | return $this->rear - $this->front; 36 | return $this->limit - $this->front + $this->rear; 37 | } 38 | 39 | public function isEmpty() { 40 | return $this->rear == $this->front; 41 | } 42 | 43 | public function isFull() { 44 | $diff = $this->rear - $this->front; 45 | if ($diff == -1 || $diff == ($this->limit - 1)) 46 | return true; 47 | return false; 48 | } 49 | 50 | public function enqueue(string $item) { 51 | if ($this->isFull()) { 52 | throw new OverflowException("Queue is Full."); 53 | } else { 54 | $this->queue[$this->rear] = $item; 55 | $this->rear = ($this->rear + 1) % $this->limit; 56 | } 57 | } 58 | 59 | public function dequeue() { 60 | $item = ""; 61 | if ($this->isEmpty()) { 62 | throw new UnderflowException("Queue is empty"); 63 | } else { 64 | $item = $this->queue[$this->front]; 65 | $this->queue[$this->front] = NULL; 66 | $this->front = ($this->front + 1) % $this->limit; 67 | } 68 | return $item; 69 | } 70 | 71 | public function peek() { 72 | return $this->queue[$this->front]; 73 | } 74 | 75 | } 76 | 77 | try { 78 | $cq = new CircularQueue; 79 | $cq->enqueue("One"); 80 | $cq->enqueue("Two"); 81 | $cq->enqueue("Three"); 82 | $cq->enqueue("Four"); 83 | $cq->dequeue(); 84 | $cq->enqueue("Five"); 85 | echo $cq->size(); 86 | } catch (Exception $e) { 87 | echo $e->getMessage(); 88 | } -------------------------------------------------------------------------------- /Chapter04/11.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | 11 | class ListNode { 12 | 13 | public $data = NULL; 14 | public $next = NULL; 15 | 16 | public function __construct(string $data = NULL) { 17 | $this->data = $data; 18 | } 19 | 20 | } 21 | 22 | class LinkedList implements Iterator { 23 | 24 | private $_firstNode = NULL; 25 | private $_totalNode = 0; 26 | private $_currentNode = NULL; 27 | private $_currentPosition = 0; 28 | 29 | public function insert(string $data = NULL) { 30 | $newNode = new ListNode($data); 31 | if ($this->_firstNode === NULL) { 32 | $this->_firstNode = &$newNode; 33 | } else { 34 | $currentNode = $this->_firstNode; 35 | while ($currentNode->next !== NULL) { 36 | $currentNode = $currentNode->next; 37 | } 38 | $currentNode->next = $newNode; 39 | } 40 | $this->_totalNode++; 41 | return TRUE; 42 | } 43 | 44 | public function insertAtFirst(string $data = NULL) { 45 | $newNode = new ListNode($data); 46 | if ($this->_firstNode === NULL) { 47 | $this->_firstNode = &$newNode; 48 | } else { 49 | $currentFirstNode = $this->_firstNode; 50 | $this->_firstNode = &$newNode; 51 | $newNode->next = $currentFirstNode; 52 | } 53 | $this->_totalNode++; 54 | return TRUE; 55 | } 56 | 57 | public function search(string $data = NULL) { 58 | if ($this->_totalNode) { 59 | $currentNode = $this->_firstNode; 60 | while ($currentNode !== NULL) { 61 | if ($currentNode->data === $data) { 62 | return $currentNode; 63 | } 64 | $currentNode = $currentNode->next; 65 | } 66 | } 67 | return FALSE; 68 | } 69 | 70 | public function insertBefore(string $data = NULL, string $query = NULL) { 71 | $newNode = new ListNode($data); 72 | 73 | if ($this->_firstNode) { 74 | $previous = NULL; 75 | $currentNode = $this->_firstNode; 76 | while ($currentNode !== NULL) { 77 | if ($currentNode->data === $query) { 78 | $newNode->next = $currentNode; 79 | $previous->next = $newNode; 80 | $this->_totalNode++; 81 | break; 82 | } 83 | $previous = $currentNode; 84 | $currentNode = $currentNode->next; 85 | } 86 | } 87 | } 88 | 89 | public function insertAfter(string $data = NULL, string $query = NULL) { 90 | $newNode = new ListNode($data); 91 | 92 | if ($this->_firstNode) { 93 | $nextNode = NULL; 94 | $currentNode = $this->_firstNode; 95 | while ($currentNode !== NULL) { 96 | if ($currentNode->data === $query) { 97 | if ($nextNode !== NULL) { 98 | $newNode->next = $nextNode; 99 | } 100 | $currentNode->next = $newNode; 101 | $this->_totalNode++; 102 | break; 103 | } 104 | $currentNode = $currentNode->next; 105 | $nextNode = $currentNode->next; 106 | } 107 | } 108 | } 109 | 110 | public function deleteFirst() { 111 | if ($this->_firstNode !== NULL) { 112 | if ($this->_firstNode->next !== NULL) { 113 | $this->_firstNode = $this->_firstNode->next; 114 | } else { 115 | $this->_firstNode = NULL; 116 | } 117 | $this->_totalNode--; 118 | return TRUE; 119 | } 120 | return FALSE; 121 | } 122 | 123 | public function deleteLast() { 124 | if ($this->_firstNode !== NULL) { 125 | $currentNode = $this->_firstNode; 126 | if ($currentNode->next === NULL) { 127 | $this->_firstNode = NULL; 128 | } else { 129 | $previousNode = NULL; 130 | 131 | while ($currentNode->next !== NULL) { 132 | $previousNode = $currentNode; 133 | $currentNode = $currentNode->next; 134 | } 135 | 136 | $previousNode->next = NULL; 137 | $this->_totalNode--; 138 | return TRUE; 139 | } 140 | } 141 | return FALSE; 142 | } 143 | 144 | public function delete(string $query = NULL) { 145 | if ($this->_firstNode) { 146 | $previous = NULL; 147 | $currentNode = $this->_firstNode; 148 | while ($currentNode !== NULL) { 149 | if ($currentNode->data === $query) { 150 | if ($currentNode->next === NULL) { 151 | $previous->next = NULL; 152 | } else { 153 | $previous->next = $currentNode->next; 154 | } 155 | 156 | $this->_totalNode--; 157 | break; 158 | } 159 | $previous = $currentNode; 160 | $currentNode = $currentNode->next; 161 | } 162 | } 163 | } 164 | 165 | public function reverse() { 166 | if ($this->_firstNode !== NULL) { 167 | if ($this->_firstNode->next !== NULL) { 168 | $reversedList = NULL; 169 | $next = NULL; 170 | $currentNode = $this->_firstNode; 171 | while ($currentNode !== NULL) { 172 | $next = $currentNode->next; 173 | $currentNode->next = $reversedList; 174 | $reversedList = $currentNode; 175 | $currentNode = $next; 176 | } 177 | $this->_firstNode = $reversedList; 178 | } 179 | } 180 | } 181 | 182 | public function getNthNode(int $n = 0) { 183 | $count = 1; 184 | if ($this->_firstNode !== NULL && $n <= $this->_totalNode) { 185 | $currentNode = $this->_firstNode; 186 | while ($currentNode !== NULL) { 187 | if ($count === $n) { 188 | return $currentNode; 189 | } 190 | $count++; 191 | $currentNode = $currentNode->next; 192 | } 193 | } 194 | } 195 | 196 | public function display() { 197 | echo "Total book titles: " . $this->_totalNode . "\n"; 198 | $currentNode = $this->_firstNode; 199 | while ($currentNode !== NULL) { 200 | echo $currentNode->data . "\n"; 201 | $currentNode = $currentNode->next; 202 | } 203 | } 204 | 205 | public function getSize() { 206 | return $this->_totalNode; 207 | } 208 | 209 | public function current() { 210 | return $this->_currentNode->data; 211 | } 212 | 213 | public function next() { 214 | $this->_currentPosition++; 215 | $this->_currentNode = $this->_currentNode->next; 216 | } 217 | 218 | public function key() { 219 | return $this->_currentPosition; 220 | } 221 | 222 | public function rewind() { 223 | $this->_currentPosition = 0; 224 | $this->_currentNode = $this->_firstNode; 225 | } 226 | 227 | public function valid() { 228 | return $this->_currentNode !== NULL; 229 | } 230 | 231 | } 232 | 233 | 234 | class DeQueue { 235 | 236 | private $limit; 237 | private $queue; 238 | 239 | public function __construct(int $limit = 20) { 240 | $this->limit = $limit; 241 | $this->queue = new LinkedList(); 242 | } 243 | 244 | public function dequeueFromFront(): string { 245 | 246 | if ($this->isEmpty()) { 247 | throw new UnderflowException('Queue is empty'); 248 | } else { 249 | $lastItem = $this->peekFront(); 250 | $this->queue->deleteFirst(); 251 | return $lastItem; 252 | } 253 | } 254 | 255 | public function dequeueFromBack(): string { 256 | 257 | if ($this->isEmpty()) { 258 | throw new UnderflowException('Queue is empty'); 259 | } else { 260 | $lastItem = $this->peekBack(); 261 | $this->queue->deleteLast(); 262 | return $lastItem; 263 | } 264 | } 265 | 266 | public function enqueueAtBack(string $newItem) { 267 | 268 | if ($this->queue->getSize() < $this->limit) { 269 | $this->queue->insert($newItem); 270 | } else { 271 | throw new OverflowException('Queue is full'); 272 | } 273 | } 274 | 275 | public function enqueueAtFront(string $newItem) { 276 | 277 | if ($this->queue->getSize() < $this->limit) { 278 | $this->queue->insertAtFirst($newItem); 279 | } else { 280 | throw new OverflowException('Queue is full'); 281 | } 282 | } 283 | 284 | public function peekFront(): string { 285 | return $this->queue->getNthNode(1)->data; 286 | } 287 | 288 | public function peekBack(): string { 289 | return $this->queue->getNthNode($this->queue->getSize())->data; 290 | } 291 | 292 | public function isEmpty(): bool { 293 | return $this->queue->getSize() == 0; 294 | } 295 | 296 | } 297 | 298 | try { 299 | $agents = new DeQueue(10); 300 | $agents->enqueueAtFront("Fred"); 301 | $agents->enqueueAtFront("John"); 302 | $agents->enqueueAtBack("Keith"); 303 | $agents->enqueueAtBack("Adiyan"); 304 | $agents->enqueueAtFront("Mikhael"); 305 | echo $agents->dequeueFromBack() . "\n"; 306 | echo $agents->dequeueFromFront() . "\n"; 307 | echo $agents->peekFront() . "\n"; 308 | } catch (Exception $e) { 309 | echo $e->getMessage(); 310 | } -------------------------------------------------------------------------------- /Chapter04/2.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class ListNode { 11 | 12 | public $data = NULL; 13 | public $next = NULL; 14 | 15 | public function __construct(string $data = NULL) { 16 | $this->data = $data; 17 | } 18 | 19 | } 20 | 21 | class LinkedList implements Iterator { 22 | 23 | private $_firstNode = NULL; 24 | private $_totalNode = 0; 25 | private $_currentNode = NULL; 26 | private $_currentPosition = 0; 27 | 28 | public function insert(string $data = NULL) { 29 | $newNode = new ListNode($data); 30 | if ($this->_firstNode === NULL) { 31 | $this->_firstNode = &$newNode; 32 | } else { 33 | $currentNode = $this->_firstNode; 34 | while ($currentNode->next !== NULL) { 35 | $currentNode = $currentNode->next; 36 | } 37 | $currentNode->next = $newNode; 38 | } 39 | $this->_totalNode++; 40 | return TRUE; 41 | } 42 | 43 | public function insertAtFirst(string $data = NULL) { 44 | $newNode = new ListNode($data); 45 | if ($this->_firstNode === NULL) { 46 | $this->_firstNode = &$newNode; 47 | } else { 48 | $currentFirstNode = $this->_firstNode; 49 | $this->_firstNode = &$newNode; 50 | $newNode->next = $currentFirstNode; 51 | } 52 | $this->_totalNode++; 53 | return TRUE; 54 | } 55 | 56 | public function search(string $data = NULL) { 57 | if ($this->_totalNode) { 58 | $currentNode = $this->_firstNode; 59 | while ($currentNode !== NULL) { 60 | if ($currentNode->data === $data) { 61 | return $currentNode; 62 | } 63 | $currentNode = $currentNode->next; 64 | } 65 | } 66 | return FALSE; 67 | } 68 | 69 | public function insertBefore(string $data = NULL, string $query = NULL) { 70 | $newNode = new ListNode($data); 71 | 72 | if ($this->_firstNode) { 73 | $previous = NULL; 74 | $currentNode = $this->_firstNode; 75 | while ($currentNode !== NULL) { 76 | if ($currentNode->data === $query) { 77 | $newNode->next = $currentNode; 78 | $previous->next = $newNode; 79 | $this->_totalNode++; 80 | break; 81 | } 82 | $previous = $currentNode; 83 | $currentNode = $currentNode->next; 84 | } 85 | } 86 | } 87 | 88 | public function insertAfter(string $data = NULL, string $query = NULL) { 89 | $newNode = new ListNode($data); 90 | 91 | if ($this->_firstNode) { 92 | $nextNode = NULL; 93 | $currentNode = $this->_firstNode; 94 | while ($currentNode !== NULL) { 95 | if ($currentNode->data === $query) { 96 | if ($nextNode !== NULL) { 97 | $newNode->next = $nextNode; 98 | } 99 | $currentNode->next = $newNode; 100 | $this->_totalNode++; 101 | break; 102 | } 103 | $currentNode = $currentNode->next; 104 | $nextNode = $currentNode->next; 105 | } 106 | } 107 | } 108 | 109 | public function deleteFirst() { 110 | if ($this->_firstNode !== NULL) { 111 | if ($this->_firstNode->next !== NULL) { 112 | $this->_firstNode = $this->_firstNode->next; 113 | } else { 114 | $this->_firstNode = NULL; 115 | } 116 | $this->_totalNode--; 117 | return TRUE; 118 | } 119 | return FALSE; 120 | } 121 | 122 | public function deleteLast() { 123 | if ($this->_firstNode !== NULL) { 124 | $currentNode = $this->_firstNode; 125 | if ($currentNode->next === NULL) { 126 | $this->_firstNode = NULL; 127 | } else { 128 | $previousNode = NULL; 129 | 130 | while ($currentNode->next !== NULL) { 131 | $previousNode = $currentNode; 132 | $currentNode = $currentNode->next; 133 | } 134 | 135 | $previousNode->next = NULL; 136 | $this->_totalNode--; 137 | return TRUE; 138 | } 139 | } 140 | return FALSE; 141 | } 142 | 143 | public function delete(string $query = NULL) { 144 | if ($this->_firstNode) { 145 | $previous = NULL; 146 | $currentNode = $this->_firstNode; 147 | while ($currentNode !== NULL) { 148 | if ($currentNode->data === $query) { 149 | if ($currentNode->next === NULL) { 150 | $previous->next = NULL; 151 | } else { 152 | $previous->next = $currentNode->next; 153 | } 154 | 155 | $this->_totalNode--; 156 | break; 157 | } 158 | $previous = $currentNode; 159 | $currentNode = $currentNode->next; 160 | } 161 | } 162 | } 163 | 164 | public function reverse() { 165 | if ($this->_firstNode !== NULL) { 166 | if ($this->_firstNode->next !== NULL) { 167 | $reversedList = NULL; 168 | $next = NULL; 169 | $currentNode = $this->_firstNode; 170 | while ($currentNode !== NULL) { 171 | $next = $currentNode->next; 172 | $currentNode->next = $reversedList; 173 | $reversedList = $currentNode; 174 | $currentNode = $next; 175 | } 176 | $this->_firstNode = $reversedList; 177 | } 178 | } 179 | } 180 | 181 | public function getNthNode(int $n = 0) { 182 | $count = 1; 183 | if ($this->_firstNode !== NULL && $n <= $this->_totalNode) { 184 | $currentNode = $this->_firstNode; 185 | while ($currentNode !== NULL) { 186 | if ($count === $n) { 187 | return $currentNode; 188 | } 189 | $count++; 190 | $currentNode = $currentNode->next; 191 | } 192 | } 193 | } 194 | 195 | public function display() { 196 | echo "Total book titles: " . $this->_totalNode . "\n"; 197 | $currentNode = $this->_firstNode; 198 | while ($currentNode !== NULL) { 199 | echo $currentNode->data . "\n"; 200 | $currentNode = $currentNode->next; 201 | } 202 | } 203 | 204 | public function getSize() { 205 | return $this->_totalNode; 206 | } 207 | 208 | public function current() { 209 | return $this->_currentNode->data; 210 | } 211 | 212 | public function next() { 213 | $this->_currentPosition++; 214 | $this->_currentNode = $this->_currentNode->next; 215 | } 216 | 217 | public function key() { 218 | return $this->_currentPosition; 219 | } 220 | 221 | public function rewind() { 222 | $this->_currentPosition = 0; 223 | $this->_currentNode = $this->_firstNode; 224 | } 225 | 226 | public function valid() { 227 | return $this->_currentNode !== NULL; 228 | } 229 | 230 | } 231 | 232 | interface Stack { 233 | 234 | public function push(string $item); 235 | 236 | public function pop(); 237 | 238 | public function top(); 239 | 240 | public function isEmpty(); 241 | } 242 | 243 | class BookList implements Stack { 244 | 245 | private $stack; 246 | 247 | public function __construct() { 248 | $this->stack = new LinkedList(); 249 | } 250 | 251 | public function pop(): string { 252 | 253 | if ($this->isEmpty()) { 254 | throw new UnderflowException('Stack is empty'); 255 | } else { 256 | $lastItem = $this->top(); 257 | $this->stack->deleteLast(); 258 | return $lastItem; 259 | } 260 | } 261 | 262 | public function push(string $newItem) { 263 | 264 | $this->stack->insert($newItem); 265 | } 266 | 267 | public function top(): string { 268 | return $this->stack->getNthNode($this->stack->getSize())->data; 269 | } 270 | 271 | public function isEmpty(): bool { 272 | return $this->stack->getSize() == 0; 273 | } 274 | 275 | } 276 | 277 | 278 | try { 279 | $programmingBooks = new BookList(); 280 | $programmingBooks->push("Introduction to PHP7"); 281 | $programmingBooks->push("Mastering JavaScript"); 282 | $programmingBooks->push("MySQL Workbench tutorial"); 283 | echo $programmingBooks->pop()."\n"; 284 | echo $programmingBooks->pop()."\n"; 285 | echo $programmingBooks->top()."\n"; 286 | } catch (Exception $e) { 287 | echo $e->getMessage(); 288 | } -------------------------------------------------------------------------------- /Chapter04/3.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | */ 8 | 9 | $books = new SplStack(); 10 | $books->push("Introduction to PHP7"); 11 | $books->push("Mastering JavaScript"); 12 | $books->push("MySQL Workbench tutorial"); 13 | echo $books->pop() . "\n"; 14 | echo $books->top() . "\n"; 15 | -------------------------------------------------------------------------------- /Chapter04/4.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | */ 8 | 9 | function expressionChecker(string $expression): bool { 10 | $valid = TRUE; 11 | $stack = new SplStack(); 12 | 13 | for ($i = 0; $i < strlen($expression); $i++) { 14 | $char = substr($expression, $i, 1); 15 | 16 | switch ($char) { 17 | case '(': 18 | case '{': 19 | case '[': 20 | $stack->push($char); 21 | break; 22 | 23 | case ')': 24 | case '}': 25 | case ']': 26 | if ($stack->isEmpty()) { 27 | $valid = FALSE; 28 | } else { 29 | $last = $stack->pop(); 30 | if (($char == ")" && $last != "(") 31 | || ($char == "}" && $last != "{") 32 | || ($char == "]" && $last != "[")) { 33 | 34 | $valid = FALSE; 35 | } 36 | } 37 | break; 38 | } 39 | 40 | if (!$valid) 41 | break; 42 | } 43 | 44 | if (!$stack->isEmpty()) { 45 | $valid = FALSE; 46 | } 47 | 48 | return $valid; 49 | } 50 | 51 | $expressions = []; 52 | $expressions[] = "8 * (9 -2) + { (4 * 5) / ( 2 * 2) }"; 53 | $expressions[] = "5 * 8 * 9 / ( 3 * 2 ) )"; 54 | $expressions[] = "[{ (2 * 7) + ( 15 - 3) ]"; 55 | 56 | foreach ($expressions as $expression) { 57 | $valid = expressionChecker($expression); 58 | 59 | if ($valid) { 60 | echo "Expression is valid \n"; 61 | } else { 62 | echo "Expression is not valid \n"; 63 | } 64 | } -------------------------------------------------------------------------------- /Chapter04/5.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | interface Queue { 11 | 12 | public function enqueue(string $item); 13 | 14 | public function dequeue(); 15 | 16 | public function peek(); 17 | 18 | public function isEmpty(); 19 | } 20 | 21 | class AgentQueue implements Queue { 22 | 23 | private $limit; 24 | private $queue; 25 | 26 | public function __construct(int $limit = 20) { 27 | $this->limit = $limit; 28 | $this->queue = []; 29 | } 30 | 31 | public function dequeue(): string { 32 | 33 | if ($this->isEmpty()) { 34 | throw new UnderflowException('Queue is empty'); 35 | } else { 36 | return array_shift($this->queue); 37 | } 38 | } 39 | 40 | public function enqueue(string $newItem) { 41 | 42 | if (count($this->queue) < $this->limit) { 43 | array_push($this->queue, $newItem); 44 | } else { 45 | throw new OverflowException('Queue is full'); 46 | } 47 | } 48 | 49 | public function peek(): string { 50 | return current($this->queue); 51 | } 52 | 53 | public function isEmpty(): bool { 54 | return empty($this->queue); 55 | } 56 | 57 | } 58 | 59 | try { 60 | $agents = new AgentQueue(10); 61 | $agents->enqueue("Fred"); 62 | $agents->enqueue("John"); 63 | $agents->enqueue("Keith"); 64 | $agents->enqueue("Adiyan"); 65 | $agents->enqueue("Mikhael"); 66 | echo $agents->dequeue()."\n"; 67 | echo $agents->dequeue()."\n"; 68 | echo $agents->peek()."\n"; 69 | } catch (Exception $e) { 70 | echo $e->getMessage(); 71 | } -------------------------------------------------------------------------------- /Chapter04/6.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | 11 | class ListNode { 12 | 13 | public $data = NULL; 14 | public $next = NULL; 15 | 16 | public function __construct(string $data = NULL) { 17 | $this->data = $data; 18 | } 19 | 20 | } 21 | 22 | class LinkedList implements Iterator { 23 | 24 | private $_firstNode = NULL; 25 | private $_totalNode = 0; 26 | private $_currentNode = NULL; 27 | private $_currentPosition = 0; 28 | 29 | public function insert(string $data = NULL) { 30 | $newNode = new ListNode($data); 31 | if ($this->_firstNode === NULL) { 32 | $this->_firstNode = &$newNode; 33 | } else { 34 | $currentNode = $this->_firstNode; 35 | while ($currentNode->next !== NULL) { 36 | $currentNode = $currentNode->next; 37 | } 38 | $currentNode->next = $newNode; 39 | } 40 | $this->_totalNode++; 41 | return TRUE; 42 | } 43 | 44 | public function insertAtFirst(string $data = NULL) { 45 | $newNode = new ListNode($data); 46 | if ($this->_firstNode === NULL) { 47 | $this->_firstNode = &$newNode; 48 | } else { 49 | $currentFirstNode = $this->_firstNode; 50 | $this->_firstNode = &$newNode; 51 | $newNode->next = $currentFirstNode; 52 | } 53 | $this->_totalNode++; 54 | return TRUE; 55 | } 56 | 57 | public function search(string $data = NULL) { 58 | if ($this->_totalNode) { 59 | $currentNode = $this->_firstNode; 60 | while ($currentNode !== NULL) { 61 | if ($currentNode->data === $data) { 62 | return $currentNode; 63 | } 64 | $currentNode = $currentNode->next; 65 | } 66 | } 67 | return FALSE; 68 | } 69 | 70 | public function insertBefore(string $data = NULL, string $query = NULL) { 71 | $newNode = new ListNode($data); 72 | 73 | if ($this->_firstNode) { 74 | $previous = NULL; 75 | $currentNode = $this->_firstNode; 76 | while ($currentNode !== NULL) { 77 | if ($currentNode->data === $query) { 78 | $newNode->next = $currentNode; 79 | $previous->next = $newNode; 80 | $this->_totalNode++; 81 | break; 82 | } 83 | $previous = $currentNode; 84 | $currentNode = $currentNode->next; 85 | } 86 | } 87 | } 88 | 89 | public function insertAfter(string $data = NULL, string $query = NULL) { 90 | $newNode = new ListNode($data); 91 | 92 | if ($this->_firstNode) { 93 | $nextNode = NULL; 94 | $currentNode = $this->_firstNode; 95 | while ($currentNode !== NULL) { 96 | if ($currentNode->data === $query) { 97 | if ($nextNode !== NULL) { 98 | $newNode->next = $nextNode; 99 | } 100 | $currentNode->next = $newNode; 101 | $this->_totalNode++; 102 | break; 103 | } 104 | $currentNode = $currentNode->next; 105 | $nextNode = $currentNode->next; 106 | } 107 | } 108 | } 109 | 110 | public function deleteFirst() { 111 | if ($this->_firstNode !== NULL) { 112 | if ($this->_firstNode->next !== NULL) { 113 | $this->_firstNode = $this->_firstNode->next; 114 | } else { 115 | $this->_firstNode = NULL; 116 | } 117 | $this->_totalNode--; 118 | return TRUE; 119 | } 120 | return FALSE; 121 | } 122 | 123 | public function deleteLast() { 124 | if ($this->_firstNode !== NULL) { 125 | $currentNode = $this->_firstNode; 126 | if ($currentNode->next === NULL) { 127 | $this->_firstNode = NULL; 128 | } else { 129 | $previousNode = NULL; 130 | 131 | while ($currentNode->next !== NULL) { 132 | $previousNode = $currentNode; 133 | $currentNode = $currentNode->next; 134 | } 135 | 136 | $previousNode->next = NULL; 137 | $this->_totalNode--; 138 | return TRUE; 139 | } 140 | } 141 | return FALSE; 142 | } 143 | 144 | public function delete(string $query = NULL) { 145 | if ($this->_firstNode) { 146 | $previous = NULL; 147 | $currentNode = $this->_firstNode; 148 | while ($currentNode !== NULL) { 149 | if ($currentNode->data === $query) { 150 | if ($currentNode->next === NULL) { 151 | $previous->next = NULL; 152 | } else { 153 | $previous->next = $currentNode->next; 154 | } 155 | 156 | $this->_totalNode--; 157 | break; 158 | } 159 | $previous = $currentNode; 160 | $currentNode = $currentNode->next; 161 | } 162 | } 163 | } 164 | 165 | public function reverse() { 166 | if ($this->_firstNode !== NULL) { 167 | if ($this->_firstNode->next !== NULL) { 168 | $reversedList = NULL; 169 | $next = NULL; 170 | $currentNode = $this->_firstNode; 171 | while ($currentNode !== NULL) { 172 | $next = $currentNode->next; 173 | $currentNode->next = $reversedList; 174 | $reversedList = $currentNode; 175 | $currentNode = $next; 176 | } 177 | $this->_firstNode = $reversedList; 178 | } 179 | } 180 | } 181 | 182 | public function getNthNode(int $n = 0) { 183 | $count = 1; 184 | if ($this->_firstNode !== NULL && $n <= $this->_totalNode) { 185 | $currentNode = $this->_firstNode; 186 | while ($currentNode !== NULL) { 187 | if ($count === $n) { 188 | return $currentNode; 189 | } 190 | $count++; 191 | $currentNode = $currentNode->next; 192 | } 193 | } 194 | } 195 | 196 | public function display() { 197 | echo "Total book titles: " . $this->_totalNode . "\n"; 198 | $currentNode = $this->_firstNode; 199 | while ($currentNode !== NULL) { 200 | echo $currentNode->data . "\n"; 201 | $currentNode = $currentNode->next; 202 | } 203 | } 204 | 205 | public function getSize() { 206 | return $this->_totalNode; 207 | } 208 | 209 | public function current() { 210 | return $this->_currentNode->data; 211 | } 212 | 213 | public function next() { 214 | $this->_currentPosition++; 215 | $this->_currentNode = $this->_currentNode->next; 216 | } 217 | 218 | public function key() { 219 | return $this->_currentPosition; 220 | } 221 | 222 | public function rewind() { 223 | $this->_currentPosition = 0; 224 | $this->_currentNode = $this->_firstNode; 225 | } 226 | 227 | public function valid() { 228 | return $this->_currentNode !== NULL; 229 | } 230 | 231 | } 232 | 233 | 234 | interface Queue { 235 | 236 | public function enqueue(string $item); 237 | 238 | public function dequeue(); 239 | 240 | public function peek(); 241 | 242 | public function isEmpty(); 243 | } 244 | 245 | class AgentQueue implements Queue { 246 | 247 | private $limit; 248 | private $queue; 249 | 250 | public function __construct(int $limit = 20) { 251 | $this->limit = $limit; 252 | $this->queue = new LinkedList(); 253 | } 254 | 255 | public function dequeue(): string { 256 | 257 | if ($this->isEmpty()) { 258 | throw new UnderflowException('Queue is empty'); 259 | } else { 260 | $lastItem = $this->peek(); 261 | $this->queue->deleteFirst(); 262 | return $lastItem; 263 | } 264 | } 265 | 266 | public function enqueue(string $newItem) { 267 | 268 | if ($this->queue->getSize() < $this->limit) { 269 | $this->queue->insert($newItem); 270 | } else { 271 | throw new OverflowException('Queue is full'); 272 | } 273 | } 274 | 275 | public function peek(): string { 276 | return $this->queue->getNthNode(1)->data; 277 | } 278 | 279 | public function isEmpty(): bool { 280 | return $this->queue->getSize() == 0; 281 | } 282 | 283 | } 284 | 285 | try { 286 | $agents = new AgentQueue(10); 287 | $agents->enqueue("Fred"); 288 | $agents->enqueue("John"); 289 | $agents->enqueue("Keith"); 290 | $agents->enqueue("Adiyan"); 291 | $agents->enqueue("Mikhael"); 292 | echo $agents->dequeue()."\n"; 293 | echo $agents->dequeue()."\n"; 294 | echo $agents->peek()."\n"; 295 | } catch (Exception $e) { 296 | echo $e->getMessage(); 297 | } -------------------------------------------------------------------------------- /Chapter04/7.php: -------------------------------------------------------------------------------- 1 | enqueue("Fred"); 11 | $agents->enqueue("John"); 12 | $agents->enqueue("Keith"); 13 | $agents->enqueue("Adiyan"); 14 | $agents->enqueue("Mikhael"); 15 | echo $agents->dequeue()."\n"; 16 | echo $agents->dequeue()."\n"; 17 | echo $agents->bottom()."\n"; -------------------------------------------------------------------------------- /Chapter04/8.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | 11 | class ListNode { 12 | 13 | public $data = NULL; 14 | public $next = NULL; 15 | public $priority = NULL; 16 | 17 | public function __construct(string $data = NULL, int $priority = NULL) { 18 | $this->data = $data; 19 | $this->priority = $priority; 20 | } 21 | 22 | } 23 | 24 | class LinkedList implements Iterator { 25 | 26 | private $_firstNode = NULL; 27 | private $_totalNode = 0; 28 | private $_currentNode = NULL; 29 | private $_currentPosition = 0; 30 | 31 | public function insert(string $data = NULL, int $priority = NULL) { 32 | $newNode = new ListNode($data, $priority); 33 | $this->_totalNode++; 34 | 35 | if ($this->_firstNode === NULL) { 36 | $this->_firstNode = &$newNode; 37 | } else { 38 | $previous = $this->_firstNode; 39 | $currentNode = $this->_firstNode; 40 | while ($currentNode !== NULL) { 41 | if ($currentNode->priority < $priority) { 42 | 43 | if ($currentNode == $this->_firstNode) { 44 | $previous = $this->_firstNode; 45 | $this->_firstNode = $newNode; 46 | $newNode->next = $previous; 47 | return; 48 | } 49 | $newNode->next = $currentNode; 50 | $previous->next = $newNode; 51 | return; 52 | } 53 | $previous = $currentNode; 54 | $currentNode = $currentNode->next; 55 | } 56 | } 57 | 58 | return TRUE; 59 | } 60 | 61 | public function deleteFirst() { 62 | if ($this->_firstNode !== NULL) { 63 | if ($this->_firstNode->next !== NULL) { 64 | $this->_firstNode = $this->_firstNode->next; 65 | } else { 66 | $this->_firstNode = NULL; 67 | } 68 | $this->_totalNode--; 69 | return TRUE; 70 | } 71 | return FALSE; 72 | } 73 | 74 | 75 | 76 | 77 | public function getSize() { 78 | return $this->_totalNode; 79 | } 80 | 81 | public function current() { 82 | return $this->_currentNode->data; 83 | } 84 | 85 | public function next() { 86 | $this->_currentPosition++; 87 | $this->_currentNode = $this->_currentNode->next; 88 | } 89 | 90 | public function key() { 91 | return $this->_currentPosition; 92 | } 93 | 94 | public function rewind() { 95 | $this->_currentPosition = 0; 96 | $this->_currentNode = $this->_firstNode; 97 | } 98 | 99 | public function valid() { 100 | return $this->_currentNode !== NULL; 101 | } 102 | 103 | public function getNthNode(int $n = 0) { 104 | $count = 1; 105 | if ($this->_firstNode !== NULL && $n <= $this->_totalNode) { 106 | $currentNode = $this->_firstNode; 107 | while ($currentNode !== NULL) { 108 | if ($count === $n) { 109 | return $currentNode; 110 | } 111 | $count++; 112 | $currentNode = $currentNode->next; 113 | } 114 | } 115 | } 116 | 117 | public function display() { 118 | echo "Total book titles: " . $this->_totalNode . "\n"; 119 | $currentNode = $this->_firstNode; 120 | while ($currentNode !== NULL) { 121 | echo $currentNode->data . "\n"; 122 | $currentNode = $currentNode->next; 123 | } 124 | } 125 | } 126 | 127 | 128 | interface Queue { 129 | 130 | public function enqueue(string $item, int $p); 131 | 132 | public function dequeue(); 133 | 134 | public function peek(); 135 | 136 | public function isEmpty(); 137 | } 138 | 139 | class AgentQueue implements Queue { 140 | 141 | private $limit; 142 | private $queue; 143 | 144 | public function __construct(int $limit = 20) { 145 | $this->limit = $limit; 146 | $this->queue = new LinkedList(); 147 | } 148 | 149 | public function dequeue(): string { 150 | 151 | if ($this->isEmpty()) { 152 | throw new UnderflowException('Queue is empty'); 153 | } else { 154 | $lastItem = $this->peek(); 155 | $this->queue->deleteFirst(); 156 | return $lastItem; 157 | } 158 | } 159 | 160 | 161 | public function enqueue(string $newItem, int $priority) { 162 | 163 | if ($this->queue->getSize() < $this->limit) { 164 | $this->queue->insert($newItem, $priority); 165 | } else { 166 | throw new OverflowException('Queue is full'); 167 | } 168 | } 169 | 170 | public function peek(): string { 171 | return $this->queue->getNthNode(1)->data; 172 | } 173 | 174 | public function isEmpty(): bool { 175 | return $this->queue->getSize() == 0; 176 | } 177 | 178 | public function display() { 179 | $this->queue->display(); 180 | } 181 | 182 | } 183 | 184 | try { 185 | $agents = new AgentQueue(10); 186 | $agents->enqueue("Fred", 1); 187 | $agents->enqueue("John", 2); 188 | $agents->enqueue("Keith", 3); 189 | $agents->enqueue("Adiyan", 4); 190 | $agents->enqueue("Mikhael", 2); 191 | $agents->display(); 192 | echo $agents->dequeue()."\n"; 193 | echo $agents->dequeue()."\n"; 194 | } catch (Exception $e) { 195 | echo $e->getMessage(); 196 | } -------------------------------------------------------------------------------- /Chapter04/9.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class MyPQ extends SplPriorityQueue { 11 | 12 | public function compare($priority1, $priority2) { 13 | return $priority1 <=> $priority2; 14 | } 15 | 16 | } 17 | 18 | $agents = new MyPQ(); 19 | 20 | $agents->insert("Fred", 1); 21 | $agents->insert("John", 2); 22 | $agents->insert("Keith", 3); 23 | $agents->insert("Adiyan", 4); 24 | $agents->insert("Mikhael", 2); 25 | 26 | //mode of extraction 27 | $agents->setExtractFlags(MyPQ::EXTR_BOTH); 28 | 29 | //Go to TOP 30 | $agents->top(); 31 | 32 | while ($agents->valid()) { 33 | $current = $agents->current(); 34 | echo $current['data'] . "\n"; 35 | $agents->next(); 36 | } 37 | -------------------------------------------------------------------------------- /Chapter05/1.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function factorialx(int $n): int { 11 | if ($n == 1) 12 | return 1; 13 | 14 | return $n * factorial($n - 1); 15 | } 16 | 17 | function factorial(int $n): int { 18 | $result = 1; 19 | 20 | for ($i = $n; $i > 0; $i--) { 21 | $result *= $i; 22 | } 23 | 24 | return $result; 25 | } 26 | -------------------------------------------------------------------------------- /Chapter05/10.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function array_sum_recursive(Array $array) { 11 | $sum = 0; 12 | array_walk_recursive($array, function($v) use (&$sum) { 13 | $sum += $v; 14 | }); 15 | 16 | return $sum; 17 | } 18 | 19 | $arr = [1, 2, 3, 4, 5, [6, 7, [8, 9, 10, [11, 12, 13, [14, 15, 16]]]]]; 20 | 21 | echo array_sum_recursive($arr); 22 | -------------------------------------------------------------------------------- /Chapter05/2.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | */ 8 | 9 | function fibonacci(int $n): int { 10 | if($n == 0) { 11 | return 1; 12 | } else if($n == 1) { 13 | return 1; 14 | } else { 15 | return fibonacci($n-1) + fibonacci($n-2); 16 | } 17 | } 18 | 19 | 20 | echo fibonacci(20); -------------------------------------------------------------------------------- /Chapter05/3.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | 11 | function gcd(int $a, int $b): int { 12 | if ($b == 0) { 13 | return $a; 14 | } else { 15 | return gcd($b, $a % $b); 16 | } 17 | } 18 | 19 | echo gcd(259,111); -------------------------------------------------------------------------------- /Chapter05/4.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | $dsn = "mysql:host=127.0.0.1;port=3306;dbname=packt;charset=UTF8;"; 11 | $username = "root"; 12 | $password = ""; 13 | $dbh = new PDO($dsn, $username, $password); 14 | 15 | $result = $dbh->query("Select * from categories order by parentCategory asc, sortInd asc", PDO::FETCH_OBJ); 16 | 17 | $categories = []; 18 | 19 | foreach($result as $row) { 20 | $categories[$row->parentCategory][] = $row; 21 | } 22 | 23 | 24 | function showCategoryTree(Array $categories, int $n) { 25 | if(isset($categories[$n])) { 26 | 27 | foreach($categories[$n] as $category) { 28 | echo str_repeat("-", $n)."".$category->categoryName."\n"; 29 | showCategoryTree($categories, $category->id); 30 | } 31 | } 32 | return; 33 | } 34 | 35 | showCategoryTree($categories, 0); -------------------------------------------------------------------------------- /Chapter05/5.php: -------------------------------------------------------------------------------- 1 | 2 | 38 | 39 | 40 | 41 | 42 | 43 | 49 | * 50 | */ 51 | 52 | $dsn = "mysql:host=127.0.0.1;port=3306;dbname=packt;charset=UTF8;"; 53 | $username = "root"; 54 | $password = ""; 55 | $dbh = new PDO($dsn, $username, $password); 56 | 57 | 58 | $sql = "Select * from comments where postID = :postID order by parentID asc, datetime asc"; 59 | $stmt = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); 60 | $stmt->setFetchMode(PDO::FETCH_OBJ); 61 | $stmt->execute(array(':postID' => 1)); 62 | $result = $stmt->fetchAll(); 63 | 64 | $comments = []; 65 | 66 | foreach ($result as $row) { 67 | $comments[$row->parentID][] = $row; 68 | } 69 | 70 | function displayComment(Array $comments, int $n) { 71 | if (isset($comments[$n])) { 72 | $str = ""; 84 | 85 | return $str; 86 | } 87 | return ""; 88 | } 89 | 90 | echo displayComment($comments, 0); 91 | ?> 92 | 93 | -------------------------------------------------------------------------------- /Chapter05/6.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | */ 8 | 9 | function showFiles(string $dirName, Array &$allFiles = []) { 10 | $files = scandir($dirName); 11 | 12 | foreach ($files as $key => $value) { 13 | $path = realpath($dirName . DIRECTORY_SEPARATOR . $value); 14 | if (!is_dir($path)) { 15 | $allFiles[] = $path; 16 | } else if ($value != "." && $value != "..") { 17 | showFiles($path, $allFiles); 18 | $allFiles[] = $path; 19 | } 20 | } 21 | return; 22 | } 23 | 24 | $files = []; 25 | 26 | showFiles(".", $files); 27 | 28 | foreach($files as $file) { 29 | echo $file."\n"; 30 | } 31 | -------------------------------------------------------------------------------- /Chapter05/7.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function maxDepth() { 11 | static $i = 0; 12 | print ++$i . "\n"; 13 | return 1+maxDepth(); 14 | } 15 | 16 | maxDepth(); 17 | -------------------------------------------------------------------------------- /Chapter05/8.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | $path = realpath('.'); 11 | 12 | $files = new RecursiveIteratorIterator( 13 | new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST); 14 | foreach ($files as $name => $file) { 15 | echo "$name\n"; 16 | } 17 | -------------------------------------------------------------------------------- /Chapter05/9.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | $teams = array( 11 | 'Popular Football Teams', 12 | array( 13 | 'La Lega', 14 | array('Real Madrid', 'FC Barcelona', 'Athletico Madrid', 'Real Betis', 'Osasuna') 15 | ), 16 | array( 17 | 'English Premier League', 18 | array('Manchester United', 'Liverpool', 'Manchester City', 'Arsenal', 'Chelsea') 19 | ) 20 | ); 21 | 22 | 23 | $tree = new RecursiveTreeIterator( 24 | new RecursiveArrayIterator($teams), null, null, RecursiveIteratorIterator::LEAVES_ONLY 25 | ); 26 | 27 | foreach ($tree as $leaf) 28 | echo $leaf . PHP_EOL; -------------------------------------------------------------------------------- /Chapter05/example.sql: -------------------------------------------------------------------------------- 1 | /* 2 | * Example code for: PHP 7 Data Structures and Algorithms 3 | * 4 | * Author: Mizanur rahman 5 | * 6 | */ 7 | 8 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 9 | SET time_zone = "+00:00"; 10 | 11 | -- 12 | -- Database: `packt` 13 | -- 14 | 15 | -- -------------------------------------------------------- 16 | 17 | -- 18 | -- Table structure for table `categories` 19 | -- 20 | 21 | CREATE TABLE `categories` ( 22 | `id` int(11) NOT NULL, 23 | `categoryName` varchar(100) NOT NULL, 24 | `parentCategory` int(11) DEFAULT '0', 25 | `sortInd` int(11) NOT NULL 26 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 27 | 28 | -- 29 | -- Dumping data for table `categories` 30 | -- 31 | 32 | INSERT INTO `categories` (`id`, `categoryName`, `parentCategory`, `sortInd`) VALUES 33 | (1, 'First', 0, 0), 34 | (2, 'Second', 1, 0), 35 | (3, 'Third', 1, 0), 36 | (4, 'Fourth', 3, 0), 37 | (5, 'fifth', 4, 0), 38 | (6, 'Sixth', 5, 0), 39 | (7, 'seventh', 6, 0), 40 | (8, 'Eighth', 7, 0), 41 | (9, 'Nineth', 1, 0), 42 | (10, 'Tenth', 2, 0); 43 | 44 | -- -------------------------------------------------------- 45 | 46 | -- 47 | -- Table structure for table `comments` 48 | -- 49 | 50 | CREATE TABLE `comments` ( 51 | `id` int(11) NOT NULL, 52 | `comment` varchar(500) NOT NULL, 53 | `username` varchar(50) NOT NULL, 54 | `datetime` datetime NOT NULL, 55 | `parentID` int(11) NOT NULL, 56 | `postID` int(11) NOT NULL 57 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 58 | 59 | -- 60 | -- Dumping data for table `comments` 61 | -- 62 | 63 | INSERT INTO `comments` (`id`, `comment`, `username`, `datetime`, `parentID`, `postID`) VALUES 64 | (1, 'First comment', 'Mizan', '2016-10-01 15:10:20', 0, 1), 65 | (2, 'First reply', 'Adiyan', '2016-10-02 04:09:10', 1, 1), 66 | (3, 'Reply of first reply', 'Mikhael', '2016-10-03 11:10:47', 2, 1), 67 | (4, 'Reply of reply of first reply ', 'Arshad', '2016-10-04 21:22:45', 3, 1), 68 | (5, 'Reply of reply of reply of first reply', 'Anam', '2016-10-05 12:01:29', 4, 1), 69 | (6, 'Second comment', 'Keith', '2016-10-01 15:10:20', 0, 1), 70 | (7, 'First comment of second post', 'Milon', '2016-10-02 04:09:10', 0, 2), 71 | (8, 'Third comment', 'Ikrum', '2016-10-03 11:10:47', 0, 1), 72 | (9, 'Second comment of second post', 'Ahmed', '2016-10-04 21:22:45', 0, 2), 73 | (10, 'Reply of second comment of second post', 'Afsar', '2016-10-18 05:18:24', 9, 2); 74 | 75 | -- 76 | -- Indexes for dumped tables 77 | -- 78 | 79 | -- 80 | -- Indexes for table `categories` 81 | -- 82 | ALTER TABLE `categories` 83 | ADD PRIMARY KEY (`id`); 84 | 85 | -- 86 | -- Indexes for table `comments` 87 | -- 88 | ALTER TABLE `comments` 89 | ADD PRIMARY KEY (`id`); 90 | 91 | -- 92 | -- AUTO_INCREMENT for dumped tables 93 | -- 94 | 95 | -- 96 | -- AUTO_INCREMENT for table `categories` 97 | -- 98 | ALTER TABLE `categories` 99 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11; 100 | -- 101 | -- AUTO_INCREMENT for table `comments` 102 | -- 103 | ALTER TABLE `comments` 104 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11; 105 | -------------------------------------------------------------------------------- /Chapter06/1.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class TreeNode { 11 | 12 | public $data = NULL; 13 | public $children = []; 14 | 15 | public function __construct(string $data = NULL) { 16 | $this->data = $data; 17 | } 18 | 19 | public function addChildren(TreeNode $node) { 20 | $this->children[] = $node; 21 | } 22 | 23 | } 24 | 25 | class Tree { 26 | 27 | public $root = NULL; 28 | public function __construct(TreeNode $node) { 29 | $this->root = $node; 30 | } 31 | 32 | public function traverse(TreeNode $node, int $level = 0) { 33 | 34 | if ($node) { 35 | echo str_repeat("-", $level); 36 | echo $node->data . "\n"; 37 | 38 | foreach ($node->children as $childNode) { 39 | $this->traverse($childNode, $level + 1); 40 | } 41 | } 42 | } 43 | 44 | } 45 | 46 | try { 47 | 48 | $ceo = new TreeNode("CEO"); 49 | 50 | $tree = new Tree($ceo); 51 | 52 | $cto = new TreeNode("CTO"); 53 | $cfo = new TreeNode("CFO"); 54 | $cmo = new TreeNode("CMO"); 55 | $coo = new TreeNode("COO"); 56 | 57 | $ceo->addChildren($cto); 58 | $ceo->addChildren($cfo); 59 | $ceo->addChildren($cmo); 60 | $ceo->addChildren($coo); 61 | 62 | $seniorArchitect = new TreeNode("Senior Architect"); 63 | $softwareEngineer = new TreeNode("Software Engineer"); 64 | $userInterfaceDesigner = new TreeNode("User Interface Designer"); 65 | $qualityAssuranceEngineer = new TreeNode("Quality Assurance Engineer"); 66 | 67 | $cto->addChildren($seniorArchitect); 68 | $seniorArchitect->addChildren($softwareEngineer); 69 | $cto->addChildren($qualityAssuranceEngineer); 70 | $cto->addChildren($userInterfaceDesigner); 71 | 72 | $tree->traverse($tree->root); 73 | 74 | } catch (Exception $e) { 75 | echo $e->getMessage(); 76 | } -------------------------------------------------------------------------------- /Chapter06/2.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class BinaryNode { 11 | 12 | public $data; 13 | public $left; 14 | public $right; 15 | 16 | public function __construct(string $data = NULL) { 17 | $this->data = $data; 18 | $this->left = NULL; 19 | $this->right = NULL; 20 | } 21 | 22 | public function addChildren(BinaryNode $left, BinaryNode $right) { 23 | $this->left = $left; 24 | $this->right = $right; 25 | } 26 | 27 | } 28 | 29 | class BinaryTree { 30 | 31 | public $root = NULL; 32 | 33 | public function __construct(BinaryNode $node) { 34 | $this->root = $node; 35 | } 36 | 37 | public function isEmpty(): bool { 38 | return $this->root === NULL; 39 | } 40 | 41 | public function traverse(BinaryNode $node, int $level = 0) { 42 | 43 | if ($node) { 44 | echo str_repeat("-", $level); 45 | echo $node->data . "\n"; 46 | 47 | if ($node->left) 48 | $this->traverse($node->left, $level + 1); 49 | 50 | if ($node->right) 51 | $this->traverse($node->right, $level + 1); 52 | } 53 | } 54 | 55 | } 56 | 57 | try { 58 | 59 | $final = new BinaryNode("Final"); 60 | 61 | $tree = new BinaryTree($final); 62 | 63 | $semiFinal1 = new BinaryNode("Semi Final 1"); 64 | $semiFinal2 = new BinaryNode("Semi Final 2"); 65 | $quarterFinal1 = new BinaryNode("Quarter Final 1"); 66 | $quarterFinal2 = new BinaryNode("Quarter Final 2"); 67 | $quarterFinal3 = new BinaryNode("Quarter Final 3"); 68 | $quarterFinal4 = new BinaryNode("Quarter Final 4"); 69 | 70 | $semiFinal1->addChildren($quarterFinal1, $quarterFinal2); 71 | $semiFinal2->addChildren($quarterFinal3, $quarterFinal4); 72 | 73 | $final->addChildren($semiFinal1, $semiFinal2); 74 | 75 | $tree->traverse($tree->root); 76 | } catch (Exception $e) { 77 | echo $e->getMessage(); 78 | } -------------------------------------------------------------------------------- /Chapter06/3.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class BinaryTree { 11 | 12 | public $nodes = []; 13 | 14 | public function __construct(Array $nodes) { 15 | $this->nodes = $nodes; 16 | } 17 | 18 | public function traverse(int $num = 0, int $level = 0) { 19 | 20 | if (isset($this->nodes[$num])) { 21 | echo str_repeat("-", $level); 22 | echo $this->nodes[$num] . "\n"; 23 | 24 | $this->traverse(2 * $num + 1, $level+1); 25 | $this->traverse(2 * ($num + 1), $level+1); 26 | } 27 | } 28 | 29 | } 30 | 31 | try { 32 | 33 | $nodes = []; 34 | $nodes[] = "Final"; 35 | $nodes[] = "Semi Final 1"; 36 | $nodes[] = "Semi Final 2"; 37 | $nodes[] = "Quarter Final 1"; 38 | $nodes[] = "Quarter Final 2"; 39 | $nodes[] = "Quarter Final 3"; 40 | $nodes[] = "Quarter Final 4"; 41 | 42 | $tree = new BinaryTree($nodes); 43 | $tree->traverse(0); 44 | } catch (Exception $e) { 45 | echo $e->getMessage(); 46 | } -------------------------------------------------------------------------------- /Chapter06/4.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class Node { 11 | 12 | public $data; 13 | public $left; 14 | public $right; 15 | 16 | public function __construct(int $data = NULL) { 17 | $this->data = $data; 18 | $this->left = NULL; 19 | $this->right = NULL; 20 | } 21 | 22 | public function min() { 23 | $node = $this; 24 | 25 | while($node->left) { 26 | $node = $node->left; 27 | } 28 | 29 | return $node; 30 | } 31 | 32 | public function max() { 33 | $node = $this; 34 | 35 | while($node->right) { 36 | $node = $node->right; 37 | } 38 | 39 | return $node; 40 | } 41 | 42 | public function successor() { 43 | 44 | $node = $this; 45 | if($node->right) 46 | return $node->right->min(); 47 | else 48 | return NULL; 49 | } 50 | 51 | public function predecessor() { 52 | $node = $this; 53 | if($node->left) 54 | return $node->left->max(); 55 | else 56 | return NULL; 57 | } 58 | 59 | } 60 | 61 | class BST { 62 | 63 | public $root = NULL; 64 | 65 | public function __construct(int $data) { 66 | $this->root = new Node($data); 67 | } 68 | 69 | public function isEmpty(): bool { 70 | return $this->root === NULL; 71 | } 72 | 73 | 74 | public function search(int $data) { 75 | if ($this->isEmpty()) { 76 | return FALSE; 77 | } 78 | 79 | $node = $this->root; 80 | 81 | while ($node) { 82 | if ($data > $node->data) { 83 | $node = $node->right; 84 | } elseif ($data < $node->data) { 85 | $node = $node->left; 86 | } else { 87 | break; 88 | } 89 | } 90 | 91 | 92 | return $node; 93 | } 94 | 95 | 96 | public function insert(int $data) { 97 | 98 | if($this->isEmpty()) { 99 | $node = new Node($data); 100 | $this->root = $node; 101 | return $node; 102 | } 103 | 104 | $node = $this->root; 105 | 106 | while($node) { 107 | 108 | if($data > $node->data) { 109 | 110 | if($node->right) { 111 | $node = $node->right; 112 | } else { 113 | $node->right = new Node($data); 114 | $node = $node->right; 115 | break; 116 | } 117 | 118 | } elseif($data < $node->data) { 119 | if($node->left) { 120 | $node = $node->left; 121 | } else { 122 | $node->left = new Node($data); 123 | $node = $node->left; 124 | break; 125 | } 126 | } else { 127 | break; 128 | } 129 | 130 | } 131 | 132 | return $node; 133 | 134 | 135 | } 136 | 137 | public function traverse(Node $node) { 138 | if ($node) { 139 | if ($node->left) 140 | $this->traverse($node->left); 141 | echo $node->data . "\n"; 142 | if ($node->right) 143 | $this->traverse($node->right); 144 | } 145 | } 146 | 147 | } 148 | 149 | try { 150 | 151 | 152 | $tree = new BST(10); 153 | 154 | $tree->insert(12); 155 | $tree->insert(6); 156 | $tree->insert(3); 157 | $tree->insert(8); 158 | $tree->insert(15); 159 | $tree->insert(13); 160 | $tree->insert(36); 161 | 162 | 163 | echo $tree->search(14) ? "Found" : "Not Found"; 164 | echo "\n"; 165 | echo $tree->search(36) ? "Found" : "Not Found"; 166 | 167 | $tree->traverse($tree->root); 168 | 169 | echo $tree->root->predecessor()->data; 170 | 171 | } catch (Exception $e) { 172 | echo $e->getMessage(); 173 | } -------------------------------------------------------------------------------- /Chapter06/5.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class Node { 11 | 12 | public $data; 13 | public $left; 14 | public $right; 15 | public $parent; 16 | 17 | public function __construct(int $data = NULL, Node $parent = NULL) { 18 | $this->data = $data; 19 | $this->parent = $parent; 20 | $this->left = NULL; 21 | $this->right = NULL; 22 | } 23 | 24 | public function min() { 25 | $node = $this; 26 | 27 | while($node->left) { 28 | $node = $node->left; 29 | } 30 | 31 | return $node; 32 | } 33 | 34 | public function max() { 35 | $node = $this; 36 | 37 | while($node->right) { 38 | $node = $node->right; 39 | } 40 | 41 | return $node; 42 | } 43 | 44 | public function successor() { 45 | 46 | $node = $this; 47 | if($node->right) 48 | return $node->right->min(); 49 | else 50 | return NULL; 51 | } 52 | 53 | public function predecessor() { 54 | $node = $this; 55 | if($node->left) 56 | return $node->left->max(); 57 | else 58 | return NULL; 59 | } 60 | 61 | public function delete() { 62 | $node = $this; 63 | if (!$node->left && !$node->right) { 64 | if ($node->parent->left === $node) { 65 | $node->parent->left = NULL; 66 | } else { 67 | $node->parent->right = NULL; 68 | } 69 | } elseif ($node->left && $node->right) { 70 | $successor = $node->successor(); 71 | $node->data = $successor->data; 72 | $successor->delete(); 73 | } elseif ($node->left) { 74 | if ($node->parent->left === $node) { 75 | $node->parent->left = $node->left; 76 | $node->left->parent = $node->parent->left; 77 | } else { 78 | $node->parent->right = $node->left; 79 | $node->left->parent = $node->parent->right; 80 | } 81 | $node->left = NULL; 82 | } elseif ($node->right) { 83 | 84 | if ($node->parent->left === $node) { 85 | $node->parent->left = $node->right; 86 | $node->right->parent = $node->parent->left; 87 | } else { 88 | $node->parent->right = $node->right; 89 | $node->right->parent = $node->parent->right; 90 | } 91 | $node->right = NULL; 92 | } 93 | } 94 | 95 | } 96 | 97 | class BST { 98 | 99 | public $root = NULL; 100 | 101 | public function __construct(int $data) { 102 | $this->root = new Node($data); 103 | } 104 | 105 | public function isEmpty(): bool { 106 | return $this->root === NULL; 107 | } 108 | 109 | 110 | public function remove(int $data) { 111 | 112 | $node = $this->search($data); 113 | 114 | if($node) 115 | $node->delete(); 116 | 117 | } 118 | 119 | 120 | public function search(int $data) { 121 | if ($this->isEmpty()) { 122 | return FALSE; 123 | } 124 | 125 | $node = $this->root; 126 | 127 | while ($node) { 128 | if ($data > $node->data) { 129 | $node = $node->right; 130 | } elseif ($data < $node->data) { 131 | $node = $node->left; 132 | } else { 133 | break; 134 | } 135 | } 136 | 137 | 138 | return $node; 139 | } 140 | 141 | 142 | public function insert(int $data) { 143 | 144 | if($this->isEmpty()) { 145 | $node = new Node($data); 146 | $this->root = $node; 147 | return $node; 148 | } 149 | 150 | $node = $this->root; 151 | 152 | while($node) { 153 | 154 | if($data > $node->data) { 155 | 156 | if($node->right) { 157 | $node = $node->right; 158 | } else { 159 | $node->right = new Node($data, $node); 160 | $node = $node->right; 161 | break; 162 | } 163 | 164 | } elseif($data < $node->data) { 165 | if($node->left) { 166 | $node = $node->left; 167 | } else { 168 | $node->left = new Node($data, $node); 169 | $node = $node->left; 170 | break; 171 | } 172 | } else { 173 | break; 174 | } 175 | 176 | } 177 | 178 | return $node; 179 | 180 | 181 | } 182 | 183 | public function traverse(Node $node) { 184 | if ($node) { 185 | if ($node->left) 186 | $this->traverse($node->left); 187 | echo $node->data . "\n"; 188 | if ($node->right) 189 | $this->traverse($node->right); 190 | } 191 | } 192 | 193 | } 194 | 195 | try { 196 | 197 | 198 | $tree = new BST(10); 199 | 200 | $tree->insert(12); 201 | $tree->insert(6); 202 | $tree->insert(3); 203 | $tree->insert(8); 204 | $tree->insert(15); 205 | $tree->insert(13); 206 | $tree->insert(36); 207 | 208 | 209 | $tree->traverse($tree->root); 210 | 211 | $tree->remove(15); 212 | 213 | $tree->traverse($tree->root); 214 | 215 | } catch (Exception $e) { 216 | echo $e->getMessage(); 217 | } -------------------------------------------------------------------------------- /Chapter06/6.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class Node { 11 | 12 | public $data; 13 | public $left; 14 | public $right; 15 | public $parent; 16 | 17 | public function __construct(int $data = NULL, Node $parent = NULL) { 18 | $this->data = $data; 19 | $this->parent = $parent; 20 | $this->left = NULL; 21 | $this->right = NULL; 22 | } 23 | 24 | public function min() { 25 | $node = $this; 26 | 27 | while($node->left) { 28 | $node = $node->left; 29 | } 30 | 31 | return $node; 32 | } 33 | 34 | public function max() { 35 | $node = $this; 36 | 37 | while($node->right) { 38 | $node = $node->right; 39 | } 40 | 41 | return $node; 42 | } 43 | 44 | public function successor() { 45 | 46 | $node = $this; 47 | if($node->right) 48 | return $node->right->min(); 49 | else 50 | return NULL; 51 | } 52 | 53 | public function predecessor() { 54 | $node = $this; 55 | if($node->left) 56 | return $node->left->max(); 57 | else 58 | return NULL; 59 | } 60 | 61 | public function delete() { 62 | $node = $this; 63 | if (!$node->left && !$node->right) { 64 | if ($node->parent->left === $node) { 65 | $node->parent->left = NULL; 66 | } else { 67 | $node->parent->right = NULL; 68 | } 69 | } elseif ($node->left && $node->right) { 70 | $successor = $node->successor(); 71 | $node->data = $successor->data; 72 | $successor->delete(); 73 | } elseif ($node->left) { 74 | if ($node->parent->left === $node) { 75 | $node->parent->left = $node->left; 76 | $node->left->parent = $node->parent->left; 77 | } else { 78 | $node->parent->right = $node->left; 79 | $node->left->parent = $node->parent->right; 80 | } 81 | $node->left = NULL; 82 | } elseif ($node->right) { 83 | 84 | if ($node->parent->left === $node) { 85 | $node->parent->left = $node->right; 86 | $node->right->parent = $node->parent->left; 87 | } else { 88 | $node->parent->right = $node->right; 89 | $node->right->parent = $node->parent->right; 90 | } 91 | $node->right = NULL; 92 | } 93 | } 94 | 95 | } 96 | 97 | class BST { 98 | 99 | public $root = NULL; 100 | 101 | public function __construct(int $data) { 102 | $this->root = new Node($data); 103 | } 104 | 105 | public function isEmpty(): bool { 106 | return $this->root === NULL; 107 | } 108 | 109 | 110 | public function remove(int $data) { 111 | $node = $this->search($data); 112 | 113 | if($node) 114 | $node->delete(); 115 | } 116 | 117 | 118 | public function search(int $data) { 119 | if ($this->isEmpty()) { 120 | return FALSE; 121 | } 122 | 123 | $node = $this->root; 124 | 125 | while ($node) { 126 | if ($data > $node->data) { 127 | $node = $node->right; 128 | } elseif ($data < $node->data) { 129 | $node = $node->left; 130 | } else { 131 | break; 132 | } 133 | } 134 | 135 | 136 | return $node; 137 | } 138 | 139 | 140 | public function insert(int $data) { 141 | 142 | if($this->isEmpty()) { 143 | $node = new Node($data); 144 | $this->root = $node; 145 | return $node; 146 | } 147 | 148 | $node = $this->root; 149 | 150 | while($node) { 151 | 152 | if($data > $node->data) { 153 | 154 | if($node->right) { 155 | $node = $node->right; 156 | } else { 157 | $node->right = new Node($data, $node); 158 | $node = $node->right; 159 | break; 160 | } 161 | 162 | } elseif($data < $node->data) { 163 | if($node->left) { 164 | $node = $node->left; 165 | } else { 166 | $node->left = new Node($data, $node); 167 | $node = $node->left; 168 | break; 169 | } 170 | } else { 171 | break; 172 | } 173 | 174 | } 175 | 176 | return $node; 177 | 178 | 179 | } 180 | 181 | public function traverse(Node $node, string $type="in-order") { 182 | switch($type) { 183 | case "in-order": 184 | $this->inOrder($node); 185 | break; 186 | 187 | case "pre-order": 188 | $this->preOrder($node); 189 | break; 190 | 191 | case "post-order": 192 | $this->postOrder($node); 193 | break; 194 | } 195 | } 196 | 197 | 198 | public function preOrder(Node $node) { 199 | if ($node) { 200 | echo $node->data . " "; 201 | if ($node->left) $this->traverse($node->left); 202 | if ($node->right) $this->traverse($node->right); 203 | } 204 | } 205 | 206 | public function inOrder(Node $node) { 207 | if ($node) { 208 | if ($node->left) $this->traverse($node->left); 209 | echo $node->data . " "; 210 | if ($node->right) $this->traverse($node->right); 211 | } 212 | } 213 | 214 | public function postOrder(Node $node) { 215 | if ($node) { 216 | if ($node->left) $this->traverse($node->left); 217 | if ($node->right) $this->traverse($node->right); 218 | echo $node->data . " "; 219 | } 220 | } 221 | 222 | 223 | } 224 | 225 | try { 226 | 227 | 228 | $tree = new BST(10); 229 | 230 | $tree->insert(12); 231 | $tree->insert(6); 232 | $tree->insert(3); 233 | $tree->insert(8); 234 | $tree->insert(15); 235 | $tree->insert(13); 236 | $tree->insert(36); 237 | 238 | 239 | $tree->traverse($tree->root, 'pre-order'); 240 | echo "\n"; 241 | $tree->traverse($tree->root, 'in-order'); 242 | echo "\n"; 243 | $tree->traverse($tree->root, 'post-order'); 244 | 245 | } catch (Exception $e) { 246 | echo $e->getMessage(); 247 | } -------------------------------------------------------------------------------- /Chapter07/1.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function bubbleSort(array $arr): array { 11 | $count = 0; 12 | $len = count($arr); 13 | 14 | for ($i = 0; $i < $len; $i++) { 15 | for ($j = 0; $j < $len - 1; $j++) { 16 | $count++; 17 | if ($arr[$j] > $arr[$j + 1]) { 18 | $tmp = $arr[$j + 1]; 19 | $arr[$j + 1] = $arr[$j]; 20 | $arr[$j] = $tmp; 21 | } 22 | } 23 | } 24 | echo $count."\n"; 25 | return $arr; 26 | } 27 | 28 | $arr = [20, 45, 93, 67, 10, 97, 52, 88, 33, 92]; 29 | 30 | $sortedArray = bubbleSort($arr); 31 | echo implode(",", $sortedArray); 32 | 33 | -------------------------------------------------------------------------------- /Chapter07/10.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | 11 | 12 | function radixSort(array &$data) { 13 | 14 | $n = count($data); 15 | 16 | if ($n <= 0) 17 | return; 18 | 19 | $min = min($data); 20 | $max = max($data); 21 | $arr = []; 22 | 23 | $len = $max - $min + 1; 24 | $arr = array_fill($min, $len, 0); 25 | 26 | foreach ($data as $key => $value) { 27 | $arr[$value] ++; 28 | } 29 | 30 | $data = []; 31 | foreach ($arr as $key => $value) { 32 | if ($value == 1) { 33 | $data[] = $key; 34 | } else { 35 | while ($value--) { 36 | $data[] = $key; 37 | } 38 | } 39 | } 40 | } 41 | 42 | $arr = [20, 45, 93, 67, 10, 97, 52, 88, 33, 92]; 43 | 44 | radixSort($arr); 45 | echo implode(",", $arr); -------------------------------------------------------------------------------- /Chapter07/2.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function bubbleSort(array $arr): array { 11 | $len = count($arr); 12 | $count = 0; 13 | 14 | for ($i = 0; $i < $len; $i++) { 15 | $swapped = FALSE; 16 | for ($j = 0; $j < $len - 1; $j++) { 17 | $count++; 18 | if ($arr[$j] > $arr[$j + 1]) { 19 | $tmp = $arr[$j + 1]; 20 | $arr[$j + 1] = $arr[$j]; 21 | $arr[$j] = $tmp; 22 | $swapped = TRUE; 23 | 24 | } 25 | } 26 | if(! $swapped) break; 27 | } 28 | echo $count."\n"; 29 | return $arr; 30 | } 31 | 32 | $arr = [20, 45, 93, 67, 10, 97, 52, 88, 33, 92]; 33 | 34 | $sortedArray = bubbleSort($arr); 35 | echo implode(",", $sortedArray); 36 | 37 | -------------------------------------------------------------------------------- /Chapter07/3.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function bubbleSort(array $arr): array { 11 | $len = count($arr); 12 | $count = 0; 13 | 14 | for ($i = 0; $i < $len; $i++) { 15 | $swapped = FALSE; 16 | for ($j = 0; $j < $len - $i - 1; $j++) { 17 | $count++; 18 | if ($arr[$j] > $arr[$j + 1]) { 19 | $tmp = $arr[$j + 1]; 20 | $arr[$j + 1] = $arr[$j]; 21 | $arr[$j] = $tmp; 22 | $swapped = TRUE; 23 | 24 | } 25 | } 26 | if(! $swapped) break; 27 | } 28 | echo $count."\n"; 29 | return $arr; 30 | } 31 | 32 | $arr = [20, 45, 93, 67, 10, 97, 52, 88, 33, 92]; 33 | 34 | $sortedArray = bubbleSort($arr); 35 | echo implode(",", $sortedArray); 36 | 37 | -------------------------------------------------------------------------------- /Chapter07/4.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function bubbleSort(array $arr): array { 11 | $len = count($arr); 12 | $count = 0; 13 | $bound = $len-1; 14 | 15 | for ($i = 0; $i < $len; $i++) { 16 | $swapped = FALSE; 17 | $newBound = 0; 18 | for ($j = 0; $j < $bound; $j++) { 19 | $count++; 20 | if ($arr[$j] > $arr[$j + 1]) { 21 | $tmp = $arr[$j + 1]; 22 | $arr[$j + 1] = $arr[$j]; 23 | $arr[$j] = $tmp; 24 | $swapped = TRUE; 25 | $newBound = $j; 26 | 27 | } 28 | } 29 | $bound = $newBound; 30 | 31 | if(! $swapped) break; 32 | } 33 | echo $count."\n"; 34 | return $arr; 35 | } 36 | 37 | $arr = [20, 45, 93, 67, 10, 97, 52, 88, 33, 92]; 38 | 39 | $sortedArray = bubbleSort($arr); 40 | echo implode(",", $sortedArray); 41 | 42 | -------------------------------------------------------------------------------- /Chapter07/5.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function selectionSort(array $arr): array { 11 | $len = count($arr); 12 | for ($i = 0; $i < $len; $i++) { 13 | $min = $i; 14 | for ($j = $i+1; $j < $len; $j++) { 15 | if ($arr[$j] > $arr[$min]) { 16 | $min = $j; 17 | } 18 | } 19 | 20 | if ($min != $i) { 21 | $tmp = $arr[$i]; 22 | $arr[$i] = $arr[$min]; 23 | $arr[$min] = $tmp; 24 | } 25 | } 26 | return $arr; 27 | } 28 | 29 | $arr = [20, 45, 93, 67, 10, 97, 52, 88, 33, 92]; 30 | 31 | $sortedArray = selectionSort($arr); 32 | echo implode(",", $sortedArray); 33 | 34 | -------------------------------------------------------------------------------- /Chapter07/6.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function insertionSort(array &$arr) { 11 | $len = count($arr); 12 | for ($i = 1; $i < $len; $i++) { 13 | $key = $arr[$i]; 14 | $j = $i - 1; 15 | 16 | while($j >= 0 && $arr[$j] > $key) { 17 | $arr[$j+1] = $arr[$j]; 18 | $j--; 19 | } 20 | $arr[$j+1] = $key; 21 | } 22 | } 23 | 24 | $arr = [20, 45, 93, 67, 10, 97, 52, 88, 33, 92]; 25 | 26 | insertionSort($arr); 27 | echo implode(",", $arr); 28 | 29 | -------------------------------------------------------------------------------- /Chapter07/7.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function mergeSort(array $arr): array { 11 | $len = count($arr); 12 | $mid = (int) $len / 2; 13 | if ($len == 1) 14 | return $arr; 15 | 16 | $left = mergeSort(array_slice($arr, 0, $mid)); 17 | $right = mergeSort(array_slice($arr, $mid)); 18 | 19 | return merge($left, $right); 20 | } 21 | 22 | function merge(array $left, array $right): array { 23 | $combined = []; 24 | $countLeft = count($left); 25 | $countRight = count($right); 26 | $leftIndex = $rightIndex = 0; 27 | 28 | while ($leftIndex < $countLeft && $rightIndex < $countRight) { 29 | if ($left[$leftIndex] > $right[$rightIndex]) { 30 | $combined[] = $right[$rightIndex]; 31 | $rightIndex++; 32 | } else { 33 | $combined[] = $left[$leftIndex]; 34 | $leftIndex++; 35 | } 36 | } 37 | while ($leftIndex < $countLeft) { 38 | $combined[] = $left[$leftIndex]; 39 | $leftIndex++; 40 | } 41 | while ($rightIndex < $countRight) { 42 | $combined[] = $right[$rightIndex]; 43 | $rightIndex++; 44 | } 45 | return $combined; 46 | } 47 | 48 | $arr = [20, 45, 93, 67, 10, 97, 52, 88, 33, 92]; 49 | 50 | $arr = mergeSort($arr); 51 | echo implode(",", $arr); -------------------------------------------------------------------------------- /Chapter07/8.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function quickSort(array &$arr, int $p, int $r) { 11 | if($p < $r) { 12 | $q = partition($arr, $p, $r); 13 | quickSort($arr, $p, $q); 14 | quickSort($arr, $q+1, $r); 15 | } 16 | } 17 | 18 | function partition(array &$arr, int $p, int $r){ 19 | $pivot = $arr[$p]; 20 | $i = $p-1; 21 | $j = $r+1; 22 | while(true) 23 | { 24 | do { 25 | $i++; 26 | } while($arr[$i] < $pivot && $arr[$i] != $pivot); 27 | 28 | do { 29 | $j--; 30 | } while($arr[$j] > $pivot && $arr[$j] != $pivot); 31 | 32 | if($i < $j){ 33 | $temp = $arr[$i]; 34 | $arr[$i] = $arr[$j]; 35 | $arr[$j] = $temp; 36 | } else { 37 | return $j; 38 | } 39 | } 40 | } 41 | 42 | 43 | $arr = [20, 45, 93, 67, 10, 97, 52, 88, 33, 92]; 44 | 45 | quickSort($arr, 0, count($arr)-1); 46 | echo implode(",", $arr); -------------------------------------------------------------------------------- /Chapter07/9.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function bucketSort(array &$data) { 11 | 12 | $n = count($data); 13 | if ($n <= 0) 14 | return; 15 | 16 | $min = min($data); 17 | $max = max($data); 18 | $bucket = []; 19 | $bLen = $max - $min + 1; 20 | 21 | $bucket = array_fill(0, $bLen, []); 22 | 23 | for ($i = 0; $i < $n; $i++) { 24 | array_push($bucket[$data[$i] - $min], $data[$i]); 25 | } 26 | 27 | $k = 0; 28 | for ($i = 0; $i < $bLen; $i++) { 29 | $bCount = count($bucket[$i]); 30 | 31 | for ($j = 0; $j < $bCount; $j++) { 32 | $data[$k] = $bucket[$i][$j]; 33 | $k++; 34 | } 35 | } 36 | } 37 | 38 | $arr = [20, 45, 93, 67, 10, 97, 52, 88, 33, 92]; 39 | 40 | bucketSort($arr); 41 | echo implode(",", $arr); -------------------------------------------------------------------------------- /Chapter08/1.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function search(array $numbers, int $neeedle): bool { 11 | $totalItems = count($numbers); 12 | 13 | for ($i = 0; $i < $totalItems; $i++) { 14 | if($numbers[$i] === $neeedle){ 15 | return TRUE; 16 | } 17 | } 18 | return FALSE; 19 | } 20 | 21 | $numbers = range(1, 200, 5); 22 | 23 | if (search($numbers, 31)) { 24 | echo "Found"; 25 | } else { 26 | echo "Not found"; 27 | } -------------------------------------------------------------------------------- /Chapter08/10.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class TreeNode { 11 | 12 | public $data = NULL; 13 | public $children = []; 14 | 15 | public function __construct(string $data = NULL) { 16 | $this->data = $data; 17 | } 18 | 19 | public function addChildren(TreeNode $node) { 20 | $this->children[] = $node; 21 | } 22 | 23 | } 24 | 25 | class Tree { 26 | public $root = NULL; 27 | 28 | public function __construct(TreeNode $node) { 29 | $this->root = $node; 30 | } 31 | 32 | public function DFS(TreeNode $node): SplQueue { 33 | 34 | $stack = new SplStack; 35 | $visited = new SplQueue; 36 | 37 | $stack->push($node); 38 | 39 | while (!$stack->isEmpty()) { 40 | $current = $stack->pop(); 41 | $visited->enqueue($current); 42 | $current->children = array_reverse($current->children); 43 | foreach ($current->children as $child) { 44 | $stack->push($child); 45 | } 46 | } 47 | return $visited; 48 | } 49 | } 50 | 51 | try { 52 | 53 | $root = new TreeNode("8"); 54 | 55 | $tree = new Tree($root); 56 | 57 | $node1 = new TreeNode("3"); 58 | $node2 = new TreeNode("10"); 59 | $root->addChildren($node1); 60 | $root->addChildren($node2); 61 | 62 | $node3 = new TreeNode("1"); 63 | $node4 = new TreeNode("6"); 64 | $node5 = new TreeNode("14"); 65 | $node1->addChildren($node3); 66 | $node1->addChildren($node4); 67 | $node2->addChildren($node5); 68 | 69 | $node6 = new TreeNode("4"); 70 | $node7 = new TreeNode("7"); 71 | $node8 = new TreeNode("13"); 72 | $node4->addChildren($node6); 73 | $node4->addChildren($node7); 74 | $node5->addChildren($node8); 75 | 76 | 77 | $visited = $tree->DFS($tree->root); 78 | 79 | while (!$visited->isEmpty()) { 80 | echo $visited->dequeue()->data . "\n"; 81 | } 82 | } catch (Exception $e) { 83 | echo $e->getMessage(); 84 | } -------------------------------------------------------------------------------- /Chapter08/2.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function binarySearch(array $numbers, int $neeedle): bool { 11 | $low = 0; 12 | $high = count($numbers)-1; 13 | 14 | while ($low <= $high) { 15 | $mid = (int) (($low + $high) / 2); 16 | 17 | if ($numbers[$mid] > $neeedle) { 18 | $high = $mid - 1; 19 | } else if ($numbers[$mid] < $neeedle) { 20 | $low = $mid + 1; 21 | } else { 22 | return TRUE; 23 | } 24 | } 25 | return FALSE; 26 | } 27 | 28 | $numbers = range(1, 200, 5); 29 | 30 | $number = 31; 31 | if (binarySearch($numbers, $number) !== FALSE) { 32 | echo "$number Found \n"; 33 | } else { 34 | echo "$number Not found \n"; 35 | } 36 | 37 | $number = 196; 38 | if (binarySearch($numbers, $number) !== FALSE) { 39 | echo "$number Found \n"; 40 | } else { 41 | echo "$number Not found \n"; 42 | } -------------------------------------------------------------------------------- /Chapter08/3.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function binarySearch(array $numbers, int $neeedle, int $low, int $high): int { 11 | 12 | if ($high < $low) { 13 | return -1; 14 | } 15 | $mid = (int) (($low + $high) / 2); 16 | 17 | if ($numbers[$mid] > $neeedle) { 18 | return binarySearch($numbers, $neeedle, $low, $mid - 1); 19 | } else if ($numbers[$mid] < $neeedle) { 20 | return binarySearch($numbers, $neeedle, $mid + 1, $high); 21 | } else { 22 | return $mid; 23 | } 24 | } 25 | 26 | $numbers = range(1, 200, 5); 27 | 28 | $number = 31; 29 | if (binarySearch($numbers, $number, 0, count($numbers) - 1) >= 0) { 30 | echo "$number Found \n"; 31 | } else { 32 | echo "$number Not found \n"; 33 | } 34 | 35 | $number = 500; 36 | if (binarySearch($numbers, $number, 0, count($numbers) - 1) >= 0) { 37 | echo "$number Found \n"; 38 | } else { 39 | echo "$number Not found \n"; 40 | } -------------------------------------------------------------------------------- /Chapter08/4.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | 11 | function repetitiveBinarySearch(array $numbers, int $neeedle): int { 12 | $low = 0; 13 | $high = count($numbers) - 1; 14 | $firstOccurrence = -1; 15 | 16 | while ($low <= $high) { 17 | $mid = (int) (($low + $high) / 2); 18 | 19 | if ($numbers[$mid] === $neeedle) { 20 | $firstOccurrence = $mid; 21 | $high = $mid - 1; 22 | } else if ($numbers[$mid] > $neeedle) { 23 | $high = $mid - 1; 24 | } else { 25 | $low = $mid + 1; 26 | } 27 | } 28 | return $firstOccurrence; 29 | } 30 | 31 | $numbers = [1,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,5,5]; 32 | 33 | $number = 2; 34 | 35 | $pos = repetitiveBinarySearch($numbers, $number); 36 | 37 | if ($pos >= 0) { 38 | echo "$number Found at position $pos \n"; 39 | } else { 40 | echo "$number Not found \n"; 41 | } 42 | 43 | $number = 5; 44 | $pos = repetitiveBinarySearch($numbers, $number); 45 | 46 | if ($pos >= 0) { 47 | echo "$number Found at position $pos \n"; 48 | } else { 49 | echo "$number Not found \n"; 50 | } -------------------------------------------------------------------------------- /Chapter08/5.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function interpolationSearch(array $arr, int $key): int { 11 | $low = 0; 12 | $high = count($arr) - 1; 13 | 14 | while ($arr[$high] != $arr[$low] && $key >= $arr[$low] && $key <= $arr[$high]) { 15 | $mid = intval($low + (($key - $arr[$low]) * ($high - $low) / ($arr[$high] - $arr[$low]))); 16 | 17 | if ($arr[$mid] < $key) 18 | $low = $mid + 1; 19 | else if ($key < $arr[$mid]) 20 | $high = $mid - 1; 21 | else 22 | return $mid; 23 | } 24 | 25 | if ($key == $arr[$low]) 26 | return $low; 27 | else 28 | return -1; 29 | } 30 | 31 | $numbers = range(1, 200, 5); 32 | 33 | $number = 31; 34 | if (interpolationSearch($numbers, $number) >= 0) { 35 | echo "$number Found \n"; 36 | } else { 37 | echo "$number Not found \n"; 38 | } 39 | 40 | $number = 196; 41 | if (interpolationSearch($numbers, $number) >= 0) { 42 | echo "$number Found \n"; 43 | } else { 44 | echo "$number Not found \n"; 45 | } -------------------------------------------------------------------------------- /Chapter08/6.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function binarySearch(array $numbers, int $neeedle, int $low, int $high): int { 11 | 12 | if ($high < $low) { 13 | return -1; 14 | } 15 | $mid = (int) (($low + $high) / 2); 16 | 17 | if ($numbers[$mid] > $neeedle) { 18 | return binarySearch($numbers, $neeedle, $low, $mid - 1); 19 | } else if ($numbers[$mid] < $neeedle) { 20 | return binarySearch($numbers, $neeedle, $mid + 1, $high); 21 | } else { 22 | return $mid; 23 | } 24 | } 25 | 26 | function exponentialSearch(array $arr, int $key): int { 27 | $size = count($arr); 28 | 29 | if ($size == 0) 30 | return -1; 31 | 32 | $bound = 1; 33 | while ($bound < $size && $arr[$bound] < $key) { 34 | $bound *= 2; 35 | } 36 | return binarySearch($arr, $key, intval($bound / 2), min($bound, $size)); 37 | } 38 | 39 | $numbers = range(1, 200, 5); 40 | 41 | $number = 31; 42 | if (exponentialSearch($numbers, $number) >= 0) { 43 | echo "$number Found \n"; 44 | } else { 45 | echo "$number Not found \n"; 46 | } 47 | 48 | $number = 196; 49 | if (exponentialSearch($numbers, $number) >= 0) { 50 | echo "$number Found \n"; 51 | } else { 52 | echo "$number Not found \n"; 53 | } -------------------------------------------------------------------------------- /Chapter08/7.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | $arr = []; 11 | $count = rand(10, 30); 12 | 13 | for($i = 0; $i<$count;$i++) { 14 | $val = rand(1,500); 15 | $arr[$val] = $val; 16 | } 17 | 18 | $number = 100; 19 | 20 | if(isset($arr[$number])) { 21 | echo "$number found "; 22 | } else { 23 | echo "$number not found"; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter08/8.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class TreeNode { 11 | 12 | public $data = NULL; 13 | public $children = []; 14 | 15 | public function __construct(string $data = NULL) { 16 | $this->data = $data; 17 | } 18 | 19 | public function addChildren(TreeNode $node) { 20 | $this->children[] = $node; 21 | } 22 | 23 | } 24 | 25 | class Tree { 26 | 27 | public $root = NULL; 28 | 29 | public function __construct(TreeNode $node) { 30 | $this->root = $node; 31 | } 32 | 33 | public function BFS(TreeNode $node): SplQueue { 34 | 35 | $queue = new SplQueue; 36 | $visited = new SplQueue; 37 | 38 | $queue->enqueue($node); 39 | 40 | while (!$queue->isEmpty()) { 41 | $current = $queue->dequeue(); 42 | $visited->enqueue($current); 43 | 44 | foreach ($current->children as $child) { 45 | $queue->enqueue($child); 46 | } 47 | } 48 | return $visited; 49 | } 50 | } 51 | 52 | try { 53 | 54 | $root = new TreeNode("8"); 55 | 56 | $tree = new Tree($root); 57 | 58 | $node1 = new TreeNode("3"); 59 | $node2 = new TreeNode("10"); 60 | $root->addChildren($node1); 61 | $root->addChildren($node2); 62 | 63 | $node3 = new TreeNode("1"); 64 | $node4 = new TreeNode("6"); 65 | $node5 = new TreeNode("14"); 66 | $node1->addChildren($node3); 67 | $node1->addChildren($node4); 68 | $node2->addChildren($node5); 69 | 70 | $node6 = new TreeNode("4"); 71 | $node7 = new TreeNode("7"); 72 | $node8 = new TreeNode("13"); 73 | $node4->addChildren($node6); 74 | $node4->addChildren($node7); 75 | $node5->addChildren($node8); 76 | 77 | 78 | $visited = $tree->BFS($tree->root); 79 | 80 | while (!$visited->isEmpty()) { 81 | echo $visited->dequeue()->data . "\n"; 82 | } 83 | } catch (Exception $e) { 84 | echo $e->getMessage(); 85 | } -------------------------------------------------------------------------------- /Chapter08/9.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class TreeNode { 11 | 12 | public $data = NULL; 13 | public $children = []; 14 | 15 | public function __construct(string $data = NULL) { 16 | $this->data = $data; 17 | } 18 | 19 | public function addChildren(TreeNode $node) { 20 | $this->children[] = $node; 21 | } 22 | 23 | } 24 | 25 | class Tree { 26 | 27 | public $root = NULL; 28 | public $visited; 29 | 30 | 31 | public function __construct(TreeNode $node) { 32 | $this->root = $node; 33 | $this->visited = new SplQueue; 34 | } 35 | 36 | public function DFS(TreeNode $node) { 37 | 38 | $this->visited->enqueue($node); 39 | 40 | if($node->children){ 41 | foreach ($node->children as $child) { 42 | $this->DFS($child); 43 | } 44 | } 45 | 46 | } 47 | } 48 | 49 | try { 50 | 51 | $root = new TreeNode("8"); 52 | 53 | $tree = new Tree($root); 54 | 55 | $node1 = new TreeNode("3"); 56 | $node2 = new TreeNode("10"); 57 | $root->addChildren($node1); 58 | $root->addChildren($node2); 59 | 60 | $node3 = new TreeNode("1"); 61 | $node4 = new TreeNode("6"); 62 | $node5 = new TreeNode("14"); 63 | $node1->addChildren($node3); 64 | $node1->addChildren($node4); 65 | $node2->addChildren($node5); 66 | 67 | $node6 = new TreeNode("4"); 68 | $node7 = new TreeNode("7"); 69 | $node8 = new TreeNode("13"); 70 | $node4->addChildren($node6); 71 | $node4->addChildren($node7); 72 | $node5->addChildren($node8); 73 | 74 | 75 | $tree->DFS($tree->root); 76 | 77 | $visited = $tree->visited; 78 | while (!$visited->isEmpty()) { 79 | echo $visited->dequeue()->data . "\n"; 80 | } 81 | } catch (Exception $e) { 82 | echo $e->getMessage(); 83 | } -------------------------------------------------------------------------------- /Chapter09/1.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | 11 | 12 | function topologicalSortKahnV2(array $matrix): array { 13 | $sorted = []; 14 | $nodes = []; 15 | 16 | $size = count($matrix); 17 | 18 | // finding all nodes where indegree = 0 19 | for ($i = 0; $i < $size; $i++) { 20 | $sum = 0; 21 | for ($j = 0; $j < $size; $j++) 22 | $sum += $matrix[$j][$i]; 23 | 24 | if ($sum == 0) 25 | array_push($nodes, $i); 26 | } 27 | 28 | while ($nodes) { 29 | 30 | $node = array_shift($nodes); 31 | array_push($sorted, $node); 32 | 33 | foreach ($matrix[$node] as $index => $hasEdge) { 34 | if ($hasEdge) { 35 | $matrix[$node][$index] = 0; 36 | 37 | $sum = 0; 38 | for ($i = 0; $i < $size; $i++) { 39 | $sum += $matrix[$i][$index]; 40 | } 41 | 42 | if (!$sum) { 43 | array_push($nodes, $index); 44 | } 45 | } 46 | } 47 | } 48 | 49 | return $sorted; 50 | } 51 | 52 | function topologicalSort(array $matrix): SplQueue { 53 | $order = new SplQueue; 54 | $queue = new SplQueue; 55 | $size = count($matrix); 56 | $incoming = array_fill(0, $size, 0); 57 | 58 | 59 | for ($i = 0; $i < $size; $i++) { 60 | for ($j = 0; $j < $size; $j++) { 61 | if ($matrix[$j][$i]) { 62 | $incoming[$i] ++; 63 | } 64 | } 65 | if ($incoming[$i] == 0) { 66 | $queue->enqueue($i); 67 | } 68 | } 69 | 70 | while (!$queue->isEmpty()) { 71 | $node = $queue->dequeue(); 72 | 73 | for ($i = 0; $i < $size; $i++) { 74 | if ($matrix[$node][$i] == 1) { 75 | $matrix[$node][$i] = 0; 76 | $incoming[$i] --; 77 | if ($incoming[$i] == 0) { 78 | $queue->enqueue($i); 79 | } 80 | } 81 | } 82 | $order->enqueue($node); 83 | } 84 | 85 | if ($order->count() != $size) // cycle detected 86 | return new SplQueue; 87 | 88 | return $order; 89 | } 90 | 91 | /* 92 | $arr = [ 93 | [0, 1, 1, 0, 0, 0, 0], 94 | [0, 0, 0, 1, 0, 0, 0], 95 | [0, 0, 0, 0, 1, 0, 0], 96 | [0, 0, 0, 0, 1, 0, 0], 97 | [0, 0, 0, 0, 0, 0, 1], 98 | [0, 0, 0, 0, 0, 0, 1], 99 | [0, 0, 0, 0, 0, 0, 0], 100 | ]; 101 | 102 | $count = 5; 103 | $arr = []; 104 | 105 | for($i = 0;$i<$count;$i++) 106 | { 107 | $arr[] = array_fill(0, $count, 0); 108 | } 109 | 110 | $arr[0][4] = 1; 111 | $arr[1][0] = 1; 112 | $arr[2][1] = 1; 113 | $arr[2][3] = 1; 114 | $arr[1][3] = 1; 115 | */ 116 | 117 | $graph = [ 118 | [0, 0, 0, 0, 1], 119 | [1, 0, 0, 1, 0], 120 | [0, 1, 0, 1, 0], 121 | [0, 0, 0, 0, 0], 122 | [0, 0, 0, 0, 0], 123 | ]; 124 | 125 | $sorted = topologicalSort($graph); 126 | 127 | while (!$sorted->isEmpty()) { 128 | echo $sorted->dequeue() . "\t"; 129 | } 130 | -------------------------------------------------------------------------------- /Chapter09/2.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function BFS(array &$graph, int $start, array $visited): SplQueue { 11 | $queue = new SplQueue; 12 | $path = new SplQueue; 13 | 14 | $queue->enqueue($start); 15 | $visited[$start] = 1; 16 | 17 | while (!$queue->isEmpty()) { 18 | $node = $queue->dequeue(); 19 | $path->enqueue($node); 20 | foreach ($graph[$node] as $key => $vertex) { 21 | if (!$visited[$key] && $vertex == 1) { 22 | $visited[$key] = 1; 23 | $queue->enqueue($key); 24 | } 25 | } 26 | } 27 | 28 | return $path; 29 | } 30 | 31 | $graph = [ 32 | 0 => [0, 1, 1, 0, 0, 0], 33 | 1 => [1, 0, 0, 1, 0, 0], 34 | 2 => [1, 0, 0, 1, 0, 0], 35 | 3 => [0, 1, 1, 0, 1, 0], 36 | 4 => [0, 0, 0, 1, 0, 1], 37 | 5 => [0, 0, 0, 0, 1, 0], 38 | ]; 39 | 40 | $graph = []; 41 | $visited = []; 42 | $vertexCount = 6; 43 | 44 | for($i = 1;$i<=$vertexCount;$i++) { 45 | $graph[$i] = array_fill(1, $vertexCount, 0); 46 | $visited[$i] = 0; 47 | } 48 | 49 | $graph[1][2] = $graph[2][1] = 1; 50 | $graph[1][5] = $graph[5][1] = 1; 51 | $graph[5][2] = $graph[2][5] = 1; 52 | $graph[5][4] = $graph[4][5] = 1; 53 | $graph[4][3] = $graph[3][4] = 1; 54 | $graph[3][2] = $graph[2][3] = 1; 55 | $graph[6][4] = $graph[4][6] = 1; 56 | 57 | $path = BFS($graph, 5, $visited); 58 | 59 | while (!$path->isEmpty()) { 60 | echo $path->dequeue()."\t"; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /Chapter09/3.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function DFS(array &$graph, int $start, array $visited): SplQueue { 11 | $stack = new SplStack; 12 | $path = new SplQueue; 13 | 14 | $stack->push($start); 15 | $visited[$start] = 1; 16 | 17 | while (!$stack->isEmpty()) { 18 | $node = $stack->pop(); 19 | $path->enqueue($node); 20 | foreach ($graph[$node] as $key => $vertex) { 21 | if (!$visited[$key] && $vertex == 1) { 22 | $visited[$key] = 1; 23 | $stack->push($key); 24 | } 25 | } 26 | } 27 | 28 | return $path; 29 | } 30 | 31 | $graph = [ 32 | 0 => [0, 1, 1, 0, 0, 0], 33 | 1 => [1, 0, 0, 1, 0, 0], 34 | 2 => [1, 0, 0, 1, 0, 0], 35 | 3 => [0, 1, 1, 0, 1, 0], 36 | 4 => [0, 0, 0, 1, 0, 1], 37 | 5 => [0, 0, 0, 0, 1, 0], 38 | ]; 39 | 40 | $graph = []; 41 | $visited = []; 42 | $vertexCount = 6; 43 | 44 | for($i = 1;$i<=$vertexCount;$i++) { 45 | $graph[$i] = array_fill(1, $vertexCount, 0); 46 | $visited[$i] = 0; 47 | } 48 | 49 | $graph[1][2] = $graph[2][1] = 1; 50 | $graph[1][5] = $graph[5][1] = 1; 51 | $graph[5][2] = $graph[2][5] = 1; 52 | $graph[5][4] = $graph[4][5] = 1; 53 | $graph[4][3] = $graph[3][4] = 1; 54 | $graph[3][2] = $graph[2][3] = 1; 55 | $graph[6][4] = $graph[4][6] = 1; 56 | 57 | $path = DFS($graph, 1, $visited); 58 | 59 | while (!$path->isEmpty()) { 60 | echo $path->dequeue()."\t"; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /Chapter09/4.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function floydWarshall(array $graph): array { 11 | $dist = []; 12 | $dist = $graph; 13 | $size = count($dist); 14 | 15 | for ($k = 0; $k < $size; $k++) 16 | for ($i = 0; $i < $size; $i++) 17 | for ($j = 0; $j < $size; $j++) 18 | $dist[$i][$j] = min($dist[$i][$j], $dist[$i][$k] + $dist[$k][$j]); 19 | 20 | return $dist; 21 | } 22 | 23 | $totalVertices = 5; 24 | $graph = []; 25 | for ($i = 0; $i < $totalVertices; $i++) { 26 | for ($j = 0; $j < $totalVertices; $j++) { 27 | $graph[$i][$j] = $i == $j ? 0 : PHP_INT_MAX; 28 | } 29 | } 30 | 31 | $graph[0][1] = $graph[1][0] = 10; 32 | $graph[2][1] = $graph[1][2] = 5; 33 | $graph[0][3] = $graph[3][0] = 5; 34 | $graph[3][1] = $graph[1][3] = 5; 35 | $graph[4][1] = $graph[1][4] = 10; 36 | $graph[3][4] = $graph[4][3] = 20; 37 | 38 | $distance = floydWarshall($graph); 39 | 40 | echo "Shortest distance between A to E is:" . $distance[0][4] . "\n"; 41 | echo "Shortest distance between D to C is:" . $distance[3][2] . "\n"; 42 | -------------------------------------------------------------------------------- /Chapter09/5.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function Dijkstra(array $graph, string $source, string $target): array { 11 | $dist = []; 12 | $pred = []; 13 | $Queue = new SplPriorityQueue(); 14 | 15 | foreach ($graph as $v => $adj) { 16 | $dist[$v] = PHP_INT_MAX; 17 | $pred[$v] = null; 18 | $Queue->insert($v, min($adj)); 19 | } 20 | 21 | $dist[$source] = 0; 22 | 23 | while (!$Queue->isEmpty()) { 24 | $u = $Queue->extract(); 25 | if (!empty($graph[$u])) { 26 | foreach ($graph[$u] as $v => $cost) { 27 | if ($dist[$u] + $cost < $dist[$v]) { 28 | $dist[$v] = $dist[$u] + $cost; 29 | $pred[$v] = $u; 30 | } 31 | } 32 | } 33 | } 34 | 35 | $S = new SplStack(); 36 | $u = $target; 37 | $distance = 0; 38 | 39 | while (isset($pred[$u]) && $pred[$u]) { 40 | $S->push($u); 41 | $distance += $graph[$u][$pred[$u]]; 42 | $u = $pred[$u]; 43 | } 44 | 45 | if ($S->isEmpty()) { 46 | return ["distance" => 0, "path" => $S]; 47 | } else { 48 | $S->push($source); 49 | return ["distance" => $distance, "path" => $S]; 50 | } 51 | } 52 | 53 | $graph = [ 54 | 'A' => ['B' => 3, 'C' => 5, 'D' => 9], 55 | 'B' => ['A' => 3, 'C' => 3, 'D' => 4, 'E' => 7], 56 | 'C' => ['A' => 5, 'B' => 3, 'D' => 2, 'E' => 6, 'F' => 3], 57 | 'D' => ['A' => 9, 'B' => 4, 'C' => 2, 'E' => 2, 'F' => 2], 58 | 'E' => ['B' => 7, 'C' => 6, 'D' => 2, 'F' => 5], 59 | 'F' => ['C' => 3, 'D' => 2, 'E' => 5], 60 | ]; 61 | 62 | $source = "A"; 63 | $target = "F"; 64 | 65 | $result = Dijkstra($graph, $source, $target); 66 | extract($result); 67 | 68 | echo "Distance from $source to $target is $distance \n"; 69 | echo "Path to follow : "; 70 | 71 | while (!$path->isEmpty()) { 72 | echo $path->pop() . "\t"; 73 | } -------------------------------------------------------------------------------- /Chapter09/6.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function bellmanFord(array $graph, int $source): array { 11 | $dist = []; 12 | $len = count($graph); 13 | 14 | foreach ($graph as $v => $adj) { 15 | $dist[$v] = PHP_INT_MAX; 16 | } 17 | 18 | $dist[$source] = 0; 19 | 20 | for ($k = 0; $k < $len - 1; $k++) { 21 | for ($i = 0; $i < $len; $i++) { 22 | for ($j = 0; $j < $len; $j++) { 23 | if ($dist[$i] > $dist[$j] + $graph[$j][$i]) { 24 | $dist[$i] = $dist[$j] + $graph[$j][$i]; 25 | } 26 | } 27 | } 28 | } 29 | 30 | for ($i = 0; $i < $len; $i++) { 31 | for ($j = 0; $j < $len; $j++) { 32 | if ($dist[$i] > $dist[$j] + $graph[$j][$i]) { 33 | echo 'The graph contains a negative-weight cycle!'; 34 | return []; 35 | } 36 | } 37 | } 38 | return $dist; 39 | } 40 | 41 | define("I", PHP_INT_MAX); 42 | 43 | $graph = [ 44 | 0 => [I, 3, 5, 9, I, I], 45 | 1 => [3, I, 3, 4, 7, I], 46 | 2 => [5, 3, I, 2, 6, 3], 47 | 3 => [9, 4, 2, I, 2, 2], 48 | 4 => [I, 7, 6, 2, I, 5], 49 | 5 => [I, I, 3, 2, 5, I] 50 | ]; 51 | 52 | $matrix = array( 53 | 0 => array(0, 3, 4), 54 | 1 => array(0, 0, 2), 55 | 2 => array(0, -2, 0), 56 | ); 57 | 58 | 59 | 60 | $source = 0; 61 | 62 | $distances = bellmanFord($graph, $source); 63 | 64 | foreach($distances as $target => $distance) { 65 | echo "distance from $source to $target is $distance \n"; 66 | } 67 | -------------------------------------------------------------------------------- /Chapter09/7.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function primMST(array $graph) { 11 | $parent = []; // Array to store the MST 12 | $key = []; // Key values used to pick minimum weight edge in cut 13 | $visited = []; // represent set of vertices not yet included in MST 14 | $len = count($graph); 15 | 16 | // Initialize all keys as MAX 17 | for ($i = 0; $i < $len; $i++) { 18 | $key[$i] = PHP_INT_MAX; 19 | $visited[$i] = false; 20 | } 21 | 22 | $key[0] = 0; 23 | $parent[0] = -1; 24 | 25 | // The MST will have V vertices 26 | for ($count = 0; $count < $len - 1; $count++) { 27 | // Pick thd minimum key vertex 28 | $minValue = PHP_INT_MAX; 29 | $minIndex = -1; 30 | 31 | foreach (array_keys($graph) as $v) { 32 | if ($visited[$v] == false && $key[$v] < $minValue) { 33 | $minValue = $key[$v]; 34 | $minIndex = $v; 35 | } 36 | } 37 | 38 | $u = $minIndex; 39 | 40 | // Add the picked vertex to the MST Set 41 | $visited[$u] = true; 42 | 43 | for ($v = 0; $v < $len; $v++) { 44 | if ($graph[$u][$v] != 0 && $visited[$v] == false && 45 | $graph[$u][$v] < $key[$v]) { 46 | $parent[$v] = $u; 47 | $key[$v] = $graph[$u][$v]; 48 | } 49 | } 50 | } 51 | 52 | // Print MST 53 | echo "Edge\tWeight\n"; 54 | $minimumCost = 0; 55 | for ($i = 1; $i < $len; $i++) { 56 | echo $parent[$i] . " - " . $i . "\t" . $graph[$i][$parent[$i]] . "\n"; 57 | $minimumCost += $graph[$i][$parent[$i]]; 58 | } 59 | echo "Minimum cost: $minimumCost \n"; 60 | } 61 | 62 | $G = [[0, 2, 0, 6, 0], 63 | [2, 0, 3, 8, 5], 64 | [0, 3, 0, 0, 7], 65 | [6, 8, 0, 0, 9], 66 | [0, 5, 7, 9, 0], 67 | ]; 68 | 69 | $G = [ 70 | [0, 3, 1, 6, 0, 0], 71 | [3, 0, 5, 0, 3, 0], 72 | [1, 5, 0, 5, 6, 4], 73 | [6, 0, 5, 0, 0, 2], 74 | [0, 3, 6, 0, 0, 6], 75 | [0, 0, 4, 2, 6, 0] 76 | ]; 77 | 78 | primMST($G); 79 | -------------------------------------------------------------------------------- /Chapter09/8.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function Kruskal(array $graph): array { 11 | $len = count($graph); 12 | $tree = []; 13 | 14 | $set = []; 15 | foreach ($graph as $k => $adj) { 16 | $set[$k] = [$k]; 17 | } 18 | 19 | $edges = []; 20 | for ($i = 0; $i < $len; $i++) { 21 | for ($j = 0; $j < $i; $j++) { 22 | if ($graph[$i][$j]) { 23 | $edges[$i . ',' . $j] = $graph[$i][$j]; 24 | } 25 | } 26 | } 27 | 28 | asort($edges); 29 | 30 | foreach ($edges as $k => $w) { 31 | list($i, $j) = explode(',', $k); 32 | 33 | $iSet = findSet($set, $i); 34 | $jSet = findSet($set, $j); 35 | if ($iSet != $jSet) { 36 | $tree[] = ["from" => $i, "to" => $j, "cost" => $graph[$i][$j]]; 37 | unionSet($set, $iSet, $jSet); 38 | } 39 | } 40 | 41 | return $tree; 42 | } 43 | 44 | function findSet(array &$set, int $index) { 45 | foreach ($set as $k => $v) { 46 | if (in_array($index, $v)) { 47 | return $k; 48 | } 49 | } 50 | 51 | return false; 52 | } 53 | 54 | function unionSet(array &$set, int $i, int $j) { 55 | $a = $set[$i]; 56 | $b = $set[$j]; 57 | unset($set[$i], $set[$j]); 58 | $set[] = array_merge($a, $b); 59 | } 60 | 61 | $graph = [ 62 | [0, 3, 1, 6, 0, 0], 63 | [3, 0, 5, 0, 3, 0], 64 | [1, 5, 0, 5, 6, 4], 65 | [6, 0, 5, 0, 0, 2], 66 | [0, 3, 6, 0, 0, 6], 67 | [0, 0, 4, 2, 6, 0] 68 | ]; 69 | 70 | $mst = Kruskal($graph); 71 | 72 | $minimumCost = 0; 73 | /* 74 | foreach ($mst as $v) { 75 | echo "From " . $v["from"] . " to " . $v["to"] . " cost is " . $v["cost"] . PHP_EOL; 76 | $minimumCost += $v["cost"]; 77 | } 78 | echo "Minimum cost: " . $minimumCost; 79 | */ 80 | 81 | foreach($mst as $v) { 82 | echo "From {$v['from']} to {$v['to']} cost is {$v['cost']} \n"; 83 | $minimumCost += $v['cost']; 84 | } 85 | 86 | echo "Minimum cost: $minimumCost \n"; 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /Chapter10/1.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class MinHeap { 11 | 12 | public $heap; 13 | public $count; 14 | 15 | public function __construct(int $size) { 16 | $this->heap = array_fill(0, $size + 1, 0); 17 | $this->count = 0; 18 | } 19 | 20 | public function create(array $arr = []) { 21 | if ($arr) { 22 | foreach ($arr as $val) { 23 | $this->insert($val); 24 | } 25 | } 26 | } 27 | 28 | public function display() { 29 | echo implode("\t", array_slice($this->heap, 1)) . "\n"; 30 | } 31 | 32 | public function insert(int $i) { 33 | if ($this->count == 0) { 34 | $this->heap[1] = $i; 35 | $this->count = 2; 36 | } else { 37 | $this->heap[$this->count++] = $i; 38 | $this->siftUp(); 39 | } 40 | } 41 | 42 | public function siftUp() { 43 | $tmpPos = $this->count - 1; 44 | $tmp = intval($tmpPos / 2); 45 | 46 | while ($tmpPos > 0 && $this->heap[$tmp] > $this->heap[$tmpPos]) { 47 | $this->swap($tmpPos, $tmp); 48 | $tmpPos = intval($tmpPos / 2); 49 | $tmp = intval($tmpPos / 2); 50 | } 51 | } 52 | 53 | public function swap(int $a, int $b) { 54 | $tmp = $this->heap[$a]; 55 | $this->heap[$a] = $this->heap[$b]; 56 | $this->heap[$b] = $tmp; 57 | } 58 | 59 | public function extractMin() { 60 | $min = $this->heap[1]; 61 | $this->heap[1] = $this->heap[$this->count - 1]; 62 | $this->heap[--$this->count] = 0; 63 | $this->siftDown(1); 64 | return $min; 65 | } 66 | 67 | public function siftDown(int $k) { 68 | $smallest = $k; 69 | $left = 2 * $k; 70 | $right = 2 * $k + 1; 71 | if ($left < $this->count && $this->heap[$smallest] > $this->heap[$left]) { 72 | $smallest = $left; 73 | } 74 | if ($right < $this->count && $this->heap[$smallest] > $this->heap[$right]) { 75 | $smallest = $right; 76 | } 77 | if ($smallest != $k) { 78 | $this->swap($k, $smallest); 79 | $this->siftDown($smallest); 80 | } 81 | } 82 | 83 | } 84 | 85 | $numbers = [37, 44, 34, 65, 26, 86, 129, 83, 9]; 86 | echo "Initial array \n" . implode("\t", $numbers) . "\n"; 87 | $heap = new MinHeap(count($numbers)); 88 | $heap->create($numbers); 89 | echo "Constructed Heap\n"; 90 | $heap->display(); 91 | echo "Min Extract: " . $heap->extractMin() . "\n"; 92 | $heap->display(); 93 | echo "Min Extract: " . $heap->extractMin() . "\n"; 94 | $heap->display(); 95 | echo "Min Extract: " . $heap->extractMin() . "\n"; 96 | $heap->display(); 97 | echo "Min Extract: " . $heap->extractMin() . "\n"; 98 | $heap->display(); 99 | echo "Min Extract: " . $heap->extractMin() . "\n"; 100 | $heap->display(); 101 | echo "Min Extract: " . $heap->extractMin() . "\n"; 102 | $heap->display(); 103 | -------------------------------------------------------------------------------- /Chapter10/2.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | class MaxHeap { 11 | 12 | public $heap; 13 | public $count; 14 | 15 | public function __construct(int $size) { 16 | $this->heap = array_fill(0, $size, 0); 17 | $this->count = 0; 18 | } 19 | 20 | public function create(array $arr = []) { 21 | if ($arr) { 22 | foreach ($arr as $val) { 23 | $this->insert($val); 24 | } 25 | } 26 | } 27 | 28 | public function display() { 29 | echo implode("\t", array_slice($this->heap, 0)) . "\n"; 30 | } 31 | 32 | public function insert(int $i) { 33 | if ($this->count == 0) { 34 | $this->heap[0] = $i; 35 | $this->count = 1; 36 | } else { 37 | $this->heap[$this->count++] = $i; 38 | $this->siftUp(); 39 | } 40 | } 41 | 42 | public function siftUp() { 43 | $tmpPos = $this->count - 1; 44 | $tmp = intval($tmpPos / 2); 45 | 46 | while ($tmpPos > 0 && $this->heap[$tmp] < $this->heap[$tmpPos]) { 47 | $this->swap($tmpPos, $tmp); 48 | 49 | $tmpPos = intval($tmpPos / 2); 50 | $tmp = intval($tmpPos / 2); 51 | } 52 | } 53 | 54 | public function extractMax() { 55 | $min = $this->heap[0]; 56 | $this->heap[0] = $this->heap[$this->count - 1]; 57 | $this->heap[$this->count - 1] = 0; 58 | $this->count--; 59 | $this->siftDown(0); 60 | return $min; 61 | } 62 | 63 | public function siftDown(int $k) { 64 | $largest = $k; 65 | $left = 2 * $k + 1; 66 | $right = 2 * $k + 2; 67 | if ($left < $this->count && $this->heap[$largest] < $this->heap[$left]) { 68 | $largest = $left; 69 | } 70 | if ($right < $this->count && $this->heap[$largest] < $this->heap[$right]) { 71 | $largest = $right; 72 | } 73 | if ($largest != $k) { 74 | $this->swap($k, $largest); 75 | $this->siftDown($largest); 76 | } 77 | } 78 | 79 | public function swap(int $a, int $b) { 80 | $temp = $this->heap[$a]; 81 | $this->heap[$a] = $this->heap[$b]; 82 | $this->heap[$b] = $temp; 83 | } 84 | } 85 | 86 | class PriorityQ extends MaxHeap { 87 | 88 | public function __construct(int $size) { 89 | parent::__construct($size); 90 | } 91 | 92 | public function enqueue(int $val) { 93 | parent::insert($val); 94 | } 95 | 96 | public function dequeue() { 97 | return parent::extractMax(); 98 | } 99 | 100 | } 101 | 102 | $numbers = [37, 44, 34, 65, 26, 86, 129, 83, 9]; 103 | $pq = new PriorityQ(count($numbers)); 104 | foreach ($numbers as $number) { 105 | $pq->enqueue($number); 106 | } 107 | echo "Constructed Heap\n"; 108 | $pq->display(); 109 | echo "DeQueued: " . $pq->dequeue() . "\n"; 110 | $pq->display(); 111 | echo "DeQueued: " . $pq->dequeue() . "\n"; 112 | $pq->display(); 113 | echo "DeQueued: " . $pq->dequeue() . "\n"; 114 | $pq->display(); 115 | echo "DeQueued: " . $pq->dequeue() . "\n"; 116 | $pq->display(); 117 | echo "DeQueued: " . $pq->dequeue() . "\n"; 118 | $pq->display(); 119 | echo "DeQueued: " . $pq->dequeue() . "\n"; 120 | $pq->display(); 121 | -------------------------------------------------------------------------------- /Chapter10/3.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function heapSort(array &$a) { 11 | $length = count($a); 12 | buildHeap($a); 13 | $heapSize = $length - 1; 14 | for ($i = $heapSize; $i >= 0; $i--) { 15 | $tmp = $a[0]; 16 | $a[0] = $a[$heapSize]; 17 | $a[$heapSize] = $tmp; 18 | $heapSize--; 19 | heapify($a, 0, $heapSize); 20 | } 21 | } 22 | 23 | function buildHeap(array &$a) { 24 | $length = count($a); 25 | $heapSize = $length - 1; 26 | for ($i = ($length / 2); $i >= 0; $i--) { 27 | heapify($a, $i, $heapSize); 28 | } 29 | } 30 | 31 | function heapify(array &$a, int $i, int $heapSize) { 32 | $largest = $i; 33 | $l = 2 * $i + 1; 34 | $r = 2 * $i + 2; 35 | if ($l <= $heapSize && $a[$l] > $a[$i]) { 36 | $largest = $l; 37 | } 38 | 39 | if ($r <= $heapSize && $a[$r] > $a[$largest]) { 40 | $largest = $r; 41 | } 42 | 43 | if ($largest != $i) { 44 | $tmp = $a[$i]; 45 | $a[$i] = $a[$largest]; 46 | $a[$largest] = $tmp; 47 | heapify($a, $largest, $heapSize); 48 | } 49 | } 50 | 51 | $numbers = [37, 44, 34, 65, 26, 86, 143, 129, 9]; 52 | heapSort($numbers); 53 | echo implode("\t", $numbers); -------------------------------------------------------------------------------- /Chapter10/4.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | $numbers = [37, 44, 34, 65, 26, 86, 143, 129, 9]; 11 | 12 | $heap = new SplMaxHeap; 13 | 14 | foreach ($numbers as $number) { 15 | $heap->insert($number); 16 | } 17 | 18 | while (!$heap->isEmpty()) { 19 | echo $heap->extract() . "\t"; 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter11/1.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | $startTime = microtime(); 11 | $count = 0; 12 | 13 | function fibonacci(int $n): int { 14 | global $count; 15 | $count++; 16 | if ($n == 0) { 17 | return 1; 18 | } else if ($n == 1) { 19 | return 1; 20 | } else { 21 | return fibonacci($n - 1) + fibonacci($n - 2); 22 | } 23 | } 24 | 25 | echo fibonacci(30) . "\n"; 26 | echo "Function called: " . $count . "\n"; 27 | $endTime = microtime(); 28 | echo "time =" . ($endTime - $startTime) . "\n"; 29 | 30 | 31 | $startTime = microtime(); 32 | $fibCache = []; 33 | $count = 0; 34 | 35 | function fibonacciMemoized(int $n): int { 36 | global $fibCache; 37 | global $count; 38 | $count++; 39 | if ($n == 0) { 40 | return 1; 41 | } else if ($n == 1) { 42 | return 1; 43 | } else { 44 | 45 | if (isset($fibCache[$n - 1])) { 46 | $tmp = $fibCache[$n - 1]; 47 | } else { 48 | $tmp = fibonacciMemoized($n - 1); 49 | $fibCache[$n - 1] = $tmp; 50 | } 51 | 52 | if (isset($fibCache[$n - 2])) { 53 | $tmp1 = $fibCache[$n - 2]; 54 | } else { 55 | $tmp1 = fibonacciMemoized($n - 2); 56 | $fibCache[$n - 2] = $tmp1; 57 | } 58 | 59 | return $tmp + $tmp1; 60 | } 61 | } 62 | 63 | echo fibonacciMemoized(30) . "\n"; 64 | echo "Function called: " . $count . "\n"; 65 | $endTime = microtime(); 66 | echo "time =" . ($endTime - $startTime) . "\n"; 67 | 68 | -------------------------------------------------------------------------------- /Chapter11/10.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function pearsonScore(array $reviews, string $person1, string $person2): float { 11 | $commonItems = array(); 12 | foreach ($reviews[$person1] as $restaurant1 => $rating) { 13 | foreach ($reviews[$person2] as $restaurant2 => $rating) { 14 | if ($restaurant1 == $restaurant2) { 15 | $commonItems[$restaurant1] = 1; 16 | } 17 | } 18 | } 19 | 20 | $n = count($commonItems); 21 | 22 | if ($n == 0) 23 | return 0.0; 24 | 25 | $sum1 = 0; 26 | $sum2 = 0; 27 | $sqrSum1 = 0; 28 | $sqrSum2 = 0; 29 | $pSum = 0; 30 | foreach ($commonItems as $restaurant => $common) { 31 | $sum1 += $reviews[$person1][$restaurant]; 32 | $sum2 += $reviews[$person2][$restaurant]; 33 | $sqrSum1 += $reviews[$person1][$restaurant] ** 2; 34 | $sqrSum2 += $reviews[$person2][$restaurant] ** 2; 35 | $pSum += $reviews[$person1][$restaurant] * $reviews[$person2][$restaurant]; 36 | } 37 | 38 | $num = $pSum - (($sum1 * $sum2) / $n); 39 | $den = sqrt(($sqrSum1 - (($sum1 ** 2) / $n)) * ($sqrSum2 - (($sum2 ** 2) / $n))); 40 | 41 | if ($den == 0) { 42 | $pearsonCorrelation = 0; 43 | } else { 44 | $pearsonCorrelation = $num / $den; 45 | } 46 | 47 | return (float) $pearsonCorrelation; 48 | } 49 | 50 | function similarReviewers(array $reviews, string $person, int $n): array { 51 | $scoresArray = []; 52 | foreach ($reviews as $reviewer => $restaurants) { 53 | if ($person != $reviewer) { 54 | $scoresArray[$reviewer] = pearsonScore($reviews, $person, $reviewer); 55 | } 56 | } 57 | arsort($scoresArray); 58 | return array_slice($scoresArray, 0, $n); 59 | } 60 | 61 | function getRecommendations(array $reviews, string $person): array { 62 | $calculation = []; 63 | foreach ($reviews as $reviewer => $restaurants) { 64 | $similarityScore = pearsonScore($reviews, $person, $reviewer); 65 | if ($person == $reviewer || $similarityScore <= 0) { 66 | continue; 67 | } 68 | 69 | foreach ($restaurants as $restaurant => $rating) { 70 | if (!array_key_exists($restaurant, $reviews[$person])) { 71 | if (!array_key_exists($restaurant, $calculation)) { 72 | $calculation[$restaurant] = []; 73 | $calculation[$restaurant]['Total'] = 0; 74 | $calculation[$restaurant]['SimilarityTotal'] = 0; 75 | } 76 | 77 | $calculation[$restaurant]['Total'] += $similarityScore * $rating; 78 | $calculation[$restaurant]['SimilarityTotal'] += $similarityScore; 79 | } 80 | } 81 | } 82 | $recommendations = []; 83 | foreach ($calculation as $restaurant => $values) { 84 | $recommendations[$restaurant] = $calculation[$restaurant]['Total'] / $calculation[$restaurant]['SimilarityTotal']; 85 | } 86 | 87 | arsort($recommendations); 88 | return $recommendations; 89 | } 90 | 91 | $reviews = []; 92 | $reviews['Adiyan'] = ["McDonalds" => 5, "KFC" => 5, "Pizza Hut" => 4.5, "Burger King" => 4.7, "American Burger" => 3.5, "Pizza Roma" => 2.5]; 93 | $reviews['Mikhael'] = ["McDonalds" => 3, "KFC" => 4, "Pizza Hut" => 3.5, "Burger King" => 4, "American Burger" => 4, "Jafran" => 4]; 94 | $reviews['Zayeed'] = ["McDonalds" => 5, "KFC" => 4, "Pizza Hut" => 2.5, "Burger King" => 4.5, "American Burger" => 3.5, "Sbarro" => 2]; 95 | $reviews['Arush'] = ["KFC" => 4.5, "Pizza Hut" => 3, "Burger King" => 4, "American Burger" => 3, "Jafran" => 2.5, "FFC" => 3.5]; 96 | $reviews['Tajwar'] = ["Burger King" => 3, "American Burger" => 2, "KFC" => 2.5, "Pizza Hut" => 3, "Pizza Roma" => 2.5, "FFC" => 3]; 97 | $reviews['Aayan'] = [ "KFC" => 5, "Pizza Hut" => 4, "Pizza Roma" => 4.5, "FFC" => 4]; 98 | 99 | $person1 = 'Adiyan'; 100 | $person2 = 'Arush'; 101 | $person3 = 'Mikhael'; 102 | 103 | echo 'The similarity score calculated with the Pearson Correlation between ' . $person1 . ' and ' . $person2 . ' is: ' . pearsonScore($reviews, $person1, $person2) . '\n'; 104 | echo 'The similarity score calculated with the Pearson Correlation between ' . $person2 . ' and ' . $person3 . ' is: ' . pearsonScore($reviews, $person2, $person3) . '\n'; 105 | 106 | print_r(similarReviewers($reviews, $person1, 2)); 107 | 108 | $person = 'Arush'; 109 | echo 'Restaurant recommendations for ' . $person . "\n"; 110 | $recommendations = getRecommendations($reviews, $person); 111 | foreach ($recommendations as $restaturant => $score) { 112 | echo $restaturant . " \n"; 113 | } 114 | echo '

'; 115 | -------------------------------------------------------------------------------- /Chapter11/11.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | $sparseArray = []; 11 | $sparseArray[0][5] = 1; 12 | $sparseArray[1][0] = 1; 13 | $sparseArray[2][4] = 2; 14 | $sparseArray[3][2] = 2; 15 | $sparseArray[4][6] = 1; 16 | $sparseArray[5][7] = 2; 17 | $sparseArray[6][6] = 1; 18 | $sparseArray[7][1] = 1; 19 | 20 | function getSparseValue(array $array, int $i, int $j): int { 21 | if (isset($array[$i][$j])) 22 | return $array[$i][$j]; 23 | else 24 | return 0; 25 | } 26 | 27 | echo getSparseValue($sparseArray, 0, 2) . "\n"; 28 | echo getSparseValue($sparseArray, 7, 1) . "\n"; 29 | echo getSparseValue($sparseArray, 8, 8) . "\n"; 30 | -------------------------------------------------------------------------------- /Chapter11/2.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function strFindAll(string $pattern, string $txt): array { 11 | $M = strlen($pattern); 12 | $N = strlen($txt); 13 | $positions = []; 14 | 15 | for ($i = 0; $i <= $N - $M; $i++) { 16 | for ($j = 0; $j < $M; $j++) 17 | if ($txt[$i + $j] != $pattern[$j]) 18 | break; 19 | 20 | if ($j == $M) 21 | $positions[] = $i; 22 | } 23 | 24 | return $positions; 25 | } 26 | 27 | $txt = "AABAACAADAABABBBAABAA"; 28 | $pattern = "AABA"; 29 | $matches = strFindAll($pattern, $txt); 30 | 31 | if ($matches) { 32 | foreach ($matches as $pos) { 33 | echo "Pattern found at index : " . $pos . "\n"; 34 | } 35 | } -------------------------------------------------------------------------------- /Chapter11/3.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function KMPStringMatching(string $str, string $pattern): array { 11 | $matches = []; 12 | $M = strlen($pattern); 13 | $N = strlen($str); 14 | $i = $j = 0; 15 | $lps = []; 16 | 17 | ComputeLPS($pattern, $lps); 18 | 19 | while ($i < $N) { 20 | if ($pattern[$j] == $str[$i]) { 21 | $j++; 22 | $i++; 23 | } 24 | 25 | if ($j == $M) { 26 | array_push($matches, $i - $j); 27 | $j = $lps[$j - 1]; 28 | } else if ($i < $N && $pattern[$j] != $str[$i]) { 29 | if ($j != 0) 30 | $j = $lps[$j - 1]; 31 | else 32 | $i = $i + 1; 33 | } 34 | } 35 | return $matches; 36 | } 37 | 38 | function ComputeLPS(string $pattern, array &$lps) { 39 | $len = 0; 40 | $i = 1; 41 | $M = strlen($pattern); 42 | 43 | $lps[0] = 0; 44 | 45 | while ($i < $M) { 46 | if ($pattern[$i] == $pattern[$len]) { 47 | $len++; 48 | $lps[$i] = $len; 49 | $i++; 50 | } else { 51 | if ($len != 0) { 52 | $len = $lps[$len - 1]; 53 | } else { 54 | $lps[$i] = 0; 55 | $i++; 56 | } 57 | } 58 | } 59 | } 60 | 61 | $txt = "AABAACAADAABABBBAABAA"; 62 | $pattern = "AABA"; 63 | $matches = KMPStringMatching($txt, $pattern); 64 | 65 | if ($matches) { 66 | foreach ($matches as $pos) { 67 | echo "Pattern found at index : " . $pos . "\n"; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Chapter11/4.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | 11 | function huffmanEncode(array $symbols): array { 12 | $heap = new SplPriorityQueue; 13 | $heap->setExtractFlags(SplPriorityQueue::EXTR_BOTH); 14 | foreach ($symbols as $symbol => $weight) { 15 | $heap->insert(array($symbol => ''), -$weight); 16 | } 17 | 18 | while ($heap->count() > 1) { 19 | $low = $heap->extract(); 20 | $high = $heap->extract(); 21 | foreach ($low['data'] as &$x) 22 | $x = '0' . $x; 23 | foreach ($high['data'] as &$x) 24 | $x = '1' . $x; 25 | $heap->insert($low['data'] + $high['data'], $low['priority'] + $high['priority']); 26 | } 27 | $result = $heap->extract(); 28 | return $result['data']; 29 | } 30 | 31 | $txt = 'PHP 7 Data structures and Algorithms'; 32 | $symbols = array_count_values(str_split($txt)); 33 | $codes = huffmanEncode($symbols); 34 | echo "Symbol\t\tWeight\t\tHuffman Code\n"; 35 | foreach ($codes as $sym => $code) { 36 | echo "$sym\t\t$symbols[$sym]\t\t$code\n"; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter11/5.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function velocityMagnifier(array $jobs) { 11 | 12 | $n = count($jobs); 13 | usort($jobs, function($opt1, $opt2) { 14 | return $opt1['velocity'] < $opt2['velocity']; 15 | }); 16 | 17 | $dMax = max(array_column($jobs, "deadline")); 18 | 19 | $slot = array_fill(1, $dMax, -1); 20 | $filledTimeSlot = 0; 21 | 22 | for ($i = 0; $i < $n; $i++) { 23 | $k = min($dMax, $jobs[$i]['deadline']); 24 | while ($k >= 1) { 25 | if ($slot[$k] == -1) { 26 | $slot[$k] = $i; 27 | $filledTimeSlot++; 28 | break; 29 | } 30 | $k--; 31 | } 32 | 33 | if ($filledTimeSlot == $dMax) { 34 | break; 35 | } 36 | } 37 | 38 | echo("Stories to Complete: "); 39 | for ($i = 1; $i <= $dMax; $i++) { 40 | echo $jobs[$slot[$i]]['id']; 41 | 42 | if ($i < $dMax) { 43 | echo "\t"; 44 | } 45 | } 46 | 47 | $maxVelocity = 0; 48 | for ($i = 1; $i <= $dMax; $i++) { 49 | $maxVelocity += $jobs[$slot[$i]]['velocity']; 50 | } 51 | echo "\nMax Velocity: " . $maxVelocity; 52 | } 53 | 54 | $jobs = [ 55 | ["id" => "S1", "deadline" => 2, "velocity" => 95], 56 | ["id" => "S2", "deadline" => 1, "velocity" => 32], 57 | ["id" => "S3", "deadline" => 2, "velocity" => 47], 58 | ["id" => "S4", "deadline" => 1, "velocity" => 42], 59 | ["id" => "S5", "deadline" => 3, "velocity" => 28], 60 | ["id" => "S6", "deadline" => 4, "velocity" => 64] 61 | ]; 62 | 63 | velocityMagnifier($jobs); 64 | -------------------------------------------------------------------------------- /Chapter11/6.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | 11 | function knapSack(int $maxWeight, array $weights, array $values, int $n) { 12 | $DP = []; 13 | for ($i = 0; $i <= $n; $i++) { 14 | for ($w = 0; $w <= $maxWeight; $w++) { 15 | if ($i == 0 || $w == 0) 16 | $DP[$i][$w] = 0; 17 | else if ($weights[$i - 1] <= $w) 18 | $DP[$i][$w] = max($values[$i - 1] + $DP[$i - 1][$w - $weights[$i - 1]], $DP[$i - 1][$w]); 19 | else 20 | $DP[$i][$w] = $DP[$i - 1][$w]; 21 | } 22 | } 23 | return $DP[$n][$maxWeight]; 24 | } 25 | 26 | $values = [60, 100, 120, 280, 90]; 27 | $weights = [10, 20, 30, 40, 50]; 28 | $values = [10, 20, 30, 40, 50]; 29 | $weights = [1, 2, 3, 4, 5]; 30 | $maxWeight = 10; 31 | $n = count($values); 32 | echo knapSack($maxWeight, $weights, $values, $n); 33 | -------------------------------------------------------------------------------- /Chapter11/7.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | function LCS(string $X, string $Y): int { 11 | $M = strlen($X); 12 | $N = strlen($Y); 13 | $L = []; 14 | 15 | for ($i = 0; $i <= $M; $i++) 16 | $L[$i][0] = 0; 17 | for ($j = 0; $j <= $N; $j++) 18 | $L[0][$j] = 0; 19 | 20 | for ($i = 0; $i <= $M; $i++) { 21 | for ($j = 0; $j <= $N; $j++) { 22 | if($i == 0 || $j == 0) 23 | $L[$i][$j] = 0; 24 | else if ($X[$i - 1] == $Y[$j - 1]) 25 | $L[$i][$j] = $L[$i - 1][$j - 1] + 1; 26 | else 27 | $L[$i][$j] = max($L[$i - 1][$j], $L[$i][$j - 1]); 28 | } 29 | } 30 | return $L[$M][$N]; 31 | } 32 | 33 | $X = "AGGTAB"; 34 | $Y = "GGTXAYB"; 35 | echo "LCS Length:".LCS( $X, $Y ); -------------------------------------------------------------------------------- /Chapter11/8.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | 11 | define("GC", "-"); 12 | define("SP", 1); 13 | define("GP", -1); 14 | define("MS", -1); 15 | 16 | function NWSquencing(string $s1, string $s2) { 17 | $grid = []; 18 | $M = strlen($s1); 19 | $N = strlen($s2); 20 | 21 | for ($i = 0; $i <= $N; $i++) { 22 | $grid[$i] = []; 23 | for ($j = 0; $j <= $M; $j++) { 24 | $grid[$i][$j] = null; 25 | } 26 | } 27 | $grid[0][0] = 0; 28 | 29 | for ($i = 1; $i <= $M; $i++) { 30 | $grid[0][$i] = -1 * $i; 31 | } 32 | 33 | for ($i = 1; $i <= $N; $i++) { 34 | $grid[$i][0] = -1 * $i; 35 | } 36 | 37 | for ($i = 1; $i <= $N; $i++) { 38 | for ($j = 1; $j <= $M; $j++) { 39 | $grid[$i][$j] = max( 40 | $grid[$i - 1][$j - 1] + ($s2[$i - 1] == $s1[$j - 1] ? SP : MS), $grid[$i - 1][$j] + GP, $grid[$i][$j - 1] + GP 41 | ); 42 | } 43 | } 44 | 45 | printSequence($grid, $s1, $s2, $M, $N); 46 | } 47 | 48 | function printSequence($grid, $s1, $s2, $j, $i) { 49 | $sq1 = []; 50 | $sq2 = []; 51 | $sq3 = []; 52 | 53 | do { 54 | $t = $grid[$i - 1][$j]; 55 | $d = $grid[$i - 1][$j - 1]; 56 | $l = $grid[$i][$j - 1]; 57 | $max = max($t, $d, $l); 58 | 59 | switch ($max) { 60 | 61 | case $d: 62 | $j--; 63 | $i--; 64 | array_push($sq1, $s1[$j]); 65 | array_push($sq2, $s2[$i]); 66 | if ($s1[$j] == $s2[$i]) 67 | array_push($sq3, "|"); 68 | else 69 | array_push($sq3, " "); 70 | break; 71 | case $t: 72 | $i--; 73 | array_push($sq1, GC); 74 | array_push($sq2, $s2[$i]); 75 | array_push($sq3, " "); 76 | break; 77 | 78 | case $l: 79 | $j--; 80 | array_push($sq1, $s1[$j]); 81 | array_push($sq2, GC); 82 | array_push($sq3, " "); 83 | break; 84 | } 85 | } while ($i > 0 && $j > 0); 86 | 87 | echo implode("", array_reverse($sq1)) . "\n"; 88 | echo implode("", array_reverse($sq3)) . "\n"; 89 | echo implode("", array_reverse($sq2)) . "\n"; 90 | } 91 | 92 | $X = "GAATTCAGTTA"; 93 | $Y = "GGATCGA"; 94 | NWSquencing($X, $Y); 95 | -------------------------------------------------------------------------------- /Chapter11/9.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | 11 | define("N", 9); 12 | define("UNASSIGNED", 0); 13 | 14 | function SolveSudoku(array &$grid): bool { 15 | $row = $col = 0; 16 | 17 | if (!FindUnassignedLocation($grid, $row, $col)) 18 | return true; // success! no empty space 19 | 20 | for ($num = 1; $num <= N; $num++) { 21 | if (isSafe($grid, $row, $col, $num)) { 22 | $grid[$row][$col] = $num; // make tentative assignment 23 | 24 | if (SolveSudoku($grid)) 25 | return true; // return, if success// return, if success 26 | 27 | $grid[$row][$col] = UNASSIGNED; // failure, unmake & try again 28 | } 29 | } 30 | return false; // triggers backtracking 31 | } 32 | 33 | function FindUnassignedLocation(array &$grid, int &$row, int &$col): bool { 34 | for ($row = 0; $row < N; $row++) 35 | for ($col = 0; $col < N; $col++) 36 | if ($grid[$row][$col] == UNASSIGNED) 37 | return true; 38 | return false; 39 | } 40 | 41 | function UsedInRow(array &$grid, int $row, int $num): bool { 42 | return in_array($num, $grid[$row]); 43 | } 44 | 45 | function UsedInColumn(array &$grid, int $col, int $num): bool { 46 | return in_array($num, array_column($grid, $col)); 47 | } 48 | 49 | function UsedInBox(array &$grid, int $boxStartRow, int $boxStartCol, int $num):bool { 50 | for ($row = 0; $row < 3; $row++) 51 | for ($col = 0; $col < 3; $col++) 52 | if ($grid[$row + $boxStartRow][$col + $boxStartCol] == $num) 53 | return true; 54 | return false; 55 | } 56 | 57 | function isSafe(array $grid, int $row, int $col, int $num): bool { 58 | 59 | return !UsedInRow($grid, $row, $num) && 60 | !UsedInColumn($grid, $col, $num) && 61 | !UsedInBox($grid, $row - $row % 3, $col - $col % 3, $num); 62 | } 63 | 64 | /* A utility function to print grid */ 65 | 66 | function printGrid(array $grid) { 67 | foreach ($grid as $row) { 68 | echo implode("", $row) . "\n"; 69 | } 70 | } 71 | 72 | /* 73 | $str = []; 74 | 75 | $str[] = "123456780"; 76 | $str[] = "456780123"; 77 | $str[] = "780123456"; 78 | $str[] = "234567801"; 79 | $str[] = "567801234"; 80 | $str[] = "801234567"; 81 | $str[] = "345678012"; 82 | $str[] = "678012345"; 83 | $str[] = "012345678"; 84 | $grid = []; 85 | 86 | foreach($str as $row) 87 | $grid[] = str_split ($row); 88 | */ 89 | 90 | $grid = [ 91 | [0, 0, 7, 0, 3, 0, 8, 0, 0], 92 | [0, 0, 0, 2, 0, 5, 0, 0, 0], 93 | [4, 0, 0, 9, 0, 6, 0, 0, 1], 94 | [0, 4, 3, 0, 0, 0, 2, 1, 0], 95 | [1, 0, 0, 0, 0, 0, 0, 0, 5], 96 | [0, 5, 8, 0, 0, 0, 6, 7, 0], 97 | [5, 0, 0, 1, 0, 8, 0, 0, 9], 98 | [0, 0, 0, 5, 0, 3, 0, 0, 0], 99 | [0, 0, 2, 0, 9, 0, 5, 0, 0] 100 | ]; 101 | 102 | if (SolveSudoku($grid) == true) 103 | printGrid($grid); 104 | else 105 | echo "No solution exists"; -------------------------------------------------------------------------------- /Chapter12/1.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | $inputStr = 'Bingo'; 11 | $fruites = ['Apple', 'Orange', 'Grapes', 'Banana', 'Water melon', 'Mango']; 12 | 13 | $matchScore = -1; 14 | $matchedStr = ''; 15 | 16 | foreach ($fruites as $fruit) { 17 | $tmpScore = levenshtein($inputStr, $fruit); 18 | 19 | if ($tmpScore == 0 || ($matchScore < 0 || $matchScore > $tmpScore)) { 20 | $matchScore = $tmpScore; 21 | $matchedStr = $fruit; 22 | } 23 | } 24 | 25 | echo $matchScore == 0 ? 'Exact match found : ' . $matchedStr : 'Did you mean: ' . $matchedStr . '?\n'; 26 | 27 | 28 | $str1 = "Mango"; 29 | $str2 = "Tango"; 30 | 31 | echo "Match length: " . similar_text($str1, $str2) . "\n"; 32 | similar_text($str1, $str2, $percent); 33 | echo "Percentile match: " . $percent . "%"; 34 | 35 | 36 | $word1 = "Pray"; 37 | $word2 = "Prey"; 38 | echo $word1 . " = " . soundex($word1) . "\n"; 39 | echo $word2 . " = " . soundex($word2) . "\n"; 40 | 41 | $word3 = "There"; 42 | $word4 = "Their"; 43 | echo $word3 . " = " . soundex($word3) . "\n"; 44 | echo $word4 . " = " . soundex($word4) . "\n"; 45 | 46 | 47 | $word1 = "Pray"; 48 | $word2 = "Prey"; 49 | echo $word1 . " = " . metaphone($word1) . "\n"; 50 | echo $word2 . " = " . metaphone($word2) . "\n"; 51 | 52 | $word3 = "There"; 53 | $word4 = "Their"; 54 | echo $word3 . " = " . metaphone($word3) . "\n"; 55 | echo $word4 . " = " . metaphone($word4) . "\n"; 56 | 57 | 58 | $arr = ['file1', 'file2', 'file10', 'file11', 'file3', 'file15', 'file21']; 59 | sort($arr); 60 | echo "Regular Sorting: " . implode(",", $arr)."\n"; 61 | natsort($arr); 62 | echo "Natural Sorting: " . implode(",", $arr); 63 | 64 | 65 | $data = "hello"; 66 | 67 | foreach (hash_algos() as $v) { 68 | $r = hash($v, $data, false); 69 | printf("%-12s %3d %s\n", $v, strlen($r), $r); 70 | } -------------------------------------------------------------------------------- /Chapter12/2.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | $countries = []; 11 | array_push($countries, 'Bangladesh', 'Bhutan'); 12 | 13 | 14 | $countries = ["Bangladesh", "Nepal", "Bhutan"]; 15 | 16 | $key = array_search("Bangladesh", $countries); 17 | if ($key !== FALSE) 18 | echo "Found in: " . $key; 19 | else 20 | echo "Not found"; 21 | 22 | $countries = ["bangladesh", "nepal", "bhutan"]; 23 | $newCountries = array_map(function($country) { 24 | return strtoupper($country); 25 | }, $countries); 26 | 27 | foreach ($newCountries as $country) 28 | echo $country . "\n"; 29 | 30 | $countries = ["bangladesh", "nepal", "bhutan"]; 31 | $newCountries = array_map('strtoupper', $countries); 32 | 33 | foreach ($newCountries as $country) 34 | echo $country . "\n"; 35 | 36 | 37 | $countries = ["bangladesh", "nepal", "bhutan"]; 38 | $top = array_shift($countries); 39 | echo $top; 40 | 41 | $baseNumber = "123456754"; 42 | $newNumber = base_convert($baseNumber, 8, 16); 43 | echo $newNumber; 44 | 45 | 46 | -------------------------------------------------------------------------------- /Chapter12/3.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | $a = new \Ds\Vector([1, 2, 3]); 11 | $b = $a->copy(); 12 | 13 | $b->push(4); 14 | 15 | print_r($a); 16 | print_r($b); 17 | 18 | $vector = new \Ds\Vector(["a", "b", "c"]); 19 | echo $vector->get(1)."\n"; 20 | $vector[1] = "d"; 21 | echo $vector->get(1)."\n"; 22 | $vector->push('f'); 23 | echo "Size of vector: ".$vector->count()."\n"; 24 | 25 | 26 | $set = new \Ds\Set(); 27 | $set->add(1); 28 | $set->add(1); 29 | $set->add("test"); 30 | $set->add(3); 31 | echo $set->get(1); 32 | 33 | -------------------------------------------------------------------------------- /Chapter13/1.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | */ 8 | 9 | $languages = ["php", "python", "java", "c", "erlang"]; 10 | 11 | foreach ($languages as $ind => $language) { 12 | $languages[$ind] = ucfirst($language); 13 | } 14 | 15 | 16 | $languages = array_map('ucfirst', $languages); 17 | 18 | function sum($a, $b, $c) { 19 | return $a + $b + $c; 20 | } 21 | 22 | function currySum($a) { 23 | return function($b) use ($a) { 24 | return function ($c) use ($a, $b) { 25 | return $a + $b + $c; 26 | }; 27 | }; 28 | } 29 | 30 | $sum = currySum(10)(20)(30); 31 | 32 | echo $sum; 33 | 34 | 35 | function partial($funcName, ...$args) { 36 | return function(...$innerArgs) use ($funcName, $args) { 37 | $allArgs = array_merge($args, $innerArgs); 38 | return call_user_func_array($funcName, $allArgs); 39 | }; 40 | } 41 | 42 | $sum = partial("sum", 10, 20); 43 | $sum = $sum(30); 44 | 45 | echo $sum; 46 | -------------------------------------------------------------------------------- /Chapter13/2.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | */ 8 | 9 | require __DIR__ . '/vendor/autoload.php'; 10 | 11 | use Tarsana\Functional as F; 12 | 13 | $stack = []; 14 | 15 | $push = F\append(F\__(), F\__()); 16 | $top = F\last(F\__()); 17 | $pop = F\init(F\__()); 18 | 19 | $stack = $push(1, $stack); 20 | $stack = $push(2, $stack); 21 | $stack = $push(3, $stack); 22 | 23 | echo "Stack is ".F\toString($stack)."\n"; 24 | 25 | $item = $top($stack); 26 | $stack = $pop($stack); 27 | 28 | echo "Pop-ed item: ".$item."\n"; 29 | echo "Stack is ".F\toString($stack)."\n"; 30 | 31 | $stack = $push(4, $stack); 32 | 33 | echo "Stack is ".F\toString($stack)."\n"; 34 | -------------------------------------------------------------------------------- /Chapter13/4.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | */ 8 | 9 | require __DIR__ . '/vendor/autoload.php'; 10 | 11 | use Tarsana\Functional as F; 12 | 13 | $queue = []; 14 | 15 | $enqueue = F\append(F\__(), F\__()); 16 | $head = F\head(F\__()); 17 | $dequeue = F\tail(F\__()); 18 | 19 | $queue = $enqueue(1, $queue); 20 | $queue = $enqueue(2, $queue); 21 | $queue = $enqueue(3, $queue); 22 | 23 | echo "Queue is ".F\toString($queue)."\n"; 24 | 25 | $item = $head($queue); 26 | $queue = $dequeue($queue); 27 | 28 | echo "Dequeue-ed item: ".$item."\n"; 29 | echo "Queue is ".F\toString($queue)."\n"; 30 | 31 | $queue = $enqueue(4, $queue); 32 | 33 | echo "Queue is ".F\toString($queue)."\n"; 34 | -------------------------------------------------------------------------------- /Chapter13/5.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | */ 8 | 9 | 10 | function treeTraverse(array &$tree, int $index = 0, int $level = 0, &$outputStr = "") : ?bool { 11 | 12 | if(isset($tree[$index])) { 13 | $outputStr .= str_repeat("-", $level); 14 | $outputStr .= $tree[$index] . "\n"; 15 | 16 | treeTraverse($tree, 2 * $index + 1, $level+1,$outputStr); 17 | treeTraverse($tree, 2 * ($index + 1), $level+1,$outputStr); 18 | } else { 19 | return false; 20 | } 21 | 22 | return null; 23 | } 24 | 25 | 26 | $nodes = []; 27 | $nodes[] = "Final"; 28 | $nodes[] = "Semi Final 1"; 29 | $nodes[] = "Semi Final 2"; 30 | $nodes[] = "Quarter Final 1"; 31 | $nodes[] = "Quarter Final 2"; 32 | $nodes[] = "Quarter Final 3"; 33 | $nodes[] = "Quarter Final 4"; 34 | 35 | $treeStr = ""; 36 | treeTraverse($nodes,0,0,$treeStr); 37 | echo $treeStr; 38 | 39 | -------------------------------------------------------------------------------- /Chapter13/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "tarsana/functional": "^2.2" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Chapter13/composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "09a79649712b0c06c209e27a07dd46cd", 8 | "packages": [ 9 | { 10 | "name": "tarsana/functional", 11 | "version": "2.2.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/tarsana/functional.git", 15 | "reference": "8e74c6f6ae11ec4ad5f0ee0f8988db6eda45fb25" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/tarsana/functional/zipball/8e74c6f6ae11ec4ad5f0ee0f8988db6eda45fb25", 20 | "reference": "8e74c6f6ae11ec4ad5f0ee0f8988db6eda45fb25", 21 | "shasum": "" 22 | }, 23 | "require-dev": { 24 | "phpunit/phpunit": "~4.0" 25 | }, 26 | "type": "library", 27 | "autoload": { 28 | "psr-4": { 29 | "Tarsana\\Functional\\": "src/Classes/", 30 | "Tarsana\\UnitTests\\Functional\\": "tests/" 31 | }, 32 | "files": [ 33 | "src/Internal/_functions.php", 34 | "src/Internal/_stream.php", 35 | "src/functions.php", 36 | "src/operators.php", 37 | "src/common.php", 38 | "src/object.php", 39 | "src/string.php", 40 | "src/list.php", 41 | "src/math.php" 42 | ] 43 | }, 44 | "notification-url": "https://packagist.org/downloads/", 45 | "license": [ 46 | "MIT" 47 | ], 48 | "authors": [ 49 | { 50 | "name": "Amine Ben hammou", 51 | "email": "webneat@gmail.com" 52 | } 53 | ], 54 | "description": "functional programming library for Tarsana", 55 | "time": "2017-05-14T02:30:25+00:00" 56 | } 57 | ], 58 | "packages-dev": [], 59 | "aliases": [], 60 | "minimum-stability": "stable", 61 | "stability-flags": [], 62 | "prefer-stable": false, 63 | "prefer-lowest": false, 64 | "platform": [], 65 | "platform-dev": [] 66 | } 67 | -------------------------------------------------------------------------------- /Chapter13/vendor/autoload.php: -------------------------------------------------------------------------------- 1 | 7 | * Jordi Boggiano 8 | * 9 | * For the full copyright and license information, please view the LICENSE 10 | * file that was distributed with this source code. 11 | */ 12 | 13 | namespace Composer\Autoload; 14 | 15 | /** 16 | * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. 17 | * 18 | * $loader = new \Composer\Autoload\ClassLoader(); 19 | * 20 | * // register classes with namespaces 21 | * $loader->add('Symfony\Component', __DIR__.'/component'); 22 | * $loader->add('Symfony', __DIR__.'/framework'); 23 | * 24 | * // activate the autoloader 25 | * $loader->register(); 26 | * 27 | * // to enable searching the include path (eg. for PEAR packages) 28 | * $loader->setUseIncludePath(true); 29 | * 30 | * In this example, if you try to use a class in the Symfony\Component 31 | * namespace or one of its children (Symfony\Component\Console for instance), 32 | * the autoloader will first look for the class under the component/ 33 | * directory, and it will then fallback to the framework/ directory if not 34 | * found before giving up. 35 | * 36 | * This class is loosely based on the Symfony UniversalClassLoader. 37 | * 38 | * @author Fabien Potencier 39 | * @author Jordi Boggiano 40 | * @see http://www.php-fig.org/psr/psr-0/ 41 | * @see http://www.php-fig.org/psr/psr-4/ 42 | */ 43 | class ClassLoader 44 | { 45 | // PSR-4 46 | private $prefixLengthsPsr4 = array(); 47 | private $prefixDirsPsr4 = array(); 48 | private $fallbackDirsPsr4 = array(); 49 | 50 | // PSR-0 51 | private $prefixesPsr0 = array(); 52 | private $fallbackDirsPsr0 = array(); 53 | 54 | private $useIncludePath = false; 55 | private $classMap = array(); 56 | private $classMapAuthoritative = false; 57 | private $missingClasses = array(); 58 | private $apcuPrefix; 59 | 60 | public function getPrefixes() 61 | { 62 | if (!empty($this->prefixesPsr0)) { 63 | return call_user_func_array('array_merge', $this->prefixesPsr0); 64 | } 65 | 66 | return array(); 67 | } 68 | 69 | public function getPrefixesPsr4() 70 | { 71 | return $this->prefixDirsPsr4; 72 | } 73 | 74 | public function getFallbackDirs() 75 | { 76 | return $this->fallbackDirsPsr0; 77 | } 78 | 79 | public function getFallbackDirsPsr4() 80 | { 81 | return $this->fallbackDirsPsr4; 82 | } 83 | 84 | public function getClassMap() 85 | { 86 | return $this->classMap; 87 | } 88 | 89 | /** 90 | * @param array $classMap Class to filename map 91 | */ 92 | public function addClassMap(array $classMap) 93 | { 94 | if ($this->classMap) { 95 | $this->classMap = array_merge($this->classMap, $classMap); 96 | } else { 97 | $this->classMap = $classMap; 98 | } 99 | } 100 | 101 | /** 102 | * Registers a set of PSR-0 directories for a given prefix, either 103 | * appending or prepending to the ones previously set for this prefix. 104 | * 105 | * @param string $prefix The prefix 106 | * @param array|string $paths The PSR-0 root directories 107 | * @param bool $prepend Whether to prepend the directories 108 | */ 109 | public function add($prefix, $paths, $prepend = false) 110 | { 111 | if (!$prefix) { 112 | if ($prepend) { 113 | $this->fallbackDirsPsr0 = array_merge( 114 | (array) $paths, 115 | $this->fallbackDirsPsr0 116 | ); 117 | } else { 118 | $this->fallbackDirsPsr0 = array_merge( 119 | $this->fallbackDirsPsr0, 120 | (array) $paths 121 | ); 122 | } 123 | 124 | return; 125 | } 126 | 127 | $first = $prefix[0]; 128 | if (!isset($this->prefixesPsr0[$first][$prefix])) { 129 | $this->prefixesPsr0[$first][$prefix] = (array) $paths; 130 | 131 | return; 132 | } 133 | if ($prepend) { 134 | $this->prefixesPsr0[$first][$prefix] = array_merge( 135 | (array) $paths, 136 | $this->prefixesPsr0[$first][$prefix] 137 | ); 138 | } else { 139 | $this->prefixesPsr0[$first][$prefix] = array_merge( 140 | $this->prefixesPsr0[$first][$prefix], 141 | (array) $paths 142 | ); 143 | } 144 | } 145 | 146 | /** 147 | * Registers a set of PSR-4 directories for a given namespace, either 148 | * appending or prepending to the ones previously set for this namespace. 149 | * 150 | * @param string $prefix The prefix/namespace, with trailing '\\' 151 | * @param array|string $paths The PSR-4 base directories 152 | * @param bool $prepend Whether to prepend the directories 153 | * 154 | * @throws \InvalidArgumentException 155 | */ 156 | public function addPsr4($prefix, $paths, $prepend = false) 157 | { 158 | if (!$prefix) { 159 | // Register directories for the root namespace. 160 | if ($prepend) { 161 | $this->fallbackDirsPsr4 = array_merge( 162 | (array) $paths, 163 | $this->fallbackDirsPsr4 164 | ); 165 | } else { 166 | $this->fallbackDirsPsr4 = array_merge( 167 | $this->fallbackDirsPsr4, 168 | (array) $paths 169 | ); 170 | } 171 | } elseif (!isset($this->prefixDirsPsr4[$prefix])) { 172 | // Register directories for a new namespace. 173 | $length = strlen($prefix); 174 | if ('\\' !== $prefix[$length - 1]) { 175 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 176 | } 177 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 178 | $this->prefixDirsPsr4[$prefix] = (array) $paths; 179 | } elseif ($prepend) { 180 | // Prepend directories for an already registered namespace. 181 | $this->prefixDirsPsr4[$prefix] = array_merge( 182 | (array) $paths, 183 | $this->prefixDirsPsr4[$prefix] 184 | ); 185 | } else { 186 | // Append directories for an already registered namespace. 187 | $this->prefixDirsPsr4[$prefix] = array_merge( 188 | $this->prefixDirsPsr4[$prefix], 189 | (array) $paths 190 | ); 191 | } 192 | } 193 | 194 | /** 195 | * Registers a set of PSR-0 directories for a given prefix, 196 | * replacing any others previously set for this prefix. 197 | * 198 | * @param string $prefix The prefix 199 | * @param array|string $paths The PSR-0 base directories 200 | */ 201 | public function set($prefix, $paths) 202 | { 203 | if (!$prefix) { 204 | $this->fallbackDirsPsr0 = (array) $paths; 205 | } else { 206 | $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; 207 | } 208 | } 209 | 210 | /** 211 | * Registers a set of PSR-4 directories for a given namespace, 212 | * replacing any others previously set for this namespace. 213 | * 214 | * @param string $prefix The prefix/namespace, with trailing '\\' 215 | * @param array|string $paths The PSR-4 base directories 216 | * 217 | * @throws \InvalidArgumentException 218 | */ 219 | public function setPsr4($prefix, $paths) 220 | { 221 | if (!$prefix) { 222 | $this->fallbackDirsPsr4 = (array) $paths; 223 | } else { 224 | $length = strlen($prefix); 225 | if ('\\' !== $prefix[$length - 1]) { 226 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 227 | } 228 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 229 | $this->prefixDirsPsr4[$prefix] = (array) $paths; 230 | } 231 | } 232 | 233 | /** 234 | * Turns on searching the include path for class files. 235 | * 236 | * @param bool $useIncludePath 237 | */ 238 | public function setUseIncludePath($useIncludePath) 239 | { 240 | $this->useIncludePath = $useIncludePath; 241 | } 242 | 243 | /** 244 | * Can be used to check if the autoloader uses the include path to check 245 | * for classes. 246 | * 247 | * @return bool 248 | */ 249 | public function getUseIncludePath() 250 | { 251 | return $this->useIncludePath; 252 | } 253 | 254 | /** 255 | * Turns off searching the prefix and fallback directories for classes 256 | * that have not been registered with the class map. 257 | * 258 | * @param bool $classMapAuthoritative 259 | */ 260 | public function setClassMapAuthoritative($classMapAuthoritative) 261 | { 262 | $this->classMapAuthoritative = $classMapAuthoritative; 263 | } 264 | 265 | /** 266 | * Should class lookup fail if not found in the current class map? 267 | * 268 | * @return bool 269 | */ 270 | public function isClassMapAuthoritative() 271 | { 272 | return $this->classMapAuthoritative; 273 | } 274 | 275 | /** 276 | * APCu prefix to use to cache found/not-found classes, if the extension is enabled. 277 | * 278 | * @param string|null $apcuPrefix 279 | */ 280 | public function setApcuPrefix($apcuPrefix) 281 | { 282 | $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; 283 | } 284 | 285 | /** 286 | * The APCu prefix in use, or null if APCu caching is not enabled. 287 | * 288 | * @return string|null 289 | */ 290 | public function getApcuPrefix() 291 | { 292 | return $this->apcuPrefix; 293 | } 294 | 295 | /** 296 | * Registers this instance as an autoloader. 297 | * 298 | * @param bool $prepend Whether to prepend the autoloader or not 299 | */ 300 | public function register($prepend = false) 301 | { 302 | spl_autoload_register(array($this, 'loadClass'), true, $prepend); 303 | } 304 | 305 | /** 306 | * Unregisters this instance as an autoloader. 307 | */ 308 | public function unregister() 309 | { 310 | spl_autoload_unregister(array($this, 'loadClass')); 311 | } 312 | 313 | /** 314 | * Loads the given class or interface. 315 | * 316 | * @param string $class The name of the class 317 | * @return bool|null True if loaded, null otherwise 318 | */ 319 | public function loadClass($class) 320 | { 321 | if ($file = $this->findFile($class)) { 322 | includeFile($file); 323 | 324 | return true; 325 | } 326 | } 327 | 328 | /** 329 | * Finds the path to the file where the class is defined. 330 | * 331 | * @param string $class The name of the class 332 | * 333 | * @return string|false The path if found, false otherwise 334 | */ 335 | public function findFile($class) 336 | { 337 | // class map lookup 338 | if (isset($this->classMap[$class])) { 339 | return $this->classMap[$class]; 340 | } 341 | if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { 342 | return false; 343 | } 344 | if (null !== $this->apcuPrefix) { 345 | $file = apcu_fetch($this->apcuPrefix.$class, $hit); 346 | if ($hit) { 347 | return $file; 348 | } 349 | } 350 | 351 | $file = $this->findFileWithExtension($class, '.php'); 352 | 353 | // Search for Hack files if we are running on HHVM 354 | if (false === $file && defined('HHVM_VERSION')) { 355 | $file = $this->findFileWithExtension($class, '.hh'); 356 | } 357 | 358 | if (null !== $this->apcuPrefix) { 359 | apcu_add($this->apcuPrefix.$class, $file); 360 | } 361 | 362 | if (false === $file) { 363 | // Remember that this class does not exist. 364 | $this->missingClasses[$class] = true; 365 | } 366 | 367 | return $file; 368 | } 369 | 370 | private function findFileWithExtension($class, $ext) 371 | { 372 | // PSR-4 lookup 373 | $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; 374 | 375 | $first = $class[0]; 376 | if (isset($this->prefixLengthsPsr4[$first])) { 377 | $subPath = $class; 378 | while (false !== $lastPos = strrpos($subPath, '\\')) { 379 | $subPath = substr($subPath, 0, $lastPos); 380 | $search = $subPath.'\\'; 381 | if (isset($this->prefixDirsPsr4[$search])) { 382 | foreach ($this->prefixDirsPsr4[$search] as $dir) { 383 | $length = $this->prefixLengthsPsr4[$first][$search]; 384 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { 385 | return $file; 386 | } 387 | } 388 | } 389 | } 390 | } 391 | 392 | // PSR-4 fallback dirs 393 | foreach ($this->fallbackDirsPsr4 as $dir) { 394 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { 395 | return $file; 396 | } 397 | } 398 | 399 | // PSR-0 lookup 400 | if (false !== $pos = strrpos($class, '\\')) { 401 | // namespaced class name 402 | $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) 403 | . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); 404 | } else { 405 | // PEAR-like class name 406 | $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; 407 | } 408 | 409 | if (isset($this->prefixesPsr0[$first])) { 410 | foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { 411 | if (0 === strpos($class, $prefix)) { 412 | foreach ($dirs as $dir) { 413 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 414 | return $file; 415 | } 416 | } 417 | } 418 | } 419 | } 420 | 421 | // PSR-0 fallback dirs 422 | foreach ($this->fallbackDirsPsr0 as $dir) { 423 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 424 | return $file; 425 | } 426 | } 427 | 428 | // PSR-0 include paths. 429 | if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { 430 | return $file; 431 | } 432 | 433 | return false; 434 | } 435 | } 436 | 437 | /** 438 | * Scope isolated include. 439 | * 440 | * Prevents access to $this/self from included files. 441 | */ 442 | function includeFile($file) 443 | { 444 | include $file; 445 | } 446 | -------------------------------------------------------------------------------- /Chapter13/vendor/composer/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) Nils Adermann, Jordi Boggiano 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /Chapter13/vendor/composer/autoload_classmap.php: -------------------------------------------------------------------------------- 1 | $vendorDir . '/tarsana/functional/src/Internal/_functions.php', 10 | '074162fde8cc05bb516fe2da4bdde1e2' => $vendorDir . '/tarsana/functional/src/Internal/_stream.php', 11 | 'e49490e34f69c2b5dc378287aff873a3' => $vendorDir . '/tarsana/functional/src/functions.php', 12 | '86e6e0fbb8e27bd3acbcdbc4203d813e' => $vendorDir . '/tarsana/functional/src/operators.php', 13 | 'a32120ba94fa97a51d3028c3c72c6a2c' => $vendorDir . '/tarsana/functional/src/common.php', 14 | '828e32b012c9305974510428dface37d' => $vendorDir . '/tarsana/functional/src/object.php', 15 | '2f4f606cc5bf2a20346afa245643e51c' => $vendorDir . '/tarsana/functional/src/string.php', 16 | '67815361e2d72888c0507e858ef42a16' => $vendorDir . '/tarsana/functional/src/list.php', 17 | 'cffc2f002a7818ea4be857a6cb09c019' => $vendorDir . '/tarsana/functional/src/math.php', 18 | ); 19 | -------------------------------------------------------------------------------- /Chapter13/vendor/composer/autoload_namespaces.php: -------------------------------------------------------------------------------- 1 | array($vendorDir . '/tarsana/functional/tests'), 10 | 'Tarsana\\Functional\\' => array($vendorDir . '/tarsana/functional/src/Classes'), 11 | ); 12 | -------------------------------------------------------------------------------- /Chapter13/vendor/composer/autoload_real.php: -------------------------------------------------------------------------------- 1 | = 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); 27 | if ($useStaticLoader) { 28 | require_once __DIR__ . '/autoload_static.php'; 29 | 30 | call_user_func(\Composer\Autoload\ComposerStaticInit162d5f8ec26d0f35f7a435b58f506e91::getInitializer($loader)); 31 | } else { 32 | $map = require __DIR__ . '/autoload_namespaces.php'; 33 | foreach ($map as $namespace => $path) { 34 | $loader->set($namespace, $path); 35 | } 36 | 37 | $map = require __DIR__ . '/autoload_psr4.php'; 38 | foreach ($map as $namespace => $path) { 39 | $loader->setPsr4($namespace, $path); 40 | } 41 | 42 | $classMap = require __DIR__ . '/autoload_classmap.php'; 43 | if ($classMap) { 44 | $loader->addClassMap($classMap); 45 | } 46 | } 47 | 48 | $loader->register(true); 49 | 50 | if ($useStaticLoader) { 51 | $includeFiles = Composer\Autoload\ComposerStaticInit162d5f8ec26d0f35f7a435b58f506e91::$files; 52 | } else { 53 | $includeFiles = require __DIR__ . '/autoload_files.php'; 54 | } 55 | foreach ($includeFiles as $fileIdentifier => $file) { 56 | composerRequire162d5f8ec26d0f35f7a435b58f506e91($fileIdentifier, $file); 57 | } 58 | 59 | return $loader; 60 | } 61 | } 62 | 63 | function composerRequire162d5f8ec26d0f35f7a435b58f506e91($fileIdentifier, $file) 64 | { 65 | if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { 66 | require $file; 67 | 68 | $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Chapter13/vendor/composer/autoload_static.php: -------------------------------------------------------------------------------- 1 | __DIR__ . '/..' . '/tarsana/functional/src/Internal/_functions.php', 11 | '074162fde8cc05bb516fe2da4bdde1e2' => __DIR__ . '/..' . '/tarsana/functional/src/Internal/_stream.php', 12 | 'e49490e34f69c2b5dc378287aff873a3' => __DIR__ . '/..' . '/tarsana/functional/src/functions.php', 13 | '86e6e0fbb8e27bd3acbcdbc4203d813e' => __DIR__ . '/..' . '/tarsana/functional/src/operators.php', 14 | 'a32120ba94fa97a51d3028c3c72c6a2c' => __DIR__ . '/..' . '/tarsana/functional/src/common.php', 15 | '828e32b012c9305974510428dface37d' => __DIR__ . '/..' . '/tarsana/functional/src/object.php', 16 | '2f4f606cc5bf2a20346afa245643e51c' => __DIR__ . '/..' . '/tarsana/functional/src/string.php', 17 | '67815361e2d72888c0507e858ef42a16' => __DIR__ . '/..' . '/tarsana/functional/src/list.php', 18 | 'cffc2f002a7818ea4be857a6cb09c019' => __DIR__ . '/..' . '/tarsana/functional/src/math.php', 19 | ); 20 | 21 | public static $prefixLengthsPsr4 = array ( 22 | 'T' => 23 | array ( 24 | 'Tarsana\\UnitTests\\Functional\\' => 29, 25 | 'Tarsana\\Functional\\' => 19, 26 | ), 27 | ); 28 | 29 | public static $prefixDirsPsr4 = array ( 30 | 'Tarsana\\UnitTests\\Functional\\' => 31 | array ( 32 | 0 => __DIR__ . '/..' . '/tarsana/functional/tests', 33 | ), 34 | 'Tarsana\\Functional\\' => 35 | array ( 36 | 0 => __DIR__ . '/..' . '/tarsana/functional/src/Classes', 37 | ), 38 | ); 39 | 40 | public static function getInitializer(ClassLoader $loader) 41 | { 42 | return \Closure::bind(function () use ($loader) { 43 | $loader->prefixLengthsPsr4 = ComposerStaticInit162d5f8ec26d0f35f7a435b58f506e91::$prefixLengthsPsr4; 44 | $loader->prefixDirsPsr4 = ComposerStaticInit162d5f8ec26d0f35f7a435b58f506e91::$prefixDirsPsr4; 45 | 46 | }, null, ClassLoader::class); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Chapter13/vendor/composer/installed.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "tarsana/functional", 4 | "version": "2.2.0", 5 | "version_normalized": "2.2.0.0", 6 | "source": { 7 | "type": "git", 8 | "url": "https://github.com/tarsana/functional.git", 9 | "reference": "8e74c6f6ae11ec4ad5f0ee0f8988db6eda45fb25" 10 | }, 11 | "dist": { 12 | "type": "zip", 13 | "url": "https://api.github.com/repos/tarsana/functional/zipball/8e74c6f6ae11ec4ad5f0ee0f8988db6eda45fb25", 14 | "reference": "8e74c6f6ae11ec4ad5f0ee0f8988db6eda45fb25", 15 | "shasum": "" 16 | }, 17 | "require-dev": { 18 | "phpunit/phpunit": "~4.0" 19 | }, 20 | "time": "2017-05-14T02:30:25+00:00", 21 | "type": "library", 22 | "installation-source": "dist", 23 | "autoload": { 24 | "psr-4": { 25 | "Tarsana\\Functional\\": "src/Classes/", 26 | "Tarsana\\UnitTests\\Functional\\": "tests/" 27 | }, 28 | "files": [ 29 | "src/Internal/_functions.php", 30 | "src/Internal/_stream.php", 31 | "src/functions.php", 32 | "src/operators.php", 33 | "src/common.php", 34 | "src/object.php", 35 | "src/string.php", 36 | "src/list.php", 37 | "src/math.php" 38 | ] 39 | }, 40 | "notification-url": "https://packagist.org/downloads/", 41 | "license": [ 42 | "MIT" 43 | ], 44 | "authors": [ 45 | { 46 | "name": "Amine Ben hammou", 47 | "email": "webneat@gmail.com" 48 | } 49 | ], 50 | "description": "functional programming library for Tarsana" 51 | } 52 | ] 53 | -------------------------------------------------------------------------------- /Chapter13/vendor/tarsana/functional/build.php: -------------------------------------------------------------------------------- 1 | IO 73 | * @param array $modules 74 | * @return void 75 | */ 76 | function build_main($modules) { 77 | build_init_stream_operations(); 78 | each(_f('build_module'), $modules); 79 | build_close_stream_operations(); 80 | } 81 | 82 | /** 83 | * Writes the header of the stream operations file. 84 | * 85 | * @signature IO 86 | * @return void 87 | */ 88 | function build_init_stream_operations() { 89 | file_put_contents( 90 | 'src/Internal/_stream_operations.php', 91 | " Any -> Any', F\_f('_stream_then')],\n" 92 | ); 93 | file_put_contents( 94 | 'docs/stream-operations.md', 95 | "# Stream Operations" 96 | ); 97 | } 98 | 99 | /** 100 | * Writes the footer of the stream operations file. 101 | * 102 | * @signature IO 103 | * @return void 104 | */ 105 | function build_close_stream_operations() { 106 | file_put_contents( 107 | 'src/Internal/_stream_operations.php', 108 | "\n]);\n", FILE_APPEND 109 | ); 110 | } 111 | 112 | /** 113 | * Extracts the modules files from composer.json. 114 | * 115 | * @signature [String] 116 | * @return array 117 | */ 118 | function get_modules() { 119 | $composer = json_decode(file_get_contents(__DIR__.'/composer.json')); 120 | return $composer->autoload->files; 121 | } 122 | 123 | /** 124 | * Generates unit tests and documentation for a module. 125 | * 126 | * @signature String -> IO 127 | * @param string $path 128 | * @return void 129 | */ 130 | function build_module($path) { 131 | apply(process_of([ 132 | 'module_of', 133 | 'generate_docs', 134 | 'generate_tests', 135 | 'generate_stream_operations', 136 | 'generate_stream_methods', 137 | 'write_module' 138 | ]), [$path]); 139 | } 140 | 141 | /** 142 | * Writes the module's docs and tests. 143 | * 144 | * @signature Module -> IO 145 | * @param object $module 146 | * @return void 147 | */ 148 | function write_module($module) { 149 | if ($module->docs) { 150 | $docsDir = dirname($module->docsPath); 151 | if (!is_dir($docsDir)) 152 | mkdir($docsDir, 0777, true); 153 | file_put_contents($module->docsPath, $module->docs); 154 | } 155 | if ($module->tests) { 156 | $testsDir = dirname($module->testsPath); 157 | if (!is_dir($testsDir)) 158 | mkdir($testsDir, 0777, true); 159 | file_put_contents($module->testsPath, $module->tests); 160 | } 161 | if ($module->streamOperations) { 162 | file_put_contents('src/Internal/_stream_operations.php', $module->streamOperations, FILE_APPEND); 163 | } 164 | if ($module->streamMethods) { 165 | file_put_contents('docs/stream-operations.md', $module->streamMethods, FILE_APPEND); 166 | } 167 | } 168 | 169 | /** 170 | * Creates a module from a path. 171 | * 172 | * @signature String -> Module 173 | * @param string $path 174 | * @return object 175 | */ 176 | function module_of($path) { 177 | return apply(process_of([ 178 | 'fill_name', 179 | 'fill_docs_path', 180 | 'fill_tests_path', 181 | 'fill_blocks' 182 | ]), [(object)['path' => $path]]); 183 | } 184 | 185 | /** 186 | * Fills the name of the Module based on the path. 187 | * 'src/xxx/aaa.php' -> 'aaa' 188 | * 189 | * @signature Module -> Module 190 | * @param object $module 191 | * @return object 192 | */ 193 | function fill_name($module) { 194 | $module->name = apply(pipe(split('/'), last(), split('.'), head()), [$module->path]); 195 | return $module; 196 | } 197 | 198 | /** 199 | * Fills documentation file path based on source file path. 200 | * 'src/xxx.php' -> 'docs/xxx.md' 201 | * 202 | * @signature Module -> Module 203 | * @param object $module 204 | * @return object 205 | */ 206 | function fill_docs_path($module) { 207 | $module->docsPath = replace(['src', '.php'], ['docs', '.md'], $module->path); 208 | return $module; 209 | } 210 | 211 | /** 212 | * Fills tests file path based on source file path. 213 | * 'src/xxx.php' -> 'tests/xxxTest.php' 214 | * 215 | * @signature Module -> Module 216 | * @param object $module 217 | * @return object 218 | */ 219 | function fill_tests_path($module) { 220 | $name = ucfirst(camelCase($module->name)); 221 | $dir = 'tests' . remove(3, dirname($module->path)); 222 | $module->testsPath = "{$dir}/{$name}Test.php"; 223 | return $module; 224 | } 225 | 226 | /** 227 | * Fills the blocks of the Module based on the path. 228 | * 229 | * @signature Module -> Module 230 | * @param array $module 231 | * @return array 232 | */ 233 | function fill_blocks($module) { 234 | $module->blocks = apply(pipe( 235 | prepend('dox -r < '), // "dox -r < src/...php" 236 | 'shell_exec', // "[{...}, ...]" 237 | 'json_decode', // [DoxBlock] 238 | map(_f('make_block')) 239 | // sort() 240 | ), [$module->path]); 241 | return $module; 242 | } 243 | 244 | /** 245 | * Converts a DoxBlock to a Block. 246 | * 247 | * @signature DoxBlock -> Block 248 | * @param object $doxBlock 249 | * @return object 250 | */ 251 | function make_block($doxBlock) { 252 | $tags = groupBy(get('name'), tags_of($doxBlock)); 253 | 254 | $type = 'function'; 255 | if (has('file', $tags)) $type = 'file'; 256 | if (has('class', $tags)) $type = 'class'; 257 | if (has('method', $tags)) $type = 'method'; 258 | 259 | $params = map(function($tag){ 260 | $parts = split(' ', get('value', $tag)); 261 | return [ 262 | 'type' => $parts[0], 263 | 'name' => $parts[1] 264 | ]; 265 | }, get('param', $tags) ?: []); 266 | 267 | $return = getPath(['return', 0, 'value'], $tags); 268 | $signatures = get('signature', $tags); 269 | if ($signatures) 270 | $signatures = map(get('value'), $signatures); 271 | return (object) [ 272 | 'type' => $type, 273 | 'name' => getPath(['ctx', 'name'], $doxBlock), 274 | 'params' => $params, 275 | 'return' => $return, 276 | 'signatures' => $signatures, 277 | 'description' => getPath(['description', 'full'], $doxBlock), 278 | 'summary' => getPath(['description', 'summary'], $doxBlock), 279 | 'internal' => has('internal', $tags), 280 | 'ignore' => has('ignore', $tags), 281 | 'stream' => has('stream', $tags) 282 | // 'code' => get('code', $doxBlock) 283 | ]; 284 | } 285 | 286 | /** 287 | * Returns an array of tags, each having a name and a value. 288 | * 289 | * @signature DoxBlock -> [{name: String, value: String}] 290 | * @param object $doxBlock 291 | * @return array 292 | */ 293 | function tags_of($doxBlock) { 294 | if ($doxBlock->tags) 295 | return map(function($tag){ 296 | return (object) [ 297 | 'name' => $tag->type, 298 | 'value' => $tag->string 299 | ]; 300 | }, $doxBlock->tags); 301 | return []; 302 | } 303 | 304 | /** 305 | * Generates documentation contents for a module. 306 | * 307 | * @signature Module -> Module 308 | * @param object $module 309 | * @return object 310 | */ 311 | function generate_docs($module) { 312 | $module->docs = ''; 313 | if (startsWith('_', $module->name)) 314 | return $module; 315 | return apply(process_of([ 316 | 'generate_docs_header', 317 | 'generate_docs_sommaire', 318 | 'generate_docs_contents' 319 | ]), [$module]); 320 | } 321 | 322 | /** 323 | * Generates documentation header. 324 | * 325 | * @signature Module -> Module 326 | * @param object $module 327 | * @return object 328 | */ 329 | function generate_docs_header($module) { 330 | $name = $module->name; 331 | $description = get('description', head($module->blocks)); 332 | $module->docs .= "# {$name}\n\n{$description}\n\n"; 333 | return $module; 334 | } 335 | 336 | /** 337 | * Generates documentation table of contents. 338 | * 339 | * @signature Module -> Module 340 | * @param object $module 341 | * @return object 342 | */ 343 | function generate_docs_sommaire($module) { 344 | $blocks = filter ( 345 | satisfiesAll(['ignore' => not(), 'internal' => not(), 'type' => equals('function')]), 346 | $module->blocks 347 | ); 348 | $items = map(_f('generate_docs_sommaire_item'), $blocks); 349 | $module->docs .= join('', $items); 350 | return $module; 351 | } 352 | 353 | /** 354 | * Generates an item of the documentation's table of contents. 355 | * 356 | * @signature Block -> String 357 | * @param object $block 358 | * @return string 359 | */ 360 | function generate_docs_sommaire_item($block) { 361 | $title = get('name', $block); 362 | $link = lowerCase($title); 363 | return "- [{$title}](#{$link}) - {$block->summary}\n\n"; 364 | } 365 | 366 | /** 367 | * Generates documentation contents. 368 | * 369 | * @signature Module -> Module 370 | * @param object $module 371 | * @return object 372 | */ 373 | function generate_docs_contents($module) { 374 | $blocks = filter ( 375 | satisfiesAll(['ignore' => not(), 'internal' => not()]), 376 | $module->blocks 377 | ); 378 | $contents = map(_f('generate_docs_contents_item'), $blocks); 379 | $module->docs .= join('', $contents); 380 | return $module; 381 | } 382 | 383 | /** 384 | * Generates an item of the documentation's contents. 385 | * 386 | * @signature Block -> String 387 | * @param object $block 388 | * @return string 389 | */ 390 | function generate_docs_contents_item($block) { 391 | if ($block->type != 'function') 392 | return ''; 393 | $params = join(', ', map(pipe(values(), join(' ')), get('params', $block))); 394 | $return = get('return', $block); 395 | $prototype = "```php\n{$block->name}({$params}) : {$return}\n```\n\n"; 396 | $signature = ''; 397 | $blockSignature = join("\n", $block->signatures); 398 | if ($blockSignature) 399 | $signature = "```\n{$blockSignature}\n```\n\n"; 400 | return "# {$block->name}\n\n{$prototype}{$signature}{$block->description}\n\n"; 401 | } 402 | 403 | /** 404 | * Generates tests contents for a module. 405 | * 406 | * @signature Module -> Module 407 | * @param object $module 408 | * @return object 409 | */ 410 | function generate_tests($module) { 411 | $module->tests = ''; 412 | $module->testsFooter = ''; 413 | return apply(process_of([ 414 | 'generate_tests_header', 415 | 'generate_tests_contents', 416 | 'generate_tests_footer' 417 | ]), [$module]); 418 | } 419 | 420 | /** 421 | * Generates module's tests header. 422 | * 423 | * @signature Module -> Module 424 | * @param object $module 425 | * @return object 426 | */ 427 | function generate_tests_header($module) { 428 | $namespace = "Tarsana\UnitTests\Functional"; 429 | $additionalNamespace = replace("/", "\\", remove(6, dirname($module->testsPath))); 430 | if ($additionalNamespace) 431 | $namespace .= "\\" . $additionalNamespace; 432 | $name = remove(-4, last(split("/", $module->testsPath))); 433 | $module->tests .= " Module 441 | * @param object $module 442 | * @return object 443 | */ 444 | function generate_tests_contents($module) { 445 | $blocks = filter ( 446 | satisfiesAll(['ignore' => not()]), 447 | $module->blocks 448 | ); 449 | $contents = join("\n", map(function($block) use($module) { 450 | return generate_tests_contents_item($block, $module); 451 | }, $blocks)); 452 | if (trim($contents) != '') 453 | $module->tests .= $contents; 454 | else 455 | $module->tests = ''; 456 | return $module; 457 | } 458 | 459 | /** 460 | * Generates a test for a module. 461 | * 462 | * @signature Block -> Module -> String 463 | * @param object $block 464 | * @param object $module 465 | * @return string 466 | */ 467 | function generate_tests_contents_item($block, $module) { 468 | if ($block->type != 'function') 469 | return ''; 470 | 471 | $code = apply(pipe( 472 | _f('code_from_description'), 473 | chunks("\"\"''{}[]()", "\n"), 474 | map(function($part) use($module) { 475 | return add_assertions($part, $module); 476 | }), 477 | filter(pipe('trim', notEq(''))), 478 | chain(split("\n")), 479 | map(prepend("\t\t")), 480 | join("\n") 481 | ), [$block]); 482 | 483 | if ('' == trim($code)) 484 | return ''; 485 | return prepend("\tpublic function test_{$block->name}() {\n", 486 | append("\n\t}\n", $code) 487 | ); 488 | } 489 | 490 | /** 491 | * Extracts the code snippet from the description of a block. 492 | * 493 | * @signature Block -> String 494 | * @param object $block 495 | * @return string 496 | */ 497 | function code_from_description($block) { 498 | $description = get('description', $block); 499 | if (!contains('```php', $description)) 500 | return ''; 501 | $code = remove(7 + indexOf('```php', $description), $description); 502 | return remove(-4, trim($code)); 503 | } 504 | 505 | /** 506 | * Adds assertions to a part of the code. 507 | * 508 | * @signature String -> String 509 | * @param string $part 510 | * @return string 511 | */ 512 | function add_assertions($part, $module) { 513 | if (contains('; //=> ', $part)) { 514 | $pieces = split('; //=> ', $part); 515 | $part = "\$this->assertEquals({$pieces[1]}, {$pieces[0]});"; 516 | } 517 | elseif (contains('; // throws ', $part)) { 518 | $pieces = split('; // throws ', $part); 519 | $variables = match('/ \$[0-9a-zA-Z_]+/', $pieces[0]); 520 | $use = ''; 521 | if (length($variables)) { 522 | $variables = join(', ', map('trim', $variables)); 523 | $use = "use({$variables}) "; 524 | } 525 | return "\$this->assertErrorThrown(function() {$use}{\n\t$pieces[0]; \n},\n{$pieces[1]});"; 526 | } 527 | elseif (startsWith('class ', $part) || startsWith('function ', $part)) { 528 | $module->testsFooter .= $part . "\n\n"; 529 | $part = ''; 530 | } 531 | return $part; 532 | } 533 | 534 | /** 535 | * Generates module's tests footer. 536 | * 537 | * @signature Module -> Module 538 | * @param object $module 539 | * @return object 540 | */ 541 | function generate_tests_footer($module) { 542 | if ($module->tests) 543 | $module->tests .= "}\n\n{$module->testsFooter}"; 544 | return $module; 545 | } 546 | 547 | /** 548 | * Generates module's stream operations. 549 | * 550 | * @signature Module -> Module 551 | * @param array $module 552 | * @return array 553 | */ 554 | function generate_stream_operations($module) { 555 | $blocks = filter ( 556 | satisfiesAll(['ignore' => equals(false), 'stream' => equals(true)]), 557 | $module->blocks 558 | ); 559 | $operations = map(_f('stream_operation_declaration'), chain(_f('stream_operations_of_block'), $blocks)); 560 | $module->streamOperations = join("", $operations); 561 | return $module; 562 | } 563 | 564 | /** 565 | * Gets stream operations from a block. 566 | * 567 | * @signature Block -> [Operation] 568 | * @param object $block 569 | * @return string 570 | */ 571 | function stream_operations_of_block($block) { 572 | return map(function($signature) use($block) { 573 | return (object) [ 574 | 'name' => $block->name, 575 | 'signature' => normalize_signature($signature) 576 | ]; 577 | }, get('signatures', $block)); 578 | } 579 | 580 | /** 581 | * Converts a formal signature to a stream signature. 582 | * [a] becomes List 583 | * {k: v} becomes Array|Object 584 | * (a -> b) becomes Function 585 | * * becomes Any 586 | * 587 | * @signature String -> String 588 | * @param string $signature 589 | * @return string 590 | */ 591 | function normalize_signature($signature) { 592 | // This is not the best way to do it :P 593 | return join(' -> ', map(pipe( 594 | regReplace('/Maybe\([a-z][^\)]*\)/', 'Any'), 595 | regReplace('/Maybe\(([^\)]+)\)/', '$1|Null'), 596 | regReplace('/\([^\)]+\)/', 'Function'), 597 | regReplace('/\[[^\]]+\]/', 'List'), 598 | regReplace('/\{[^\}]+\}/', 'Object|Array'), 599 | regReplace('/^.$/', 'Any'), 600 | regReplace('/[\(\)\[\]\{\}]/', '') 601 | ), chunks('(){}', ' -> ', $signature))); 602 | } 603 | 604 | /** 605 | * Converts a stream operation to declaration array. 606 | * 607 | * @signature Operation -> String 608 | * @param object $operation 609 | * @return string 610 | */ 611 | function stream_operation_declaration($operation) { 612 | $name = rtrim($operation->name, '_'); 613 | return "\t['{$name}', '{$operation->signature}', F\\{$operation->name}()],\n"; 614 | } 615 | 616 | /** 617 | * Generates module's stream methods documentation. 618 | * 619 | * @signature Module -> Module 620 | * @param array $module 621 | * @return array 622 | */ 623 | function generate_stream_methods($module) { 624 | $blocks = filter ( 625 | satisfiesAll(['ignore' => equals(false), 'stream' => equals(true)]), 626 | $module->blocks 627 | ); 628 | $methods = map(stream_method_link($module->name), $blocks); 629 | $module->streamMethods = (length($methods) > 0) 630 | ? "\n\n## {$module->name}\n\n" . join("\n", $methods) 631 | : ''; 632 | return $module; 633 | } 634 | 635 | /** 636 | * Gets an element of the stream methods list. 637 | * 638 | * @signature String -> Block -> String 639 | * @param string $moduleName 640 | * @param object $block 641 | * @return string 642 | */ 643 | function stream_method_link() { 644 | static $curried = false; 645 | $curried = $curried ?: curry(function($moduleName, $block) { 646 | return "- [{$block->name}](https://github.com/tarsana/functional/blob/master/docs/{$moduleName}.md#{$block->name}) - {$block->summary}\n"; 647 | }); 648 | return _apply($curried, func_get_args()); 649 | } 650 | 651 | /** 652 | * process_of(['f1', 'f2']) == pipe(_f('f1'), _f('f2')); 653 | * 654 | * @signature [String] -> Function 655 | * @param array $fns 656 | * @return callable 657 | */ 658 | function process_of($fns) { 659 | return apply(_f('pipe'), map(_f('_f'), $fns)); 660 | } 661 | 662 | /** 663 | * Dump a variable and returns it. 664 | * 665 | * @signature a -> a 666 | * @param mixed $something 667 | * @return mixed 668 | */ 669 | function log() { 670 | $log = function($something) { 671 | echo toString($something); 672 | return $something; 673 | }; 674 | return apply(curry($log), func_get_args()); 675 | } 676 | 677 | // Convert Warnings to Exceptions 678 | set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) { 679 | if (0 === error_reporting()) 680 | return false; 681 | throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); 682 | }); 683 | 684 | // Run the build 685 | build_main(get_modules()); 686 | -------------------------------------------------------------------------------- /Chapter13/vendor/tarsana/functional/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tarsana/functional", 3 | "description": "functional programming library for Tarsana", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Amine Ben hammou", 9 | "email": "webneat@gmail.com" 10 | } 11 | ], 12 | "autoload": { 13 | "psr-4": { 14 | "Tarsana\\Functional\\": "src/Classes/", 15 | "Tarsana\\UnitTests\\Functional\\": "tests/" 16 | }, 17 | "files": [ 18 | "src/Internal/_functions.php", 19 | "src/Internal/_stream.php", 20 | "src/functions.php", 21 | "src/operators.php", 22 | "src/common.php", 23 | "src/object.php", 24 | "src/string.php", 25 | "src/list.php", 26 | "src/math.php" 27 | ] 28 | }, 29 | "require-dev": { 30 | "phpunit/phpunit": "~4.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ## $5 Tech Unlocked 2021! 5 | [Buy and download this Book for only $5 on PacktPub.com](https://www.packtpub.com/product/php-7-data-structures-and-algorithms/9781786463890) 6 | ----- 7 | *If you have read this book, please leave a review on [Amazon.com](https://www.amazon.com/gp/product/178646389X). Potential readers can then use your unbiased opinion to help them make purchase decisions. Thank you. The $5 campaign runs from __December 15th 2020__ to __January 13th 2021.__* 8 | 9 | # PHP 7 Data Structures and Algorithms 10 | This is the code repository for [PHP 7 Data Structures and Algorithms](https://www.packtpub.com/application-development/php-7-data-structures-and-algorithms?utm_source=github&utm_medium=repository&utm_campaign=9781786463890), published by [Packt](https://www.packtpub.com/?utm_source=github). It contains all the supporting project files necessary to work through the book from start to finish. 11 | ## About the Book 12 | PHP has always been the go-to language for web based application development, but there are materials and resources you can refer to to see how it works. Data structures and algorithms help you to code and execute them effectively, cutting down on processing time significantly. 13 | ## Instructions and Navigation 14 | All of the code is organized into folders. Each folder starts with a number followed by the application name. For example, Chapter02. 15 | 16 | All chapters contain code files. 17 | 18 | The code will look like the following: 19 | ``` 20 | [default] 21 | class TreeNode { 22 | public $data = NULL; 23 | public $children = []; 24 | public function __construct(string $data = NULL) { 25 | $this->data = $data; 26 | } 27 | public function addChildren(TreeNode $node) { 28 | $this->children[] = $node; 29 | } 30 | } 31 | ``` 32 | 33 | All you need to have is the latest PHP version (minimum requirement is PHP 7.x) installed 34 | on your machine. You can run the examples from a command line, which does not require a 35 | web server. However, if you want, you can install Apache or Nginx, or the following: 36 | PHP 7.x+, 37 | Nginx/apache (optional), 38 | PHP IDE or code editor. 39 | 40 | ## Related Products 41 | * [Learning PHP 7](https://www.packtpub.com/application-development/learning-php-7?utm_source=github&utm_medium=repository&utm_campaign=9781785880544) 42 | 43 | * [Learning PHP 7 High Performance](https://www.packtpub.com/application-development/learning-php-7-high-performance?utm_source=github&utm_medium=repository&utm_campaign=9781785882265) 44 | 45 | * [Modular Programming with PHP 7](https://www.packtpub.com/application-development/modular-programming-php-7?utm_source=github&utm_medium=repository&utm_campaign=9781786462954) 46 | 47 | ### Download a free PDF 48 | 49 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
50 |

https://packt.link/free-ebook/9781786463890

--------------------------------------------------------------------------------