Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/reusable-CI-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ jobs:
uses: yoanm/.github/.github/workflows/reusable-CI-for-PHP.yml@v1
with:
supported-versions-file-path: .supported-versions.json
with-phpstan: true
with-functional-tests-coverage: false # no functional tests (yet!)
23 changes: 22 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ configure:

# Project tests
.PHONY: test
test: test-unit test-functional codestyle
test: test-unit test-functional codestyle phpstan

.PHONY: coverage
coverage:
Expand Down Expand Up @@ -102,6 +102,27 @@ codestyle: create-build-directories
codestyle-fix:
./vendor/bin/phpcbf ${PHPCS_DISABLE_WARNING_OPTION} ${PHPCS_STANDARD_OPTION} ${PHPCS_COLOR_OPTION} ${PHPCS_REPORT_FILE_OPTION}

.PHONY: phpstan
phpstan: phpstan-sources phpstan-tests

.PHONY: phpstan-sources
phpstan-sources:
XDEBUG_MODE=off ./vendor/bin/phpstan analyse --error-format=table

.PHONY: phpstan-tests
phpstan-tests:
XDEBUG_MODE=off ./vendor/bin/phpstan analyse --configuration tests/phpstan-tests.neon.dist --error-format=table


.PHONY: phpstan-update-sources-baseline
phpstan-update-sources-baseline:
XDEBUG_MODE=off ./vendor/bin/phpstan analyse --generate-baseline=tests/phpstan-baseline.neon

.PHONY: phpstan-update-tests-baseline
phpstan-update-tests-baseline:
XDEBUG_MODE=off ./vendor/bin/phpstan analyse --configuration tests/phpstan-tests.neon.dist --generate-baseline=tests/phpstan-tests-baseline.neon


# Internal commands
.PHONY: create-build-directories
create-build-directories:
Expand Down
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
"php": "^8.0"
},
"require-dev": {
"jangregor/phpstan-prophecy": "^2.2",
"phpspec/prophecy": "^1.22",
"phpspec/prophecy-phpunit": "^2.4",
"phpstan/phpstan": "^2.1",
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^9.6",
"squizlabs/php_codesniffer": "^4.0",
"yoanm/php-unit-extended": "^2.0"
Expand Down
14 changes: 14 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
includes:
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
- vendor/jangregor/phpstan-prophecy/extension.neon
- tests/phpstan-baseline.neon

parameters:
phpVersion: 80100
level: 9
paths:
- ./src

bootstrapFiles:
- vendor/autoload.php
61 changes: 37 additions & 24 deletions src/Algorithm/BinarySearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

namespace Yoanm\CommonDSA\Algorithm;

use ArrayAccess;

class BinarySearch
{
/**
Expand All @@ -21,34 +19,39 @@ class BinarySearch
* SC: 𝑂⟮𝟷⟯ - Constant extra space
*
*
* @param list<int|float>|ArrayAccess<int, int|float> $list ⚠ Must be sorted in non-decreasing order (min→max)!<br>
* May contain duplicates.
* @param int|float $target
* @param int $lowIdx Lookup start index.<br>
* Default to 0 (head index).
* @param int|null $highIdx Lookup end index.<br>
* @template TValue of (int|float)
*
*
* @param array<int|float> $list ⚠ Must be a 0 indexed list, 0 to n consecutive indexes, sorted in non-decreasing
* order (min→max)!<br>
* May contain duplicates.
* @phpstan-param list<TValue> $list
* @phpstan-param TValue $target
* @param int $headIdx Lookup start index.<br>
* Default to 0 (head index).
* @param int|null $tailIdx Lookup end index.<br>
* Default to tail index
*
* @return int Index where $target has been found, -1 if not found
*/
public static function find(
array|ArrayAccess $list,
array $list,
int|float $target,
int $lowIdx = 0,
int|null $highIdx = null,
int $headIdx = 0,
int|null $tailIdx = null,
): int {
$highIdx ??= count($list) - 1;
$tailIdx ??= count($list) - 1;

while ($lowIdx <= $highIdx) {
while ($headIdx <= $tailIdx) {
// Prevent ($lowIdx + $highIdx) overflow !
$midIdx = $lowIdx + (($highIdx - $lowIdx) >> 1);
$midIdx = $headIdx + (($tailIdx - $headIdx) >> 1);

if ($list[$midIdx] < $target) {
// Current value is too small ? => Ignore left side and current
$lowIdx = $midIdx + 1;
$headIdx = $midIdx + 1;
} elseif ($list[$midIdx] > $target) {
// Current value is greater ? => Ignore right side and current
$highIdx = $midIdx - 1;
$tailIdx = $midIdx - 1;
} else {
return $midIdx;
}
Expand All @@ -70,9 +73,14 @@ public static function find(
* SC: 𝑂⟮𝟷⟯ - Constant extra space
*
*
* @param list<int|float>|ArrayAccess<int, int|float> $list ⚠ Must be sorted in non-decreasing order (min→max)!<br>
* May contain duplicates.
* @param int|float $target
* @template TValue of (int|float)
*
*
* @param array<int|float> $list ⚠ Must be a 0 indexed list, 0 to n consecutive indexes, sorted in non-decreasing
* order (min→max)!<br>
* May contain duplicates.
* @phpstan-param list<TValue> $list
* @phpstan-param TValue $target
* @param int $lowIdx Lookup start index.<br>
* Default to 0 (head index).
* @param int|null $highIdx Lookup end index.<br>
Expand All @@ -82,7 +90,7 @@ public static function find(
* ⚠ Might be beyond $list current indexes if $target is greater than tail value !
*/
public static function lowerBound(
array|ArrayAccess $list,
array $list,
int|float $target,
int $lowIdx = 0,
int|null $highIdx = null,
Expand Down Expand Up @@ -119,9 +127,14 @@ public static function lowerBound(
* SC: 𝑂⟮𝟷⟯ - Constant extra space
*
*
* @param list<int|float>|ArrayAccess<int, int|float> $list ⚠ Must be sorted in non-decreasing order (min→max)!<br>
* May contain duplicates.
* @param int|float $target
* @template TValue of (int|float)
*
*
* @param array<int|float> $list ⚠ Must be a 0 indexed list, 0 to n consecutive indexes, sorted in non-decreasing
* order (min→max)!<br>
* May contain duplicates.
* @phpstan-param list<TValue> $list
* @phpstan-param TValue $target
* @param int $lowIdx Lookup start index.<br>
* Default to 0 (head index).
* @param int|null $highIdx Lookup end index.<br>
Expand All @@ -131,7 +144,7 @@ public static function lowerBound(
* ⚠ Might be beyond $list current indexes if $target is greater than or equal to tail value !
*/
public static function upperBound(
array|ArrayAccess $list,
array $list,
int|float $target,
int $lowIdx = 0,
int|null $highIdx = null,
Expand Down
Empty file added tests/phpstan-baseline.neon
Empty file.
Empty file.
17 changes: 17 additions & 0 deletions tests/phpstan-tests.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
includes:
- ../vendor/phpstan/phpstan-phpunit/extension.neon
- ../vendor/phpstan/phpstan-phpunit/rules.neon
- ../vendor/jangregor/phpstan-prophecy/extension.neon
- ./phpstan-tests-baseline.neon

parameters:
phpVersion: 80100
level: 9
paths:
- .
ignoreErrors:
- identifier: missingType.iterableValue # Pretty useless for tests !
- identifier: argument.type # Too heavy if everything has to be fully typed !

bootstrapFiles:
- ../vendor/autoload.php