Skip to content

Instantly share code, notes, and snippets.

@3zcurdia
Created May 20, 2021 02:26
Show Gist options
  • Save 3zcurdia/61c7390fbb14550cab52e5a10629ff66 to your computer and use it in GitHub Desktop.
Save 3zcurdia/61c7390fbb14550cab52e5a10629ff66 to your computer and use it in GitHub Desktop.
Rick And Morty death toll
# frozen_string_literal: true
require 'json'
require 'net/http'
require 'concurrent'
class RickAndMorty
def character(id)
response = get_response("https://rickandmortyapi.com/api/character/#{id}")
return {} unless response.is_a?(Net::HTTPSuccess)
safe_parse(response.body)
end
private
def get_response(uri)
uri = URI(uri)
Net::HTTP.get_response(uri)
rescue SocketError
sleep(0.1)
retry
end
def safe_parse(content)
JSON.parse(content, symbolize_names: true)
rescue JSON::ParserError
{}
end
end
class DeathToll
def initialize(max = 671)
@max = max
end
def call
hist.each do |species, count|
puts "#{species}: #{'💀' * count}"
end
puts "Total deaths: #{hist.values.sum}"
puts "Total characters: #{all.count}"
puts "%.2f %% has died" % ((hist.values.sum/all.count.to_f) * 100.0)
end
def all
@all ||= fetch_all_thread
end
def hist
@hist ||= calc_hist
end
private
def fetch_all
(1..@max).map do |idx|
RickAndMorty.new.character(idx)
end
end
def fetch_all_fiber
(1..@max).map do |idx|
Fiber.new { RickAndMorty.new.character(idx) }
end.map(&:resume)
end
def fetch_all_thread
(1..@max).map do |idx|
Thread.new { RickAndMorty.new.character(idx) }
end.map(&:value)
end
def fetch_all_thread_pool
pool = Concurrent::FixedThreadPool.new(100)
characters = []
(1..@max).each do |idx|
pool.post do
characters << RickAndMorty.new.character(idx)
end
end
pool.shutdown
pool.wait_for_termination
characters
end
def calc_hist
all.each_with_object(Hash.new { 0 }) do |character, hist|
hist[character[:species]] += 1 if character[:status] == 'Dead'
end
end
end
DeathToll.new.call
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment