Similar RGB Color
Problem
Given a hex string "#abcdef", return the closest similar color of the form "#XYZXYZ" (a 3-digit hex shorthand). Two colors are compared by sum of squared channel differences.
color = "#09f166""#11ee66"def similarRGB(color):
def closest(pair):
val = int(pair, 16)
q = round(val / 17)
return f"{q*17:02x}"
return '#' + closest(color[1:3]) + closest(color[3:5]) + closest(color[5:7])
var similarRGB = function(color) {
const closest = (pair) => {
const v = parseInt(pair, 16);
const q = Math.round(v / 17);
return (q * 17).toString(16).padStart(2, '0');
};
return '#' + closest(color.slice(1,3)) + closest(color.slice(3,5)) + closest(color.slice(5,7));
};
class Solution {
public String similarRGB(String color) {
return "#" + closest(color.substring(1, 3)) + closest(color.substring(3, 5)) + closest(color.substring(5, 7));
}
private String closest(String pair) {
int v = Integer.parseInt(pair, 16);
int q = (int) Math.round(v / 17.0);
return String.format("%02x", q * 17);
}
}
class Solution {
string closest(const string& pair) {
int v = stoi(pair, nullptr, 16);
int q = (int) round(v / 17.0);
char buf[3]; snprintf(buf, sizeof(buf), "%02x", q * 17);
return string(buf);
}
public:
string similarRGB(string color) {
return "#" + closest(color.substr(1, 2)) + closest(color.substr(3, 2)) + closest(color.substr(5, 2));
}
};
Explanation
A shorthand color like #XYZXYZ means each channel must be a repeated hex digit — 00, 11, 22, ... up to ff. Those values are exactly the multiples of 17 (since 0x11 = 17).
The key insight is that the three channels are independent: to minimize the total squared difference, we just round each channel separately to its nearest allowed value. No need to try combinations.
For each 2-hex pair we parse it to a number val (0 to 255), compute q = round(val / 17), and turn q * 17 back into a 2-digit hex string. Doing this for R, G, and B and joining with # gives the answer.
Example: #09f166. The R pair 09 is 9; round(9/17) = 1 → 17 → "11". The G pair f1 is 241; round(241/17) = 14 → 238 → "ee". The B pair 66 is 102 = 6·17 → stays "66". Result: #11ee66.
Rounding each channel to the closest multiple of 17 is optimal because the squared error splits into a sum of per-channel terms that don't affect each other.