Menu
CoddyTech

Ôn tập: phân số

Thuộc phần Lập trình hướng đối tượng trong hành trình Ruby của Coddy. Bài học 41 trên 57.

challenge icon

Thử thách

Khó

Hoàn thiện lớp giá trị Frac. initialize(num, den) rút gọn phân số và giữ dấu ở tử số, đồng thời phát sinh ZeroDivisionError với zero denominator khi den bằng 0. Định nghĩa +, -, * và / để trả về các phân số mới (/ với một phân số bằng 0 sẽ phát sinh ZeroDivisionError với division by zero), -@, ==, eql? và hash để các phân số bằng nhau trở thành cùng một khóa Hash, đồng thời định nghĩa <=> với Comparable. to_s trả về 3/4, hoặc 2 khi mẫu số bằng 1.

Code được cung cấp đọc các lệnh: 1/2 + 1/3 (dùng một trong bốn toán tử), neg 3/4, sort 1/2 1/3 3/4, max 1/2 2/3, uniq 1/2 2/4 1/3 (in ra số lượng và các phân số riêng biệt) và cmp 1/2 2/4 (in ra =, < hoặc >). Lỗi sẽ in ra thông báo tương ứng.

Viết code của bạn trong frac.rb. main.rb chứa code đầu vào/đầu ra được cung cấp và không thể chỉnh sửa.

Tự làm thử

require_relative 'frac'

# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
input = []
while (line = gets)
  input << line.chomp
end
def frac(text)
  n, d = text.split("/").map(&:to_i)
  Frac.new(n, d || 1)
end

input.each do |line|
  parts = line.split
  begin
    case parts[0]
    when "neg" then puts(-frac(parts[1]))
    when "sort" then puts parts[1..].map { |t| frac(t) }.sort.join(" ")
    when "max" then puts parts[1..].map { |t| frac(t) }.max
    when "uniq"
      distinct = parts[1..].map { |t| frac(t) }.uniq
      puts "#{distinct.size}: #{distinct.join(" ")}"
    when "cmp"
      order = frac(parts[1]) <=> frac(parts[2])
      puts ["<", "=", ">"][order + 1]
    else
      a = frac(parts[0])
      b = frac(parts[2])
      puts a.public_send(parts[1], b)
    end
  rescue ZeroDivisionError => e
    puts e.message
  end
end

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Ruby online