Раздел «Язык Ruby».RubyTest1Solutions:

Решения задач теста 1

Удаление дубликатов

puts gets.split.map {|x| x.to_i}.uniq.join(" ")

Имена собственные

File.open("a.txt") do |file|
    puts file.scan(/[A-Z][a-z]+\s+[A-Z][a-z]+/).uniq.join("\n")
end

Проверка арифметической прогрессии

class Array
    def arithmetic?
        return true if size <=2  
        step = self[1]-self[0]
        (1..size-1).all? {|i| self[i-1]+step == self[i] }
    end
end
gets.split.map{|x| x.to_i}.arifmetic?

Наименьшее общее кратное

class Numeric
  def gcd(b)
    a = self
    while b != 0
      a,b = b,a%b
    end
    a
  end
  def lcm(b)
    self*b/self.gcd(b)
  end
end
puts gets.split.map {|x| x.to_i}.inject {|f,x| f.lcm x }

Вычисление цепной дроби

require 'rational'
class Array
  def to_rational
      a = self.reverse
      i = a.shift
      a.inject(Rational(i)) {|f,x| x + 1/f}
  end
end
# Test
puts [10,2,3,4,5].to_rational
puts 10+1/(2+1/(3+1/(4+1/(Rational(5)))))

Частоты слов

File.open("a.txt") do |file|
   file.read.scan(/[A-Za-zА-Яа-я]+/).select{|w| w.size>6}.inject(Hash.new(0)){|f,word|
      f[word] += 1
      f
   }.to_a.sort_by {|x| x[1]}.reverse[0..9].each {|pair|
      printf("%10s %5d\n", pair[0], pair[1])
   }
end

Или более оптимизированный вариант:

File.open("a.txt") do |file|
   file.read.scan(/[A-Za-zА-Яа-я]{6,}/).inject(Hash.new(0)){|f,word|
      f[word] += 1
      f
   }.to_a.sort_by {|x| -x[1]}[0..9].each {|pair|
      printf("%10s %5d\n", pair[0], pair[1])
   }
end

Таблица

file=File.open("c:/a.txt")
header=file.gets
totals=Array.new(header.split.size,0)
lines=file.readlines.sort_by{|line| line.split[1].to_f }
lines.each {|line|
    line.split.map{|x| x.to_f}.each_with_index {|x,i| totals[i]+=x}
}
totals.shift
print header
print lines
puts "Total: " + totals.join(' ')

Стековый калькулятор

tokens=gets.scan(/[+-]?\d+\.?\d*|[\+\-\/*]/)
res=[]
tokens.each do |token|
  if token =~ /[+-]?\d+\.?\d*/
    res.push token.to_f
  else
    case token
    when '-'
      res.push(-res.pop + res.pop)
    when '+'
      res.push(res.pop + res.pop)
    when '*'
      res.push(res.pop * res.pop)
    when '/'
      res.push(1/res.pop * res.pop)
    else
      puts "Bad token #{token}"
      res.shift
    end
  end
end
puts "WARNING: Stack has more than one number" if res.size > 1
res.each_with_index {|r,i| puts "[#{i}]=#{r}"}

Перемешивание массива

class Array
  def shuffle!
    each_index do |i|
      j = rand self.size
      self[i],self[j]=self[j],self[i]
    end
  end
  def shuffle
    self.dup.shuffle!
  end
end

Двоичная запись

Решение для умных:

class Integer
   def Integer.create_from_bits(bits)
      bits.inject(0){|a,bit| a * 2 + bit }
   end
   def to_bits
      return [0] if self == 0
      a = self
      res = []
      while a != 0 
         res << a%2
         a /= 2
      end 
      res.reverse
   end
end

Решение для ленивых:

class Integer
   def Integer.create_from_bits(bits)
      bits.join.to_i(2)
   end
   def to_bits
      self.to_s(2).split('').map{|b| b.to_i}
   end
end