CMSI 386
Homework #1
Partial Answers

Problems 1-6: misc.rb

# Returns the string like the input except with undecorated
# Latin vowels removed.
def strip_vowels(s)
  s.delete("aeiouAEIOU")
end

# Returns a permutation of the input string.
# Can be written in one line:
#   s.split(//).sort_by {rand}.join
# but the following is interesting too.
def scramble(s)
  t = String.new s
  for i in 0 ... t.length
    j = rand(t.length)
    t[i], t[j] = t[j], t[i]
  end
  s
end

# Generates powers of two up to n.
def powers_of_two(n)
  x = 1
  while x <= n
    yield x
    x *= 2
  end
end

# Generates powers of base up to limit.
def powers(base, limit)
  x = 1
  while x <= limit
    yield x
    x *= base
  end
end

# Interleaves two arrays.
def interleave(a, b)
  result = []
  k = a.length <= b.length ? a.length : b.length
  (0...k).each {|i| result << a[i] << b[i]}
  result.concat(a[k...a.length]).concat(b[k...b.length])
end

class Array
  # Returns the array containing each element of self replaced
  # with two copies of itself.
  def stutter
    result = []
    each {|x| result << x << x}
    result
  end
end

Problem 7: prefixes.rb

# This script writes successive prefixes of its first input
# argument to standard output.

s = ARGV[0];
0.upto(s.length) {|i| puts s[0...i]} if s

Problem 8: lines.rb

# Writes the number of lines of the file named by the first
# input argument.

File.open(ARGV[0]) {|f| while f.gets; end; puts $.}

Problem 9: misctest.rb

require 'test/unit'
require 'misc'

class String
  def is_permutation_of(other)
    self.split(//).sort == other.split(//).sort
  end
end

class TestUtil < Test::Unit::TestCase

  def test_strip_vowels()
    assert_equal(strip_vowels(""), "");
    assert_equal(strip_vowels("abc"), "bc");
    assert_equal(strip_vowels("U"), "");
    assert_equal(strip_vowels("ouT"), "T");
    assert_equal(strip_vowels("ATE"), "T");
    assert_equal(strip_vowels("AAaaEEeeUUxUUuuuuoOiI"), "x");
    assert_equal(strip_vowels("    "), "    ");
    assert_equal(strip_vowels("$a$"), "$$");
  end

  def test_scramble()
    ["", "a", "aaaa", "aaba", "abfswegwtewr"].each do |s|
      assert(s.is_permutation_of(scramble(s)))
    end
    assert(!"abc".is_permutation_of(scramble("aab")))
  end

  def test_powers_of_two()
    expected = [1,2,4,8,16,32,64,128,256,512,1024];
    i = 0
    powers_of_two(1500) do |x|
        assert_equal(x, expected[i])
        i += 1
    end
  end

  def test_powers()
    # TODO
  end

  def test_interleave()
    assert_equal(interleave([1, 2], [nil, 5, 7, 10]), [1, nil, 2, 5, 7, 10])
    assert_equal(interleave([false, 4, nil], [8]), [false, 8, 4, nil])
    assert_equal(interleave([], []), [])
    assert_equal(interleave([], [false, [1]]), [false, [1]])
    assert_equal(interleave([100, 100], []), [100, 100])
  end

  def test_stutter()
    assert_equal([].stutter, []);
    assert_equal([true].stutter, [true, true]);
    assert_equal([1, 1].stutter, [1, 1, 1, 1]);
    assert_equal([nil, 7, nil].stutter, [nil, nil, 7, 7, nil, nil]);
    assert_equal([1, [2, 3]].stutter, [1, 1, [2, 3], [2, 3]]);
  end

end