[SOLUTION] Mexican Blanket (#127)


#1

Here is my solution for the Mexican Blanket Quiz.
It’s also available here:
http://code.rendale.com/svn/RubyQuiz/MexicanBlanket_127/Mexican_Blanket.htmlhttp://code.rendale.com/svn/RubyQuiz/MexicanBlanket

I was having a hard time seeing the pattern in the ascii so I added a
feature to convert the ascii string into an html image composed of
colored
divs.

The colors in the blanket are randomly selected from an array of
possible
colors and gradients are alternately separated by Mexican flag bands and
black bands. The technique I use is to create a string with enough of
the
pattern to fill the entire blanket and then shift back by one unit per
row.

Any feedback on how I can improve this code would be much appreciated.


#!/usr/local/bin/ruby
module RubyQuiz

#creates the pattern
class Pattern
attr_reader :colors
attr_reader :value

def initialize(length)
  @length = length
  @color_count = {:color1=>5, :color2=>1}
  @colors =

Hash[“0”,“black”,“1”,“red”,“2”,“orange”,“3”,“yellow”,“4”,“green”,“5”,“blue”,“6”,“indigo”,“7”,“violet”,“8”,“white”,“9”,“grey”]

  @value=""
  @flag_switch = true
  generate
end

def generate
  pick_new_colors
    (0..(@length.to_f/6).ceil).each do |i|
      @value += (@color1.to_s * @color_count[:color1]) + 

(@color2.to_s *
@color_count[:color2])
update_colors
end
end

private
  def update_colors
    if @color_count[:color1] > 1
      @color_count[:color1]-=1
      @color_count[:color2]+=1
    else
      @color_count[:color1],@color_count[:color2]=5,1
      @flag_switch ? add_flag : add_seperator
      pick_new_colors
    end
  end

  def add_flag
    @value += "01840"
    @flag_switch = false
  end

  def add_seperator
    @value += "000"
    @flag_switch = true
  end

  def pick_new_colors
    @color1 = (rand*9).ceil
    @color2 = @color1 < 2 ? @color1 + 1 : @color1 - 1
  end

end

composes the pattern into a blanket

class Blanket
attr_reader :ascii
attr_accessor :scale
def initialize(width=75,height=100, scale=2)
@width, @height, @scale = width.to_i, height.to_i, scale.to_i
@ascii, @html = ["",""]
@pattern = Pattern.new(@width+@height)
weave
end

private
  def weave
    0.upto(@height) do |i|
      @ascii += (@pattern.value[0 + i,@width])[0,@width] + "\n"
    end
    puts @ascii + "\n"
    puts "open Mexican_Blanket.html in your interweb browser to see 

it
in full color"
html
end

  def html
    @html = "<html>\n<head>\n<title>Mexican Blanket

Solution\n\n"
@html +="\n"
@html
+="\nbody{background:#ccc;font-weight:bold;text-align:center}\ndiv.pixel{float:left;
width:#{@scale}px; height:#{@scale}px;}\n.wrapper{border:2px solid #fff;
width:#{@width*@scale}px; margin:auto;}\n\n"
@html +="<div class=“wrapper”>\n"
@ascii.split("\n").each do |line|
line.gsub (/(.)/) do |char|
@html += “<div class=“pixel” style=”
background:#{@pattern.colors[char]}">"
end
end
@html += “\n<div style=“clear:both”>\n”
@html += “\n

\n#{@ascii}\n
\n”
@html += “\n”
to_file
end
  def to_file
    output_file = File.open("Mexican_Blanket.html","w")do |f|
      f.write(@html)
    end
  end

end
end

Blanket.new accepts height, width, and scale (used for html version)

if FILE == $0
blanket = RubyQuiz::Blanket.new(*ARGV)
end


#2

On Jun 10, 2007, at 10:39 AM, Will Bailey wrote:

Any feedback on how I can improve this code would be much appreciated.

One idea came to me on a quick glance at the code…



 @colors =

Hash
[“0”,“black”,“1”,“red”,“2”,“orange”,“3”,“yellow”,“4”,“green”,“5”,"blue
",“6”,“indigo”,“7”,“violet”,“8”,“white”,“9”,“grey”]

First, you can drop a lot of punctuation from a line like this using
Ruby’s word Array syntax:

@colors = Hash[ *%w[ 0 black 1 red 2 orange 3 yellow
4 green 5 blue 6 indigo 7 violet
8 white 9 grey ] ]

Of course, those keys are just indices, and we should probably treat
them as such:

require “enumerator”
@color = Hash[ *%w[ black red orange yellow green
blue indigo violet white gray ].
enum_with_index.to_a.flatten.reverse ]

I do realize that’s not quite as readable though.

James Edward G. II


#3

cool…I was trying to figure out how to use %w but was missing the
leading
*.

Now it seems like I could have just used an array. Originally I was
looking
at using the letters to key the colors, which is why I was thinking
hash.
Isn’t the result of your second suggestion almost an array in hash
clothing?

Thanks for the tips
Will


#4

On Jun 11, 2007, at 9:44 AM, Will Bailey wrote:

Now it seems like I could have just used an array. Originally I
was looking
at using the letters to key the colors, which is why I was thinking
hash.
Isn’t the result of your second suggestion almost an array in hash
clothing?

It is. That’s a very good point.

James Edward G. II