Looping without loops
Sun Sep 17 18:09:04 EST 2006
A standard exercise when first learning to program is to draw a triangle of stars using for loops, i.e.
*
**
***
****
How do you do this in a language that doesn't allow variable assignment? By (tail) recursion with an extra accumulator argument and loop index. Below is the Ocaml code for drawing a number of different triangles. Note the use of the higher order function string_gen.
let make_line c n = String.make n c let make_tri c n = let rec aux k acc = if k=0 then acc else aux (k-1) ((make_line c k) :: acc) in aux n [] let string_gen shift_fun ind_update lst = snd (List.fold_left (fun (ind,acc) x -> (ind_update ind, acc ^ (shift_fun ind) ^ x ^ "\n")) (0,"") lst) let odd_els lst = List.rev (snd (List.fold_left (fun (ind, acc) x -> if ind=0 then (1,x::acc) else (0,acc)) (0,[]) lst)) (* Offset all strings in list by n spaces *) let offset n lst = List.map (fun x-> (String.make n ' ') ^ x) lst let up_left_tri n = string_gen (fun x->"") (fun x->x) (make_tri '*' n) let up_right_tri n = string_gen (fun x-> String.make (n-1-x) ' ') (fun x->x+1) (make_tri '*' n) let dn_left_tri n = string_gen (fun x->"") (fun x->x) (List.rev (make_tri '*' n)) let dn_right_tri n = string_gen (fun x-> String.make x ' ') (fun x->x+1) (List.rev (make_tri '*' n)) let up_sym_tri n = string_gen (fun x-> String.make (n-1-x) ' ') (fun x->x+1) (odd_els (make_tri '*' (2*n))) let dn_sym_tri n = string_gen (fun x-> String.make x ' ') (fun x->x+1) (List.rev (odd_els (make_tri '*' (2*n)))) let dn_sym_tri_offset d n = string_gen (fun x-> String.make x ' ') (fun x->x+1) (offset d (List.rev (odd_els (make_tri '*' (2*n))))) let draw_ul n = Printf.printf "%s" (up_left_tri n) let draw_ur n = Printf.printf "%s" (up_right_tri n) let draw_dl n = Printf.printf "%s" (dn_left_tri n) let draw_dr n = Printf.printf "%s" (dn_right_tri n) let draw_us n = Printf.printf "%s" (up_sym_tri n) let draw_ds n = Printf.printf "%s" (dn_sym_tri n) let draw_dia n = Printf.printf "%s%s" (up_sym_tri n) (dn_sym_tri_offset 1 (n-1))
[code]
[permlink]