From bab89b0fa3d5951d14cb3dadf28e679770ce3f51 Mon Sep 17 00:00:00 2001 From: Andrey Bukanin Date: Wed, 15 Mar 2017 17:06:05 +0300 Subject: [PATCH 1/4] Completed: arrays, fp --- test/bukanin/arrays/solution.rb | 27 +++++++++++++++++++ test/bukanin/arrays/test.rb | 26 ++++++++++++++++++ test/bukanin/fp/solution.rb | 37 ++++++++++++++++++++++++++ test/bukanin/fp/test.rb | 25 ++++++++++++++++++ test/bukanin/fp2/solution.rb | 24 +++++++++++++++++ test/bukanin/fp2/test.rb | 47 +++++++++++++++++++++++++++++++++ 6 files changed, 186 insertions(+) create mode 100644 test/bukanin/arrays/solution.rb create mode 100644 test/bukanin/arrays/test.rb create mode 100644 test/bukanin/fp/solution.rb create mode 100644 test/bukanin/fp/test.rb create mode 100644 test/bukanin/fp2/solution.rb create mode 100644 test/bukanin/fp2/test.rb diff --git a/test/bukanin/arrays/solution.rb b/test/bukanin/arrays/solution.rb new file mode 100644 index 0000000..43b951f --- /dev/null +++ b/test/bukanin/arrays/solution.rb @@ -0,0 +1,27 @@ +module Bukanin + module Arrays + class << self + def replace(array) + max = array.max + array.map { |item| item > 0 ? max : item } + end + + def search(array, query) + right = array.size + left = 0 + + loop do + break if left >= right + mid = left + (right - left) / 2 + if query <= array[mid] + right = mid + else + left = mid + 1 + end + end + + (array[right] == query) ? right : -1 + end + end + end +end diff --git a/test/bukanin/arrays/test.rb b/test/bukanin/arrays/test.rb new file mode 100644 index 0000000..66817a0 --- /dev/null +++ b/test/bukanin/arrays/test.rb @@ -0,0 +1,26 @@ +require './test/test_helper.rb' +require_relative './solution.rb' + +class Bukanin::ArraysTest < Minitest::Test + # Заменить все положительные элементы целочисленного массива на максимальное значение элементов массива. + def test_replace + array = [3, 2, -8, 4, 100, -6, 7, 8, -99] + new_array = Bukanin::Arrays.replace(array) + + assert new_array == [100, 100, -8, 100, 100, -6, 100, 100, -99] + end + + # Реализовать бинарный поиск + # Функция должна возвращать индекс элемента + def test_bin_search + assert Bukanin::Arrays.search([1], 900) == -1 + assert Bukanin::Arrays.search([1], 1) == 0 + assert Bukanin::Arrays.search([], 900) == -1 + assert Bukanin::Arrays.search([1, 4, 5, 7, 8, 9], 9) == 5 + assert Bukanin::Arrays.search([1, 4, 5, 7, 8, 9], 1) == 0 + assert Bukanin::Arrays.search([1, 4, 5, 7, 8, 9], 6) == -1 + + array = (1..10000).to_a + assert Bukanin::Arrays.search(array, array[1000]) == 1000 + end +end diff --git a/test/bukanin/fp/solution.rb b/test/bukanin/fp/solution.rb new file mode 100644 index 0000000..58af8c8 --- /dev/null +++ b/test/bukanin/fp/solution.rb @@ -0,0 +1,37 @@ +module Bukanin + module Fp + class << self + # Обратиться к параметрам фильма можно так: + # film["name"], film["rating_kinopoisk"], film["rating_imdb"], + # film["genres"], film["year"], film["access_level"], film["country"] + def rating(array) + sumstat = 0.0 + counted = 0 + + for idx in 0..(array.size - 1) + item = array[idx] + + next if item['country'].nil? || item['country'].split(',').count < 2 + + if (rate = item['rating_kinopoisk'].to_f) > 0 + counted += 1 + sumstat += rate + end + end + + sumstat / counted + end + + def chars_count(films, threshold) + counted = 0 + + for idx in 0..(films.size - 1) + next if films[idx]['rating_kinopoisk'].to_f < threshold + counted += films[idx]['name'].scan(/и/i).length + end + + counted + end + end + end +end diff --git a/test/bukanin/fp/test.rb b/test/bukanin/fp/test.rb new file mode 100644 index 0000000..d396062 --- /dev/null +++ b/test/bukanin/fp/test.rb @@ -0,0 +1,25 @@ +require 'csv' +require './test/test_helper.rb' +require_relative './solution.rb' + +class Bukanin::FpTest < Minitest::Test + # Посчитать средний рейтинг фильмов по версии кинопоиска у которых две или больше стран + # Фильмы у которых рейтиг не задан или равен 0 не учитывать в расчете среднего. + def test_rating + array = CSV.readlines('./test/fixtures/films.csv', headers: true) + + result = Bukanin::Fp.rating(array) + assert result == 6.809410385259628 + end + + # Посчитать количесвто букв 'и' в названиях всех фильмов с рейтингом кинопоиска больше или равным заданному значению + def test_chars_count + array = CSV.readlines('./test/fixtures/films.csv', headers: true) + + result = Bukanin::Fp.chars_count(array, 5) + assert result == 3966 + + result = Bukanin::Fp.chars_count(array, 8.5) + assert result == 42 + end +end diff --git a/test/bukanin/fp2/solution.rb b/test/bukanin/fp2/solution.rb new file mode 100644 index 0000000..29baffa --- /dev/null +++ b/test/bukanin/fp2/solution.rb @@ -0,0 +1,24 @@ +module Template + module Fp2 + class MyArray < Array + # Использовать стандартные функции массива для решения задач нельзя. + # Использовать свои написанные функции для реализации следующих - можно. + + # Написать свою функцию my_each + def my_each + end + + # Написать свою функцию my_map + def my_map + end + + # Написать свою функцию my_compact + def my_compact + end + + # Написать свою функцию my_reduce + def my_reduce + end + end + end +end diff --git a/test/bukanin/fp2/test.rb b/test/bukanin/fp2/test.rb new file mode 100644 index 0000000..fb1419e --- /dev/null +++ b/test/bukanin/fp2/test.rb @@ -0,0 +1,47 @@ +require 'csv' +require './test/test_helper.rb' +require_relative './solution.rb' + +class Template::Fp2Test < Minitest::Test + def setup + @array = generate :array + @my_array = Template::Fp2::MyArray.new(@array) + @int = generate :int + end + + def test_my_each + skip + result = [] + my_result = [] + + func = -> (element) { result << element if element.odd? } + my_func = -> (element) { my_result << element if element.odd? } + + assert @array.each(&func) == @my_array.my_each(&my_func) + assert result == my_result + end + + def test_my_map + skip + func = -> (element) { element * @int } + assert @array.map(&func) == @my_array.my_map(&func) + assert @array.map(&func).map(&func) == @my_array.my_map(&func).my_map(&func) + end + + def test_my_compact + skip + func = -> (element) { element if element.even? } + func_another = -> (element) { element * @int } + assert @array.map(&func).compact == @my_array.my_map(&func).my_compact + assert @array.map(&func).compact.map(&func_another) == @my_array.my_map(&func).my_compact.my_map(&func_another) + end + + def test_my_reduce + skip + func = -> (acc, element) { acc * element } + + assert @array.reduce(&func) == @my_array.my_reduce(&func) + assert @array.reduce(2, &func) == @my_array.my_reduce(2, &func) + assert @array.reduce(&:+) == @my_array.my_reduce(&:+) + end +end From 1d069aba0fcbdb0e147eaf7ff297856928b1a615 Mon Sep 17 00:00:00 2001 From: Andrey Bukanin Date: Wed, 15 Mar 2017 19:09:56 +0300 Subject: [PATCH 2/4] fp2 partly: no reduce method --- test/bukanin/fp2/solution.rb | 17 ++++++++++++++++- test/bukanin/fp2/test.rb | 8 ++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/test/bukanin/fp2/solution.rb b/test/bukanin/fp2/solution.rb index 29baffa..93966ab 100644 --- a/test/bukanin/fp2/solution.rb +++ b/test/bukanin/fp2/solution.rb @@ -1,4 +1,4 @@ -module Template +module Bukanin module Fp2 class MyArray < Array # Использовать стандартные функции массива для решения задач нельзя. @@ -6,18 +6,33 @@ class MyArray < Array # Написать свою функцию my_each def my_each + for elem in self + yield(elem) + end + self end # Написать свою функцию my_map def my_map + result = MyArray.new + my_each do |elem| + result.append(yield(elem)) + end + result end # Написать свою функцию my_compact def my_compact + result = MyArray.new + my_each do |elem| + result.append(elem) if elem + end + result end # Написать свою функцию my_reduce def my_reduce + end end end diff --git a/test/bukanin/fp2/test.rb b/test/bukanin/fp2/test.rb index fb1419e..f423554 100644 --- a/test/bukanin/fp2/test.rb +++ b/test/bukanin/fp2/test.rb @@ -2,15 +2,14 @@ require './test/test_helper.rb' require_relative './solution.rb' -class Template::Fp2Test < Minitest::Test +class Bukanin::Fp2Test < Minitest::Test def setup @array = generate :array - @my_array = Template::Fp2::MyArray.new(@array) + @my_array = Bukanin::Fp2::MyArray.new(@array) @int = generate :int end def test_my_each - skip result = [] my_result = [] @@ -22,14 +21,12 @@ def test_my_each end def test_my_map - skip func = -> (element) { element * @int } assert @array.map(&func) == @my_array.my_map(&func) assert @array.map(&func).map(&func) == @my_array.my_map(&func).my_map(&func) end def test_my_compact - skip func = -> (element) { element if element.even? } func_another = -> (element) { element * @int } assert @array.map(&func).compact == @my_array.my_map(&func).my_compact @@ -37,7 +34,6 @@ def test_my_compact end def test_my_reduce - skip func = -> (acc, element) { acc * element } assert @array.reduce(&func) == @my_array.my_reduce(&func) From 9fe8c885878a90b65986f51506a56dd944f61462 Mon Sep 17 00:00:00 2001 From: Andrey Bukanin Date: Thu, 16 Mar 2017 19:40:59 +0300 Subject: [PATCH 3/4] Bukanin. Code refactoring, fp2 reduce --- test/bukanin/arrays/solution.rb | 21 +++++++++------------ test/bukanin/fp/solution.rb | 26 +++----------------------- test/bukanin/fp2/solution.rb | 18 ++++++++++++------ 3 files changed, 24 insertions(+), 41 deletions(-) diff --git a/test/bukanin/arrays/solution.rb b/test/bukanin/arrays/solution.rb index 43b951f..00db059 100644 --- a/test/bukanin/arrays/solution.rb +++ b/test/bukanin/arrays/solution.rb @@ -7,20 +7,17 @@ def replace(array) end def search(array, query) - right = array.size - left = 0 + r = search_bin(array, 0, array.size, query) + array[r] == query ? r : -1 + end + + def search_bin(array, left, right, query) + return right if left >= right - loop do - break if left >= right - mid = left + (right - left) / 2 - if query <= array[mid] - right = mid - else - left = mid + 1 - end - end + mid = left + (right - left) / 2 + query <= array[mid] ? right = mid : left = mid + 1 - (array[right] == query) ? right : -1 + search_bin(array, left, right, query) end end end diff --git a/test/bukanin/fp/solution.rb b/test/bukanin/fp/solution.rb index 58af8c8..a3b3ae7 100644 --- a/test/bukanin/fp/solution.rb +++ b/test/bukanin/fp/solution.rb @@ -5,32 +5,12 @@ class << self # film["name"], film["rating_kinopoisk"], film["rating_imdb"], # film["genres"], film["year"], film["access_level"], film["country"] def rating(array) - sumstat = 0.0 - counted = 0 - - for idx in 0..(array.size - 1) - item = array[idx] - - next if item['country'].nil? || item['country'].split(',').count < 2 - - if (rate = item['rating_kinopoisk'].to_f) > 0 - counted += 1 - sumstat += rate - end - end - - sumstat / counted + items = array.select { |elem| !elem['country'].nil? && elem['rating_kinopoisk'].to_f > 0 && elem['country'].count(',') > 0 } + items.map { |elem| elem['rating_kinopoisk'].to_f }.reduce(:+) / items.size end def chars_count(films, threshold) - counted = 0 - - for idx in 0..(films.size - 1) - next if films[idx]['rating_kinopoisk'].to_f < threshold - counted += films[idx]['name'].scan(/и/i).length - end - - counted + films.map { |elem| elem['rating_kinopoisk'].to_f >= threshold ? elem['name'].scan(/и/i).length : 0 }.reduce(:+) end end end diff --git a/test/bukanin/fp2/solution.rb b/test/bukanin/fp2/solution.rb index 93966ab..17733c5 100644 --- a/test/bukanin/fp2/solution.rb +++ b/test/bukanin/fp2/solution.rb @@ -7,7 +7,7 @@ class MyArray < Array # Написать свою функцию my_each def my_each for elem in self - yield(elem) + block_given? ? yield(elem) : elem end self end @@ -16,7 +16,7 @@ def my_each def my_map result = MyArray.new my_each do |elem| - result.append(yield(elem)) + result << yield(elem) end result end @@ -24,15 +24,21 @@ def my_map # Написать свою функцию my_compact def my_compact result = MyArray.new - my_each do |elem| - result.append(elem) if elem - end + my_each.each { |elem| result << elem if elem } result end # Написать свою функцию my_reduce - def my_reduce + def my_reduce(memo = nil) + if memo.nil? + shift = 1 + memo = self[0] + else + shift = 0 + end + drop(shift).my_each { |e| memo = yield(memo, e) } + memo end end end From 26b36d43f9afa6fcbd223e941036b0331470e9ce Mon Sep 17 00:00:00 2001 From: Andrey Bukanin Date: Fri, 17 Mar 2017 12:21:09 +0300 Subject: [PATCH 4/4] Test fixes fb2 --- test/bukanin/fp2/solution.rb | 2 +- test/bukanin/fp2/test.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/test/bukanin/fp2/solution.rb b/test/bukanin/fp2/solution.rb index 17733c5..8d2d789 100644 --- a/test/bukanin/fp2/solution.rb +++ b/test/bukanin/fp2/solution.rb @@ -24,7 +24,7 @@ def my_map # Написать свою функцию my_compact def my_compact result = MyArray.new - my_each.each { |elem| result << elem if elem } + my_each.each { |elem| result << elem unless elem.nil? } result end diff --git a/test/bukanin/fp2/test.rb b/test/bukanin/fp2/test.rb index f423554..d501000 100644 --- a/test/bukanin/fp2/test.rb +++ b/test/bukanin/fp2/test.rb @@ -31,6 +31,13 @@ def test_my_compact func_another = -> (element) { element * @int } assert @array.map(&func).compact == @my_array.my_map(&func).my_compact assert @array.map(&func).compact.map(&func_another) == @my_array.my_map(&func).my_compact.my_map(&func_another) + + func_yet_another = -> (element) { element.even? } + + puts @array.map(&func_yet_another).compact.inspect + puts @my_array.my_map(&func_yet_another).my_compact.inspect + + assert @array.map(&func_yet_another).compact == @my_array.my_map(&func_yet_another).my_compact end def test_my_reduce