Skip to Content
Event Information

SAP Community Coding Challenge Nr.2

Welcome to the second challenge in the SAP Community Coding Challenge Series. Just like the first challenge, we have a puzzle for you to solve. Again, something fun and simple enough to solve in a reasonably short period of time.

(The deadline for this challenge has now passed – for an update, please read SAP Community Coding Challenge 2 – Update.)

For this second challenge we take a short departure from our technology roots towards where many of us are already heading (and indeed many of us are already there in some shape or form). And that is the age of Web application UIs and cloud based backend services.

If there’s one language that joins both of these worlds together, it’s JavaScript, in its two main incarnations – Web browser based, and server-side in the form of Node.js. The SAP Fiori world is facilitated by the fantastic UI5 engine which is powered by JavaScript. Backend services in the SAP Cloud Platform Cloud Foundry environment can be written in many languages, and a popular one is indeed JavaScript (Node.js). The SAP Cloud Application Programming Model (CAP) supports both Java and JavaScript for your custom logic. Even the Script Tasks in Workflow definitions on SAP Cloud Platform are written in JavaScript.

So what are you waiting for? Dive in, the water’s lovely!

Challenge Directions

Just like the first challenge, there are certain requirements that have to be met. First, there’s a specific problem to be solved. And that is the Longest Collatz sequence problem from the Project Euler archives, which is this:

The Collatz conjecture is a fascinating one, and with a few lines of code we are able to explore it, in the form of this Project Euler problem, in our challenge series.

Here are the requirements for your solution:

  • it must produce the correct answer (according to Project Euler) in the form of a single integer value
  • it must be written in JavaScript
  • it must be provided in the form of a link to your code, somewhere on the web, preferably in a runnable form*
  • that link must also show not only the code but the answer as well

*see the Sharing Your Solution section below

While of course your solution will only be considered if it meets the above requirements, the judging will be based on subjective matters. It’s up to you how you want to play that. Here are some example considerations with respect to the code you provide (but there are almost certainly going to be others too):

  • does it nicely demonstrate a certain style of programming (OO, FP, imperative, etc)?
  • does it make use of libraries, and if so, in what way and with what advantages or disadvantages?
  • how short and succinct is it? How short is too short? How long is too long?
  • what’s your take on whitespace?
  • how easy is it to read, understand and / or modify?
  • what strategy did you take with respect to variables and their names?
  • how creative is the solution?

Submission & Judging

Once you have a solution you are happy with, please do the following:

  1. Follow this blog post (use the green “Follow” button at the top left of this page)
  2. Email us at community@sap.com with the following:
    • a link to your solution* (do not send code or the answer in the email)
    • a link to your public SAP Community profile

*see the Sharing Your Solution section below

You have until the end of Thu 14 May 2020 whenever that is in your own timezone to send that email in. The community and SAP Developer Advocates will then do the first round of judging to narrow the solutions down to 5 finalists. Those finalist’s solutions will be posted in an SAP Community Q&A entry so that everyone will have a chance to vote on the best overall solution.

And, just like the first challenge, the fabulous prize for the winner of the Coding Challenge will be a No-Prize. The coveted No-Prize also comes as usual with the unending adulation & admiration of the community of fellow developers.

console.log('Good luck!')

Sharing Your Solution

We are in the age of the Web as the true native platform and there are many places on the Web to write and execute code, and make that publicly available. We are not dictating any particular site, but can certainly point you in the direction of a few:

With any of these sites, you can create code and make the source available, and also have it executable. These sites are great for what you might need in this challenge (and there are others too).

If you prefer, you can instead share your solution (code & answer) here on the SAP Community. Do this by creating a new Coffee Corner Discussion and make sure that if you do, you use “CCC2” as the first word in the title, and that you also use the “code” button (highlighted) to properly format your code so that it’s readable. Here’s an example:

Either way, once you’ve added your solution, you should provide a link to it (either to your code in one of the websites above or to your Coffee Corner Discussion entry) in the email as described above.

11 Comments
You must be Logged on to comment or reply to a post.
  • Just a note to other participants: jsbin.com didn’t show the right result for my code. It may have something to do with the iterative approach using too many resources,… repl.it worked like a charm though

    • That depends on the algorithm

      And O is not everything: my fastest solution runs in 50 ms, the slowest about an hour (on a core i9 ). And they use the same algorithm, except the latter uses immutable arrays and spends 99.9% of the time copying them around 🙂

      • I think the O() notation is something that tells you if a good computer can help you. If you have a complex algorithm it doesn’t make much sense to improve your hardware.

        On the other hand if you have such a big difference in your timing I would think, that the algorithm is not the same since memory handling/moving is part of the algorithm at least if you look at sorting algorithms.

        Cheers,
        Peter

        • That’s what computer scientist like to say. But different hardware can be several order of magnitudes faster.

          In my case the hardware didn’t change, only the code

          version 1 (not the actual code)

          lengths.push(x)

          version 2 (also modified, was not mutating any data ):

          lengths = [...lengths,x]

          Now, you could argue that since the array grows and I copy it every time this became quadratic, but only if you give up the pretense that only the algorythm matters and not the implementation. BTW, the vanilla quadratic version ran in around 2.7s, so this O(n log n)/O(n^2) version was a full 1000 times slower than that

          • IMHO the algorithm is everything, not just the top-level sketch. That’s why complete different algorithms have emerged when sorting in memory, sorting data on disk, or sorting data on tape. Because the algorithm take into account if access to a single element is constant or just linear or even worse.

            Just my point of view, but that might be totally off.

          • I agree, but if you look at my slowest implementation, it looks O(n log n)

            const nextCollatz = n => (n % 2 ? 3 * n + 1 : n / 2)
            const naturals = n => [...Array(n + 1).keys()].slice(1)
            const max = s => s.lengths[s.maxIdx]
            
            const collatzLengths = n =>
              naturals(n).reduce(
                (state, current) => {
                  const calcLength = idx => {
                    if (idx === 1) return 1
                    if (idx < current) return state.lengths[idx]
                    return calcLength(nextCollatz(idx)) + 1
                  }
                  const length = calcLength(current)
                  const lengths = state.lengths.concat(length)
                  const maxIdx = length > max(state) ? current : state.maxIdx
                  return { lengths, maxIdx }
                },
                { lengths: [0], maxIdx: 0 }
              )
            
            const longestCollatz = n => {
              const { maxIdx, lengths } = collatzLengths(n)
              return { max: maxIdx, length: lengths[maxIdx] }
            }
            
            const result = longestCollatz(1000000)
            console.log(`Longest sequence at ${result.max}, length ${result.length}`)

             

            All the complexity is in this line:

            // grows the cache. Costs MUCH more than it saves in lookups
            const lengths = state.lengths.concat(length)
            // replace with the following to get around 1000 times faster for 1000000
            // const lengths = state.lengths;lengths.push(length)