Advent of Code 2018 Day 1 in OCaml: Find length of cycles when accumulating deltas [on hold]











up vote
1
down vote

favorite












I just started Advent of Code 2018. This is exercise 2 of day 1, and I can't understand why my code is so slow (4 minutes 37 seconds, compared to 200ms for a friend who did it in Clojure with the same computer).



Basically, it accumulates integers from a provided list of ints, named input. Whenever the current value of the accumulator is equal to one of its previous values, it is returned. We might have to loop many times over the provided list before we find such an occurrence. Here is the code:



  let main () =
let rec my_slow_code lst history =
if lst == then my_slow_code input history
else
let current = List.hd lst + List.hd history in
if List.mem current history then current
else my_slow_code (List.tl lst) (current :: history)
in
my_slow_code input [0]


I can't understand what mistake here makes such a slow code, maybe the use of List.mem?










share|improve this question









New contributor




laurentmeyer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











put on hold as off-topic by Toby Speight, IEatBagels, Sᴀᴍ Onᴇᴌᴀ, alecxe, Dannnno 8 hours ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Toby Speight, Sᴀᴍ Onᴇᴌᴀ, Dannnno

If this question can be reworded to fit the rules in the help center, please edit the question.













  • Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles.
    – Toby Speight
    13 hours ago















up vote
1
down vote

favorite












I just started Advent of Code 2018. This is exercise 2 of day 1, and I can't understand why my code is so slow (4 minutes 37 seconds, compared to 200ms for a friend who did it in Clojure with the same computer).



Basically, it accumulates integers from a provided list of ints, named input. Whenever the current value of the accumulator is equal to one of its previous values, it is returned. We might have to loop many times over the provided list before we find such an occurrence. Here is the code:



  let main () =
let rec my_slow_code lst history =
if lst == then my_slow_code input history
else
let current = List.hd lst + List.hd history in
if List.mem current history then current
else my_slow_code (List.tl lst) (current :: history)
in
my_slow_code input [0]


I can't understand what mistake here makes such a slow code, maybe the use of List.mem?










share|improve this question









New contributor




laurentmeyer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











put on hold as off-topic by Toby Speight, IEatBagels, Sᴀᴍ Onᴇᴌᴀ, alecxe, Dannnno 8 hours ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Toby Speight, Sᴀᴍ Onᴇᴌᴀ, Dannnno

If this question can be reworded to fit the rules in the help center, please edit the question.













  • Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles.
    – Toby Speight
    13 hours ago













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I just started Advent of Code 2018. This is exercise 2 of day 1, and I can't understand why my code is so slow (4 minutes 37 seconds, compared to 200ms for a friend who did it in Clojure with the same computer).



Basically, it accumulates integers from a provided list of ints, named input. Whenever the current value of the accumulator is equal to one of its previous values, it is returned. We might have to loop many times over the provided list before we find such an occurrence. Here is the code:



  let main () =
let rec my_slow_code lst history =
if lst == then my_slow_code input history
else
let current = List.hd lst + List.hd history in
if List.mem current history then current
else my_slow_code (List.tl lst) (current :: history)
in
my_slow_code input [0]


I can't understand what mistake here makes such a slow code, maybe the use of List.mem?










share|improve this question









New contributor




laurentmeyer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I just started Advent of Code 2018. This is exercise 2 of day 1, and I can't understand why my code is so slow (4 minutes 37 seconds, compared to 200ms for a friend who did it in Clojure with the same computer).



Basically, it accumulates integers from a provided list of ints, named input. Whenever the current value of the accumulator is equal to one of its previous values, it is returned. We might have to loop many times over the provided list before we find such an occurrence. Here is the code:



  let main () =
let rec my_slow_code lst history =
if lst == then my_slow_code input history
else
let current = List.hd lst + List.hd history in
if List.mem current history then current
else my_slow_code (List.tl lst) (current :: history)
in
my_slow_code input [0]


I can't understand what mistake here makes such a slow code, maybe the use of List.mem?







programming-challenge time-limit-exceeded ocaml






share|improve this question









New contributor




laurentmeyer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




laurentmeyer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 10 hours ago









200_success

128k15149412




128k15149412






New contributor




laurentmeyer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 13 hours ago









laurentmeyer

82




82




New contributor




laurentmeyer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





laurentmeyer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






laurentmeyer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




put on hold as off-topic by Toby Speight, IEatBagels, Sᴀᴍ Onᴇᴌᴀ, alecxe, Dannnno 8 hours ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Toby Speight, Sᴀᴍ Onᴇᴌᴀ, Dannnno

If this question can be reworded to fit the rules in the help center, please edit the question.




put on hold as off-topic by Toby Speight, IEatBagels, Sᴀᴍ Onᴇᴌᴀ, alecxe, Dannnno 8 hours ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Toby Speight, Sᴀᴍ Onᴇᴌᴀ, Dannnno

If this question can be reworded to fit the rules in the help center, please edit the question.












  • Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles.
    – Toby Speight
    13 hours ago


















  • Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles.
    – Toby Speight
    13 hours ago
















Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles.
– Toby Speight
13 hours ago




Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles.
– Toby Speight
13 hours ago










1 Answer
1






active

oldest

votes

















up vote
4
down vote



accepted










I won't give it all away, since that would take away some of the fun of Advent of Code, but I'll point out:



