Skip to content

Conversation

@jiegillet
Copy link
Contributor

This is me procrastinating on working on exercism/elm-analyzer#96 because finding recursive functions in is hard :)

This one is potentially very hard, and I'm not sure of what the best approach is.
This exercise is about finding the largest/smallest product i * j that are also a palindromes for numbers i and j integer values within a certain range.
If you go at it naively (listing all possible pairs, finding the palindrome products and keeping the largest ones) two tests in particular will never pass because their range is 1000 to 9999, which is more than 80 million pairs (half if you only consider ordered pairs), which is simply too much for Elm to complete within the test runner time limit (of the order of 10 seconds I think).

If you take a smarter approach, such as generating pairs in descending/ascending order and stopping the search at the first palindrome product, then it's not problem, but it's a lot harder to code. For example, I wanted to use an algorithm requiring the use of a priority queue, so I had to build my own, which was difficult (although I love those kind of challenges).

In the Elixir track, we chose to mark those two test as "slow" and exclude them from the test runner, with this message to students. We could do something similar, although I don't like the approach so much, because to me, this exercise is about finding an efficient algorithm. I'm sure most students would try a simplest/brute force approach, see it pass, and move on, which to be honest is fine if our goal is to teach the Elm syntax.

I was leaning towards leaving all the tests in and adding a note saying that this exercise is about finding an efficient algorithm.

@ceddlyburge what's your take on this?

@ceddlyburge
Copy link
Contributor

I agree, the code does look tricky to implement !
Would the naive code create a stack overflow without tail call elimination? If so we could mention that and it could be a requirement of the solution, which would maybe address the slow tests issue?
Maybe adding an estimate if how long it takes to implement would be good too, so that students only stay it off they are happy to put in the time?

Copy link
Contributor

@ceddlyburge ceddlyburge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exercise looks good, so I've approved it, but we can still discuss the tests / requiring the code to be efficient

@jiegillet
Copy link
Contributor Author

I agree, the code does look tricky to implement ! Would the naive code create a stack overflow without tail call elimination? If so we could mention that and it could be a requirement of the solution, which would maybe address the slow tests issue? Maybe adding an estimate if how long it takes to implement would be good too, so that students only stay it off they are happy to put in the time?

While implementing it, I certainly hit my share of stack overflows. And even with tail call elimination, I've written solutions that would not solve the difficult tests within a minute or something (maybe longer? I usually shut them down within seconds).

For the hard tests, you definitely need the right algorithm, tail call elimination will not help you. I'm not 100% certain if tail call elimination is mandatory if you have a good algorithm, but I suspect you need it. Knowing about tail calls should certainly be a prerequisite for this exercise, but this is already handled by the config file.

I added an instructions.append.md in my latest commit, please have a look, we can iterate on it. I didn't want to mention a specific time requirement, there might be a better solution than mine that I don't know about. I just know that brute force is not an option.

@ceddlyburge
Copy link
Contributor

That instruction appendix looks good. I think we have two options. We can go ahead and release it, and then if we get any feedback (which is unlikely I think, as we never get any), then we can make changes. Or we can find a better way to test / know whether the solution is naive or good. This will be time consuming, probably result in extra complication and move us further away from the problem_specs. So I think I would vote for the first option.

@jiegillet jiegillet merged commit c2ac0e6 into main Jul 7, 2025
6 checks passed
@jiegillet jiegillet deleted the jie-palindrome-products branch July 7, 2025 08:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants