Решение на Трета задача от Деян Боиклиев

Обратно към всички решения

Към профила на Деян Боиклиев

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 39 успешни тест(а)
  • 5 неуспешни тест(а)

Код

module RBFS
class File
attr_reader :data_type
def data
@data
end
def data=(data)
case data
when NilClass then @data_type = :nil
when TrueClass, FalseClass then @data_type = :boolean
when Symbol then @data_type = :symbol
when Numeric then @data_type = :number
when String then @data_type = :string
end
@data = data
end
def initialize(data = nil)
self.data = data
end
def serialize
"#{@data_type}:#{@data == nil ? 'nil' : @data}"
end
def to_s
serialize
end
def self.parse(string_data)
keyValuePair = string_data.split(':')
type = keyValuePair[0]
data = keyValuePair[1]
get_file(type, data)
end
def self.get_file(type, data)
return File.new(data.to_f) if /^\d+\.\d+$/ === data and type == 'number'
return File.new(data.to_i) if /^\d+$/ === data and type == 'number'
return File.new(data == 'true') if type === 'boolean'
return File.new(data.to_sym) if type == 'symbol'
return File.new(data) if type == 'string'
return File.new(nil) if type == 'nil'
end
end
class Directory
attr_accessor :is_root
attr_reader :files, :directories, :name
def initialize
@files = Hash.new
@directories = Hash.new
@is_root = true
end
def add_file(name, file)
@files[name] = file
@is_root = true
@name = name
end
def add_directory(name, directory = Directory.new)
@directories[name] = directory
directory.is_root = false
end
def [](name)
@directories[name] || @files[name]
end
def serialize
DirectorySerializer.serialize_directory('', self)
end
public
def self.parse(string_data, root = Directory.new)
DirectoryParser.parse(string_data, root)
return root
end
end
class DirectorySerializer
def self.serialize_directory(name, directory)
if DirectorySerializer.is_root_and_empty?(directory)
'0:0:'
elsif directory.directories.any?
DirectorySerializer.serialize_node_directory(name, directory)
else
DirectorySerializer.serialize_leaf_directory(name, directory)
end
end
def self.serialize_node_directory(name, directory)
files = DirectorySerializer.serialize_files(directory)
dirs = DirectorySerializer.serialize_dirs(directory)
if !directory.is_root
files_and_dirs = "#{files}#{dirs}"
"#{name}:#{files_and_dirs.length}:#{files}#{dirs}"
else
"#{files}#{dirs}"
end
end
def self.serialize_leaf_directory(name, directory)
serialized_files = serialize_files(directory)
"#{name}:#{serialized_files.length + 2}:#{serialized_files}0:"
end
def self.is_root_and_empty?(directory)
files = directory.files
directories = directory.directories
directory.is_root and !files.any? and !directories.any?
end
def self.serialize_dirs(directory)
dirs = "#{directory.directories.size}:"
directory.directories.each do |name, dir|
dir = serialize_directory(name, dir)
dirs << dir
end
dirs
end
def self.serialize_files(directory)
serialized_files = "#{directory.files.size}:"
directory.files.each do |name, file|
serialized_file = file.serialize
file_size = serialized_file.length
serialized_files << "#{name}:#{file_size}:#{serialized_file}"
end
serialized_files
end
end
class DirectoryParser
def self.parse(string_data, root = Directory.new)
@next_index = 0
DirectoryParser.parse_files(string_data, root)
DirectoryParser.parse_directories(string_data, root)
return root
end
def self.parse_files(string_data, root = Directory.new)
file_count = DirectoryParser.next_data(string_data).to_i
(1..file_count).each do |_|
file_name = DirectoryParser.next_data(string_data)
file_length = DirectoryParser.next_data(string_data).to_i
file_content = DirectoryParser.file_content(string_data, file_length)
root.add_file(file_name, File.parse(file_content))
end
end
def self.parse_directories(string_data, root = Directory.new)
dir_count = DirectoryParser.next_data(string_data).to_i
(1..dir_count).each do |_|
dir_name = DirectoryParser.next_data(string_data)
dir_length = DirectoryParser.next_data(string_data).to_i
root.add_directory(dir_name)
remaining_data = string_data[@next_index..string_data.length]
DirectoryParser.parse(remaining_data, root)
end
end
def self.next_data(string_data)
data = ''
indeces = (@next_index..string_data.length).to_a
$i = indeces[0]
while $i < string_data.length && string_data[$i] != ':' do
data << string_data[$i].to_s
$i += 1
end
@next_index = $i + 1
data
end
def self.file_content(string_data, file_length)
content = ''
indeces = (@next_index..string_data.length).to_a
index = indeces[0]
while content.length < file_length.to_i
content << string_data[index].to_s
index += 1
end
@next_index += file_length.to_i
content
end
end
end

