Formula vs looping for varying items per day.

40 Views Asked by At

I have the following problem, which I have solved using a for loop and a couple arrays. I have the nagging suspicion that there is a formula I could be using rather than the looping algorithm. Part of my problem is I don't know what this class of problem is called in mathematics.

A client of ours makes cars. They only make one color of car a day. On weekends they do not make any cars. Each day they make cars they move to the next color in the sequence, Red, Orange, Yellow, Green, Blue, Purple, and Black. Their first day of production was on Monday and they began making Red cars. They have asked us to build them software that will help them plan what color car they will be making in 30 days.

My looping solution follows:

// What color today?
// This is a simulator style solution.  I'm convinced I can find a formulaic
// solution that doesn't involve a loop

function paintday (futureday) {
  var colors = ['Red', 'Orange', 'Yellow', 'Green', 'Blue', 'Purple', 'Black']
  var weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
  var workday = 0

  for (var day = 0; day <= futureday; day++) {
    if (weekdays[day % 7][0] !== 'S') {
      workday++
    }
  }
  return {
    weekday: weekdays[(day - 1) % 7],
    color: weekdays[(day - 1) % 7][0] !== 'S' ? colors[(workday - 1) % colors.length] : 'none' }
}

console.log(paintday(30))
1

There are 1 best solutions below

2
On BEST ANSWER

(Note: I notice that it seems like in your solution you implicitly assume that we're starting on a Monday, so I do the same here. If we're not starting on a Monday, this might require a slightly more nuanced solution.)

I'll simplify this problem by breaking it down into two parts. Let us call the week that futuredaylands in as the final, incomplete week, and recognise that obviously before this week there must occur some (possibly $0$) finite number of complete weeks. e.g., if futureday is two and a half weeks from now, we have two complete weeks, and we can deal with the last half a week like a sort of remainder.

We know that we change colours five times per week (once for each of the working days). Then

Math.floor(futureday/7) * 5

Should give us the number of colour changes due to the complete weeks. All that remains is the number of colour changes that we perform in the last, incomplete week.

If futureday is on a week-day, this is clearly futureday % 7. If we're on a week-end, this is just 5.

Synthesising this together, you can say

var color = colors[(Math.floor(futureday/7)*5 + Math.max(futureday % 7, 5)) % 7];

I didn't test this myself on a computer, and I assumed you were writing this in JavaScript (I at least think this is valid JS), so definitely test that this gives you results consistent with your method before pushing it out, but I think this should pretty much do what you're after.