First, yes, List.mem takes time proportional to the length of your list, which means if you're calling it over and over again it can be quite slow indeed. There might be faster structures you could use if you want to track if a previous value has been seen before, like Sets. Also, you should not be using == for equality here but rather =; I recommend learning the difference between = and ==, you will want to know it.



Second, your code is not very idiomatic OCaml; in general, if you're doing things like nesting lots of ifs and using List.hd instead of pattern matching, you may not be doing things quite right. This won't impact your performance but might impact readability and correctness. (For example, the match l with | -> ... pattern will warn you if a pattern match isn't exhaustive, which avoids nasty bugs.)






share|improve this answer










New contributor




Perry is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.


















  • thanks for the tips! Using = instead of == is indeed more correct - even if it did not improve the efficiency. On the other hand, using Set made it much, much faster (more than 500x)
    – laurentmeyer
    10 hours ago


















1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
4
down vote



accepted










I won't give it all away, since that would take away some of the fun of Advent of Code, but I'll point out:



First, yes, List.mem takes time proportional to the length of your list, which means if you're calling it over and over again it can be quite slow indeed. There might be faster structures you could use if you want to track if a previous value has been seen before, like Sets. Also, you should not be using == for equality here but rather =; I recommend learning the difference between = and ==, you will want to know it.



Second, your code is not very idiomatic OCaml; in general, if you're doing things like nesting lots of ifs and using List.hd instead of pattern matching, you may not be doing things quite right. This won't impact your performance but might impact readability and correctness. (For example, the match l with | -> ... pattern will warn you if a pattern match isn't exhaustive, which avoids nasty bugs.)






share|improve this answer










New contributor




Perry is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.


















  • thanks for the tips! Using = instead of == is indeed more correct - even if it did not improve the efficiency. On the other hand, using Set made it much, much faster (more than 500x)
    – laurentmeyer
    10 hours ago















up vote
4
down vote



accepted










I won't give it all away, since that would take away some of the fun of Advent of Code, but I'll point out:



First, yes, List.mem takes time proportional to the length of your list, which means if you're calling it over and over again it can be quite slow indeed. There might be faster structures you could use if you want to track if a previous value has been seen before, like Sets. Also, you should not be using == for equality here but rather =; I recommend learning the difference between = and ==, you will want to know it.



Second, your code is not very idiomatic OCaml; in general, if you're doing things like nesting lots of ifs and using List.hd instead of pattern matching, you may not be doing things quite right. This won't impact your performance but might impact readability and correctness. (For example, the match l with | -> ... pattern will warn you if a pattern match isn't exhaustive, which avoids nasty bugs.)






share|improve this answer










New contributor




Perry is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.


















  • thanks for the tips! Using = instead of == is indeed more correct - even if it did not improve the efficiency. On the other hand, using Set made it much, much faster (more than 500x)
    – laurentmeyer
    10 hours ago













up vote
4
down vote



accepted







up vote
4
down vote



accepted






I won't give it all away, since that would take away some of the fun of Advent of Code, but I'll point out:



First, yes, List.mem takes time proportional to the length of your list, which means if you're calling it over and over again it can be quite slow indeed. There might be faster structures you could use if you want to track if a previous value has been seen before, like Sets. Also, you should not be using == for equality here but rather =; I recommend learning the difference between = and ==, you will want to know it.



Second, your code is not very idiomatic OCaml; in general, if you're doing things like nesting lots of ifs and using List.hd instead of pattern matching, you may not be doing things quite right. This won't impact your performance but might impact readability and correctness. (For example, the match l with | -> ... pattern will warn you if a pattern match isn't exhaustive, which avoids nasty bugs.)






share|improve this answer










New contributor




Perry is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









I won't give it all away, since that would take away some of the fun of Advent of Code, but I'll point out:



First, yes, List.mem takes time proportional to the length of your list, which means if you're calling it over and over again it can be quite slow indeed. There might be faster structures you could use if you want to track if a previous value has been seen before, like Sets. Also, you should not be using == for equality here but rather =; I recommend learning the difference between = and ==, you will want to know it.



Second, your code is not very idiomatic OCaml; in general, if you're doing things like nesting lots of ifs and using List.hd instead of pattern matching, you may not be doing things quite right. This won't impact your performance but might impact readability and correctness. (For example, the match l with | -> ... pattern will warn you if a pattern match isn't exhaustive, which avoids nasty bugs.)







share|improve this answer










New contributor




Perry is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this answer



share|improve this answer








edited 12 hours ago





















New contributor




Perry is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









answered 13 hours ago









Perry

1562




1562




New contributor




Perry is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Perry is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Perry is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • thanks for the tips! Using = instead of == is indeed more correct - even if it did not improve the efficiency. On the other hand, using Set made it much, much faster (more than 500x)
    – laurentmeyer
    10 hours ago


















  • thanks for the tips! Using = instead of == is indeed more correct - even if it did not improve the efficiency. On the other hand, using Set made it much, much faster (more than 500x)
    – laurentmeyer
    10 hours ago
















thanks for the tips! Using = instead of == is indeed more correct - even if it did not improve the efficiency. On the other hand, using Set made it much, much faster (more than 500x)
– laurentmeyer
10 hours ago




thanks for the tips! Using = instead of == is indeed more correct - even if it did not improve the efficiency. On the other hand, using Set made it much, much faster (more than 500x)
– laurentmeyer
10 hours ago



Popular posts from this blog

Quarter-circle Tiles

build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

Mont Emei