Skip to content

Instantly share code, notes, and snippets.

@abratashov
Last active January 23, 2019 21:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abratashov/63d3e1de762a4991086a58f410b3748d to your computer and use it in GitHub Desktop.
Save abratashov/63d3e1de762a4991086a58f410b3748d to your computer and use it in GitHub Desktop.
class ArrayCompressor
def initialize(arr:)
@arr = arr.dup
end
def compressed
compressed_array = []
while !@arr.empty? do
first = @arr.first
first_elements = @arr.take_while {|e| e == first }
compressed_array << if first_elements.size > 2
"#{first} (#{first_elements.size})"
else
first_elements
end
@arr.shift(first_elements.size)
end
compressed_array.flatten
end
end
class ArrayCompressorTest
class << self
def passed?
match(['cat', 'cat', 'cat', 'dog', 'dog', 'dog'], ['cat (3)', 'dog (3)']) &&
match(['cat', 'cat', 'dog', 'dog', 'dog'], ['cat', 'cat', 'dog (3)']) &&
match(['cat', 'dog', 'dog', 'dog'], ['cat', 'dog (3)']) &&
match(['cat', 'dog', 'dog'], ['cat', 'dog', 'dog']) &&
match(['cat', 'dog'], ['cat', 'dog']) &&
match(['cat'], ['cat']) &&
match([], [])
end
private
def match(set, result)
compressed = ArrayCompressor.new(arr: set).compressed
puts "Array '#{set}' should be compressed to the '#{result}'"
compressed == result
end
end
end
puts (ArrayCompressorTest.passed? ? 'Tests passed successfully' : 'Tests passed with failure')
load 'string_compressor.rb'
load 'array_compressor.rb'
class ObjectCompressor
def initialize(obj)
@obj = obj
end
def compressed
case @obj.class.to_s
when 'String' then StringCompressor.new(str: @obj).compressed
when 'Array' then ArrayCompressor.new(arr: @obj).compressed
else 'Incorrect input format. The only String and Array are acceptable.'
end
end
end
class ObjectCompressorTest
class << self
def passed?
match('abcdab987612', 'a-dab9-612') &&
match(['cat', 'cat', 'dog', 'dog', 'dog'], ['cat', 'cat', 'dog (3)']) &&
match(1, 'Incorrect input format. The only String and Array are acceptable.')
end
private
def match(set, result)
compressed = ObjectCompressor.new(set).compressed
puts "Object '#{set}' should be compressed to the '#{result}'"
compressed == result
end
end
end
puts (ObjectCompressorTest.passed? ? 'Tests passed successfully' : 'Tests passed with failure')
class StringCompressor
BORDER = 0
def initialize(str:)
@str = str
end
def compressed
splited_lexemes.map do |lexem|
if lexem.size == 1
lexem[0].first
elsif lexem.size == 2
"#{lexem[0].first}#{lexem[-1].first}"
elsif lexem.size > 2
"#{lexem[0].first}-#{lexem[-1].first}"
end
end.join
end
private
def zippped_neighbour_differences
numbers = @str.chars.map(&:ord)
differences = [0] + numbers[0..-2].each_with_index.map{|num, i| num - numbers[i+1] }
differences.map! {|code| code.abs == 1 ? code : 0 }
numbers.map(&:chr).zip(differences)
end
def splited_lexemes
lexemes = []
marked_chars = zippped_neighbour_differences
while !marked_chars.empty? do
lexeme = [marked_chars.shift]
delta = marked_chars.first
if delta && delta[1].abs == 1
while delta && delta[1].abs != BORDER do
lexeme << marked_chars.shift
delta = marked_chars.first
end
lexemes << lexeme
else
lexemes << lexeme
end
end
lexemes
end
end
class StringCompressorTest
class << self
def passed?
match('abcdab987612', 'a-dab9-612') &&
match('abbdab987612', 'abbdab9-612') &&
match('cbaddd9712345', 'c-addd971-5') &&
match('abcd', 'a-d') &&
match('a', 'a') &&
match('', '')
end
private
def match(set, result)
compressed = StringCompressor.new(str: set).compressed
puts "String '#{set}' should be compressed to the '#{result}'"
compressed == result
end
end
end
puts (StringCompressorTest.passed? ? 'Tests passed successfully' : 'Tests passed with failure')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment