Définissez une fonction einstein u v
qui prend en argument deux vitesses et qui calcule leur somme avec la loi d'addition des vitesses en relativité restreinte.
où la vitesse de la lumière $c= 300000 km.s^{-1}$ est une constante que vous définirez en dehors de votre fonction.
Le type de la fonction doit être float -> float -> float
let c = 300000.
let einstein u v = (u +. v) /. (1. +. (u *. v) /. (c ** 2.))
Définissez de quatre façons différentes la fonction flatten : 'a list list -> 'a list
telle que flatten [l1; ... ln]
renvoie la concaténation l1@...@ln
. Par exemple, flatten [[1;2];[];[3]]
renvoie [1;2;3]
.
List.fold_left
(* 1. definition recursive "naturelle" *)
let rec flatten = function
| [] -> []
| l::ll -> l @ (flatten ll)
(* 2. definition recursive terminale *)
let flatten ll =
let rec f res = function
| [] -> res
| l::ll -> f (res @ l) ll
in f [] ll
(* 2' (avance). definition recursive terminale en temps lineaire (non demande) *)
let flatten ll =
let rec f res = function
| [] -> res
| []::ll -> f res ll
| (x::l)::ll -> f (x::res) (l::ll)
in f [] (List.rev (List.map List.rev ll))
(* 3. imperatif *)
let flatten ll =
let res = ref [] in
let p = ref ll in
while !p <> [] do
res := !res @ List.hd !p;
p := List.tl !p
done;
!res
(* 4. avec fold_left *)
let flatten ll = List.fold_left ( @ ) [] ll
(* ou encore *)
let flatten = List.fold_left ( @ ) []
(* 4' avec fold_left en temps linéaire (avancé) *)
let flatten ll = ll |> List.fold_left List.rev_append [] |> List.rev
Un nombre entier $n\geq 1$ est dit quadratfrei s'il n'existe pas de nombre $m\geq 2$ tel que $m^2$ divise $n$. Par exemple
Définissez une fonction est_quadratfrei : int -> bool
qui permet de tester si un entier $n\geq 1$ est quadratfrei.
let est_quadratfrei n =
let rec iter = function
| m when m * m > n -> true
| m when n mod (m * m) = 0 -> false
| m -> iter (m+1)
in iter 2
let est_quadratfrei n =
let m = ref 2 in
while !m * !m <= n && n mod !m * !m <> 0 do
m := !m + 1
done;
!m * !m > n
On veut définir un type complexe
qui permet de représenter un nombre complexe soit "en scalaire", avec sa partie réelle et sa partie imaginaire, soit "en polaire", avec son module et son argument. On introduit les types de données suivants.
type scalaire = {re:float; im:float}
type polaire = {mo:float; arg:float}
type complexe =
| Scalaire of scalaire
| Polaire of polaire
Définissez la fonction module_p : polaire -> float
qui calcule le module d'un enregistrement de type polaire
, autrement dit le contenu du champs mo
.
Définissez la fonction module_s : scalaire -> float
qui calcule le module d'un enregistrement de type scalaire
. On rappelle que si $x$ et $y$ sont les parties réelle et imaginaire d'un nombre complexe, alors son module est égal à $\sqrt{x^2+y^2}$.
Définissez la fonction module_c : complexe -> float
qui calcule le module d'un nombre complexe, représenté soit par ses coordonnées scalaires, soit par ses coordonnées polaires.
type scalaire = {re:float; im:float}
type polaire = {mo:float; arg:float}
type complexe =
| Scalaire of scalaire
| Polaire of polaire
let module_p pol = pol.mo
let module_p {mo} = mo
let module_s sca = sqrt (sca.re ** 2. +. sca.im ** 2.)
let module_s {re=x;im=y} = sqrt (x ** 2. +. y ** 2.)
let module_c = function
| Scalaire(sca) -> module_s sca
| Polaire(pol) -> module_p pol
On rappelle le type des arbres binaires d'expressions vu en cours
type arbre =
| Feuille of feuille
| Noeud of operateur * arbre * arbre
and feuille =
| Const of int
| Var of string
and operateur = PLUS | SUB | MULT | DIV
let rec nb_feuilles = function
| Feuille(_) -> 1
| Noeud(_, arbre1, arbre2) -> (nb_feuilles arbre1) + (nb_feuilles arbre2)
let rec sans_div = function
| Feuille(_) -> true
| Noeud(DIV, _, _) -> false
| Noeud(_, arbre1, arbre2) -> sans_div arbre1 && sans_div arbre2
Ecrivez une fonction wc : string -> int
. L'entier wc nom_fichier
renvoyé par la fonction est le nombre de lignes du fichier nom_fichier
.
Remarque (souvenir de L1?) : le nom de la fonction est tiré de l'utilitaire shell wc
(word count) qui fait la même chose avec l'option -l
.
let wc fichier =
let ic = open_in fichier in
let res = ref 0 in
try
while true do
ignore (input_line ic);
res := !res + 1
done;
assert false
with
End_of_file -> close_in ic; !res
(* autre solution *)
let wc fichier =
let ic = open_in fichier in
let iter n =
try input_line ic; iter (n+1)
with End_of_file -> close_in ic; n
in iter 0
sqrt 2. +. 3. ** 2.
let pi = 4. *. atan 1.
List.fold_left (++) x0 [x1;...;xn]
renvoie (...(x0++x1)++...)++xn
.
List.fold_left (^) "" ["hello"; " "; "world"; "!"]
List.hd [1;2;3]
List.tl [1;2;3]
let r = ref 0
while !r <> 10 do r := !r + 1; print_int !r done
int_of_string "23"
int_of_string "23 : 30"
let premiere_ligne fichier =
let ic = open_in fichier in
let res = input_line ic in
close_in ic;
res