-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathproblem41.ml
76 lines (69 loc) · 1.73 KB
/
problem41.ml
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
let int_pow a b = truncate ((float a) ** (float b));;
let isprime n =
let bound = truncate (sqrt (float n)) in
let rec aux i =
if i > bound then true else
match (n mod i) with
| 0 -> false
| _ -> aux (i+1)
in
aux 2
;;
let swap ind1 ind2 tbl =
let temp = tbl.(ind1) in
tbl.(ind1) <- tbl.(ind2);
tbl.(ind2) <- temp
;;
let rec reverse ind1 ind2 tbl =
match (ind2-ind1) with
| 0 -> ()
| 1 -> swap ind1 ind2 tbl
| _ -> swap ind1 ind2 tbl;
reverse (ind1 + 1) (ind2 - 1) tbl
;;
let fact num =
let rec aux i acc =
match i with
| i when (i=num) -> acc*num
| i -> aux (i+1) (acc*i)
in
aux 2 1
;;
let permutations digits =
let perm = Array.make digits 0 in
let k = ref 0 in
let l = ref 0 in
let lst = ref [] in
let num = ref 0 in
let bound = fact digits in
Array.iteri (fun ind _ -> perm.(ind) <- (ind+1)) perm;
for i = 2 to bound do
k := (digits-2);
while (perm.(!k) >= perm.((!k)+1)) do
k := (!k) - 1;
done;
l := (digits-1);
while (perm.(!k) >= perm.(!l)) do
l := (!l) - 1;
done;
swap (!k) (!l) perm;
reverse ((!k)+1) (digits-1) perm;
num := 0;
Array.iteri (fun ind value -> (num:= (!num) + value*(int_pow 10 (digits-ind-1)))) perm;
lst:=((!num)::(!lst));
done;
let rec iterate lst =
match lst with
| [] -> 0
| (x::xs) -> if (isprime x) then x else iterate xs
in
iterate (!lst)
;;
let solve =
let rec aux i =
match permutations i with
| 0 -> aux (i-1)
| x -> x
in
aux 9
;;