Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Problems with input values to a list

I’m quite new at this and I have a problem. I want to read an input and store it at a list, for example:

2 -> number of trees that will be formed after this all
2 -> number of nodes of the first tree
1 -> node 1
2 -> node 2
1 -> number of nodes of the second tree
2 -> node 1

The code below doesn’t work as I wanted. That means for example, using the input before:

2 -> number of trees that will be formed after this all
2 -> number of nodes of the first tree
1 -> number of nodes of the second tree
2 -> node 1 of the second tree
1 -> node 1 of the first tree
2 -> node 2 of the first tree 

Output that the program shows for the input above is:
1 2 2

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

But I expected to have this:
1 2 1
How I can fix this?

let rec inputs number_of_nodes =
  match number_of_nodes with 
  | 0 -> []
  | _ -> let a = read_int() in a :: (inputs (number_of_nodes - 1))


let rec fill_tree_values number_of_trees = 
  match number_of_trees with
  | 0 -> []
  | _ -> let number_of_nodes = read_int() in 
    (inputs number_of_nodes) :: fill_tree_values (number_of_trees - 1)


let number_of_trees = read_int()
let trees = fill_tree_values number_of_trees

let printlist l = List.iter (Printf.printf "%d ") l

let () = List.iter (fun ll -> printlist ll) trees

>Solution :

You wrote:

    (inputs number_of_nodes) :: fill_tree_values (number_of_trees - 1)

but the evaluation order between both operands of :: is unspecified. So it might very well be the case — and unless I’m mistaken, it is effectively the case — that they are evaluated right-to-left, i.e. fill_tree_values (number_of_trees - 1) is performed before inputs number_of_nodes. So you’re reading inputs in a broken order. You can test this right-to-left behavior:

let _ = print_int 1 :: print_int 2 :: print_int 3 :: []
(* with OCaml 4.12, this prints me "321" *)

You must enforce the evaluation order by rewriting your code as:

    let trees = inputs number_of_nodes in
    trees :: fill_tree_values (number_of_trees - 1)

Note: I believe the evaluation order around :: might change in cutting-edge versions of OCaml, with the introduction of the “tail-call-modulo-constructor” optimisation. In any case, you should not rely on it.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading