File: sieve.ml

package info (click to toggle)
ocaml-doc 3.09-1
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 10,428 kB
  • ctags: 4,963
  • sloc: ml: 9,244; makefile: 2,413; ansic: 122; sh: 49; asm: 17
file content (95 lines) | stat: -rw-r--r-- 2,616 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
(***********************************************************************)
(*                                                                     *)
(*                           Objective Caml                            *)
(*                                                                     *)
(*               Pierre Weis, projet Cristal, INRIA Rocquencourt       *)
(*                                                                     *)
(*  Copyright 2001 Institut National de Recherche en Informatique et   *)
(*  en Automatique.  All rights reserved.  This file is distributed    *)
(*  only by permission.                                                *)
(*                                                                     *)
(***********************************************************************)
(*
  Manipulation of lists.

  - [] is the empty list
  - :: is the infix operator that builds list cells.
    Hence 1 :: (2 :: []) is the list that contains 1 and 2 in this order.

*)
(* interval min max = [min; min+1; ...; max-1; max] *)

let rec interval min max =
  if min > max then [] else min :: interval (succ min) max
;;

(*

  Case analysis on list l is written
  match l with
  | [] -> ``nil case''
  | x :: tail -> ``non nil case,
                   with x (the head of l) and tail (the tail of l) available''

  Function can perform direct case analysis on their argument,
  if introduced by the function keyword. Hence,

    let f (x) =
      match x with
      | [] -> ...
      | ...

  can be abreviated as

    let f = function
      | [] -> ...
      | ...

*)

(* filter p L returns the list of the elements in list L
   that satisfy predicate p *)

let rec filter p = function
  | []  -> []
  | a :: r -> if p a then a :: filter p r else filter p r
;;

(* Application: removing all numbers multiple of n from a list of integers *)

let remove_multiples_of n =
  filter (fun m -> m mod n <> 0)
;;

(* The sieve itself *)

let sieve max =
  let rec filter_again = function
  | [] -> []
  | n :: r as l ->
      if n * n > max then l else n :: filter_again (remove_multiples_of n r)
  in
    filter_again (interval 2 max)
;;

let usage() =
  print_string "Usage: sieve <n>\n";
  exit 2
;;

(* The entry point *)

let main () =
  if Array.length Sys.argv <> 2 then usage () else
  begin
    try
      let n = int_of_string Sys.argv.(1) in
      List.iter (fun n -> print_int n; print_string " ") (sieve n);
      print_newline ()
    with Failure "int_of_string" ->
      print_string "Bad integer constant";
      print_newline ()
  end
;;

if !Sys.interactive then () else main ();;