algorithmclockmodulocolor-wheel

Modulo algorithm proving elusive


I have a color-wheel that maps a color to each hour on a 24-hour clock. Now given the hour of day, I want to map those colors to a 12-hour clock such that the colors 5 hours before and 6 hours after the current hour are used. But it gets a bit tricky b/c the 0th index of the result always has to be the 0th color or the 12th color of the 24 color-wheel.

For example, given colors24 as an array of 24 colors and a hour time of 5 then the final color12 array would map to colors24's indexes as:

{0,1,2,3,4,5,6,7,8,9,10,11}

If the hour is 3, then:

{0,1,2,3,4,5,6,7,8,9,22,23}

And if the hour is 9, then:

{12,13,14,15,4,5,6,7,8,9,10,11}

Bonus points if the algorithm can be generalized to any two arrays regardless of size so long as the first is evenly divisible by the second.


Solution

  • If hours is the total number of hours (24), length the number of colors displayed at a time (12), and hour is the current hour, then this is a generic algorithm to get the indexes into the color array:

    result = [];
    add = hour + hours - (length / 2) - (length % 2) + 1;
    for (i = 0; i < length; i++) {
        result[(add + i) % length] = (add + i) % hours;
    }
    

    Here is a Javascript implementation (generic, can be used with other ranges than 24/12):

    function getColorIndexes(hour, hours, length) {
        var i, result, add;
    
        if (hours % length) throw "number of hours must be multiple of length";
        result = [];
        add = hour + hours - (length / 2) - (length % 2) + 1;
        for (i = 0; i < length; i++) {
            result[(add + i) % length] = (add + i) % hours;
        }
        return result;
    }
    
    console.log ('hour=3: ' + getColorIndexes(3, 24, 12));
    console.log ('hour=5: ' + getColorIndexes(5, 24, 12));
    console.log ('hour=9: ' + getColorIndexes(9, 24, 12));
    console.log ('hour=23: ' + getColorIndexes(23, 24, 12));

    As stated in the question, the number of hours (24) must be a multiple of the length of the array to return.