Ruby - Zadania
Przykładowe zadania na kolokwium
Typy danych i struktury języka
- Posortowanie tablicy w porządku malejącym
- Znajdowanie mediany liczb w nieposortowanej tablicy
- Znajdowanie dominanty liczb w tablicy
- Obliczenie statystyki wystąpień słów w pliku (odmienne formy tego samego słowa traktować jako odmienne słowa)
- Zamiana łańcucha znaków, na przyjazny adres URL (zawierający małe litery, cyfry i znak – ), w którym wszystkie znaki nie-alfanumeryczne są usuwane i zastępowane pojedynczym znakiem – . Na początku i końcu napisu nie mogą występować znaki – . Polskie znaki traktować jak znaki niealfanumeryczne. (np. dla “Zazieleniło się 21. listopada!” efekt: “zazieleni-o-si-21-listopada”).
- Linię tekstu rozbić na poszczególne słowa i przekształcić w tablicę posortowaną w kolejności rosnących długości napisów (np. “Ala ma kotka” -> [“kotka”, “Ala”, “ma”])
- Wypisanie indeksów wszystkich elementów w tablicy, których wartość jest powyżej/poniżej pewnej wartości.
- Wczytywanie liczb wprowadzanych przez użytkownika do tablicy (‘k’ kończy wprowadzanie). Wypisanie w odwrotnej kolejności.
- Jw. ale wypisywać tylko n najmniejszych liczb (bez powtórzeń).
- Określanie typu napisu, tzn. jeśli zawiera (Podpowiedź – wykorzystanie instrukcji
case
):- same znaki alfabetu, na wyjściu powinien pojawiać napis ‘znaki alfabetu’
- same cyfry -> ‘cyfry’
- znaki alfanumeryczne -> ‘znaki alfanumeryczne’
- w pozostałych przypadkach -> ‘groch z kapustą’
- Wczytać z wejścia plik, na wyjściu powinien pojawić się ten sam plik z numerami poszczególnych linii i usuniętymi pustymi liniami (pominięte linie nie mają być uwzględnione w numeracji)
- Wczytać z wejścia plik i wyszukać wszystkie linie zawierające ciąg znaków zawarty w pierwszej linii pliku. Dopasowany fragment powinien być wyróżniony.
- Sprawdzanie poprawności numeru PESEL
Programowanie obiektowe
1. Napisać klasę Weight, która w konstruktorze przyjmuje jako parametr masę wyrażoną w kilogramach oraz pozwala na jej odczyt w kilogramach i gramach:
w = Weight.new(1) w.in_kilos #=> 1 w.in_grams #=> 1000
2. Napisać klasę Temerature, która w konstruktorze przyjmuje dwa parametry – temperaturę oraz symbol oznaczający system pomiaru (:c – stopnie Celsjusza, :f – stopnie Fahrenheita, :k – Kelviny). Klasa powinna definiować metody, które pozwalają na odczyt temperatury w dowolnym z systemów:
t = Temperature.new(100, :c) t.in_celsius #=> 100 t.in_kelvins #=> 373.15 t.in_fahrenheits #=> 212
t = Temperature.new(100, :k) t.in_celsius #=> -173.15 t.in_kelvins #=> 100 t.in_fahrenheits #=> -279.67
3. Dla klasy Temperature z poprzedniego punktu dodać metody pozwalające na ustawianie wartości w dowolnym systemie. Zmienić konstruktor tak, aby domyślnie tworzył temperaturę 0 Kelwinów:
t = Temerature.new() t.in_kelvins #=> 0 t.in_celsius = 100 t.in_kelvins #=> 373.15
4. Zdefiniować klasy CD i Book, tak aby w konstruktorze jako parametr przyjmowały cenę i tytuł,
które mogą być odczytane poprzez metody price
i title
. Cena wraz z jednostką
monetarną powinna być wyświetlana w metodzie diplay_price
, natomiast metoda to_s
powinna zwracać informację o typie produktu, tytule i jego cenie:
cd = CD.new(60,"Hot '80 summer hits") cd.price #=> 60 cd.display_price #=> "60 PLN" cd.title #=> "Hot '80 summer hits" cd.to_s #=> "CD: Hot '80 summer hits, 60 PLN" book = Book.new(30, "Imię róży") book.price #=> 30 book.display_price #=> "30 PLN" book.title #=> "Imię róży" book.to_s #=> "Książka: Imię róży, 30 PLN"
5. Zdefiniować klasę Product, z której dziedziczyłyby klasy CD i Book z poprzedniego punktu tak, aby usunąć duplikację kodu w tych klasach (wskazówka: zastosować dziedziczenie).
6. Zmodyfikować klasy Book i CD w taki sposób, aby klasa Book przyjmowała
jako parametr konstruktora liczbę stron, natomiast CD liczbę utworów.
Informacje te powinny być wyświetlane w metodzie to_s
oraz powinny istnieć akcesory
dla tych atrybutów (ograniczyć do minimum powtarzający się kod):
cd = CD.new(60, "Hot '80 summer hits", 10) cd.to_s #=> "CD: Hot '80 summer hits, 60 PLN, 10 utworów" cd.tracks #=> 10 book = Book.new(30, "Imię róży",411) book.to_s #=> "Książka: Imię róży, 30 PLN, 411 stron" book.pages #=> 411
Rozwiązania
Typy danych i struktury języka
1. Sortowanie tablicy
a = [1,3,7,2,5].sort.reverse
2. Mediana
a = [1,3,2,4].sort if a.size % 2 == 0 (a[a.size/2-1] + a[a.size/2]) / 2.0 else a[a.size/2] end
3. Dominanta
a = [1,2,1,3,2,4,2,5] histogram = Hash.new(0) a.each{|e| histogram[e] += 1} histogram.index(histogram.values.sort[-1])
4. Statystyka słów
stat = Hash.new(0) while line = gets line.chop.gsub(/[^a-zA-Z]/," ").split(/\s+/).each{|word| stat[word] += 1} end puts stat.inspect
5. Przyjazny URL
"Zazieleniło się 21. listopada!".gsub(/[^a-zAZ0-9]/," ").squeeze(" ").strip.gsub(" ","-").downcase
6. Sortowanie słów w linii
"Ala ma kota".split(/\s+/).sort{|a,b| b.size <=> a.size}
7. Filtr górnoprzepustowy
min_value = 10 puts [5,11,10,3,123].select{|e| e >= min_value}
8. Wczytywanie liczb
a = [] while line = gets.chop break if line == "k" a << line.to_i end puts a.reverse
9. Wczytywanie liczb, wypisywanie najmniejszych
a = [] n = 3 while line = gets.chop break if line == "k" a << line.to_i end puts a.sort[0...n]
10. Typ napisu
napis = gets.chop puts case napis when /^$/ "napis pusty" when /^[a-zA-Z]*$/ "znaki alfabetu" when /^[0-9]*$/ "cyfry" when /^\s*$/ "białe spacje" when /^\w*$/ "znaki alfanumeryczne" else "groch z kapustą" end
11. Dekorowanie pliku
line_number = 1 while line = gets next if line =~ /^\s*$/ puts "#{line_number}: #{line}" line_number += 1 end
12. Prymitywny grep
query = gets.chop while line = gets puts line.sub(/#{query}/,"<#{query}>") if line =~ /#{query}/ end
13. Pesel
a. Wersja rozwlekła
factors = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3, 1] pesel = [8, 5, 0, 4, 2, 2, 4, 5, 6, 7, 3] sum = 0 index = 0 for digit in pesel sum += digit * factors[index] index += 1 end puts (sum % 10 == 0 ? "Pesel poprawny" : "Pesel niepoprawny")
b. Wersja zwięźlejsza
factors = "13791379131".split("") sum = 0 "85042245673".split("").each_with_index do |digit, index| sum += digit.to_i * factors[index].to_i end puts (sum % 10 == 0 ? "Pesel poprawny" : "Pesel niepoprawny")
c. Wersja najkrótsza
factors = "13791379131".split("") valid = "85042245673".split("").inject(0){|sum,e| sum + e.to_i * factors.shift.to_i} % 10 == 0 puts (valid ? "Pesel poprawny" : "Pesel niepoprawny")
Programowanie obiektowe
1. Waga
class Weight def initialize(value) @value = value end def in_kilos @value end def in_grams @value * 1000 end end
2. Temperatura (1)
class Temperature ABSOLUTE_ZERO = - 273.15 CELSIUS_TO_FAHRENHEIT_FACTOR = 9.0/5 CELSIUS_TO_FAHRENHEIT_OFFSET = 32 def initialize(value, system) # store the value always in Kelvins case system when :c @value = celsius_to_kelvin(value) when :f @value = celsius_to_kelvin(fahrenheit_to_celsius(value)) else @value = value end end def in_kelvins @value end def in_celsius kelvin_to_celsius(@value) end def in_fahrenheits celsius_to_fahrenheit(kelvin_to_celsius(@value)) end protected def celsius_to_kelvin(value) value - ABSOLUTE_ZERO end def kelvin_to_celsius(value) value + ABSOLUTE_ZERO end def celsius_to_fahrenheit(value) value * CELSIUS_TO_FAHRENHEIT_FACTOR + CELSIUS_TO_FAHRENHEIT_OFFSET end def fahrenheit_to_celsius(value) (value - CELSIUS_TO_FAHRENHEIT_OFFSET) * CELSIUS_TO_FAHRENHEIT_FACTOR end end
3. Temperatura (2)
Klasę Temperature z poprzedniego punktu rozszerzamy o następujące kod:
class Temperature def initialize(value=0, system=:k) # store the value always in Kelvins case system when :c @value = celsius_to_kelvin(value) when :f @value = celsius_to_kelvin(fahrenheit_to_celsius(value)) else @value = value end end def in_kelvins=(value) @value = value end def in_celsius=(value) @value = celsius_to_kelvin(value) end def in_fahrenheits=(value) @value = celsius_to_kelvin(fahrenheit_to_celsius(value)) end end
4. Produkty (1)
class CD attr_accessor :price, :title def initialize(price, title) @price = price @title = title end def display_price "#{price} PLN" end def to_s "CD: #{title}, #{display_price}" end end
class Book attr_accessor :price, :title def initialize(price, title) @price = price @title = title end def display_price "#{price} PLN" end def to_s "Książka: #{title}, #{display_price}" end end
5. Produkty (2)
class Product attr_accessor :price, :title NAME = "Produkt" def initialize(price, title) @price = price @title = title end def display_price "#{price} PLN" end def product_name self.class::NAME end def to_s "#{product_name}: #{title}, #{display_price}" end end class CD < Product NAME = "CD" end class Book < Product NAME = "Książka" end
6. Produkty (3)
Klasy CD oraz Book z poprzedniego punktu rozszerzamy o następujący kod:
class CD < Product attr_accessor :tracks def initialize(price, title, tracks) super(price, title) @tracks = tracks end def to_s super + ", #{self.tracks} utworów" end end class Book < Product attr_accessor :pages def initialize(price, title, pages) super(price, title) @pages = pages end def to_s super + ", #{self.pages} stron" end end