ocaml-programming

Simple OCaml programs
git clone git://git.laack.co/ocaml-programming.git
Log | Files | Refs | README

exercises_p2.ipynb (6952B)


      1 {
      2  "cells": [
      3   {
      4    "cell_type": "code",
      5    "execution_count": null,
      6    "id": "ef154598-e0d1-4721-a171-f8cdb8340bc8",
      7    "metadata": {},
      8    "outputs": [],
      9    "source": [
     10     "(* 15\n",
     11     "\n",
     12     "NEW IDEA: recursion that stops when it is close enough, because floats cannot\n",
     13     "be compared for equality.\n",
     14     "\n",
     15     "newton_sqrt x approximates the square root of x >= 0 by Newton's method. Start\n",
     16     "from a guess and repeatedly improve it with\n",
     17     "\n",
     18     "    next = (guess +. x /. guess) /. 2.\n",
     19     "\n",
     20     "Stop when the guess is good enough, when abs_float (guess *. guess -. x) is\n",
     21     "below a small tolerance such as 1e-10. Note that x itself works as a starting\n",
     22     "guess, except for x = 0.\n",
     23     "\n",
     24     "Do not write guess *. guess = x. Floats are approximations, that test would\n",
     25     "loop forever, and it is the same reason 0.1 +. 0.2 = 0.3 is false in every\n",
     26     "language with binary floats.\n",
     27     "\n",
     28     "newton_sqrt 2.0 is about 1.4142135, newton_sqrt 81.0 = 9.0,\n",
     29     "newton_sqrt 0.0 = 0.0.\n",
     30     "\n",
     31     "Afterwards try newton_sqrt 1e12 and work out why an absolute tolerance of\n",
     32     "1e-10 cannot terminate there. A double has about 16 significant digits, so near\n",
     33     "1e12 the gap between neighbouring representable values is already larger than\n",
     34     "1e-10. Fixing it means comparing relatively, for instance stopping when\n",
     35     "successive guesses barely change.\n",
     36     "\n",
     37     "*)"
     38    ]
     39   },
     40   {
     41    "cell_type": "code",
     42    "execution_count": 54,
     43    "id": "11e1e0c3-1f65-4251-998a-69804398e6a3",
     44    "metadata": {},
     45    "outputs": [
     46     {
     47      "data": {
     48       "text/plain": [
     49        "val abs_diff : float -> float -> float = <fun>\n"
     50       ]
     51      },
     52      "execution_count": 54,
     53      "metadata": {},
     54      "output_type": "execute_result"
     55     },
     56     {
     57      "data": {
     58       "text/plain": [
     59        "val newton_sqrt : float -> float = <fun>\n"
     60       ]
     61      },
     62      "execution_count": 54,
     63      "metadata": {},
     64      "output_type": "execute_result"
     65     }
     66    ],
     67    "source": [
     68     "let abs_diff x y = abs_float (x -. y);;\n",
     69     "\n",
     70     "let newton_sqrt x = \n",
     71     "    let rec go guess = \n",
     72     "        let diff = abs_diff x (guess *. guess) in\n",
     73     "            if diff < 0.0000000001\n",
     74     "                then guess\n",
     75     "            else go ((guess +. x /. guess) /. 2.)\n",
     76     "    in go x;;\n"
     77    ]
     78   },
     79   {
     80    "cell_type": "code",
     81    "execution_count": 55,
     82    "id": "1c13de25-3a65-4c53-be93-30aeaa43e3f4",
     83    "metadata": {},
     84    "outputs": [
     85     {
     86      "name": "stdout",
     87      "output_type": "stream",
     88      "text": [
     89       "- : unit = ()\n",
     90       "Findlib has been successfully loaded. Additional directives:\n",
     91       "  #require \"package\";;      to load a package\n",
     92       "  #list;;                   to list the available packages\n",
     93       "  #camlp4o;;                to load camlp4 (standard syntax)\n",
     94       "  #camlp4r;;                to load camlp4 (revised syntax)\n",
     95       "  #predicates \"p,q,...\";;   to set these predicates\n",
     96       "  Topfind.reset();;         to force that packages will be reloaded\n",
     97       "  #thread;;                 to enable threads\n",
     98       "\n",
     99       "- : unit = ()\n"
    100      ]
    101     }
    102    ],
    103    "source": [
    104     "#use \"topfind\";;\n",
    105     "#require \"qcheck\";;"
    106    ]
    107   },
    108   {
    109    "cell_type": "code",
    110    "execution_count": 56,
    111    "id": "c54a0a4c-a9f0-4ebd-bd59-d7fc331b51ad",
    112    "metadata": {},
    113    "outputs": [
    114     {
    115      "data": {
    116       "text/plain": [
    117        "val abs_diff : float -> float -> float = <fun>\n"
    118       ]
    119      },
    120      "execution_count": 56,
    121      "metadata": {},
    122      "output_type": "execute_result"
    123     }
    124    ],
    125    "source": [
    126     "let abs_diff x y = abs_float (x -. y);;"
    127    ]
    128   },
    129   {
    130    "cell_type": "code",
    131    "execution_count": 57,
    132    "id": "3bc48b8e-6aee-4438-9db0-561c4045ce99",
    133    "metadata": {},
    134    "outputs": [
    135     {
    136      "data": {
    137       "text/plain": [
    138        "- : float = 2.00000000000451061\n"
    139       ]
    140      },
    141      "execution_count": 57,
    142      "metadata": {},
    143      "output_type": "execute_result"
    144     }
    145    ],
    146    "source": [
    147     "newton_sqrt 2. *. newton_sqrt 2."
    148    ]
    149   },
    150   {
    151    "cell_type": "code",
    152    "execution_count": 58,
    153    "id": "f307630e-b1a1-45a1-a42f-6a934f0602dd",
    154    "metadata": {},
    155    "outputs": [
    156     {
    157      "data": {
    158       "text/plain": [
    159        "- : bool = true\n"
    160       ]
    161      },
    162      "execution_count": 58,
    163      "metadata": {},
    164      "output_type": "execute_result"
    165     }
    166    ],
    167    "source": [
    168     "(abs_diff 2. ((newton_sqrt 2.) *. (newton_sqrt 2.))) < 0.01"
    169    ]
    170   },
    171   {
    172    "cell_type": "code",
    173    "execution_count": 59,
    174    "id": "04f59f1f-fbb1-40f3-a8e8-67dc1aa54231",
    175    "metadata": {},
    176    "outputs": [],
    177    "source": [
    178     "(* 16\n",
    179     "\n",
    180     "NEW IDEA: two accumulators tracking the best answer so far, the functional\n",
    181     "version of keeping a running maximum.\n",
    182     "\n",
    183     "busiest_collatz lo hi returns which n in the range lo..hi takes the most\n",
    184     "Collatz steps to reach 1. On a tie, return the smallest such n.\n",
    185     "\n",
    186     "*)"
    187    ]
    188   },
    189   {
    190    "cell_type": "code",
    191    "execution_count": 103,
    192    "id": "2030e995-98d6-4ca4-b450-d50004487746",
    193    "metadata": {},
    194    "outputs": [
    195     {
    196      "data": {
    197       "text/plain": [
    198        "val busiest_collatz : int -> int -> int = <fun>\n"
    199       ]
    200      },
    201      "execution_count": 103,
    202      "metadata": {},
    203      "output_type": "execute_result"
    204     }
    205    ],
    206    "source": [
    207     "let busiest_collatz lo hi = \n",
    208     "    let rec col_calc n = \n",
    209     "        if n = 1 then 1 else\n",
    210     "        if n mod 2 = 0 \n",
    211     "            then ((col_calc (n / 2))) + 1\n",
    212     "            else ((col_calc ((3 * n) + 1))) + 1\n",
    213     "    in \n",
    214     "    let rec go best_num best_count current_num =\n",
    215     "        if current_num < lo then best_num\n",
    216     "        else\n",
    217     "            let current_count = (col_calc current_num) in\n",
    218     "            if current_count >= best_count\n",
    219     "                then go current_num current_count (current_num - 1)\n",
    220     "            else\n",
    221     "                go best_num best_count (current_num - 1)\n",
    222     "    in go 0 0 hi"
    223    ]
    224   },
    225   {
    226    "cell_type": "code",
    227    "execution_count": 106,
    228    "id": "a17b339d-0d3b-455c-8f31-2c6d10251134",
    229    "metadata": {},
    230    "outputs": [
    231     {
    232      "data": {
    233       "text/plain": [
    234        "- : int = 837799\n"
    235       ]
    236      },
    237      "execution_count": 106,
    238      "metadata": {},
    239      "output_type": "execute_result"
    240     }
    241    ],
    242    "source": [
    243     "busiest_collatz 1 1000000"
    244    ]
    245   }
    246  ],
    247  "metadata": {
    248   "kernelspec": {
    249    "display_name": "OCaml default",
    250    "language": "OCaml",
    251    "name": "ocaml-jupyter"
    252   },
    253   "language_info": {
    254    "codemirror_mode": "text/x-ocaml",
    255    "file_extension": ".ml",
    256    "mimetype": "text/x-ocaml",
    257    "name": "OCaml",
    258    "nbconverter_exporter": null,
    259    "pygments_lexer": "OCaml",
    260    "version": "4.14.2"
    261   }
    262  },
    263  "nbformat": 4,
    264  "nbformat_minor": 5
    265 }