1

I'm currently learning CoffeeScript, since it's more "expressive" than JavaScript, and therefore, I'd like to know how I would optimize the code that I have below

lastDay = 6
weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
weeksToDivide = 0

for x in [1..9001] 
    if x % 5 == 0
        if x % 4 == 0
            if x % 3 == 0
                nextDay = x
                break               

totalDays = lastDay + nextDay
day = (totalDays -= 7 while totalDays > 7)
weekday = weekdays[day[day.length - 1] - 1]

alert "Days until next meeting: #{nextDay}"
alert "That day is on a #{weekday}"

I'm mainly looking for a way to optimize the if nest, but any other tips would be appreciated too.

Thanks in advance.

EDIT:
I was being stupid and forgot how maths work, thanks Zeta. Also, thanks to epidemian for further optimization.

Myrkvi
  • 133
  • 1
  • 5
  • This seems like a job for http://codereview.stackexchange.com, since your script is already working. Also, since all your numbers relatively prime (3, 4, 5) you can simply take the product and solve your problem one expression instead of using a loop. – Zeta Apr 09 '13 at 18:17
  • Uh, do you think you could show me an example of that? – Myrkvi Apr 09 '13 at 18:25
  • 2
    `nextDay = 3 * 4 * 5`. 60 is the first number that's divisible by three, four and five. That's not a property of CoffeeScript, that's simple mathematics ;). – Zeta Apr 09 '13 at 18:37
  • Oh, I feel stupid now :/ – Myrkvi Apr 09 '13 at 18:40

2 Answers2

0

These optimizations have very little to do with CoffeeScript:

First, the nested ifs could be converted to chained ands, like:

for x in [1..9001] 
  if x % 5 is 0 and x % 4 is 0 and x % 3 is 0 
    nextDay = x
    break

But asking if a number "x" is divisible by 5 and divisible by 4 and divisible by 3 is the same as asking if it's divisible by the the least common multiple of those three numbers, which is 60. So the loop is equivalent to:

for x in [1..9001] 
  if x % 60 is 0 
    nextDay = x
    break

But, that loop is always going to do the same: assign nextDay to 60. So it can be optimized to a single assignment:

nextDay = 60

If the 5, 4 and 3 divisors are not constant and your algorithm should be able different divisors, them you can set nextDay to the least common multiple of those numbers.

Then, the (totalDays -= 7 while totalDays > 7) loop creates an array to then only use its final element. The logic can be replaced with a modulo operator:

totalDays = lastDay + nextDay - 1
weekday = weekdays[totalDays % 7]
Community
  • 1
  • 1
epidemian
  • 18,817
  • 3
  • 62
  • 71
0

You could shorten the loop to (despite the fact that you also could do nextday = 60 ;-):

for x in [1..9001] when x % 60 is 0
  nextDay = x
  break
TheHippo
  • 61,720
  • 15
  • 75
  • 100