Last active
September 18, 2022 20:12
-
-
Save Proavtor/27841633bf2ab247007eb5c620e00463 to your computer and use it in GitHub Desktop.
The code demonstrate an elegance of Ruby with its object oriented approach to solve popular task about finding a celebrity among a group of persons.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class Array | |
def except(value) | |
self - [value] | |
end | |
end | |
class Person | |
attr_reader :name, :known_persons_names | |
def initialize(name, known_persons_names = []) | |
@name = name | |
@known_persons_names = {} | |
add_known_persons(known_persons_names) unless known_persons_names.empty? | |
end | |
def add_known_persons(known_persons_names) | |
known_persons_names.each do |p| | |
@known_persons_names[p] = true | |
end | |
end | |
def knows?(person_name) | |
@known_persons_names[person_name] | |
end | |
def doesnt_knows?(person_name) | |
!knows?(person_name) | |
end | |
end | |
class PersonGroup | |
attr_reader :persons | |
def initialize(persons = []) | |
@persons = [] | |
add(persons) unless persons.empty? | |
end | |
def add(persons) | |
persons.each do |person| | |
@persons << person | |
end | |
end | |
def find_celebrity_candidate | |
l = 0 | |
h = @persons.count - 1 | |
while l != h | |
if @persons[l].knows?(@persons[h].name) | |
l += 1 | |
else | |
h -= 1 | |
end | |
end | |
@persons[l] | |
end | |
def find_celebrity | |
candidate = find_celebrity_candidate | |
@persons.except(candidate).each do |other_person| | |
return nil if candidate.knows?(other_person.name) || other_person.doesnt_knows?(candidate.name) | |
end | |
candidate | |
end | |
end | |
my_group = PersonGroup.new( | |
[ | |
Person.new('Kamil', %w[Ivan Alex Diman Madonna]), | |
Person.new('Ivan', %w[Kamil Alex Diman Madonna]), | |
Person.new('Alex', %w[Kamil Ivan Diman Madonna]), | |
Person.new('Diman', %w[Kamil Ivan Alex Madonna]), | |
Person.new('Madonna', []) | |
] | |
) | |
puts my_group.find_celebrity.inspect |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment