Forum: Ruby A challenge: generate web colors for tree nodes.

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
73c04e9ef9ca435c5b19a2e765ae6d20?d=identicon&s=25 Max Williams (max-williams)
on 2009-04-14 11:26
hey all

here's a nice little ruby challenge to welcome everyone back after
easter:

I have a long (about 1100) list of elements (class name Property),
arranged into a tree structure.  I want each node to have its own unique
color, as a web color format string (eg "#112233").  Each has an id, a
parent_id and a name - the color can be generated using any or all of
these, or by some other (consistent) method.

Further requirements:
The color can't be brighter than #aaaaaa.
Properties with the same parent_id should have distinctly different
colors.
The color can be essentially random, but should be consistent - ie if
it's generated using the name then it should only ever change if the
name changes.

I've got a few vague ideas involving SHA1 but i thought i'd throw this
out as a fun ruby task :)  Hopefully i'll post my own idea soon.

cheers
max
73c04e9ef9ca435c5b19a2e765ae6d20?d=identicon&s=25 Max Williams (max-williams)
on 2009-04-14 18:43
OK, here's a stab which doesn't satisfy all the requirements.

It makes all unique colors for all 1123 properties, probably by a fluke.
It does set a brightness limit but *doesn't* make all children of a
given node have not-similar colors:

  #generate a unique color for this property
  def web_color
    hashable = "#{self.id}_#{self.parent_id}_#{self.name}"
    "#" + Digest::SHA1.hexdigest(hashable)[0..5]
  end

  #normalise color so that it's not above an overall 'brightness'
  def normalised_web_color(max_brightness=200)
    color = self.web_color
    arr = [color[1..2], color[3..4], color[5..6]].collect(&:hex)
    #we only want to normalise if *all* values are over max_brightness
    if arr.all?{|x| x > max_brightness}
      arr = arr.collect { |x| x = ((x.to_f/255)*max_brightness).to_i }
    end
    "##{arr.collect{|x| sprintf("%02x", x)}.join}"
  end

Feels kind of hacky and dirty to me...any thoughts, anyone?
134ea397777886d6f0aa992672a50eaa?d=identicon&s=25 Mark Thomas (Guest)
on 2009-04-14 21:36
(Received via mailing list)
On Apr 14, 12:43 pm, Max Williams <toastkid.willi...@gmail.com> wrote:
> OK, here's a stab which doesn't satisfy all the requirements.
>
> It makes all unique colors for all 1123 properties, probably by a fluke.
> It does set a brightness limit but *doesn't* make all children of a
> given node have not-similar colors:

That's the hard part. What defines color similarity? This involves
color perception theory. We lose our ability to differentiate colors
as the brightness goes down. Can you tell #000002 from #020000?
Perhaps you should have a minimum brightness. Also, how many colors
can we reasonably distinguish? What if a node has 20 children? 50? 250?
This topic is locked and can not be replied to.