2016-05-28 19 views
1

Ich habe ein Farbrad, das eine Farbe zu jeder Stunde im 24-Stunden-Format abbildet. Nun gebe ich die Stunde des Tages an und möchte diese Farben auf eine 12-Stunden-Uhr abbilden, so dass die Farben 5 Stunden vor und 6 Stunden nach der aktuellen Stunde verwendet werden. Aber es wird ein bisschen schwierig b/c der 0. Index des Ergebnisses muss immer die 0. Farbe oder die 12. Farbe des 24 Farbrads sein.Modulo-Algorithmus erweist sich schwer fassbar

Zum Beispiel gegeben colors24 als ein Array von 24 Farben und eine Stunde Zeit von 5 dann die endgültige color12 Array colors24 die Indizes als Karte würde:

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

Wenn die Stunde 3 ist, dann gilt:

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

Und wenn die Stunde 9, dann:

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

B onus-Punkte, wenn der Algorithmus unabhängig von der Größe auf zwei beliebige Arrays verallgemeinert werden kann, solange der erste durch die Sekunde gleichmäßig teilbar ist.

Antwort

2

Wenn hours die Gesamtzahl der Stunden (24) ist, length die Anzahl der Farben angezeigt zu einem Zeitpunkt (12), und hour ist die aktuelle Stunde, dann ist dies ein generischer Algorithmus, um die ind zu bekommen exe-Dateien in die Farb Array:

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));

Wie bereits erwähnt in der:

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

Hier ist eine JavaScript-Implementierung (generic, kann mit anderen Bereichen als 24/12 verwendet werden) Frage, die Anzahl der Stunden (24) muss ein Vielfaches der Länge des Arrays sein, um zurückzukehren.

+0

Erstaunlich! Ich wusste, dass es eine knappe Lösung geben musste, aber ich konnte es einfach nicht verstehen. Danke, als richtige Antwort markiert. – trans

+0

Sorry wegen der Verzögerung. Ich bin auf andere Teile meiner App gekommen und bin gerade wieder dazu gekommen. Danke für diese Antwort. Ich bin beeindruckt. War das eine Herausforderung für dich oder bist du direkt zu dir gekommen? – trans

0

Können Sie die Farben nicht sofort erhalten, d. H. Von (C-Y/2 + X + 1)% X bis (C + Y/2)% X, und sortieren Sie sie dann?

(Dies ist die gleiche wie Looping (C + Z + X + 1) X% von Z = -Y/2 bis Z = Y/2-1):

for (i = 0, j = c+x+1, z = -y/2; z < y/2; z++) { 
    color[i++] = (z+j)%x; 
} 

Für C = 3 , X = 24 und Y = 12, erhalten Sie:

(C-12/2+24+1)%24 = 3-6+24+1 = 22, 23, 0, 1 .. 9 

Nach dem Sortieren Sie 0 erhalten, 1 ... 9, 22, 23, wie verlangt.

Ohne Sortierung erhalten Sie immer eine Sequenz mit der aktuellen Stunde in der Mitte (was für einige Anwendungen gut sein könnte), während Ihr 3 Beispiel hat es zwei Plätze nach links verschoben.

Sie können dies tun, indem Sie verschieben anstatt zu sortieren, indem Sie bemerken, dass Sie nur verschieben müssen, wenn c unter Y/2 ist (C = 3 beginnt von -2, das 22 wird), in welchem ​​Fall Sie umschalten negatives y/2-c (hier 2 oder 12 + 2 unter Verwendung eines anderen Moduls) oder wenn c> (xy/2), in diesem Fall würden Sie über x hinausgehen: Wenn c = 20, ist c + 6 26 , die auf 2 zurückgesetzt wird:

15 16 17 18 19 20 21 22 23 0 1 2 

und gibt als den Faktor 2 + 1 = 3 ist, oder (c + y/2)% x + 1 im allgemeinen:

0 1 2 15 16 17 18 19 20 21 22 23 


for (i = 0, j = c+x+1, z = -y/2; z < y/2; z++) { 
    color[(s+i++)%y] = (z+j)%x; 
} 

jedoch Ich denke, du hast ein Problem, wenn x > 2 * y; In diesem Fall erhalten Sie einige c-Werte, für die weder 0 noch x/2 "in Reichweite" von c sind. Das heißt, "gleichmäßig teilbar" muss dann bedeuten, dass x immer gleich zu y * 2 sein muss.

1

Dies kann getan werden, indem man zuerst die Zahlen in ein temporäres Array platziert, dann den Ort von 0 oder 12 darin findet und die Ergebnisse von dieser Position aus druckt und den Index als zirkulär behandelt (d. H.modulo die Array-Länge)

Hier ist ein Beispiel-Implementierung:

int num[12]; 
// Populate the values that we are going to need 
for (int i = 0 ; i != 12 ; i++) { 
    // 19 is 24-5 
    num[i] = (h+i+19) % 24; 
} 
int p = 0; 
// Find p, the position of 0 or 12 
while (num[p] != 0 && num[p] != 12) { 
    p++; 
} 
// Print num[] array with offset of p 
for (int i = 0 ; i != 12 ; i++) { 
    printf("%d ", num[(p+i) % 12]); 
} 

Demo.

Anmerkung: Die erste und die zweite Schleife kombiniert werden können. Fügen Sie eine Prüfung hinzu, wenn die gerade eingegebene Nummer 0 oder 12 ist, und legen Sie den Wert fest, wenn Sie eine Übereinstimmung finden.

+0

Dies ist im Grunde, wie ich am Ende auch (kurz nachdem ich die Frage gepostet habe). Aber ich wusste, dass es einen direkteren Weg geben musste. – trans

0

Hier ist eine Lösung in JavaScript:

function f(h) { 
    var retval = []; 
    for (var i = h - 5; i <= h + 6; ++i) 
    retval.push((i+24) % 24); 
    return retval.sort(function(a,b){return a-b;}); // This is just a regular sort 
} 

https://repl.it/CWQf

Zum Beispiel

f(5) // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] 
f(3) // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 22, 23 ] 
f(9) // [ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ] 
+1

Die Frage sagt 'f (9)' sollte etwas anderes sein. –

+0

@ n.m. Gleiche Nummern, andere Reihenfolge. Es war nicht klar aus der Frage, ob die Bestellung wichtig war oder nicht; In dieser Lösung wird immer sortiert. – Matt