Skip to content

Instantly share code, notes, and snippets.

@krainboltgreene
Created April 26, 2018 06:50
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 krainboltgreene/55d961af8d4d120d54d881f80bc3102c to your computer and use it in GitHub Desktop.
Save krainboltgreene/55d961af8d4d120d54d881f80bc3102c to your computer and use it in GitHub Desktop.
require "set"
require "rspec/autorun"
GRAPH = Hash.new { |accumulated, key| accumulated[key] = Set.new}
LIBRARIES = Set.new
def depend(subject, *dependencies)
GRAPH[subject].merge(dependencies)
dependencies.each(&GRAPH.method(:[]))
end
def install(library)
return puts "#{library} is already installed." if LIBRARIES.include?(library)
LIBRARIES.add(library)
LIBRARIES.merge(GRAPH[library])
if GRAPH[library].any?
GRAPH[library].each do |dependency|
puts "Installing #{dependency}"
end
end
end
def uninstall(library)
return puts "#{library} is still needed." if GRAPH.any? do |subject, dependencies|
LIBRARIES.include?(subject) && dependencies.include?(library)
end
return puts "#{library} is not installed." unless LIBRARIES.include?(library)
LIBRARIES.delete(library)
LIBRARIES.subtract(GRAPH[library].reject do |dependency|
GRAPH.any? do |subject, dependencies|
LIBRARIES.include?(subject) && dependencies.include?(dependency)
end
end)
end
def list
puts *LIBRARIES
end
def parse(line)
command, *arguments = line.split(" ")
puts line
case command
when "DEPEND" then depend(*arguments)
when "INSTALL" then install(*arguments)
when "REMOVE" then uninstall(*arguments)
when "LIST" then list()
when "END" then nil
else raise ArgumentError, "line not recognized: #{line}"
end
end
RSpec.describe "ProgA" do
it "works" do
expect {
parse("DEPEND TELNET TCPIP NETCARD")
parse("DEPEND TCPIP NETCARD")
parse("DEPEND DNS TCPIP NETCARD")
parse("DEPEND BROWSER TCPIP HTML")
}.to change {
GRAPH
}.from({}).to({
"TELNET" => Set.new(["TCPIP", "NETCARD"]),
"TCPIP" => Set.new(["NETCARD"]),
"DNS" => Set.new(["TCPIP", "NETCARD"]),
"BROWSER" => Set.new(["TCPIP", "HTML"]),
"NETCARD" => Set.new,
"HTML" => Set.new,
})
expect {
parse("INSTALL NETCARD")
parse("INSTALL TELNET")
parse("INSTALL foo")
}.to change {
LIBRARIES
}.from(Set.new).to(
Set.new([
"NETCARD",
"TELNET",
"TCPIP",
"foo"
])
)
expect {
parse("REMOVE NETCARD")
}.to output("REMOVE NETCARD\nNETCARD is still needed.\n").to_stdout
expect {
parse("INSTALL BROWSER")
parse("INSTALL DNS")
}.to change {
LIBRARIES
}.from(Set.new([
"NETCARD",
"TELNET",
"TCPIP",
"foo"
])).to(Set.new([
"NETCARD",
"TELNET",
"TCPIP",
"foo",
"BROWSER",
"HTML",
"DNS"
]))
expect {
parse("LIST")
}.to output("LIST\nNETCARD\nTELNET\nTCPIP\nfoo\nBROWSER\nHTML\nDNS\n").to_stdout
expect {
parse("REMOVE TELNET")
}.to change {
LIBRARIES
}.from(Set.new([
"NETCARD",
"TELNET",
"TCPIP",
"foo",
"BROWSER",
"HTML",
"DNS"
])).to(Set.new([
"NETCARD",
"TCPIP",
"foo",
"BROWSER",
"HTML",
"DNS"
]))
expect {
parse("REMOVE NETCARD")
}.to output("REMOVE NETCARD\nNETCARD is still needed.\n").to_stdout
expect {
parse("REMOVE DNS")
}.to change {
LIBRARIES
}.from(Set.new([
"NETCARD",
"TCPIP",
"foo",
"BROWSER",
"HTML",
"DNS"
])).to(Set.new([
"NETCARD",
"TCPIP",
"foo",
"BROWSER",
"HTML"
]))
expect {
parse("REMOVE NETCARD")
}.to output("REMOVE NETCARD\nNETCARD is still needed.\n").to_stdout
expect {
parse("INSTALL NETCARD")
}.to output("INSTALL NETCARD\nNETCARD is already installed.\n").to_stdout
expect {
parse("REMOVE TCPIP")
}.to output("REMOVE TCPIP\nTCPIP is still needed.\n").to_stdout
expect {
parse("REMOVE BROWSER")
}.to change {
LIBRARIES
}.from(Set.new([
"NETCARD",
"TCPIP",
"foo",
"BROWSER",
"HTML"
])).to(Set.new([
"NETCARD",
"foo"
]))
expect {
parse("REMOVE TCPIP")
}.to output("REMOVE TCPIP\nTCPIP is not installed.\n").to_stdout
expect {
parse("LIST")
}.to output("LIST\nNETCARD\nfoo\n").to_stdout
expect {
parse("END")
}.to output("END\n").to_stdout
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment