├── 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 = "";
73 | foreach ($comments[$n] as $comment) {
74 | $str .= "- ";
77 |
78 | $str .= displayComment($comments, $comment->id);
79 |
80 | $str .= "
";
81 | }
82 |
83 | $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
--------------------------------------------------------------------------------