Лог от изпълнението

.........F..FF.........F....F...............

Failures:

  1) RBFS Directory serialization #serialize can serialize multiple directories recursively
     Failure/Error: expect(directory.serialize).to eq recursive_serialized_string
       
       expected: "2:README:19:string:Hello world!spec.rb:20:string:describe RBFS2:rbfs:64:1:solution.rb:13:symbol:hidden1:spec:24:1:test:12:boolean:true0:sample:4:0:0:"
            got: "2:README:19:string:Hello world!spec.rb:20:string:describe RBFS2:1:solution.rb:13:symbol:hidden1:spec:24:1:test:12:boolean:true0:sample:4:0:0:"
       
       (compared using ==)
     # /tmp/d20141111-26053-1hwtoa5/spec.rb:95:in `block (5 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) RBFS Directory serialization ::parse can parse directory trees without files
     Failure/Error: expect(parsed_directory['dir1']['dir2']).to be_an RBFS::Directory
       expected nil to be a kind of RBFS::Directory
     # /tmp/d20141111-26053-1hwtoa5/spec.rb:120:in `block (5 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) RBFS Directory serialization ::parse can parse directories recursively
     Failure/Error: expect(parsed_directory.files.size     ).to eq 2
       
       expected: 2
            got: 4
       
       (compared using ==)
     # /tmp/d20141111-26053-1hwtoa5/spec.rb:127:in `block (5 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) RBFS File data type nil can be serialized
     Failure/Error: expect(file.serialize).to eq 'nil:'
       
       expected: "nil:"
            got: "nil:nil"
       
       (compared using ==)
     # /tmp/d20141111-26053-1hwtoa5/spec.rb:226:in `block (5 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) RBFS File data type string can parse a string with colons
     Failure/Error: expect(file.data     ).to eq 'Hay :)'
       
       expected: "Hay :)"
            got: "Hay "
       
       (compared using ==)
     # /tmp/d20141111-26053-1hwtoa5/spec.rb:257:in `block (5 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.04519 seconds
44 examples, 5 failures

Failed examples:

rspec /tmp/d20141111-26053-1hwtoa5/spec.rb:84 # RBFS Directory serialization #serialize can serialize multiple directories recursively
rspec /tmp/d20141111-26053-1hwtoa5/spec.rb:116 # RBFS Directory serialization ::parse can parse directory trees without files
rspec /tmp/d20141111-26053-1hwtoa5/spec.rb:124 # RBFS Directory serialization ::parse can parse directories recursively
rspec /tmp/d20141111-26053-1hwtoa5/spec.rb:225 # RBFS File data type nil can be serialized
rspec /tmp/d20141111-26053-1hwtoa5/spec.rb:254 # RBFS File data type string can parse a string with colons

История (1 версия и 0 коментара)

Деян обнови решението на 10.11.2014 08:49 (преди над 9 години)

+module RBFS
+ class File
+ attr_reader :data_type
+
+ def data
+ @data
+ end
+
+ def data=(data)
+ case data
+ when NilClass then @data_type = :nil
+ when TrueClass, FalseClass then @data_type = :boolean
+ when Symbol then @data_type = :symbol
+ when Numeric then @data_type = :number
+ when String then @data_type = :string
+ end
+ @data = data
+ end
+
+ def initialize(data = nil)
+ self.data = data
+ end
+
+
+ def serialize
+ "#{@data_type}:#{@data == nil ? 'nil' : @data}"
+ end
+
+ def to_s
+ serialize
+ end
+
+ def self.parse(string_data)
+ keyValuePair = string_data.split(':')
+ type = keyValuePair[0]
+ data = keyValuePair[1]
+ get_file(type, data)
+ end
+
+ def self.get_file(type, data)
+ return File.new(data.to_f) if /^\d+\.\d+$/ === data and type == 'number'
+ return File.new(data.to_i) if /^\d+$/ === data and type == 'number'
+ return File.new(data == 'true') if type === 'boolean'
+ return File.new(data.to_sym) if type == 'symbol'
+ return File.new(data) if type == 'string'
+ return File.new(nil) if type == 'nil'
+ end
+ end
+
+ class Directory
+ attr_accessor :is_root
+ attr_reader :files, :directories, :name
+
+ def initialize
+ @files = Hash.new
+ @directories = Hash.new
+ @is_root = true
+ end
+
+ def add_file(name, file)
+ @files[name] = file
+ @is_root = true
+ @name = name
+ end
+
+ def add_directory(name, directory = Directory.new)
+ @directories[name] = directory
+ directory.is_root = false
+ end
+
+ def [](name)
+ @directories[name] || @files[name]
+ end
+
+ def serialize
+ DirectorySerializer.serialize_directory('', self)
+ end
+
+
+ public
+ def self.parse(string_data, root = Directory.new)
+ DirectoryParser.parse(string_data, root)
+ return root
+ end
+ end
+
+ class DirectorySerializer
+ def self.serialize_directory(name, directory)
+ if DirectorySerializer.is_root_and_empty?(directory)
+ '0:0:'
+ elsif directory.directories.any?
+ DirectorySerializer.serialize_node_directory(name, directory)
+ else
+ DirectorySerializer.serialize_leaf_directory(name, directory)
+ end
+ end
+
+ def self.serialize_node_directory(name, directory)
+ files = DirectorySerializer.serialize_files(directory)
+ dirs = DirectorySerializer.serialize_dirs(directory)
+ if !directory.is_root
+ files_and_dirs = "#{files}#{dirs}"
+ "#{name}:#{files_and_dirs.length}:#{files}#{dirs}"
+ else
+ "#{files}#{dirs}"
+ end
+ end
+
+ def self.serialize_leaf_directory(name, directory)
+ serialized_files = serialize_files(directory)
+ "#{name}:#{serialized_files.length + 2}:#{serialized_files}0:"
+ end
+
+ def self.is_root_and_empty?(directory)
+ files = directory.files
+ directories = directory.directories
+ directory.is_root and !files.any? and !directories.any?
+ end
+
+ def self.serialize_dirs(directory)
+ dirs = "#{directory.directories.size}:"
+ directory.directories.each do |name, dir|
+ dir = serialize_directory(name, dir)
+ dirs << dir
+ end
+ dirs
+ end
+
+ def self.serialize_files(directory)
+ serialized_files = "#{directory.files.size}:"
+ directory.files.each do |name, file|
+ serialized_file = file.serialize
+ file_size = serialized_file.length
+ serialized_files << "#{name}:#{file_size}:#{serialized_file}"
+ end
+ serialized_files
+ end
+ end
+
+ class DirectoryParser
+ def self.parse(string_data, root = Directory.new)
+ @next_index = 0
+ DirectoryParser.parse_files(string_data, root)
+ DirectoryParser.parse_directories(string_data, root)
+ return root
+ end
+
+ def self.parse_files(string_data, root = Directory.new)
+ file_count = DirectoryParser.next_data(string_data).to_i
+ (1..file_count).each do |_|
+ file_name = DirectoryParser.next_data(string_data)
+ file_length = DirectoryParser.next_data(string_data).to_i
+ file_content = DirectoryParser.file_content(string_data, file_length)
+ root.add_file(file_name, File.parse(file_content))
+ end
+ end
+
+ def self.parse_directories(string_data, root = Directory.new)
+ dir_count = DirectoryParser.next_data(string_data).to_i
+
+ (1..dir_count).each do |_|
+ dir_name = DirectoryParser.next_data(string_data)
+ dir_length = DirectoryParser.next_data(string_data).to_i
+
+ root.add_directory(dir_name)
+ remaining_data = string_data[@next_index..string_data.length]
+ DirectoryParser.parse(remaining_data, root)
+ end
+ end
+
+ def self.next_data(string_data)
+ data = ''
+ indeces = (@next_index..string_data.length).to_a
+ $i = indeces[0]
+ while $i < string_data.length && string_data[$i] != ':' do
+ data << string_data[$i].to_s
+ $i += 1
+ end
+ @next_index = $i + 1
+ data
+ end
+
+ def self.file_content(string_data, file_length)
+ content = ''
+ indeces = (@next_index..string_data.length).to_a
+ index = indeces[0]
+ while content.length < file_length.to_i
+ content << string_data[index].to_s
+ index += 1
+ end
+ @next_index += file_length.to_i
+ content
+ end
+ end
+end