Skip to content

Instantly share code, notes, and snippets.

@rodrigomanhaes
Created November 30, 2011 03:39
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rodrigomanhaes/1407898 to your computer and use it in GitHub Desktop.
Save rodrigomanhaes/1407898 to your computer and use it in GitHub Desktop.
Soluções em Ruby da Lista 1 de exercícios de Programação Orientada a Objetos
class Fixnum
def mdc(outro)
menor = self < outro ? self : outro
menor.downto(1) do |divisor|
return divisor if self % divisor == 0 && outro % divisor == 0
end
1
end
def mmc(outro)
mmc_candidato = self > outro ? self : outro;
incremento = mmc_candidato
while !(mmc_candidato % self == 0 && mmc_candidato % outro == 0)
mmc_candidato += incremento
end
mmc_candidato
end
end
# coding: utf-8
require './algebra'
describe Integer do
it 'calcula o máximo divisor comum em relação a outro inteiro' do
15.mdc(10).should == 5
35.mdc(63).should == 7
11.mdc(88).should == 11
end
it 'calcula o mínimo múltiplo comum em relação a outro inteiro' do
25.mmc(10).should == 50
20.mmc(8).should == 40
2.mmc(3).should == 6
end
end
class Array
def sum
inject {|a, b| a + b }
end
end
# coding: utf-8
require './array_sum'
describe Array do
it 'soma seus elementos' do
[1, 2, 3].sum.should == 6
[[1, 2, 3], [5]].sum.should == [1, 2, 3, 5]
%w(ab cd ef gh).sum.should == 'abcdefgh'
end
end
class Bola
def initialize(cor)
@cor = cor
end
attr_accessor :cor
end
require './bola'
describe Bola do
it 'possui uma cor' do
bola = Bola.new('verde')
bola.cor.should == 'verde'
end
it 'permite alterar sua cor' do
bola = Bola.new('verde')
bola.cor = 'vermelha'
bola.cor.should == 'vermelha'
end
end
class Bomba
def initialize(cap, ppl)
self.capacidade = cap
self.preco_por_litro = ppl
@quantidade = 0
end
attr_reader :capacidade, :preco_por_litro, :quantidade
def encher
@quantidade = capacidade
end
def abastecer_por_valor(valor)
litros = valor / preco_por_litro
verificar_capacidade(litros)
@quantidade -= litros
litros
end
def abastecer_por_litros(litros)
verificar_capacidade(litros)
@quantidade -= litros
litros * preco_por_litro
end
def preco_por_litro=(ppl)
validar_positivo(ppl)
@preco_por_litro = ppl
end
private
def capacidade=(cap)
validar_positivo(cap)
@capacidade = cap
end
def verificar_capacidade(litros)
raise if capacidade < litros
end
def validar_positivo(medida)
raise unless medida > 0
end
end
# coding: utf-8
require './bomba'
describe Bomba do
let(:bomba) { Bomba.new(1000, 3.00) }
it 'possui capacidade e preço por litro' do
bomba.capacidade.should == 1000
bomba.preco_por_litro.should == 3
end
it 'se enche' do
expect { bomba.encher }.to change { bomba.quantidade }.from(0).to(1000)
end
it 'abastece por valor' do
bomba.encher
bomba.abastecer_por_valor(30).should == 10
bomba.quantidade.should == 990
end
it 'abastece por litros' do
bomba.encher
bomba.abastecer_por_litros(30).should == 90
bomba.quantidade.should == 970
end
it 'permite alterar preço por litro' do
bomba.preco_por_litro = 2
bomba.preco_por_litro.should == 2
bomba.encher
bomba.abastecer_por_litros(30).should == 60
end
it 'não aceita preço zero nem negativo' do
expect { Bomba.new(1000, 0) }.to raise_error
expect { bomba.preco_por_litro = 0 }.to raise_error
expect { Bomba.new(1000, -0.1) }.to raise_error
expect { bomba.preco_por_litro = -0.1 }.to raise_error
end
it 'não aceita capacidade zero nem negativa' do
expect { Bomba.new(0, 3) }.to raise_error
expect { Bomba.new(-1, 3) }.to raise_error
end
it 'não aceita abastecimento sem combustível suficiente' do
bomba.encher
expect { bomba.abastecer_por_litros(1000.1) }.to raise_error
expect { bomba.abastecer_por_valor(3000.10) }.to raise_error
end
end
class NumeroComplexo
def initialize(real, imaginaria)
@real, @imaginaria = real, imaginaria
end
attr_reader :real, :imaginaria
def somar(outro)
NumeroComplexo.new(real + outro.real, imaginaria + outro.imaginaria)
end
def subtrair(outro)
NumeroComplexo.new(real - outro.real, imaginaria - outro.imaginaria)
end
def multiplicar(outro)
NumeroComplexo.new(
real * outro.real - imaginaria * outro.imaginaria,
imaginaria * outro.real + real * outro.imaginaria)
end
def to_s
'%.1f+%.1fi' % [real, imaginaria]
end
def ==(outro)
real == outro.real && imaginaria == outro.imaginaria
end
end
# coding: utf-8
require './complexo'
def complexo(r, i)
NumeroComplexo.new(r, i)
end
describe NumeroComplexo do
it 'possui partes real e imaginária' do
c = complexo(2, 3)
c.real.should == 2
c.imaginaria.should == 3
end
it 'realiza adição' do
complexo(-2, 3).somar(complexo(4, -2)).should == complexo(2, 1)
end
it 'realiza subtração' do
complexo(-2, 3).subtrair(complexo(4, -2)).should == complexo(-6, 5)
end
it 'realiza multiplicação' do
complexo(-2, 3).multiplicar(complexo(4, -2)).should == complexo(-2, 16)
end
it 'fornece representação em string' do
complexo(-2, 3).to_s.should == '-2.0+3.0i'
end
it 'compara igualdade com outro número complexo' do
complexo(-2, 3).should == complexo(-2, 3)
complexo(-2, 3).should_not == complexo(3, -2)
end
end
class Conta
def initialize(nome_correntista, numero)
@nome_correntista, @numero = nome_correntista, numero
@saldo = 0
end
attr_reader :saldo, :nome_correntista, :numero
def depositar(valor)
@saldo += valor
end
def sacar(valor)
raise if @saldo - valor < 0
@saldo -= valor
end
end
# coding: utf-8
require './conta'
describe Conta do
before(:each) { @conta = Conta.new('Linus', '12345') }
it 'possui nome do correntista e número' do
@conta.nome_correntista.should == 'Linus'
@conta.numero.should == '12345'
end
it 'possui saldo inicial zero' do
@conta.saldo.should == 0
end
it 'permite realizar depósitos' do
@conta.depositar(110)
@conta.saldo.should == 110
@conta.depositar(10.5)
@conta.saldo.should == 120.5
end
it 'permite realizar saques' do
@conta.depositar(100)
@conta.sacar(75)
@conta.saldo.should == 25
@conta.sacar(10.5)
@conta.saldo.should == 14.5
end
it 'permite sacar até zerar o saldo' do
@conta.depositar(100)
@conta.sacar(75)
@conta.sacar(25)
@conta.saldo.should == 0
end
it 'dispara exceção para saque maior que saldo' do
@conta.depositar(100)
expect { @conta.sacar(100.01) }.should raise_error
end
end
require './array_sum'
class Integer
def prime?
!(2..(self/2)).find {|n| self % n == 0 }
end
def perfect?
self == (1..(self/2)).select {|n| self % n == 0 }.sum
end
def happy?(anteriores = [])
return true if self == 1
return false if anteriores.include?(self)
total = self.to_s.chars.map {|part| part.to_i ** 2 }.sum
total.happy?(anteriores << self)
end
end
# coding: utf-8
require './numero'
describe Integer do
it 'responde se é primo' do
1.should be_prime
2.should be_prime
3.should be_prime
4.should_not be_prime
5.should be_prime
6.should_not be_prime
7.should be_prime
8.should_not be_prime
9.should_not be_prime
end
it 'responde se é perfeito' do
3.should_not be_perfect
4.should_not be_perfect
5.should_not be_perfect
6.should be_perfect
8.should_not be_perfect
28.should be_perfect
350.should_not be_perfect
496.should be_perfect
500.should_not be_perfect
end
it 'responde se é feliz' do
1.should be_happy
2.should_not be_happy
3.should_not be_happy
4.should_not be_happy
5.should_not be_happy
6.should_not be_happy
7.should be_happy
8.should_not be_happy
9.should_not be_happy
10.should be_happy
11.should_not be_happy
12.should_not be_happy
13.should be_happy
14.should_not be_happy
15.should_not be_happy
16.should_not be_happy
17.should_not be_happy
18.should_not be_happy
19.should be_happy
20.should_not be_happy
end
end
class Pessoa
def initialize(idade, peso, altura)
@idade, @peso, @altura = idade, peso, altura
end
def fazer_aniversario
@idade += 1
@altura += 0.015 if @idade < 21
end
def emagrecer
@peso -= 1
end
def engordar
@peso += 1
end
attr_reader :idade, :peso, :altura
end
# coding: utf-8
require './pessoa'
describe Pessoa do
before(:each) { @pessoa = Pessoa.new(22, 70, 1.70) }
it 'possui idade, peso e altura' do
@pessoa.idade.should == 22
@pessoa.peso.should == 70
@pessoa.altura.should == 1.70
end
it 'envelhece' do
@pessoa.fazer_aniversario
@pessoa.idade.should == 23
end
it 'engorda' do
@pessoa.engordar
@pessoa.peso.should == 71
end
it 'emagrece' do
@pessoa.emagrecer
@pessoa.peso.should == 69
end
context 'se menor de 21' do
before(:each) { @pessoa = Pessoa.new(18, 70, 1.70) }
it 'cresce ao envelhecer' do
@pessoa.fazer_aniversario
@pessoa.idade.should == 19
@pessoa.altura.should be_within(0.0001).of(1.715)
@pessoa.fazer_aniversario
@pessoa.idade.should == 20
@pessoa.altura.should be_within(0.0001).of(1.73)
@pessoa.fazer_aniversario
@pessoa.idade.should == 21
@pessoa.altura.should be_within(0.0001).of(1.73)
end
end
end
class Ponto
def initialize(x, y)
@x, @y = x, y
end
attr_reader :x, :y
def ==(outro)
x == outro.x && y == outro.y
end
end
# coding: utf-8
require './ponto'
describe Ponto do
let(:ponto) { Ponto.new(1, 2) }
it 'possui x e y' do
ponto.x.should == 1
ponto.y.should == 2
end
it 'compara igualdade com outro ponto' do
ponto.should == Ponto.new(1, 2)
ponto.should_not == Ponto.new(2, 1)
end
end
class Quadrado
def initialize(lado)
validar lado
@lado = lado
end
def area
lado * lado
end
attr_reader :lado
def lado=(novo_lado)
validar novo_lado
@lado = novo_lado
end
private
def validar(lado)
raise if lado <= 0
end
end
# coding: utf-8
require './quadrado'
describe Quadrado do
before(:each) { @quadrado = Quadrado.new(5.0) }
it 'possui um tamanho dos lados' do
@quadrado.lado.should == 5.0
end
it 'permite alterar o tamanho dos lados' do
@quadrado.lado = 5.1
@quadrado.lado.should == 5.1
end
it 'calcula a sua área' do
@quadrado.area.should == 25
end
it 'não aceita lado negativo nem zero' do
expect { Quadrado.new(0) }.to raise_error
expect { @quadrado.lado = 0 }.to raise_error
expect { Quadrado.new(-0.1) }.to raise_error
expect { @quadrado.lado = -0.1 }.to raise_error
end
end
require './algebra'
class NumeroRacional
def initialize(numerador, denominador)
@numerador, @denominador = numerador, denominador
simplificar
end
attr_reader :numerador, :denominador
def +(outro)
mmc = denominador.mmc(outro.denominador)
NumeroRacional.new(mmc / denominador * numerador + mmc / outro.denominador * outro.numerador, mmc)
end
def -(outro)
self + outro.aditiva_inversa
end
def *(outro)
NumeroRacional.new(numerador * outro.numerador, denominador * outro.denominador)
end
def /(outro)
self * outro.multiplicativa_inversa
end
def to_s
'%d/%d' % [numerador, denominador]
end
def como_ponto_flutuante(casas)
"%.#{casas}f" % valor
end
def ==(outro)
numerador == outro.numerador && denominador == outro.denominador
end
private
def valor
numerador.to_f / denominador
end
def simplificar
mdc = numerador.mdc(denominador)
@numerador /= mdc
@denominador /= mdc
end
protected
def aditiva_inversa
NumeroRacional.new(-numerador, denominador)
end
def multiplicativa_inversa
NumeroRacional.new(denominador, numerador)
end
end
# coding: utf-8
require './racional'
def racional(numerador, denominador)
NumeroRacional.new(numerador, denominador)
end
describe NumeroRacional do
it 'possui numerador e denominador' do
r = racional(3, 5)
r.numerador.should == 3
r.denominador.should == 5
end
it 'fica sempre na forma simplificada' do
r = racional(4, 6)
r.numerador.should == 2
r.denominador.should == 3
end
it 'realiza adição' do
(racional(1, 3) + racional(2, 5)).should == racional(11, 15)
end
it 'realiza subtração' do
(racional(1, 3) - racional(2, 5)).should == racional(-1, 15)
end
it 'realiza multiplicação' do
(racional(1, 3) * racional(2, 5)).should == racional(2, 15)
end
it 'realiza divisão' do
(racional(1, 3) / racional(2, 5)).should == racional(5, 6)
end
it 'fornece representação em string' do
racional(7, 3).to_s.should == '7/3'
end
it 'fornece representação em ponto flutuante' do
r = racional(1, 8)
r.como_ponto_flutuante(1).should == '0.1'
r.como_ponto_flutuante(2).should == '0.12'
r.como_ponto_flutuante(3).should == '0.125'
end
end
class Retangulo
def initialize(largura, altura)
validar largura, altura
@largura, @altura = largura, altura
end
def area
largura * altura
end
def perimetro
largura * 2 + altura * 2
end
attr_reader :largura, :altura
def largura=(nova_largura)
validar nova_largura, altura
@largura = nova_largura
end
def altura=(nova_altura)
validar largura, nova_altura
@altura = nova_altura
end
private
def validar(largura, altura)
raise unless largura > 0 && altura > 0
end
end
require './ponto'
class Retangulo
def initialize(altura, largura, centro)
@altura, @largura, @centro = altura, largura, centro
end
attr_reader :altura, :largura
attr_accessor :centro
def vertices
x_desl = largura / 2
y_desl = altura / 2
[Ponto.new(centro.x - x_desl, centro.y - y_desl),
Ponto.new(centro.x + x_desl, centro.y - y_desl),
Ponto.new(centro.x - x_desl, centro.y + y_desl),
Ponto.new(centro.x + x_desl, centro.y + y_desl)]
end
end
# coding: utf-8
require './retangulo'
describe Retangulo do
before(:each) { @retangulo = Retangulo.new(4, 3) }
it 'possui largura e altura' do
@retangulo.largura.should == 4
@retangulo.altura.should == 3
end
it 'permite alterar largura e altura' do
@retangulo.largura = 10
@retangulo.largura.should == 10
@retangulo.altura = 20
@retangulo.altura.should == 20
end
it 'calcula sua área' do
@retangulo.area.should == 12
end
it 'calcula seu perímetro' do
@retangulo.perimetro.should == 14
end
it 'não aceita largura zero nem negativa' do
expect { Retangulo.new(0, 3) }.to raise_error
expect { @retangulo.largura = 0 }.to raise_error
expect { Retangulo.new(-0.1, 3) }.to raise_error
expect { @retangulo.largura = -0.1 }.to raise_error
end
it 'não aceita altura zero nem negativa' do
expect { Retangulo.new(3, 0) }.to raise_error
expect { @retangulo.altura = 0 }.to raise_error
expect { Retangulo.new(3, -0.1) }.to raise_error
expect { @retangulo.altura = -0.1 }.to raise_error
end
end
# coding: utf-8
require './retangulo'
describe Retangulo do
it 'possui largura, altura e centro' do
centro = Ponto.new(10, 8)
retangulo = Retangulo.new(3, 4, centro)
retangulo.altura.should == 3
retangulo.largura.should == 4
retangulo.centro.should == centro
end
it 'calcula seus vértices' do
retangulo = Retangulo.new(4, 2, Ponto.new(10, 8))
retangulo.vertices.should == [
Ponto.new(9, 6), Ponto.new(11, 6),
Ponto.new(9, 10), Ponto.new(11, 10)]
end
it 'permite alterar centro' do
retangulo = Retangulo.new(4, 2, Ponto.new(10, 8))
retangulo.centro = Ponto.new(5, 5)
retangulo.vertices.should == [
Ponto.new(4, 3), Ponto.new(6, 3),
Ponto.new(4, 7), Ponto.new(6, 7)]
end
end
class TV
def initialize
@volume = 0
end
def ligar
@ligada = true
end
def desligar
@ligada = false
end
def ligada?
@ligada
end
PRIMEIRO_CANAL = 1
ULTIMO_CANAL = 60
attr_reader :canal, :volume
def trocar_canal(canal)
raise unless (PRIMEIRO_CANAL..ULTIMO_CANAL).cover?(canal)
@canal = canal
end
def aumentar_volume
@volume += 1 if volume < 30
end
def diminuir_volume
@volume -= 1 if volume > 0
end
end
# coding: utf-8
require './tv'
describe TV do
let(:tv) { TV.new }
it 'liga e desliga' do
tv.ligar
tv.should be_ligada
tv.desligar
tv.should_not be_ligada
end
it 'troca de canal' do
tv.trocar_canal(2)
tv.canal.should == 2
end
it 'só permite a troca de canal dentro de uma faixa' do
tv.trocar_canal(TV::PRIMEIRO_CANAL)
tv.trocar_canal(TV::ULTIMO_CANAL)
expect { tv.trocar_canal(TV::PRIMEIRO_CANAL - 1) }.to raise_error
expect { tv.trocar_canal(TV::ULTIMO_CANAL + 1) }.to raise_error
end
it 'aumenta e diminui o volume' do
tv.volume.should == 0
tv.aumentar_volume
tv.volume.should == 1
tv.diminuir_volume
tv.volume.should == 0
end
it 'volume so pode ser alterado dentro de uma faixa' do
tv.volume.should == 0
expect { tv.diminuir_volume }.to_not change { tv.volume }
30.times { tv.aumentar_volume }
tv.volume.should == 30
expect { tv.aumentar_volume }.to_not change { tv.volume }
end
end
@bernardobarreto
Copy link

@rodrigomanhaes Procurei no google por "exercicios string ruby" e vim parar aqui =P

@lorran10
Copy link

onde tem o enunciado das questões

@rodrigomanhaes
Copy link
Author

@rodrigomanhaes
Copy link
Author

@lorran10
Copy link

pra que serve essa funçaõ it do

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment