exercises_unit_1.ipynb (40808B)
1 { 2 "cells": [ 3 { 4 "cell_type": "code", 5 "execution_count": 1, 6 "id": "e3d34281-2d39-48ec-8bc3-a257d071bd82", 7 "metadata": {}, 8 "outputs": [ 9 { 10 "data": { 11 "text/plain": [ 12 "- : int = 0\n" 13 ] 14 }, 15 "execution_count": 1, 16 "metadata": {}, 17 "output_type": "execute_result" 18 } 19 ], 20 "source": [ 21 "Sys.command \"opam install -y qcheck > /tmp/opam.log 2>&1\";;" 22 ] 23 }, 24 { 25 "cell_type": "code", 26 "execution_count": 2, 27 "id": "3fc0418a-4ca6-475a-b32a-7faa5527fbae", 28 "metadata": {}, 29 "outputs": [ 30 { 31 "data": { 32 "text/plain": [ 33 "val cube : int -> int = <fun>\n" 34 ] 35 }, 36 "execution_count": 2, 37 "metadata": {}, 38 "output_type": "execute_result" 39 } 40 ], 41 "source": [ 42 "let cube n = n*n*n" 43 ] 44 }, 45 { 46 "cell_type": "code", 47 "execution_count": 3, 48 "id": "a4db5988-0b39-4b2d-8bc9-952b16d54ad0", 49 "metadata": {}, 50 "outputs": [ 51 { 52 "data": { 53 "text/plain": [ 54 "val fahrenheit_of_celsius : float -> float = <fun>\n" 55 ] 56 }, 57 "execution_count": 3, 58 "metadata": {}, 59 "output_type": "execute_result" 60 } 61 ], 62 "source": [ 63 "let fahrenheit_of_celsius (c : float) = (c *. (9. /. 5.)) +. 32." 64 ] 65 }, 66 { 67 "cell_type": "code", 68 "execution_count": 4, 69 "id": "4dc8ee72-86ad-49dc-8d87-f11f129ea38d", 70 "metadata": {}, 71 "outputs": [ 72 { 73 "data": { 74 "text/plain": [ 75 "- : float = 41.\n" 76 ] 77 }, 78 "execution_count": 4, 79 "metadata": {}, 80 "output_type": "execute_result" 81 } 82 ], 83 "source": [ 84 "fahrenheit_of_celsius 5." 85 ] 86 }, 87 { 88 "cell_type": "code", 89 "execution_count": 5, 90 "id": "5b3adb38-ed81-4b18-abeb-97790f1bfee7", 91 "metadata": {}, 92 "outputs": [], 93 "source": [ 94 " (* `sign n` returns -1 if n is negative, 0 if zero, 1 if positive.\n", 95 " Use nested if/then/else expressions and notice that every branch must\n", 96 " produce an int.\n", 97 "*)" 98 ] 99 }, 100 { 101 "cell_type": "code", 102 "execution_count": 6, 103 "id": "4ced9283-2066-4f6e-b14b-555a0271fb1b", 104 "metadata": {}, 105 "outputs": [ 106 { 107 "data": { 108 "text/plain": [ 109 "val sign : int -> int = <fun>\n" 110 ] 111 }, 112 "execution_count": 6, 113 "metadata": {}, 114 "output_type": "execute_result" 115 } 116 ], 117 "source": [ 118 "let sign n = if n < 0 then -1\n", 119 " else if n = 0\n", 120 " then 0\n", 121 " else 1" 122 ] 123 }, 124 { 125 "cell_type": "code", 126 "execution_count": 7, 127 "id": "4a78286a-4406-42f8-a103-1558a7b98e7c", 128 "metadata": {}, 129 "outputs": [ 130 { 131 "data": { 132 "text/plain": [ 133 "- : int = 0\n" 134 ] 135 }, 136 "execution_count": 7, 137 "metadata": {}, 138 "output_type": "execute_result" 139 }, 140 { 141 "data": { 142 "text/plain": [ 143 "- : int = -1\n" 144 ] 145 }, 146 "execution_count": 7, 147 "metadata": {}, 148 "output_type": "execute_result" 149 }, 150 { 151 "data": { 152 "text/plain": [ 153 "- : int = 1\n" 154 ] 155 }, 156 "execution_count": 7, 157 "metadata": {}, 158 "output_type": "execute_result" 159 }, 160 { 161 "data": { 162 "text/plain": [ 163 "- : int = -1\n" 164 ] 165 }, 166 "execution_count": 7, 167 "metadata": {}, 168 "output_type": "execute_result" 169 }, 170 { 171 "data": { 172 "text/plain": [ 173 "- : int = 1\n" 174 ] 175 }, 176 "execution_count": 7, 177 "metadata": {}, 178 "output_type": "execute_result" 179 } 180 ], 181 "source": [ 182 "sign 0;;\n", 183 "sign (-1);;\n", 184 "sign 1;;\n", 185 "sign (-1000);;\n", 186 "sign 100000;;" 187 ] 188 }, 189 { 190 "cell_type": "code", 191 "execution_count": 8, 192 "id": "ad9ac3d1-1f21-4764-95ad-06706a5043ab", 193 "metadata": {}, 194 "outputs": [ 195 { 196 "data": { 197 "text/plain": [ 198 "val fib : int -> int = <fun>\n" 199 ] 200 }, 201 "execution_count": 8, 202 "metadata": {}, 203 "output_type": "execute_result" 204 } 205 ], 206 "source": [ 207 "let rec fib n = if n <= 1 then n else fib (n - 1) + fib (n - 2)\n" 208 ] 209 }, 210 { 211 "cell_type": "code", 212 "execution_count": 9, 213 "id": "32f0fbe4-4a4a-44d5-9f71-4affc1bdec98", 214 "metadata": {}, 215 "outputs": [ 216 { 217 "data": { 218 "text/plain": [ 219 "- : int = 0\n" 220 ] 221 }, 222 "execution_count": 9, 223 "metadata": {}, 224 "output_type": "execute_result" 225 }, 226 { 227 "data": { 228 "text/plain": [ 229 "- : int = 1\n" 230 ] 231 }, 232 "execution_count": 9, 233 "metadata": {}, 234 "output_type": "execute_result" 235 }, 236 { 237 "data": { 238 "text/plain": [ 239 "- : int = 1\n" 240 ] 241 }, 242 "execution_count": 9, 243 "metadata": {}, 244 "output_type": "execute_result" 245 }, 246 { 247 "data": { 248 "text/plain": [ 249 "- : int = 2\n" 250 ] 251 }, 252 "execution_count": 9, 253 "metadata": {}, 254 "output_type": "execute_result" 255 }, 256 { 257 "data": { 258 "text/plain": [ 259 "- : int = 3\n" 260 ] 261 }, 262 "execution_count": 9, 263 "metadata": {}, 264 "output_type": "execute_result" 265 } 266 ], 267 "source": [ 268 "fib 0;;\n", 269 "fib 1;;\n", 270 "fib 2;;\n", 271 "fib 3;;\n", 272 "fib 4;;" 273 ] 274 }, 275 { 276 "cell_type": "code", 277 "execution_count": 10, 278 "id": "8808ba7e-f3ec-4f10-bd90-56c784c01f72", 279 "metadata": {}, 280 "outputs": [ 281 { 282 "data": { 283 "text/plain": [ 284 "- : bool = true\n" 285 ] 286 }, 287 "execution_count": 10, 288 "metadata": {}, 289 "output_type": "execute_result" 290 }, 291 { 292 "data": { 293 "text/plain": [ 294 "- : bool = false\n" 295 ] 296 }, 297 "execution_count": 10, 298 "metadata": {}, 299 "output_type": "execute_result" 300 } 301 ], 302 "source": [ 303 "1.0 = 1.0;;\n", 304 "1.0 == 1.0;;" 305 ] 306 }, 307 { 308 "cell_type": "code", 309 "execution_count": 11, 310 "id": "be0aa1f3-2f8a-4ccb-93bd-5889ccb19fd1", 311 "metadata": {}, 312 "outputs": [], 313 "source": [ 314 "(* count digits non-tail recursive *)" 315 ] 316 }, 317 { 318 "cell_type": "code", 319 "execution_count": 12, 320 "id": "0143fdea-b247-4af2-9311-6bcd955d6160", 321 "metadata": {}, 322 "outputs": [ 323 { 324 "data": { 325 "text/plain": [ 326 "val count_digits : int -> int = <fun>\n" 327 ] 328 }, 329 "execution_count": 12, 330 "metadata": {}, 331 "output_type": "execute_result" 332 } 333 ], 334 "source": [ 335 "let rec count_digits n = if n < 0 then count_digits (n * (-1))\n", 336 " else if n > 9 \n", 337 " then count_digits (n / 10) + 1\n", 338 " else 1" 339 ] 340 }, 341 { 342 "cell_type": "code", 343 "execution_count": 13, 344 "id": "319f2854-0d2d-466a-8e12-80cd5c14b5a0", 345 "metadata": {}, 346 "outputs": [ 347 { 348 "data": { 349 "text/plain": [ 350 "- : int = 1\n" 351 ] 352 }, 353 "execution_count": 13, 354 "metadata": {}, 355 "output_type": "execute_result" 356 }, 357 { 358 "data": { 359 "text/plain": [ 360 "- : int = 3\n" 361 ] 362 }, 363 "execution_count": 13, 364 "metadata": {}, 365 "output_type": "execute_result" 366 }, 367 { 368 "data": { 369 "text/plain": [ 370 "- : int = 2\n" 371 ] 372 }, 373 "execution_count": 13, 374 "metadata": {}, 375 "output_type": "execute_result" 376 }, 377 { 378 "data": { 379 "text/plain": [ 380 "- : int = 1\n" 381 ] 382 }, 383 "execution_count": 13, 384 "metadata": {}, 385 "output_type": "execute_result" 386 }, 387 { 388 "data": { 389 "text/plain": [ 390 "- : int = 3\n" 391 ] 392 }, 393 "execution_count": 13, 394 "metadata": {}, 395 "output_type": "execute_result" 396 }, 397 { 398 "data": { 399 "text/plain": [ 400 "- : int = 4\n" 401 ] 402 }, 403 "execution_count": 13, 404 "metadata": {}, 405 "output_type": "execute_result" 406 }, 407 { 408 "data": { 409 "text/plain": [ 410 "- : int = 1\n" 411 ] 412 }, 413 "execution_count": 13, 414 "metadata": {}, 415 "output_type": "execute_result" 416 } 417 ], 418 "source": [ 419 "count_digits 0;;\n", 420 "count_digits 100;;\n", 421 "count_digits 10;;\n", 422 "count_digits 9;;\n", 423 "count_digits (-102);;\n", 424 "count_digits (-1002);;\n", 425 "count_digits (-1);;" 426 ] 427 }, 428 { 429 "cell_type": "code", 430 "execution_count": 14, 431 "id": "a2ec41ef-f24f-485a-9ee6-ab04fcbe301a", 432 "metadata": {}, 433 "outputs": [], 434 "source": [ 435 "(* count digits tail recursive *)" 436 ] 437 }, 438 { 439 "cell_type": "code", 440 "execution_count": 15, 441 "id": "880519a5-6abe-4622-9d00-cd8d6f7a0b71", 442 "metadata": {}, 443 "outputs": [ 444 { 445 "data": { 446 "text/plain": [ 447 "val cnt : int -> int -> int = <fun>\n" 448 ] 449 }, 450 "execution_count": 15, 451 "metadata": {}, 452 "output_type": "execute_result" 453 }, 454 { 455 "data": { 456 "text/plain": [ 457 "val count_digits : int -> int = <fun>\n" 458 ] 459 }, 460 "execution_count": 15, 461 "metadata": {}, 462 "output_type": "execute_result" 463 } 464 ], 465 "source": [ 466 "let rec cnt acc n = \n", 467 " if n < 0 then cnt 0 (n * (-1))\n", 468 " else if n > 9 \n", 469 " then cnt (acc + 1) (n / 10)\n", 470 " else (acc + 1)\n", 471 "\n", 472 "let count_digits = cnt 0" 473 ] 474 }, 475 { 476 "cell_type": "code", 477 "execution_count": 16, 478 "id": "63a70c83-ff18-4d95-82e2-89d4b1b05d95", 479 "metadata": {}, 480 "outputs": [ 481 { 482 "data": { 483 "text/plain": [ 484 "- : int = 1\n" 485 ] 486 }, 487 "execution_count": 16, 488 "metadata": {}, 489 "output_type": "execute_result" 490 }, 491 { 492 "data": { 493 "text/plain": [ 494 "- : int = 3\n" 495 ] 496 }, 497 "execution_count": 16, 498 "metadata": {}, 499 "output_type": "execute_result" 500 }, 501 { 502 "data": { 503 "text/plain": [ 504 "- : int = 2\n" 505 ] 506 }, 507 "execution_count": 16, 508 "metadata": {}, 509 "output_type": "execute_result" 510 }, 511 { 512 "data": { 513 "text/plain": [ 514 "- : int = 1\n" 515 ] 516 }, 517 "execution_count": 16, 518 "metadata": {}, 519 "output_type": "execute_result" 520 }, 521 { 522 "data": { 523 "text/plain": [ 524 "- : int = 3\n" 525 ] 526 }, 527 "execution_count": 16, 528 "metadata": {}, 529 "output_type": "execute_result" 530 }, 531 { 532 "data": { 533 "text/plain": [ 534 "- : int = 4\n" 535 ] 536 }, 537 "execution_count": 16, 538 "metadata": {}, 539 "output_type": "execute_result" 540 }, 541 { 542 "data": { 543 "text/plain": [ 544 "- : int = 1\n" 545 ] 546 }, 547 "execution_count": 16, 548 "metadata": {}, 549 "output_type": "execute_result" 550 } 551 ], 552 "source": [ 553 "count_digits 0;;\n", 554 "count_digits 100;;\n", 555 "count_digits 10;;\n", 556 "count_digits 9;;\n", 557 "count_digits (-102);;\n", 558 "count_digits (-1002);;\n", 559 "count_digits (-1);;" 560 ] 561 }, 562 { 563 "cell_type": "code", 564 "execution_count": 17, 565 "id": "581edd75-6dac-4cc3-937c-e16797b9fd9e", 566 "metadata": {}, 567 "outputs": [], 568 "source": [ 569 " (* `fib_fast n` computes the same thing but must be *tail recursive* and run\n", 570 " in linear time. Use an inner `let rec go ... in` helper carrying two\n", 571 " accumulators (the previous two Fibonacci numbers).\n", 572 " It must handle fib_fast 1_000_000 without overflowing the stack (the\n", 573 " number itself will wrap around, that is fine, we only care about space). *)" 574 ] 575 }, 576 { 577 "cell_type": "code", 578 "execution_count": 18, 579 "id": "01137212-a52f-4100-9398-989af9a70387", 580 "metadata": {}, 581 "outputs": [ 582 { 583 "data": { 584 "text/plain": [ 585 "val fib_fast : int -> int = <fun>\n" 586 ] 587 }, 588 "execution_count": 18, 589 "metadata": {}, 590 "output_type": "execute_result" 591 } 592 ], 593 "source": [ 594 "let fib_fast m = \n", 595 " let rec go n min_one min_two = \n", 596 " if n >= m\n", 597 " then \n", 598 " if n = 1 then m\n", 599 " else min_one + min_two\n", 600 " else go (n + 1) min_two (min_one + min_two) in\n", 601 " go 1 1 0" 602 ] 603 }, 604 { 605 "cell_type": "code", 606 "execution_count": 19, 607 "id": "7286b831-9e71-4861-b062-ede92b0405aa", 608 "metadata": {}, 609 "outputs": [ 610 { 611 "data": { 612 "text/plain": [ 613 "- : int = 0\n" 614 ] 615 }, 616 "execution_count": 19, 617 "metadata": {}, 618 "output_type": "execute_result" 619 }, 620 { 621 "data": { 622 "text/plain": [ 623 "- : int = 1\n" 624 ] 625 }, 626 "execution_count": 19, 627 "metadata": {}, 628 "output_type": "execute_result" 629 }, 630 { 631 "data": { 632 "text/plain": [ 633 "- : int = 1\n" 634 ] 635 }, 636 "execution_count": 19, 637 "metadata": {}, 638 "output_type": "execute_result" 639 }, 640 { 641 "data": { 642 "text/plain": [ 643 "- : int = 2\n" 644 ] 645 }, 646 "execution_count": 19, 647 "metadata": {}, 648 "output_type": "execute_result" 649 }, 650 { 651 "data": { 652 "text/plain": [ 653 "- : int = 3\n" 654 ] 655 }, 656 "execution_count": 19, 657 "metadata": {}, 658 "output_type": "execute_result" 659 }, 660 { 661 "data": { 662 "text/plain": [ 663 "- : int = 5\n" 664 ] 665 }, 666 "execution_count": 19, 667 "metadata": {}, 668 "output_type": "execute_result" 669 }, 670 { 671 "data": { 672 "text/plain": [ 673 "- : int = 8\n" 674 ] 675 }, 676 "execution_count": 19, 677 "metadata": {}, 678 "output_type": "execute_result" 679 }, 680 { 681 "data": { 682 "text/plain": [ 683 "- : int = 13\n" 684 ] 685 }, 686 "execution_count": 19, 687 "metadata": {}, 688 "output_type": "execute_result" 689 }, 690 { 691 "data": { 692 "text/plain": [ 693 "- : int = 21\n" 694 ] 695 }, 696 "execution_count": 19, 697 "metadata": {}, 698 "output_type": "execute_result" 699 }, 700 { 701 "data": { 702 "text/plain": [ 703 "- : int = 34\n" 704 ] 705 }, 706 "execution_count": 19, 707 "metadata": {}, 708 "output_type": "execute_result" 709 }, 710 { 711 "data": { 712 "text/plain": [ 713 "- : int = 55\n" 714 ] 715 }, 716 "execution_count": 19, 717 "metadata": {}, 718 "output_type": "execute_result" 719 } 720 ], 721 "source": [ 722 "fib_fast 0;;\n", 723 "fib_fast 1;;\n", 724 "fib_fast 2;;\n", 725 "fib_fast 3;;\n", 726 "fib_fast 4;;\n", 727 "fib_fast 5;;\n", 728 "fib_fast 6;;\n", 729 "fib_fast 7;;\n", 730 "fib_fast 8;;\n", 731 "fib_fast 9;;\n", 732 "fib_fast 10;;" 733 ] 734 }, 735 { 736 "cell_type": "code", 737 "execution_count": 20, 738 "id": "c3ebcf22-4a49-48a8-8fb7-b9635c305647", 739 "metadata": {}, 740 "outputs": [ 741 { 742 "data": { 743 "text/plain": [ 744 "val power : int -> int -> int = <fun>\n" 745 ] 746 }, 747 "execution_count": 20, 748 "metadata": {}, 749 "output_type": "execute_result" 750 } 751 ], 752 "source": [ 753 "let power base exp = \n", 754 " let rec go acc exp = \n", 755 " if exp <= 0\n", 756 " then acc\n", 757 " else go (acc * base) (exp - 1) in\n", 758 " go 1 exp" 759 ] 760 }, 761 { 762 "cell_type": "code", 763 "execution_count": 21, 764 "id": "5aa3f86f-5cc4-43ef-ba1b-ce7395c5fd45", 765 "metadata": {}, 766 "outputs": [ 767 { 768 "data": { 769 "text/plain": [ 770 "- : int = 1\n" 771 ] 772 }, 773 "execution_count": 21, 774 "metadata": {}, 775 "output_type": "execute_result" 776 }, 777 { 778 "data": { 779 "text/plain": [ 780 "- : int = 2\n" 781 ] 782 }, 783 "execution_count": 21, 784 "metadata": {}, 785 "output_type": "execute_result" 786 }, 787 { 788 "data": { 789 "text/plain": [ 790 "- : int = 4\n" 791 ] 792 }, 793 "execution_count": 21, 794 "metadata": {}, 795 "output_type": "execute_result" 796 }, 797 { 798 "data": { 799 "text/plain": [ 800 "- : int = 8\n" 801 ] 802 }, 803 "execution_count": 21, 804 "metadata": {}, 805 "output_type": "execute_result" 806 }, 807 { 808 "data": { 809 "text/plain": [ 810 "- : int = 9\n" 811 ] 812 }, 813 "execution_count": 21, 814 "metadata": {}, 815 "output_type": "execute_result" 816 } 817 ], 818 "source": [ 819 "power 2 0;;\n", 820 "power 2 1;;\n", 821 "power 2 2;;\n", 822 "power 2 3;;\n", 823 "power 3 2;;" 824 ] 825 }, 826 { 827 "cell_type": "code", 828 "execution_count": 22, 829 "id": "3ab5d14e-6518-4ecf-a4a7-a19902ca49ec", 830 "metadata": {}, 831 "outputs": [], 832 "source": [ 833 "(* `compose f g` returns the function that applies g first, then f.\n", 834 " Write no type annotation. The inferred type should be\n", 835 " ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b\n", 836 " which is your first taste of polymorphism falling out of inference. *)" 837 ] 838 }, 839 { 840 "cell_type": "code", 841 "execution_count": 23, 842 "id": "69f16a49-d963-4f27-96ea-6180931a3ea9", 843 "metadata": {}, 844 "outputs": [ 845 { 846 "data": { 847 "text/plain": [ 848 "val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>\n" 849 ] 850 }, 851 "execution_count": 23, 852 "metadata": {}, 853 "output_type": "execute_result" 854 } 855 ], 856 "source": [ 857 "let compose f g = fun x -> f (g x);;" 858 ] 859 }, 860 { 861 "cell_type": "code", 862 "execution_count": 24, 863 "id": "e6a0ad52-5b27-4384-9d3e-c320eace2da2", 864 "metadata": {}, 865 "outputs": [ 866 { 867 "data": { 868 "text/plain": [ 869 "- : int = 13\n" 870 ] 871 }, 872 "execution_count": 24, 873 "metadata": {}, 874 "output_type": "execute_result" 875 } 876 ], 877 "source": [ 878 "compose succ (( * ) 3) 4 (* = 13 *)" 879 ] 880 }, 881 { 882 "cell_type": "code", 883 "execution_count": 25, 884 "id": "578a49bd-e885-4107-8cc7-553dc5c70a79", 885 "metadata": {}, 886 "outputs": [ 887 { 888 "data": { 889 "text/plain": [ 890 "val gcd : int -> int -> int = <fun>\n" 891 ] 892 }, 893 "execution_count": 25, 894 "metadata": {}, 895 "output_type": "execute_result" 896 } 897 ], 898 "source": [ 899 "let rec gcd a b = \n", 900 " if b = 0 then a\n", 901 " else gcd b (a mod b)" 902 ] 903 }, 904 { 905 "cell_type": "code", 906 "execution_count": 26, 907 "id": "dfce273a-8c44-49c0-9011-6db991bec36f", 908 "metadata": {}, 909 "outputs": [ 910 { 911 "data": { 912 "text/plain": [ 913 "- : int = 6\n" 914 ] 915 }, 916 "execution_count": 26, 917 "metadata": {}, 918 "output_type": "execute_result" 919 }, 920 { 921 "data": { 922 "text/plain": [ 923 "- : int = 6\n" 924 ] 925 }, 926 "execution_count": 26, 927 "metadata": {}, 928 "output_type": "execute_result" 929 }, 930 { 931 "data": { 932 "text/plain": [ 933 "- : int = 1\n" 934 ] 935 }, 936 "execution_count": 26, 937 "metadata": {}, 938 "output_type": "execute_result" 939 }, 940 { 941 "data": { 942 "text/plain": [ 943 "- : int = 5\n" 944 ] 945 }, 946 "execution_count": 26, 947 "metadata": {}, 948 "output_type": "execute_result" 949 } 950 ], 951 "source": [ 952 "gcd 12 18;;\n", 953 "gcd 270 192;;\n", 954 "gcd 17 15;;\n", 955 "gcd 0 5;;" 956 ] 957 }, 958 { 959 "cell_type": "code", 960 "execution_count": 27, 961 "id": "71305179-f9ac-4684-8490-ba55e1aa5b96", 962 "metadata": {}, 963 "outputs": [], 964 "source": [ 965 "(* --- 17 ------------------------------------------------------------------\n", 966 " `repeat f n x` applies f to x exactly n times: repeat f 3 x = f (f (f x)).\n", 967 " repeat f 0 x = x. Must work for any type, so again no annotations.\n", 968 " This is your accumulator pattern with a *function* as the thing being\n", 969 " applied. *)" 970 ] 971 }, 972 { 973 "cell_type": "code", 974 "execution_count": 28, 975 "id": "068252f8-1ae0-4bce-8c73-e1da077b268b", 976 "metadata": {}, 977 "outputs": [ 978 { 979 "data": { 980 "text/plain": [ 981 "val repeat : ('a -> 'a) -> int -> 'a -> 'a = <fun>\n" 982 ] 983 }, 984 "execution_count": 28, 985 "metadata": {}, 986 "output_type": "execute_result" 987 } 988 ], 989 "source": [ 990 "let rec repeat f n x = \n", 991 " if n = 0\n", 992 " then x\n", 993 " else repeat f (n - 1) (f x)" 994 ] 995 }, 996 { 997 "cell_type": "code", 998 "execution_count": 29, 999 "id": "cf8b242f-0a0b-4169-af6e-74370bbda435", 1000 "metadata": {}, 1001 "outputs": [ 1002 { 1003 "data": { 1004 "text/plain": [ 1005 "val add_5 : int -> int = <fun>\n" 1006 ] 1007 }, 1008 "execution_count": 29, 1009 "metadata": {}, 1010 "output_type": "execute_result" 1011 }, 1012 { 1013 "data": { 1014 "text/plain": [ 1015 "- : int = 52\n" 1016 ] 1017 }, 1018 "execution_count": 29, 1019 "metadata": {}, 1020 "output_type": "execute_result" 1021 } 1022 ], 1023 "source": [ 1024 "let add_5 x = x + 5;;\n", 1025 "\n", 1026 "repeat add_5 10 2;;" 1027 ] 1028 }, 1029 { 1030 "cell_type": "code", 1031 "execution_count": 30, 1032 "id": "5b4f9d85-d6d6-4b9f-8bef-067b9df432cd", 1033 "metadata": {}, 1034 "outputs": [], 1035 "source": [ 1036 "(* --- 10 ------------------------------------------------------------------\n", 1037 " NEW IDEA: an accumulator that *builds a value* rather than counting one.\n", 1038 "\n", 1039 " `reverse_int n` reverses the decimal digits of n, for n >= 0. Leading\n", 1040 " zeros simply disappear, since the result is a number, not text.\n", 1041 "\n", 1042 " reverse_int 1234 = 4321 reverse_int 1200 = 21\n", 1043 " reverse_int 7 = 7 reverse_int 0 = 0\n", 1044 "\n", 1045 " Tail recursive. Each step peels one digit off n with `mod 10` and pushes\n", 1046 " it onto the accumulator. Pushing a digit onto a number is the arithmetic\n", 1047 " you have to work out.\n", 1048 "\n", 1049 " Once this works, note that `reverse_int n = n` is a palindrome test. *)" 1050 ] 1051 }, 1052 { 1053 "cell_type": "code", 1054 "execution_count": 31, 1055 "id": "12e04876-a113-4f9c-8ab5-b1c0065f058a", 1056 "metadata": {}, 1057 "outputs": [ 1058 { 1059 "data": { 1060 "text/plain": [ 1061 "val reverse_int : int -> int = <fun>\n" 1062 ] 1063 }, 1064 "execution_count": 31, 1065 "metadata": {}, 1066 "output_type": "execute_result" 1067 } 1068 ], 1069 "source": [ 1070 "let reverse_int n = \n", 1071 " let rec go ret_val running =\n", 1072 " if running = 0\n", 1073 " then ret_val\n", 1074 " else\n", 1075 " go (ret_val * 10 + ((running mod 10))) (running / 10)\n", 1076 " in\n", 1077 " go 0 n" 1078 ] 1079 }, 1080 { 1081 "cell_type": "code", 1082 "execution_count": 32, 1083 "id": "6bf2e53b-922f-4beb-a3d7-0e3b27887e7e", 1084 "metadata": {}, 1085 "outputs": [ 1086 { 1087 "data": { 1088 "text/plain": [ 1089 "- : int = 7\n" 1090 ] 1091 }, 1092 "execution_count": 32, 1093 "metadata": {}, 1094 "output_type": "execute_result" 1095 }, 1096 { 1097 "data": { 1098 "text/plain": [ 1099 "- : int = 4321\n" 1100 ] 1101 }, 1102 "execution_count": 32, 1103 "metadata": {}, 1104 "output_type": "execute_result" 1105 }, 1106 { 1107 "data": { 1108 "text/plain": [ 1109 "- : int = 21\n" 1110 ] 1111 }, 1112 "execution_count": 32, 1113 "metadata": {}, 1114 "output_type": "execute_result" 1115 }, 1116 { 1117 "data": { 1118 "text/plain": [ 1119 "- : int = 0\n" 1120 ] 1121 }, 1122 "execution_count": 32, 1123 "metadata": {}, 1124 "output_type": "execute_result" 1125 }, 1126 { 1127 "data": { 1128 "text/plain": [ 1129 "- : int = 921\n" 1130 ] 1131 }, 1132 "execution_count": 32, 1133 "metadata": {}, 1134 "output_type": "execute_result" 1135 } 1136 ], 1137 "source": [ 1138 "reverse_int 700;;\n", 1139 "reverse_int 1234;;\n", 1140 "reverse_int 1200;;\n", 1141 "reverse_int 0;;\n", 1142 "reverse_int 1290;;" 1143 ] 1144 }, 1145 { 1146 "cell_type": "code", 1147 "execution_count": 33, 1148 "id": "36ad5f0c-0db0-4297-b7dc-92038a2d50f7", 1149 "metadata": {}, 1150 "outputs": [ 1151 { 1152 "data": { 1153 "text/plain": [ 1154 "- : int = 11\n" 1155 ] 1156 }, 1157 "execution_count": 33, 1158 "metadata": {}, 1159 "output_type": "execute_result" 1160 } 1161 ], 1162 "source": [ 1163 "let x = 5 in ((let x = 6 in x) + x)" 1164 ] 1165 }, 1166 { 1167 "cell_type": "code", 1168 "execution_count": 34, 1169 "id": "3692ddcf-fc68-4657-9a46-991ab5d0f10d", 1170 "metadata": {}, 1171 "outputs": [ 1172 { 1173 "data": { 1174 "text/plain": [ 1175 "- : int = 2\n" 1176 ] 1177 }, 1178 "execution_count": 34, 1179 "metadata": {}, 1180 "output_type": "execute_result" 1181 } 1182 ], 1183 "source": [ 1184 "(fun x -> x + 1) 1;;" 1185 ] 1186 }, 1187 { 1188 "cell_type": "code", 1189 "execution_count": 35, 1190 "id": "8d938958-ba4f-481a-9b48-08d81d75bd78", 1191 "metadata": {}, 1192 "outputs": [ 1193 { 1194 "data": { 1195 "text/plain": [ 1196 "val add_2 : int -> int = <fun>\n" 1197 ] 1198 }, 1199 "execution_count": 35, 1200 "metadata": {}, 1201 "output_type": "execute_result" 1202 }, 1203 { 1204 "data": { 1205 "text/plain": [ 1206 "val sub_1 : int -> int = <fun>\n" 1207 ] 1208 }, 1209 "execution_count": 35, 1210 "metadata": {}, 1211 "output_type": "execute_result" 1212 }, 1213 { 1214 "data": { 1215 "text/plain": [ 1216 "val mul_2 : int -> int = <fun>\n" 1217 ] 1218 }, 1219 "execution_count": 35, 1220 "metadata": {}, 1221 "output_type": "execute_result" 1222 }, 1223 { 1224 "data": { 1225 "text/plain": [ 1226 "- : int = 6\n" 1227 ] 1228 }, 1229 "execution_count": 35, 1230 "metadata": {}, 1231 "output_type": "execute_result" 1232 } 1233 ], 1234 "source": [ 1235 "let add_2 x = x + 2;;\n", 1236 "let sub_1 x = x - 1;;\n", 1237 "let mul_2 x = x * 2;;\n", 1238 "\n", 1239 "mul_2 (sub_1 (add_2 2));; \n", 1240 "\n", 1241 "(* Parenthesis needed above. *)" 1242 ] 1243 }, 1244 { 1245 "cell_type": "code", 1246 "execution_count": 36, 1247 "id": "6b097ffd-fb7d-4694-b61a-9c7105c632e1", 1248 "metadata": {}, 1249 "outputs": [], 1250 "source": [ 1251 "(* 13\n", 1252 "\n", 1253 "NEW IDEA: the shape of the recursion changes the complexity class.\n", 1254 "\n", 1255 "power in 8 does exp multiplications. power_fast must do about log2(exp) of\n", 1256 "them, by squaring:\n", 1257 "\n", 1258 " b^e = (b*b)^(e/2) when e is even\n", 1259 " b^e = b * (b*b)^(e/2) when e is odd, using integer division\n", 1260 "\n", 1261 "Each step halves the exponent instead of decrementing it. Tail recursive, so\n", 1262 "carry the collected-so-far factor in an accumulator.\n", 1263 "\n", 1264 "power_fast 2 10 = 1024, power_fast 3 5 = 243, power_fast 7 0 = 1,\n", 1265 "power_fast 2 61 = 2305843009213693952.\n", 1266 "\n", 1267 "Then try power_fast 2 1_000_000_000. A linear version would still be running\n", 1268 "tomorrow; a logarithmic one finishes instantly. That difference is the test.\n", 1269 "\n", 1270 "*)" 1271 ] 1272 }, 1273 { 1274 "cell_type": "code", 1275 "execution_count": 37, 1276 "id": "16b79160-9c4c-414f-9e06-475b088d02a4", 1277 "metadata": {}, 1278 "outputs": [ 1279 { 1280 "data": { 1281 "text/plain": [ 1282 "val power_fast : int -> int -> int = <fun>\n" 1283 ] 1284 }, 1285 "execution_count": 37, 1286 "metadata": {}, 1287 "output_type": "execute_result" 1288 } 1289 ], 1290 "source": [ 1291 "let power_fast base exp = \n", 1292 " let rec go acc base exp =\n", 1293 " if exp = 0\n", 1294 " then\n", 1295 " acc \n", 1296 " else\n", 1297 " if exp mod 2 = 0\n", 1298 " then\n", 1299 " go acc (base * base) (exp / 2)\n", 1300 " else\n", 1301 " go (acc * base) (base * base) ((exp - 1) / 2)\n", 1302 " in go 1 base exp\n", 1303 " " 1304 ] 1305 }, 1306 { 1307 "cell_type": "code", 1308 "execution_count": 38, 1309 "id": "2ebe0d8f-7740-440e-8dfb-51d851f91de9", 1310 "metadata": {}, 1311 "outputs": [ 1312 { 1313 "data": { 1314 "text/plain": [ 1315 "- : int = 3125\n" 1316 ] 1317 }, 1318 "execution_count": 38, 1319 "metadata": {}, 1320 "output_type": "execute_result" 1321 }, 1322 { 1323 "data": { 1324 "text/plain": [ 1325 "- : int = 25\n" 1326 ] 1327 }, 1328 "execution_count": 38, 1329 "metadata": {}, 1330 "output_type": "execute_result" 1331 }, 1332 { 1333 "data": { 1334 "text/plain": [ 1335 "- : int = 1\n" 1336 ] 1337 }, 1338 "execution_count": 38, 1339 "metadata": {}, 1340 "output_type": "execute_result" 1341 }, 1342 { 1343 "data": { 1344 "text/plain": [ 1345 "- : int = 5\n" 1346 ] 1347 }, 1348 "execution_count": 38, 1349 "metadata": {}, 1350 "output_type": "execute_result" 1351 }, 1352 { 1353 "data": { 1354 "text/plain": [ 1355 "- : int = 1\n" 1356 ] 1357 }, 1358 "execution_count": 38, 1359 "metadata": {}, 1360 "output_type": "execute_result" 1361 }, 1362 { 1363 "data": { 1364 "text/plain": [ 1365 "- : int = 2\n" 1366 ] 1367 }, 1368 "execution_count": 38, 1369 "metadata": {}, 1370 "output_type": "execute_result" 1371 }, 1372 { 1373 "data": { 1374 "text/plain": [ 1375 "- : int = 4\n" 1376 ] 1377 }, 1378 "execution_count": 38, 1379 "metadata": {}, 1380 "output_type": "execute_result" 1381 }, 1382 { 1383 "data": { 1384 "text/plain": [ 1385 "- : int = 243\n" 1386 ] 1387 }, 1388 "execution_count": 38, 1389 "metadata": {}, 1390 "output_type": "execute_result" 1391 }, 1392 { 1393 "data": { 1394 "text/plain": [ 1395 "- : int = 243\n" 1396 ] 1397 }, 1398 "execution_count": 38, 1399 "metadata": {}, 1400 "output_type": "execute_result" 1401 }, 1402 { 1403 "data": { 1404 "text/plain": [ 1405 "- : int = 81\n" 1406 ] 1407 }, 1408 "execution_count": 38, 1409 "metadata": {}, 1410 "output_type": "execute_result" 1411 }, 1412 { 1413 "data": { 1414 "text/plain": [ 1415 "- : int = 243\n" 1416 ] 1417 }, 1418 "execution_count": 38, 1419 "metadata": {}, 1420 "output_type": "execute_result" 1421 } 1422 ], 1423 "source": [ 1424 "power_fast 5 5;;\n", 1425 "power_fast 5 2;;\n", 1426 "power_fast 5 0;;\n", 1427 "power_fast 5 1;;\n", 1428 "\n", 1429 "power_fast 2 0;;\n", 1430 "power_fast 2 1;;\n", 1431 "power_fast 2 2;;\n", 1432 "\n", 1433 "power_fast 3 5;;\n", 1434 "\n", 1435 "27 * power_fast 3 2;;\n", 1436 "27 * 3;;\n", 1437 "81 * 3;;" 1438 ] 1439 }, 1440 { 1441 "cell_type": "code", 1442 "execution_count": 39, 1443 "id": "bbe1a653-56d1-4d96-a13a-692e0d5296bf", 1444 "metadata": {}, 1445 "outputs": [], 1446 "source": [ 1447 "(* 12\n", 1448 "\n", 1449 "NEW IDEA: mutual recursion. Two functions that call each other are defined\n", 1450 "together, joined by and:\n", 1451 "\n", 1452 " let rec f x = ... g ... and g x = ... f ...\n", 1453 "\n", 1454 "Define is_even and is_odd for n >= 0 without using mod, division, or each\n", 1455 "other's arithmetic, only by counting down and handing off to the other\n", 1456 "function. Both must be tail recursive, so is_even 1_000_000 must not overflow\n", 1457 "the stack.\n", 1458 "\n", 1459 "is_even 0 = true, is_odd 0 = false, is_even 7 = false, is_odd 7 = true.\n", 1460 "\n", 1461 "*)" 1462 ] 1463 }, 1464 { 1465 "cell_type": "code", 1466 "execution_count": 40, 1467 "id": "71055e50-d3d3-4511-87c5-955f181dd788", 1468 "metadata": {}, 1469 "outputs": [ 1470 { 1471 "data": { 1472 "text/plain": [ 1473 "val is_even : int -> bool = <fun>\n", 1474 "val is_odd : int -> bool = <fun>\n" 1475 ] 1476 }, 1477 "execution_count": 40, 1478 "metadata": {}, 1479 "output_type": "execute_result" 1480 } 1481 ], 1482 "source": [ 1483 "let rec is_even n = \n", 1484 " if n = 0 \n", 1485 " then true\n", 1486 " else is_odd (n - 1)\n", 1487 "and is_odd n = \n", 1488 " if n = 0 \n", 1489 " then false\n", 1490 " else is_even (n - 1)\n", 1491 "(* \n", 1492 "This is tail recursive because no further computations are required\n", 1493 "once the invoked function returns to the caller\n", 1494 "*)" 1495 ] 1496 }, 1497 { 1498 "cell_type": "code", 1499 "execution_count": 41, 1500 "id": "1d868719-1713-4448-9493-dd5e3063b242", 1501 "metadata": {}, 1502 "outputs": [ 1503 { 1504 "data": { 1505 "text/plain": [ 1506 "- : bool = true\n" 1507 ] 1508 }, 1509 "execution_count": 41, 1510 "metadata": {}, 1511 "output_type": "execute_result" 1512 }, 1513 { 1514 "data": { 1515 "text/plain": [ 1516 "- : bool = false\n" 1517 ] 1518 }, 1519 "execution_count": 41, 1520 "metadata": {}, 1521 "output_type": "execute_result" 1522 }, 1523 { 1524 "data": { 1525 "text/plain": [ 1526 "- : bool = true\n" 1527 ] 1528 }, 1529 "execution_count": 41, 1530 "metadata": {}, 1531 "output_type": "execute_result" 1532 }, 1533 { 1534 "data": { 1535 "text/plain": [ 1536 "- : bool = false\n" 1537 ] 1538 }, 1539 "execution_count": 41, 1540 "metadata": {}, 1541 "output_type": "execute_result" 1542 }, 1543 { 1544 "data": { 1545 "text/plain": [ 1546 "- : bool = true\n" 1547 ] 1548 }, 1549 "execution_count": 41, 1550 "metadata": {}, 1551 "output_type": "execute_result" 1552 } 1553 ], 1554 "source": [ 1555 "is_even 0;;\n", 1556 "is_even 1;;\n", 1557 "is_even 2;;\n", 1558 "is_even 3;;\n", 1559 "is_even 300000000;;" 1560 ] 1561 }, 1562 { 1563 "cell_type": "code", 1564 "execution_count": 42, 1565 "id": "4a1fd467-9ff0-43d3-89ab-71772f42c611", 1566 "metadata": {}, 1567 "outputs": [], 1568 "source": [ 1569 "(* 11\n", 1570 "\n", 1571 "NEW IDEA: the accumulator can be a string.\n", 1572 "\n", 1573 "to_binary n returns the base-2 representation of n >= 0 as a string. Tail\n", 1574 "recursive. ^ concatenates strings and string_of_int turns a digit into one.\n", 1575 "Peeling with mod 2 produces the digits backwards, and the fix is a matter of\n", 1576 "which side you concatenate on. n = 0 needs thought, since the natural loop\n", 1577 "produces the empty string.\n", 1578 "\n", 1579 "to_binary 0 = \"0\", to_binary 1 = \"1\", to_binary 5 = \"101\",\n", 1580 "to_binary 10 = \"1010\", to_binary 255 = \"11111111\".\n", 1581 "\n", 1582 "*)" 1583 ] 1584 }, 1585 { 1586 "cell_type": "code", 1587 "execution_count": 43, 1588 "id": "b337c48c-eda6-48b0-a2cb-d88436e0a39d", 1589 "metadata": {}, 1590 "outputs": [ 1591 { 1592 "data": { 1593 "text/plain": [ 1594 "val to_binary : int -> string = <fun>\n" 1595 ] 1596 }, 1597 "execution_count": 43, 1598 "metadata": {}, 1599 "output_type": "execute_result" 1600 } 1601 ], 1602 "source": [ 1603 "let to_binary n = \n", 1604 " let rec go acc current =\n", 1605 " if current <= 1\n", 1606 " then string_of_int current ^ acc\n", 1607 " else\n", 1608 " if current mod 2 = 0\n", 1609 " then go (\"0\" ^ acc) ((current) / 2)\n", 1610 " else\n", 1611 " go (\"1\" ^ acc) ((current - 1) / 2)\n", 1612 " in go \"\" n" 1613 ] 1614 }, 1615 { 1616 "cell_type": "code", 1617 "execution_count": 44, 1618 "id": "5cb1a2ed-ac2b-4096-812f-eaf642455207", 1619 "metadata": {}, 1620 "outputs": [ 1621 { 1622 "data": { 1623 "text/plain": [ 1624 "- : string = \"1010\"\n" 1625 ] 1626 }, 1627 "execution_count": 44, 1628 "metadata": {}, 1629 "output_type": "execute_result" 1630 }, 1631 { 1632 "data": { 1633 "text/plain": [ 1634 "- : string = \"10\"\n" 1635 ] 1636 }, 1637 "execution_count": 44, 1638 "metadata": {}, 1639 "output_type": "execute_result" 1640 }, 1641 { 1642 "data": { 1643 "text/plain": [ 1644 "- : string = \"1\"\n" 1645 ] 1646 }, 1647 "execution_count": 44, 1648 "metadata": {}, 1649 "output_type": "execute_result" 1650 } 1651 ], 1652 "source": [ 1653 "to_binary 10;;\n", 1654 "to_binary 2;;\n", 1655 "to_binary 1;;" 1656 ] 1657 }, 1658 { 1659 "cell_type": "code", 1660 "execution_count": 45, 1661 "id": "c234416c-be09-4265-84f8-473c684d5e13", 1662 "metadata": {}, 1663 "outputs": [ 1664 { 1665 "data": { 1666 "text/plain": [ 1667 "- : int = 55\n" 1668 ] 1669 }, 1670 "execution_count": 45, 1671 "metadata": {}, 1672 "output_type": "execute_result" 1673 }, 1674 { 1675 "data": { 1676 "text/plain": [ 1677 "- : int = 55\n" 1678 ] 1679 }, 1680 "execution_count": 45, 1681 "metadata": {}, 1682 "output_type": "execute_result" 1683 } 1684 ], 1685 "source": [ 1686 "fib 10;;\n", 1687 "fib_fast 10;;" 1688 ] 1689 }, 1690 { 1691 "cell_type": "code", 1692 "execution_count": 46, 1693 "id": "831079e0-85d8-4799-9283-139e8b33af7c", 1694 "metadata": {}, 1695 "outputs": [], 1696 "source": [ 1697 "(* 14\n", 1698 "\n", 1699 "NEW IDEA: carrying a search interval rather than a value, and choosing an\n", 1700 "invariant you can state.\n", 1701 "\n", 1702 "int_sqrt n returns the largest k such that k*k <= n, for n >= 0, so it\n", 1703 "truncates. Do it by binary search, tail recursively, with an inner helper\n", 1704 "carrying lo and hi.\n", 1705 "\n", 1706 "Before writing it, decide the invariant in words: what must always be true of\n", 1707 "lo and hi? Getting that sentence right is most of the work, and off-by-one\n", 1708 "errors here are the norm rather than a failure.\n", 1709 "\n", 1710 "One trap worth knowing in advance: for n near 10^12, starting hi at n makes\n", 1711 "mid * mid overflow a 63-bit int silently. Either start hi somewhere smaller\n", 1712 "that is still definitely above the answer, or compare without multiplying.\n", 1713 "\n", 1714 "int_sqrt 0 = 0, int_sqrt 15 = 3, int_sqrt 16 = 4, int_sqrt 17 = 4,\n", 1715 "int_sqrt 1_000_000_000_000 = 1_000_000.\n", 1716 "\n", 1717 "*)" 1718 ] 1719 }, 1720 { 1721 "cell_type": "code", 1722 "execution_count": 47, 1723 "id": "0ac0572b-66a4-4a18-aefa-7de3d02515ba", 1724 "metadata": { 1725 "deletable": true, 1726 "editable": true, 1727 "slideshow": { 1728 "slide_type": "" 1729 }, 1730 "tags": [] 1731 }, 1732 "outputs": [ 1733 { 1734 "data": { 1735 "text/plain": [ 1736 "val int_sqrt : int -> int = <fun>\n" 1737 ] 1738 }, 1739 "execution_count": 47, 1740 "metadata": {}, 1741 "output_type": "execute_result" 1742 } 1743 ], 1744 "source": [ 1745 "let int_sqrt n = \n", 1746 " let rec go low hi =\n", 1747 " if hi - low <= 1 \n", 1748 " then \n", 1749 " if hi = 0 then 0 else\n", 1750 " if hi > n / hi then low else hi\n", 1751 " else\n", 1752 " let mid = hi - ((hi - low) / 2) in\n", 1753 " if mid > n / mid\n", 1754 " then\n", 1755 " go low mid\n", 1756 " else\n", 1757 " go mid hi\n", 1758 " in go 0 n" 1759 ] 1760 }, 1761 { 1762 "cell_type": "code", 1763 "execution_count": 69, 1764 "id": "e13a3ee4-4bde-4a15-ae6f-62db9447c748", 1765 "metadata": {}, 1766 "outputs": [ 1767 { 1768 "data": { 1769 "text/plain": [ 1770 "- : int = 4\n" 1771 ] 1772 }, 1773 "execution_count": 69, 1774 "metadata": {}, 1775 "output_type": "execute_result" 1776 }, 1777 { 1778 "data": { 1779 "text/plain": [ 1780 "- : int = 3\n" 1781 ] 1782 }, 1783 "execution_count": 69, 1784 "metadata": {}, 1785 "output_type": "execute_result" 1786 }, 1787 { 1788 "data": { 1789 "text/plain": [ 1790 "- : int = 4\n" 1791 ] 1792 }, 1793 "execution_count": 69, 1794 "metadata": {}, 1795 "output_type": "execute_result" 1796 }, 1797 { 1798 "data": { 1799 "text/plain": [ 1800 "- : int = 3\n" 1801 ] 1802 }, 1803 "execution_count": 69, 1804 "metadata": {}, 1805 "output_type": "execute_result" 1806 }, 1807 { 1808 "data": { 1809 "text/plain": [ 1810 "- : int = 3\n" 1811 ] 1812 }, 1813 "execution_count": 69, 1814 "metadata": {}, 1815 "output_type": "execute_result" 1816 }, 1817 { 1818 "data": { 1819 "text/plain": [ 1820 "- : int = 0\n" 1821 ] 1822 }, 1823 "execution_count": 69, 1824 "metadata": {}, 1825 "output_type": "execute_result" 1826 }, 1827 { 1828 "data": { 1829 "text/plain": [ 1830 "- : int = 1000000\n" 1831 ] 1832 }, 1833 "execution_count": 69, 1834 "metadata": {}, 1835 "output_type": "execute_result" 1836 } 1837 ], 1838 "source": [ 1839 "int_sqrt 17;;\n", 1840 "int_sqrt 10;;\n", 1841 "int_sqrt 16;;\n", 1842 "int_sqrt 12;;\n", 1843 "int_sqrt 11;;\n", 1844 "int_sqrt 0;;\n", 1845 "int_sqrt 1000000000000;;" 1846 ] 1847 }, 1848 { 1849 "cell_type": "code", 1850 "execution_count": 120, 1851 "id": "7415ca41-1c3a-4828-af4e-51736596bb3f", 1852 "metadata": {}, 1853 "outputs": [ 1854 { 1855 "name": "stdout", 1856 "output_type": "stream", 1857 "text": [ 1858 "- : unit = ()\n", 1859 "Findlib has been successfully loaded. Additional directives:\n", 1860 " #require \"package\";; to load a package\n", 1861 " #list;; to list the available packages\n", 1862 " #camlp4o;; to load camlp4 (standard syntax)\n", 1863 " #camlp4r;; to load camlp4 (revised syntax)\n", 1864 " #predicates \"p,q,...\";; to set these predicates\n", 1865 " Topfind.reset();; to force that packages will be reloaded\n", 1866 " #thread;; to enable threads\n", 1867 "\n", 1868 "- : unit = ()\n" 1869 ] 1870 } 1871 ], 1872 "source": [ 1873 "#use \"topfind\";;\n", 1874 "#require \"qcheck\";;" 1875 ] 1876 }, 1877 { 1878 "cell_type": "code", 1879 "execution_count": 124, 1880 "id": "7bc3f682-7c8b-4520-aeb0-9bb33a802e22", 1881 "metadata": {}, 1882 "outputs": [ 1883 { 1884 "data": { 1885 "text/plain": [ 1886 "val squared_invariant : QCheck.Test.t = QCheck2.Test.Test <abstr>\n" 1887 ] 1888 }, 1889 "execution_count": 124, 1890 "metadata": {}, 1891 "output_type": "execute_result" 1892 }, 1893 { 1894 "name": "stdout", 1895 "output_type": "stream", 1896 "text": [ 1897 "================================================================================\n", 1898 "\u001b[32;1msuccess\u001b[0m (ran 1 tests)\n" 1899 ] 1900 }, 1901 { 1902 "data": { 1903 "text/plain": [ 1904 "- : int = 0\n" 1905 ] 1906 }, 1907 "execution_count": 124, 1908 "metadata": {}, 1909 "output_type": "execute_result" 1910 } 1911 ], 1912 "source": [ 1913 "let squared_invariant = QCheck.Test.make\n", 1914 " (QCheck.int_range 0 212000)\n", 1915 " (fun n -> n == int_sqrt (n * n));;\n", 1916 "\n", 1917 "QCheck_base_runner.run_tests [ squared_invariant ];;" 1918 ] 1919 } 1920 ], 1921 "metadata": { 1922 "kernelspec": { 1923 "display_name": "OCaml default", 1924 "language": "OCaml", 1925 "name": "ocaml-jupyter" 1926 }, 1927 "language_info": { 1928 "codemirror_mode": "text/x-ocaml", 1929 "file_extension": ".ml", 1930 "mimetype": "text/x-ocaml", 1931 "name": "OCaml", 1932 "nbconverter_exporter": null, 1933 "pygments_lexer": "OCaml", 1934 "version": "4.14.2" 1935 } 1936 }, 1937 "nbformat": 4, 1938 "nbformat_minor": 5 1939 }