------art_4574_12283425.1147037228781
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Here are my solutions for both choices.

# === Choice one ===

# Determines whether a packing diagram is acceptable.
def good_diagram? packing_diagram
  # Ensure there is no packaging that surrounds no items: (()B)
  return false if packing_diagram =~ /\(\)|\[\]|\{\}/

  # Make an unfrozen copy of the original.
  packing_diagram = packing_diagram.dup

  # Remove the items: (((B))(B)(B)) -> ((())()())
  packing_diagram = packing_diagram.delete 'B'

  # Repeatedly remove matching opening-closing neighbors: ((())()()) -> (())
-> () ->
  packing_diagram.gsub! /\(\)|\[\]|\{\}/, '' while packing_diagram =~
/\(\)|\[\]|\{\}/

  # If everything was removed, the diagram was good.
  packing_diagram.empty?
end

packing_diagram = ARGV.join ' '
exit 1 unless good_diagram? packing_diagram
puts packing_diagram
exit 0

# === Choice two ===

# Repairs any errors.  When repairing, this errs on the side of too much
packaging.  To reduce excess packaging, don't have errors.
# It's a bit ugly, but I don't think I let any possible breakages through.
If I did, please let me know.
MaxCleanTime = 5
# This has optional damage prevention enhancements.  Uncomment the
paragraphs with an "# (option)" header if you want an option.
def clean_diagram packing_diagram, start_time=Time.now.to_i, length=0,
best_so_far=[1.0/0.0, nil], recursion_so_far=false
  # If we've already lost, quit.
  return nil if length >= best_so_far.first or Time.now.to_i - start_timeaxCleanTime

  unless recursion_so_far
    # Do nothing if nothing is being packed.
    return '' unless packing_diagram =~ /B/

    # Make an unfrozen copy of the original.
    packing_diagram = packing_diagram.dup

    # Remove extraneous characters: (**Chunky bacon B ) -> (B)
    packing_diagram.gsub! /[^B\(\)\[\]\{\}]/, ''

    # Remove packing that surrounds no items: (()B) -> (B)
    packing_diagram.gsub! /^[\)\]\}]|[\(\[\{][\)\]\}]|[\(\[\{]$/, '' while
packing_diagram =~ /^[\)\]\}]|[\(\[\{][\)\]\}]|[\(\[\{]$/

    # Get the length.
    length = packing_diagram.length

    # Mark items as properly nested.
    packing_diagram.gsub! /B/, 'Bm'
  end

  # Mark all properly nested packaging.
  while packing_diagram =~
/(\(([^m]m)*\)|\[([^m]m)*\]|\{([^m]m)*\})([^m]|$)/
    packing_diagram.gsub! /\(((?:[^m]m)*)\)([^m]|$)/, '(m\1)m\2'
    packing_diagram.gsub! /\[((?:[^m]m)*)\]([^m]|$)/, '[m\1]m\2'
    packing_diagram.gsub! /\{((?:[^m]m)*)\}([^m]|$)/, '{m\1}m\2'
  end

  # If we have improper nesting :
  if packing_diagram !~ /^([^m]m)+$/
    # If we have an opener with an improper closer: (B] :
    if (mismatch = /([\(\[\{])(?:[^m]m)*([\)\]\}])(?:[^m]|$)/.match
packing_diagram)
      # Fix improper nestings in two different ways: by duplicating the
opening packaging and by duplicating the closing packaging.
      clean_diagram(packing_diagram.dup.insert(mismatch.begin(2), { '(' =>
')', '[' => ']', '{' => '}' }[mismatch[1]]), start_time, length + 1,
best_so_far, true)
      clean_diagram(packing_diagram.dup.insert(mismatch.begin(1) + 1, { ')'
=> '(', ']' => '[', '}' => '{' }[mismatch[2]]), start_time, length + 1,
best_so_far, true)
      packing_diagram = nil

    # If we have an opener without even an improper closer or vice versa:
(B))(B) :
    else
      # If an unmarked opener falls off the right end :
      if (mismatch = /([\(\[\{])(?:[^m]m)*$/.match packing_diagram)
        packing_diagram << { '(' => ')', '[' => ']', '{' => '}'
}[mismatch[1]]

      # If an unmarked opener slams into an unmarked opener :
      elsif (mismatch = /([\(\[\{])(?:[^m]m)*([\(\[\{])(?:[^m]|$)/.match
packing_diagram)
        packing_diagram.insert(mismatch.begin(2), { '(' => ')', '[' => ']',
'{' => '}' }[mismatch[1]])

      # If an unmarked closer falls off the left end :
      elsif (mismatch = /^(?:[^m]m)*([\)\]\}])(?:[^m]|$)/.match
packing_diagram)
        packing_diagram.insert(0, { ')' => '(', ']' => '[', '}' => '{'
}[mismatch[1]])

      # If an unmarked closer slams into an unmarked closer :
      elsif (mismatch = /([\)\]\}])(?:[^m]m)*([\)\]\}])(?:[^m]|$)/.match
packing_diagram)
        packing_diagram.insert(mismatch.begin(1) + 1, { ')' => '(', ']' =>
'[', '}' => '{' }[mismatch[2]])
      end

      clean_diagram packing_diagram, start_time, length + 1, best_so_far,
true
      packing_diagram = nil
    end

  # If we have proper nesting :
  else
    # Remove markings.
    packing_diagram.delete! 'm'

    # (option) Ensure no items are left outside any packaging: B(BBB) ->
(B(BBB))
    #~ packing_diagram.sub! /^(B.*|.*B)$/, '(\1)'

    # (option) Ensure no item touches another item: (BBB) -> (B(B)B)
    #~ packing_diagram.gsub! /BB/, 'B(B)' while packing_diagram =~ /BB/

    # (option) Ensure all items are individually wrapped: ((B)B) -> ((B)(B))
    #~ packing_diagram.gsub! /(^|[B\)\]\}])B/, '\1(B)' while packing_diagram
=~ /(^|[B\)\]\}])B/
    #~ packing_diagram.gsub! /B([B\(\[\{]|$)/, '(B)\1' while packing_diagram
=~ /B([B\(\[\{]|$)/
  end

  # Update best_so_far.
  best_so_far.replace [packing_diagram.length, packing_diagram] if
packing_diagram.length < best_so_far.first unless packing_diagram.nil?

  best_so_far.last
end

# Choice two
puts clean_diagram(ARGV.join(' '))

------art_4574_12283425.1147037228781--