IntegerTest.php 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573
  1. <?php
  2. namespace MathPHP\Tests\NumberTheory;
  3. use MathPHP\NumberTheory\Integer;
  4. use MathPHP\Exception;
  5. class IntegerTest extends \PHPUnit\Framework\TestCase
  6. {
  7. /**
  8. * @test isPerfectNumber
  9. * @dataProvider dataProviderForPerfectNumbers
  10. * @param int $n
  11. */
  12. public function testIsPerfectNumber(int $n)
  13. {
  14. // When
  15. $isPerfectNumber = Integer::isPerfectNumber($n);
  16. // Then
  17. $this->assertTrue($isPerfectNumber);
  18. }
  19. /**
  20. * @see https://oeis.org/A000396
  21. * @return array
  22. */
  23. public function dataProviderForPerfectNumbers(): array
  24. {
  25. return [
  26. [6],
  27. [28],
  28. [496],
  29. [8128],
  30. [33550336],
  31. [8589869056],
  32. [137438691328],
  33. ];
  34. }
  35. /**
  36. * @test isPerfectNumber is not a perfect number
  37. * @dataProvider dataProviderForNonPerfectNumbers
  38. * @dataProvider dataProviderForAbundantNumbers
  39. * @dataProvider dataProviderForDeficientNumbers
  40. * @dataProvider dataProviderForPrimeFactorizationOutOfBoundsException
  41. * @param int $n
  42. */
  43. public function testIsNotPerfectNumber(int $n)
  44. {
  45. // When
  46. $isPerfectNumber = Integer::isPerfectNumber($n);
  47. // Then
  48. $this->assertFalse($isPerfectNumber);
  49. }
  50. /**
  51. * @return array
  52. */
  53. public function dataProviderForNonPerfectNumbers(): array
  54. {
  55. return [
  56. [-1],
  57. [0],
  58. [1],
  59. [2],
  60. [3],
  61. [4],
  62. [5],
  63. [7],
  64. [8],
  65. [9],
  66. [10],
  67. [26],
  68. [498],
  69. [8124],
  70. [23550336],
  71. [2589869056],
  72. [133438691328],
  73. ];
  74. }
  75. /**
  76. * @test isAbundantNumber returns true if n is an abundant number
  77. * @dataProvider dataProviderForAbundantNumbers
  78. * @param int $n
  79. * @throws \Exception
  80. */
  81. public function testIsAbundantNumber(int $n)
  82. {
  83. // When
  84. $isAbundantNumber = Integer::isAbundantNumber($n);
  85. // Then
  86. $this->assertTrue($isAbundantNumber);
  87. }
  88. /**
  89. * A005101 abundant numbers: numbers n such that σ₁(n) > 2n
  90. * @see https://oeis.org/A005101
  91. * @return array
  92. */
  93. public function dataProviderForAbundantNumbers(): array
  94. {
  95. return [
  96. [12],
  97. [18],
  98. [20],
  99. [24],
  100. [30],
  101. [36],
  102. [40],
  103. [42],
  104. [48],
  105. [54],
  106. [56],
  107. [60],
  108. [66],
  109. [70],
  110. [72],
  111. [78],
  112. [80],
  113. [84],
  114. [88],
  115. [90],
  116. [96],
  117. [100],
  118. [102],
  119. [104],
  120. [270],
  121. ];
  122. }
  123. /**
  124. * @test isNotAbundantNumber returns true if n is not an abundant number
  125. * @dataProvider dataProviderForDeficientNumbers
  126. * @dataProvider dataProviderForPerfectNumbers
  127. * @dataProvider dataProviderForPrimeFactorizationOutOfBoundsException
  128. * @param int $n
  129. * @throws \Exception
  130. */
  131. public function testIsNotAbundantNumber(int $n)
  132. {
  133. // When
  134. $isAbundantNumber = Integer::isAbundantNumber($n);
  135. // Then
  136. $this->assertFalse($isAbundantNumber);
  137. }
  138. /**
  139. * @test isDeficientNumber returns true if n is a deficient number
  140. * @dataProvider dataProviderForDeficientNumbers
  141. * @param int $n
  142. * @throws \Exception
  143. */
  144. public function testIsDeficientNumber(int $n)
  145. {
  146. // When
  147. $isDeficientNumber = Integer::isDeficientNumber($n);
  148. // Then
  149. $this->assertTrue($isDeficientNumber);
  150. }
  151. /**
  152. * A005100 deficient numbers: numbers n such that σ₁(n) < 2n
  153. * @see https://oeis.org/A005100
  154. * @return array
  155. */
  156. public function dataProviderForDeficientNumbers(): array
  157. {
  158. return [
  159. [1],
  160. [2],
  161. [3],
  162. [4],
  163. [5],
  164. [7],
  165. [8],
  166. [9],
  167. [10],
  168. [11],
  169. [13],
  170. [14],
  171. [15],
  172. [16],
  173. [17],
  174. [19],
  175. [21],
  176. [22],
  177. [23],
  178. [25],
  179. [26],
  180. [27],
  181. [29],
  182. [31],
  183. [32],
  184. ];
  185. }
  186. /**
  187. * @test isNotDeficientNumber returns true if n is not a deficient number
  188. * @dataProvider dataProviderForAbundantNumbers
  189. * @dataProvider dataProviderForPerfectNumbers
  190. * @dataProvider dataProviderForPrimeFactorizationOutOfBoundsException
  191. * @param int $n
  192. * @throws \Exception
  193. */
  194. public function testIsNotDeficientNumber(int $n)
  195. {
  196. // When
  197. $isDeficientNumber = Integer::isDeficientNumber($n);
  198. // Then
  199. $this->assertFalse($isDeficientNumber);
  200. }
  201. /**
  202. * @test isRefactorableNumber returns true if n is a refactorable number
  203. * @dataProvider dataProviderForRefactorableNumbers
  204. * @param int $n
  205. * @throws \Exception
  206. */
  207. public function testIsRefactorableNumber(int $n)
  208. {
  209. // When
  210. $isRefactorableNumber = Integer::isRefactorableNumber($n);
  211. // Then
  212. $this->assertTrue($isRefactorableNumber);
  213. }
  214. /**
  215. * A033950 Refactorable numbers: number of divisors of n divides n. Also known as tau numbers.
  216. * @see https://oeis.org/A033950
  217. * @return array
  218. */
  219. public function dataProviderForRefactorableNumbers(): array
  220. {
  221. return [
  222. [1],
  223. [2],
  224. [8],
  225. [9],
  226. [12],
  227. [18],
  228. [24],
  229. [36],
  230. [40],
  231. [56],
  232. [60],
  233. [72],
  234. [80],
  235. [84],
  236. [88],
  237. ];
  238. }
  239. /**
  240. * @test isNotRefactorableNumber returns true if n is not a refactorable number
  241. * @dataProvider dataProviderForNonRefactorableNumbers
  242. * @param int $n
  243. * @throws \Exception
  244. */
  245. public function testIsNotRefactorableNumber(int $n)
  246. {
  247. // When
  248. $isRefactorableNumber = Integer::isRefactorableNumber($n);
  249. // Then
  250. $this->assertFalse($isRefactorableNumber);
  251. }
  252. /**
  253. * @return array
  254. */
  255. public function dataProviderForNonRefactorableNumbers(): array
  256. {
  257. return [
  258. [-1],
  259. [0],
  260. [3],
  261. [10],
  262. [13],
  263. [17],
  264. ];
  265. }
  266. /**
  267. * @test testIsSphenicNumber
  268. * @dataProvider dataProviderForSphenicNumbers
  269. * @param int $n
  270. * @throws \Exception
  271. */
  272. public function testIsSphenicNumber(int $n)
  273. {
  274. // When
  275. $isSphenicNumber = Integer::isSphenicNumber($n);
  276. // Then
  277. $this->assertTrue($isSphenicNumber);
  278. }
  279. /**
  280. * A007304 Sphenic numbers: products of 3 distinct primes
  281. * @see https://oeis.org/A007304
  282. * @return array
  283. */
  284. public function dataProviderForSphenicNumbers(): array
  285. {
  286. return [
  287. [30],
  288. [42],
  289. [66],
  290. [70],
  291. [78],
  292. [102],
  293. [105],
  294. [110],
  295. [114],
  296. [130],
  297. [138],
  298. [154],
  299. [165],
  300. [170],
  301. [174],
  302. [182],
  303. [186],
  304. [190],
  305. [195],
  306. ];
  307. }
  308. /**
  309. * @test testIsNotSphenicNumber
  310. * @dataProvider dataProviderForNonSphenicNumbers
  311. * @param int $n
  312. * @throws \Exception
  313. */
  314. public function testIsNotSphenicNumber(int $n)
  315. {
  316. // When
  317. $isSphenicNumber = Integer::isSphenicNumber($n);
  318. // Then
  319. $this->assertFalse($isSphenicNumber);
  320. }
  321. /**
  322. * @return array
  323. */
  324. public function dataProviderForNonSphenicNumbers(): array
  325. {
  326. return [
  327. [2],
  328. [2 * 3],
  329. [2 * 2 * 2],
  330. [2 * 2 * 3 * 5],
  331. [2 * 3 * 5 * 7],
  332. ];
  333. }
  334. /**
  335. * @test aliquotSum returns the sum of all proper divisors of n
  336. * @dataProvider dataProviderForAliquotSums
  337. * @param int $n
  338. * @param int $expected
  339. * @throws \Exception
  340. */
  341. public function testAliquotSum(int $n, int $expected)
  342. {
  343. // When
  344. $actual = Integer::aliquotSum($n);
  345. // Then
  346. $this->assertEquals($expected, $actual);
  347. }
  348. /**
  349. * A001065 sum of proper divisors (or aliquot parts) of n
  350. * @see https://oeis.org/A001065
  351. * @return array
  352. */
  353. public function dataProviderForAliquotSums(): array
  354. {
  355. return [
  356. [1, 0],
  357. [2, 1],
  358. [3, 1],
  359. [4, 3],
  360. [5, 1],
  361. [6, 6],
  362. [7, 1],
  363. [8, 7],
  364. [9, 4],
  365. [10, 8],
  366. [11, 1],
  367. [12, 16],
  368. [13, 1],
  369. [14, 10],
  370. [15, 9],
  371. [16, 15],
  372. [17, 1],
  373. [18, 21],
  374. [19, 1],
  375. [20, 22],
  376. [21, 11],
  377. [22, 14],
  378. [23, 1],
  379. [24, 36],
  380. [25, 6],
  381. [26, 16],
  382. [27, 13],
  383. [28, 28],
  384. [29, 1],
  385. [30, 42],
  386. [31, 1],
  387. [32, 31],
  388. [33, 15],
  389. [34, 20],
  390. [35, 13],
  391. [36, 55],
  392. [2 * 3 * 5 * 7 * 11, 4602],
  393. ];
  394. }
  395. /**
  396. * @test aliquotSum throws an OutOfBoundsException if n is < 1.
  397. * @dataProvider dataProviderForPrimeFactorizationOutOfBoundsException
  398. * @param int $n
  399. * @throws \Exception
  400. */
  401. public function testAliquotSumOutOfBoundsException(int $n)
  402. {
  403. // When
  404. $this->expectException(Exception\OutOfBoundsException::class);
  405. // Then
  406. Integer::aliquotSum($n);
  407. }
  408. /**
  409. * @test testRadical
  410. * @dataProvider dataProviderForRadical
  411. * @param int $n
  412. * @param int $expected
  413. * @throws \Exception
  414. */
  415. public function testRadical(int $n, int $expected)
  416. {
  417. // When
  418. $radical = Integer::radical($n);
  419. // Then
  420. $this->assertEquals($expected, $radical);
  421. }
  422. /**
  423. * A007947 the squarefree kernel of n
  424. * @see https://oeis.org/A007947
  425. * @return array
  426. */
  427. public function dataProviderForRadical(): array
  428. {
  429. return [
  430. [1, 1],
  431. [2, 2],
  432. [3, 3],
  433. [4, 2],
  434. [5, 5],
  435. [6, 6],
  436. [7, 7],
  437. [8, 2],
  438. [9, 3],
  439. [10, 10],
  440. [11, 11],
  441. [12, 6],
  442. [13, 13],
  443. [14, 14],
  444. [15, 15],
  445. [16, 2],
  446. [17, 17],
  447. [18, 6],
  448. [19, 19],
  449. ];
  450. }
  451. /**
  452. * @test radical throws an OutOfBoundsException if n is < 1.
  453. * @dataProvider dataProviderForPrimeFactorizationOutOfBoundsException
  454. * @param int $n
  455. * @throws \Exception
  456. */
  457. public function testRadicalOutOfBoundsException(int $n)
  458. {
  459. // When
  460. $this->expectException(Exception\OutOfBoundsException::class);
  461. // Then
  462. Integer::radical($n);
  463. }
  464. /**
  465. * @test testTotient
  466. * @dataProvider dataProviderForTotient
  467. * @param int $n
  468. * @param int $k
  469. * @param int $expected
  470. * @throws \Exception
  471. */
  472. public function testTotient(int $n, int $k, int $expected)
  473. {
  474. // When
  475. $totient = Integer::totient($n, $k);
  476. // Then
  477. $this->assertEquals($expected, $totient);
  478. }
  479. /**
  480. * @see https://oeis.org/A000010 (k=1)
  481. * @see https://oeis.org/A007434 (k=2)
  482. * @see https://oeis.org/A059376 (k=3)
  483. * @see https://oeis.org/A059377 (k=4)
  484. * @see https://oeis.org/A059378 (k=5)
  485. * @return array
  486. */
  487. public function dataProviderForTotient(): array
  488. {
  489. return [
  490. [1, 1, 1],
  491. [2, 1, 1],
  492. [3, 1, 2],
  493. [4, 1, 2],
  494. [5, 1, 4],
  495. [6, 1, 2],
  496. [7, 1, 6],
  497. [8, 1, 4],
  498. [9, 1, 6],
  499. [10, 1, 4],
  500. [11, 1, 10],
  501. [12, 1, 4],
  502. [13, 1, 12],
  503. [14, 1, 6],
  504. [15, 1, 8],
  505. [16, 1, 8],
  506. [17, 1, 16],
  507. [18, 1, 6],
  508. [1, 2, 1],
  509. [2, 2, 3],
  510. [3, 2, 8],
  511. [4, 2, 12],
  512. [5, 2, 24],
  513. [6, 2, 24],
  514. [7, 2, 48],
  515. [8, 2, 48],
  516. [9, 2, 72],
  517. [10, 2, 72],
  518. [1, 3, 1],
  519. [2, 3, 7],
  520. [3, 3, 26],
  521. [4, 3, 56],
  522. [5, 3, 124],
  523. [6, 3, 182],
  524. [7, 3, 342],
  525. [8, 3, 448],
  526. [9, 3, 702],
  527. [10, 3, 868],
  528. ];
  529. }
  530. /**
  531. * @test totient throws an OutOfBoundsException if n is < 1 or k is < 1.
  532. * @dataProvider dataProviderForTotientOutOfBoundsException
  533. * @param int $n
  534. * @param int $k
  535. * @throws \Exception
  536. */
  537. public function testTotientOutOfBoundsException(int $n, int $k)
  538. {
  539. // When
  540. $this->expectException(Exception\OutOfBoundsException::class);
  541. // Then
  542. Integer::totient($n, $k);
  543. }
  544. /**
  545. * @return array
  546. */
  547. public function dataProviderForTotientOutOfBoundsException(): array
  548. {
  549. return [
  550. [2, -1],
  551. [2, 0],
  552. [0, 0],
  553. [0, 1],
  554. [-1, -1],
  555. [-1, 1],
  556. [-2, 1],
  557. [-100, 1],
  558. [-98352299832, 1],
  559. ];
  560. }
  561. /**
  562. * @test testCototient
  563. * @dataProvider dataProviderForCototient
  564. * @param int $n
  565. * @param int $expected
  566. * @throws \Exception
  567. */
  568. public function testCototient(int $n, int $expected)
  569. {
  570. // When
  571. $cototient = Integer::cototient($n);
  572. // Then
  573. $this->assertEquals($expected, $cototient);
  574. }
  575. /**
  576. * A051953 n - φ(n)
  577. * @see https://oeis.org/A051953
  578. * @return array
  579. */
  580. public function dataProviderForCototient(): array
  581. {
  582. return [
  583. [1, 0],
  584. [2, 1],
  585. [3, 1],
  586. [4, 2],
  587. [5, 1],
  588. [6, 4],
  589. [7, 1],
  590. [8, 4],
  591. [9, 3],
  592. [10, 6],
  593. [11, 1],
  594. [12, 8],
  595. [13, 1],
  596. [14, 8],
  597. [15, 7],
  598. [16, 8],
  599. [17, 1],
  600. [18, 12],
  601. [19, 1],
  602. [20, 12],
  603. [80, 48],
  604. ];
  605. }
  606. /**
  607. * @test cototient throws an OutOfBoundsException if n is < 1.
  608. * @dataProvider dataProviderForPrimeFactorizationOutOfBoundsException
  609. * @param int $n
  610. * @throws \Exception
  611. */
  612. public function testCototientOutOfBoundsException(int $n)
  613. {
  614. // When
  615. $this->expectException(Exception\OutOfBoundsException::class);
  616. // Then
  617. Integer::cototient($n);
  618. }
  619. /**
  620. * @test testReducedTotient
  621. * @dataProvider dataProviderForReducedTotient
  622. * @param int $n
  623. * @param int $expected
  624. * @throws \Exception
  625. */
  626. public function testReducedTotient(int $n, int $expected)
  627. {
  628. // When
  629. $result = Integer::reducedTotient($n);
  630. // Then
  631. $this->assertEquals($expected, $result);
  632. }
  633. /**
  634. * @see https://oeis.org/A002322
  635. * @return array
  636. */
  637. public function dataProviderForReducedTotient(): array
  638. {
  639. return [
  640. [1, 1],
  641. [2, 1],
  642. [3, 2],
  643. [4, 2],
  644. [5, 4],
  645. [6, 2],
  646. [7, 6],
  647. [8, 2],
  648. [9, 6],
  649. [10, 4],
  650. [11, 10],
  651. [12, 2],
  652. [13, 12],
  653. [14, 6],
  654. [15, 4],
  655. [16, 4],
  656. [17, 16],
  657. [18, 6],
  658. [19, 18],
  659. [64, 16],
  660. [80, 4],
  661. [81, 54],
  662. ];
  663. }
  664. /**
  665. * @test reducedTotient throws an OutOfBoundsException if n is < 1.
  666. * @dataProvider dataProviderForPrimeFactorizationOutOfBoundsException
  667. * @param int $n
  668. * @throws \Exception
  669. */
  670. public function testReducedTotientOutOfBoundsException(int $n)
  671. {
  672. // When
  673. $this->expectException(Exception\OutOfBoundsException::class);
  674. // Then
  675. Integer::reducedTotient($n);
  676. }
  677. /**
  678. * @test testMobius
  679. * @dataProvider dataProviderForMobius
  680. * @param int $n
  681. * @param int $expected
  682. * @throws \Exception
  683. */
  684. public function testMobius(int $n, int $expected)
  685. {
  686. // When
  687. $actual = Integer::mobius($n);
  688. // Then
  689. $this->assertEquals($expected, $actual);
  690. }
  691. /**
  692. * A008683
  693. * @see https://oeis.org/A008683
  694. * @return array
  695. */
  696. public function dataProviderForMobius(): array
  697. {
  698. return [
  699. [1, 1],
  700. [2, -1],
  701. [3, -1],
  702. [4, 0],
  703. [5, -1],
  704. [6, 1],
  705. [7, -1],
  706. [8, 0],
  707. [9, 0],
  708. [10, 1],
  709. [11, -1],
  710. [12, 0],
  711. [13, -1],
  712. [14, 1],
  713. [15, 1],
  714. ];
  715. }
  716. /**
  717. * @test mobius throws an OutOfBoundsException if n is < 1.
  718. * @dataProvider dataProviderForPrimeFactorizationOutOfBoundsException
  719. * @param int $n
  720. * @throws \Exception
  721. */
  722. public function testMobiusOutOfBoundsException(int $n)
  723. {
  724. // When
  725. $this->expectException(Exception\OutOfBoundsException::class);
  726. // Then
  727. Integer::mobius($n);
  728. }
  729. /**
  730. * @test testIsSquarefree
  731. * @dataProvider dataProviderForSquarefreeIntegers
  732. * @param int $n
  733. * @throws \Exception
  734. */
  735. public function testIsSquarefree(int $n)
  736. {
  737. // When
  738. $isSquarefree = Integer::isSquarefree($n);
  739. // Then
  740. $this->assertTrue($isSquarefree);
  741. }
  742. /**
  743. * A005117 squarefree numbers: numbers that are not divisible by a square greater than 1
  744. * @see https://oeis.org/A005117
  745. * @return array
  746. */
  747. public function dataProviderForSquarefreeIntegers(): array
  748. {
  749. return [
  750. [1],
  751. [2],
  752. [3],
  753. [5],
  754. [6],
  755. [7],
  756. [10],
  757. [11],
  758. [13],
  759. [14],
  760. [15],
  761. [17],
  762. [19],
  763. [21],
  764. [22],
  765. [23],
  766. [26],
  767. [29],
  768. [30],
  769. [31],
  770. ];
  771. }
  772. /**
  773. * @test testIsNotSquarefree
  774. * @dataProvider dataProviderForNonSquarefreeIntegers
  775. * @param int $n
  776. * @throws \Exception
  777. */
  778. public function testIsNotSquarefree(int $n)
  779. {
  780. // When
  781. $isSquarefree = Integer::isSquarefree($n);
  782. // Then
  783. $this->assertFalse($isSquarefree);
  784. }
  785. /**
  786. * @return array
  787. */
  788. public function dataProviderForNonSquarefreeIntegers(): array
  789. {
  790. return [
  791. [-1],
  792. [0],
  793. [2 * 2],
  794. [2 * 2 * 2],
  795. [2 * 3 * 3],
  796. [2 * 3 * 5 * 7 * 11 * 13 * 17 * 17],
  797. ];
  798. }
  799. /**
  800. * @test testSumOfDivisors
  801. * @dataProvider dataProviderForSumOfDivisors
  802. * @param int $n
  803. * @param int $expected
  804. * @throws \Exception
  805. */
  806. public function testSumOfDivisors(int $n, int $expected)
  807. {
  808. // When
  809. $actual = Integer::sumOfDivisors($n);
  810. // Then
  811. $this->assertEquals($expected, $actual);
  812. }
  813. /**
  814. * A000203 the sum of the divisors of n
  815. * @see https://oeis.org/A000203
  816. * @return array
  817. */
  818. public function dataProviderForSumOfDivisors(): array
  819. {
  820. return [
  821. [1, 1],
  822. [2, 3],
  823. [3, 4],
  824. [4, 7],
  825. [5, 6],
  826. [6, 12],
  827. [7, 8],
  828. [8, 15],
  829. [9, 13],
  830. [10, 18],
  831. [11, 12],
  832. [12, 28],
  833. [13, 14],
  834. [14, 24],
  835. [15, 24],
  836. [70, 144],
  837. [44100, 160797],
  838. ];
  839. }
  840. /**
  841. * @test sumOfDivisors throws an OutOfBoundsException if n is < 1.
  842. * @dataProvider dataProviderForPrimeFactorizationOutOfBoundsException
  843. * @param int $n
  844. * @throws \Exception
  845. */
  846. public function testSumOfDivisorsOutOfBoundsException(int $n)
  847. {
  848. // When
  849. $this->expectException(Exception\OutOfBoundsException::class);
  850. // Then
  851. Integer::sumOfDivisors($n);
  852. }
  853. /**
  854. * @test testNumberOfDivisors
  855. * @dataProvider dataProviderForNumberOfDivisors
  856. * @param int $n
  857. * @param int $expected
  858. * @throws \Exception
  859. */
  860. public function testNumberOfDivisors(int $n, int $expected)
  861. {
  862. // When
  863. $actual = Integer::numberOfDivisors($n);
  864. // Then
  865. $this->assertEquals($expected, $actual);
  866. }
  867. /**
  868. * A000005 the numbers of divisors of n
  869. * @see https://oeis.org/A000005
  870. * @return array
  871. */
  872. public function dataProviderForNumberOfDivisors(): array
  873. {
  874. return [
  875. [1, 1],
  876. [2, 2],
  877. [3, 2],
  878. [4, 3],
  879. [5, 2],
  880. [6, 4],
  881. [7, 2],
  882. [8, 4],
  883. [9, 3],
  884. [10, 4],
  885. [96, 12],
  886. [103, 2],
  887. ];
  888. }
  889. /**
  890. * @test numberOfDivisors throws an OutOfBoundsException if n is < 1.
  891. * @dataProvider dataProviderForPrimeFactorizationOutOfBoundsException
  892. * @param int $n
  893. * @throws \Exception
  894. */
  895. public function testNumberOfDivisorsOutOfBoundsException(int $n)
  896. {
  897. // When
  898. $this->expectException(Exception\OutOfBoundsException::class);
  899. // Then
  900. Integer::numberOfDivisors($n);
  901. }
  902. /**
  903. * @test isPerfectPower returns true if n is a perfect prime.
  904. * @dataProvider dataProviderForIsPerfectPower
  905. * @param int $n
  906. */
  907. public function testIsPerfectPower(int $n)
  908. {
  909. // When
  910. $isPerfectPower = Integer::isPerfectPower($n);
  911. // Then
  912. $this->assertTrue($isPerfectPower);
  913. }
  914. /**
  915. * A001597 Perfect powers: m^k where m > 0 and k >= 2.
  916. * @see https://oeis.org/A001597
  917. * @return array
  918. */
  919. public function dataProviderForIsPerfectPower(): array
  920. {
  921. return [
  922. [4],
  923. [8],
  924. [9],
  925. [16],
  926. [16],
  927. [25],
  928. [27],
  929. [32],
  930. [36],
  931. [49],
  932. [64],
  933. [64],
  934. [64],
  935. [81],
  936. [81],
  937. [100],
  938. [121],
  939. [125],
  940. [128],
  941. [144],
  942. [169],
  943. [196],
  944. [216],
  945. [225],
  946. [243],
  947. [256],
  948. [256],
  949. [256],
  950. [289],
  951. [324],
  952. [343],
  953. [361],
  954. [400],
  955. [441],
  956. [484],
  957. [512],
  958. [512],
  959. [529],
  960. [576],
  961. [625],
  962. [625],
  963. [676],
  964. [729],
  965. [729],
  966. [729],
  967. [784],
  968. [841],
  969. [900],
  970. [961],
  971. [1000],
  972. [1024],
  973. [1024],
  974. [1024],
  975. [1089],
  976. ];
  977. }
  978. /**
  979. * @test isPerfectPower returns false if n is not a perfect prime.
  980. * @dataProvider dataProviderForIsNotPerfectPower
  981. * @param int $n
  982. */
  983. public function testIsNotPerfectPower(int $n)
  984. {
  985. // When
  986. $isPerfectPower = Integer::isPerfectPower($n);
  987. // Then
  988. $this->assertFalse($isPerfectPower);
  989. }
  990. /**
  991. * A007916 Numbers that are not perfect powers.
  992. * @see https://oeis.org/A007916
  993. * @return array
  994. */
  995. public function dataProviderForIsNotPerfectPower(): array
  996. {
  997. return [
  998. [2],
  999. [3],
  1000. [5],
  1001. [6],
  1002. [7],
  1003. [10],
  1004. [11],
  1005. [12],
  1006. [13],
  1007. [14],
  1008. [15],
  1009. [17],
  1010. [18],
  1011. [19],
  1012. [20],
  1013. [21],
  1014. [22],
  1015. [23],
  1016. [24],
  1017. [26],
  1018. [28],
  1019. [29],
  1020. [30],
  1021. [31],
  1022. [33],
  1023. [34],
  1024. [35],
  1025. [37],
  1026. [38],
  1027. [39],
  1028. [40],
  1029. [41],
  1030. [42],
  1031. [43],
  1032. [44],
  1033. [45],
  1034. [46],
  1035. [47],
  1036. [48],
  1037. [50],
  1038. [51],
  1039. [52],
  1040. [53],
  1041. [54],
  1042. [55],
  1043. [56],
  1044. [57],
  1045. [58],
  1046. [59],
  1047. [60],
  1048. [61],
  1049. [62],
  1050. [63],
  1051. [65],
  1052. [66],
  1053. [67],
  1054. [68],
  1055. [69],
  1056. [70],
  1057. [71],
  1058. [72],
  1059. [73],
  1060. [74],
  1061. [75],
  1062. [76],
  1063. [77],
  1064. [78],
  1065. [79],
  1066. [80],
  1067. [82],
  1068. [83],
  1069. ];
  1070. }
  1071. /**
  1072. * @test perfectPower returns m and k for n such that mᵏ = n if n is a perfect power.
  1073. * @dataProvider dataProviderForPerfectPower
  1074. * @param int $n
  1075. * @param int $expected_m
  1076. * @param int $expected_k
  1077. */
  1078. public function testPerfectPower(int $n, int $expected_m, int $expected_k)
  1079. {
  1080. // When
  1081. [$m, $k] = Integer::perfectPower($n);
  1082. // Then
  1083. $this->assertEquals($expected_m, $m);
  1084. $this->assertEquals($expected_k, $k);
  1085. }
  1086. /**
  1087. * Perfect powers: m^k where m > 0 and k >= 2.
  1088. * @return array
  1089. */
  1090. public function dataProviderForPerfectPower(): array
  1091. {
  1092. return [
  1093. [4, 2, 2],
  1094. [8, 2, 3],
  1095. [9, 3, 2],
  1096. [16, 2, 4],
  1097. [25, 5, 2],
  1098. [27, 3, 3],
  1099. [32, 2, 5],
  1100. [36, 6, 2],
  1101. [49, 7, 2],
  1102. [64, 2, 6],
  1103. [81, 3, 4],
  1104. [100, 10, 2],
  1105. [121, 11, 2],
  1106. [125, 5, 3],
  1107. [128, 2, 7],
  1108. [144, 12, 2],
  1109. [169, 13, 2],
  1110. [196, 14, 2],
  1111. [216, 6, 3],
  1112. [225, 15, 2],
  1113. [243, 3, 5],
  1114. [256, 2, 8],
  1115. [1000, 10, 3],
  1116. [1024, 2, 10],
  1117. ];
  1118. }
  1119. /**
  1120. * @test perfectPower returns a non-empty array comtaining numeric m and k both > 1 if n is a perfect power.
  1121. * @dataProvider dataProviderForIsPerfectPower
  1122. * @param int $n
  1123. */
  1124. public function testPerfectPowerArray(int $n)
  1125. {
  1126. // When
  1127. $perfect_power = Integer::perfectPower($n);
  1128. // Then
  1129. $this->assertNotEmpty($perfect_power);
  1130. // And
  1131. $m = \array_shift($perfect_power);
  1132. $k = \array_shift($perfect_power);
  1133. $this->assertTrue(\is_numeric($m));
  1134. $this->assertTrue(\is_numeric($k));
  1135. $this->assertGreaterThan(1, $m);
  1136. $this->assertGreaterThan(1, $k);
  1137. }
  1138. /**
  1139. * @test perfectPower returns an empty array if n is not a perfect power.
  1140. * @dataProvider dataProviderForIsNotPerfectPower
  1141. * @param int $n
  1142. */
  1143. public function testEmptyPerfectPower(int $n)
  1144. {
  1145. // When
  1146. $empty = Integer::perfectPower($n);
  1147. // Then
  1148. $this->assertEmpty($empty);
  1149. }
  1150. /**
  1151. * @test primeFactorization returns an array of the prime factors of an integer n.
  1152. * @dataProvider dataProviderForPrimeFactorization
  1153. * @param int $n
  1154. * @param array $expected_actors
  1155. * @throws \Exception
  1156. */
  1157. public function testPrimeFactorization(int $n, array $expected_actors)
  1158. {
  1159. // When
  1160. $factors = Integer::primeFactorization($n);
  1161. // Then
  1162. $this->assertEquals($expected_actors, $factors);
  1163. }
  1164. /**
  1165. * @return array
  1166. */
  1167. public function dataProviderForPrimeFactorization(): array
  1168. {
  1169. return [
  1170. [1, []],
  1171. [2, [2]],
  1172. [3, [3]],
  1173. [4, [2, 2]],
  1174. [5, [5]],
  1175. [6, [2, 3]],
  1176. [7, [7]],
  1177. [8, [2, 2, 2]],
  1178. [9, [3, 3]],
  1179. [10, [2, 5]],
  1180. [11, [11]],
  1181. [12, [2, 2, 3]],
  1182. [13, [13]],
  1183. [14, [2, 7]],
  1184. [15, [3, 5]],
  1185. [16, [2, 2, 2, 2]],
  1186. [17, [17]],
  1187. [18, [2, 3, 3]],
  1188. [19, [19]],
  1189. [20, [2, 2, 5]],
  1190. [48, [2, 2, 2, 2, 3]],
  1191. [99, [3, 3, 11]],
  1192. [100, [2, 2, 5, 5]],
  1193. [101, [101]],
  1194. [111, [3, 37]],
  1195. [147, [3, 7, 7]],
  1196. [200, [2, 2, 2, 5, 5]],
  1197. [5555, [5, 11, 101]],
  1198. [8463, [3, 7, 13, 31]],
  1199. [12345, [3, 5, 823]],
  1200. [45123, [3, 13, 13, 89]],
  1201. [99999, [3, 3, 41, 271]],
  1202. [5465432, [2, 2, 2, 7, 17, 5741]],
  1203. [25794349, [7, 619, 5953]],
  1204. [87534987, [3, 23, 1268623]],
  1205. [123456789, [3, 3, 3607, 3803]],
  1206. [8654893156, [2, 2, 7, 13, 157, 269, 563]],
  1207. [2 * 3 * 5 * 7, [2, 3, 5, 7]],
  1208. [2 * 2 * 2 * 5 * 7 * 7 * 7 * 13, [2, 2, 2, 5, 7, 7, 7, 13]],
  1209. ];
  1210. }
  1211. /**
  1212. * @test primeFactorization throws an OutOfBoundsException if n is < 1.
  1213. * @dataProvider dataProviderForPrimeFactorizationOutOfBoundsException
  1214. * @param int $n
  1215. * @throws \Exception
  1216. */
  1217. public function testPrimeFactorizationOutOfBoundsException(int $n)
  1218. {
  1219. // Then
  1220. $this->expectException(Exception\OutOfBoundsException::class);
  1221. // When
  1222. Integer::primeFactorization($n);
  1223. }
  1224. /**
  1225. * @return array
  1226. */
  1227. public function dataProviderForPrimeFactorizationOutOfBoundsException(): array
  1228. {
  1229. return [
  1230. [0],
  1231. [-1],
  1232. [-2],
  1233. [-100],
  1234. [-98352299832],
  1235. ];
  1236. }
  1237. /**
  1238. * @test coprime returns true if a and b are coprime
  1239. * @dataProvider dataProviderForCoprime
  1240. * @param int $a
  1241. * @param int $b
  1242. */
  1243. public function testCoprime(int $a, int $b)
  1244. {
  1245. // When
  1246. $coprime = Integer::coprime($a, $b);
  1247. // Then
  1248. $this->assertTrue($coprime);
  1249. }
  1250. /**
  1251. * @return array
  1252. */
  1253. public function dataProviderForCoprime(): array
  1254. {
  1255. return [
  1256. [1, 0],
  1257. [-1, 1],
  1258. [1, 2],
  1259. [1, 3],
  1260. [1, 4],
  1261. [1, 5],
  1262. [1, 6],
  1263. [1, 7],
  1264. [1, 8],
  1265. [1, 9],
  1266. [1, 10],
  1267. [1, 20],
  1268. [1, 30],
  1269. [1, 100],
  1270. [2, 3],
  1271. [2, 5],
  1272. [2, 7],
  1273. [2, 9],
  1274. [2, 11],
  1275. [2, 13],
  1276. [2, 15],
  1277. [2, 17],
  1278. [2, 19],
  1279. [2, 21],
  1280. [2, 23],
  1281. [2, 25],
  1282. [2, 27],
  1283. [2, 29],
  1284. [3, 4],
  1285. [3, 5],
  1286. [3, 7],
  1287. [3, 8],
  1288. [3, 10],
  1289. [3, 11],
  1290. [3, 13],
  1291. [3, 14],
  1292. [3, 16],
  1293. [4, 3],
  1294. [4, 5],
  1295. [4, 7],
  1296. [4, 17],
  1297. [4, 21],
  1298. [4, 35],
  1299. [5, 6],
  1300. [5, 7],
  1301. [5, 8],
  1302. [5, 9],
  1303. [5, 11],
  1304. [5, 12],
  1305. [5, 13],
  1306. [5, 14],
  1307. [5, 16],
  1308. [5, 27],
  1309. [6, 7],
  1310. [6, 11],
  1311. [6, 13],
  1312. [6, 17],
  1313. [6, 29],
  1314. [6, 23],
  1315. [6, 25],
  1316. [6, 29],
  1317. [19, 20],
  1318. [20, 21],
  1319. [23, 24],
  1320. [23, 25],
  1321. [27, 16],
  1322. [28, 29],
  1323. [29, 30],
  1324. ];
  1325. }
  1326. /**
  1327. * @test coprime returns false if a and b are not coprime
  1328. * @dataProvider dataProviderForNotCoprime
  1329. * @param int $a
  1330. * @param int $b
  1331. */
  1332. public function testNotCoprime(int $a, int $b)
  1333. {
  1334. // When
  1335. $coprime = Integer::coprime($a, $b);
  1336. // Then
  1337. $this->assertFalse($coprime);
  1338. }
  1339. /**
  1340. * @return array
  1341. */
  1342. public function dataProviderForNotCoprime(): array
  1343. {
  1344. return [
  1345. [2, 4],
  1346. [2, 6],
  1347. [2, 8],
  1348. [2, 10],
  1349. [2, 12],
  1350. [2, 14],
  1351. [2, 16],
  1352. [2, 18],
  1353. [2, 20],
  1354. [2, 22],
  1355. [2, 24],
  1356. [2, 26],
  1357. [2, 28],
  1358. [2, 30],
  1359. [3, 6],
  1360. [3, 9],
  1361. [3, 12],
  1362. [3, 15],
  1363. [4, 8],
  1364. [4, 12],
  1365. [4, 20],
  1366. [4, 22],
  1367. [4, 24],
  1368. [4, 30],
  1369. [5, 10],
  1370. [5, 15],
  1371. [5, 20],
  1372. [5, 25],
  1373. [5, 30],
  1374. [5, 50],
  1375. [5, 100],
  1376. [5, 200],
  1377. [5, 225],
  1378. [5, 555],
  1379. [6, 12],
  1380. [6, 14],
  1381. [6, 16],
  1382. [6, 18],
  1383. [6, 26],
  1384. [6, 28],
  1385. [6, 30],
  1386. [6, 32],
  1387. [12, 21],
  1388. [18, 20],
  1389. [20, 22],
  1390. [21, 24],
  1391. ];
  1392. }
  1393. /**
  1394. * @test isOdd returns true for an odd number
  1395. * @dataProvider dataProviderForOddNumbers
  1396. * @param int $x
  1397. */
  1398. public function testIsOdd(int $x)
  1399. {
  1400. // When
  1401. $isOdd = Integer::isOdd($x);
  1402. // Then
  1403. $this->assertTrue($isOdd);
  1404. }
  1405. /**
  1406. * @test isOdd returns false for an even number
  1407. * @dataProvider dataProviderForEvenNumbers
  1408. * @param int $x
  1409. */
  1410. public function testIsNotOdd(int $x)
  1411. {
  1412. // When
  1413. $isOdd = Integer::isOdd($x);
  1414. // Then
  1415. $this->assertFalse($isOdd);
  1416. }
  1417. /**
  1418. * @test isEven returns true for an even number
  1419. * @dataProvider dataProviderForEvenNumbers
  1420. * @param int $x
  1421. */
  1422. public function testIsEven(int $x)
  1423. {
  1424. // When
  1425. $isEven = Integer::isEven($x);
  1426. // Then
  1427. $this->assertTrue($isEven);
  1428. }
  1429. /**
  1430. * @test isEven returns false for an odd number
  1431. * @dataProvider dataProviderForOddNumbers
  1432. * @param int $x
  1433. */
  1434. public function testIsNotEven(int $x)
  1435. {
  1436. // When
  1437. $isEven = Integer::isEven($x);
  1438. // Then
  1439. $this->assertFalse($isEven);
  1440. }
  1441. /**
  1442. * @return \Generator
  1443. */
  1444. public function dataProviderForOddNumbers(): \Generator
  1445. {
  1446. foreach (\range(-11, 101, 2) as $x) {
  1447. yield [$x];
  1448. }
  1449. }
  1450. /**
  1451. * @return \Generator
  1452. */
  1453. public function dataProviderForEvenNumbers(): \Generator
  1454. {
  1455. foreach (\range(-10, 100, 2) as $x) {
  1456. yield [$x];
  1457. }
  1458. }
  1459. }