trainworks 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bd0bbc94d01b0526100339105b0e244a47c84286
4
+ data.tar.gz: e1187451608b2347fe70790753498d9158bd65a3
5
+ SHA512:
6
+ metadata.gz: 893e1e95c8ba60a8722ddc686587a2bca8edc7a74e05e80d3440c005330ee3b7b629b80676edcd748a78f40c4d4f8061a280711bf2078e9ce9e23f957e34049a
7
+ data.tar.gz: 10385ce964d3426719dcc6a2acc86f4685fb6e774fb93ed4b0be8f84dd017d0dc81c2b28a59f73b4531d71dfd4979637ed78661af0dc3e58f5c220fd1ae0209f
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /doc/
6
+ /tmp
7
+ .vimrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,14 @@
1
+ Metrics/LineLength:
2
+ Max: 120
3
+ SpaceInsideHashLiteralBraces:
4
+ Enabled: false
5
+ SpaceInsideBrackets:
6
+ Enabled: false
7
+ Style/FrozenStringLiteralComment:
8
+ Enabled: false
9
+ Style/FrozenStringLiteralComment:
10
+ Enabled: false
11
+ Metrics/BlockLength:
12
+ Enabled: true
13
+ Exclude:
14
+ - spec/**/*
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ trainworks
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.3
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup=markdown
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in trainworks.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Andre Herculano
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # Trainworks 🚂
2
+ [![Build Status](https://semaphoreci.com/api/v1/projects/14ca60dd-4c8c-4c22-a419-b888d253491c/1073642/shields_badge.svg)](https://semaphoreci.com/andresilveirah/trainworks)
3
+
4
+ ## Problem Definition
5
+
6
+ The local commuter railroad services a number of towns in Kiwiland. Because of monetary concerns, all of the tracks are 'one-way.' That is, a route from Kaitaia to Invercargill does not imply the existence of a route from Invercargill to Kaitaia. In fact, even if both of these routes do happen to exist, they are distinct and are not necessarily the same distance!
7
+
8
+ The purpose of this problem is to help the railroad provide its customers with information about the routes. In particular, you will compute the distance along a certain route, the number of different routes between two towns, and the shortest route between two towns.
9
+
10
+ ### Input
11
+ A directed graph where a node represents a town and an edge represents a route between two towns. The weighting of the edge represents the distance between the two towns. A given route will never appear more than once, and for a given route, the starting and ending town will not be the same town.
12
+
13
+ ### Output
14
+
15
+ For test input 1 through 5, if no such route exists, output 'NO SUCH ROUTE'. Otherwise, follow the route as given; do not make any extra stops! For example, the first problem means to start at city A, then travel directly to city B (a distance of 5), then directly to city C (a distance of 4).
16
+
17
+ 1. The distance of the route A-B-C.
18
+ 2. The distance of the route A-D.
19
+ 3. The distance of the route A-D-C.
20
+ 4. The distance of the route A-E-B-C-D.
21
+ 5. The distance of the route A-E-D.
22
+ 6. The number of trips starting at C and ending at C with a maximum of 3 stops. In the sample data below, there are two such trips: C-D-C (2 stops). and C-E-B-C (3 stops).
23
+ 7. The number of trips starting at A and ending at C with exactly 4 stops. In the sample data below, there are three such trips: A to C (via B,C,D); A to C (via D,C,D); and A to C (via D,E,B).
24
+ 8. The length of the shortest route (in terms of distance to travel) from A to C.
25
+ 9. The length of the shortest route (in terms of distance to travel) from B to B.
26
+ 10. The number of different routes from C to C with a distance of less than 30. In the sample data, the trips are: CDC, CEBC, CEBCDC, CDCEBC, CDEBC, CEBCEBC, CEBCEBCEBC.
27
+
28
+ ### Test Input
29
+
30
+ For the test input, the towns are named using the first few letters of the alphabet from A to E. A route between two towns (A to B) with a distance of 5 is represented as AB5.
31
+
32
+ Graph: AB5, BC4, CD8, DC8, DE6, AD5, CE2, EB3, AE7
33
+
34
+ Expected Output:
35
+
36
+ ```
37
+ Output #1: 9
38
+ Output #2: 5
39
+ Output #3: 13
40
+ Output #4: 22
41
+ Output #5: NO SUCH ROUTE
42
+ Output #6: 2
43
+ Output #7: 3
44
+ Output #8: 9
45
+ Output #9: 9
46
+ Output #10: 7
47
+ ```
48
+
49
+ ## Installation
50
+
51
+ **Note:** Since the project is not yet publicly available, there's no way to fork/clone/install it from [Rubygems](https://rubygems.org/). The only way to use the gem is getting its source code and running `rake install`. It will install the local gem so you'll be able to require it in `irb` for example.
52
+
53
+ First you'll need [Bundler](http://bundler.io/) in order to install the dependencies (which are only necessary for development).
54
+
55
+ $ gem install bundler
56
+
57
+ Add this line to your application's Gemfile:
58
+
59
+ ```ruby
60
+ gem 'trainworks'
61
+ ```
62
+
63
+ And then execute:
64
+
65
+ $ bundle
66
+
67
+ Or install it yourself as:
68
+
69
+ $ gem install trainworks
70
+
71
+ ## Usage
72
+
73
+ ```ruby
74
+ require 'trainworks'
75
+
76
+ railroad = Trainworks::Railroad.new('examples/input.txt')
77
+
78
+ # assuming you have the following graph
79
+ # AB5, BC4, CD8, DC8, DE6, AD5, CE2, EB3, AE7
80
+ railroad.distance("A-B-C")
81
+ # => 9.0
82
+
83
+ railroad.distance("A-Z")
84
+ # => "NO SUCH ROUTE"
85
+
86
+ railroad.shortest_distance(from: "A", to: "C")
87
+ # => 9.0
88
+
89
+ railroad.trips(from: "C", to: "C", with_max_stops: 3)
90
+ # => [["C","D","C"], ["C","E","B","C"]]
91
+
92
+ railroad.trips(from: "A", to: "C", with_exact_stops: 4)
93
+ # => [["A", "B", "C", "D", "C"], ["A", "D", "C", "D", "C"], ["A", "D", "E", "B", "C"]]
94
+
95
+ railroad.trips(from: "C", to: "C", with_max_distance: 30)
96
+ # => [["C","D","C"], ["C","E","B","C"], ["C","E","B","C","D","C"], ["C","D","C","E","B","C"], ["C","D","E","B","C"], ["C","E","B","C","E","B","C"], ["C","E","B","C","E","B","C","E","B","C"]]
97
+ ```
98
+
99
+ ## Development & Contribution
100
+
101
+ **Note:** This section is only valid after the project is publicly available.
102
+
103
+ 1. Fork this repository.
104
+ 2. Clone it into your machine and run `bundle install`.
105
+ 3. Add your changes.
106
+ 4. Make sure the specs are green by running `rspec`.
107
+ 5. Make sure the code style is respected by running `rubocop`.
108
+ 6. Open a pull request.
109
+
110
+ ## License
111
+
112
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1 @@
1
+ AB5, BC4, CD8, DC8, DE6, AD5, CE2, EB3, AE7
data/lib/trainworks.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'trainworks/version'
2
+ require 'trainworks/railroad'
3
+ require 'trainworks/file_parser'
4
+ require 'trainworks/route'
5
+ require 'trainworks/graph_algorithm'
6
+ require 'trainworks/graph_builder'
7
+
8
+ # Trainworks is used only as a namespace for the trainworks gem
9
+ module Trainworks
10
+ end
@@ -0,0 +1,40 @@
1
+ require 'trainworks/file_parser/invalid_railroad_input_format'
2
+
3
+ module Trainworks
4
+ # FileParser is responsible for parsing the input file
5
+ # @example
6
+ # AB5, cd99, LetterLetterPositiveNumbers
7
+ class FileParser
8
+ # captures, for example, AB99
9
+ SINGLE_TUPLE_REGEX = /(?<from>[a-zA-Z])(?<to>[a-zA-Z])(?<distance>\d+)/
10
+
11
+ # Converts the object into textual markup given a specific format.
12
+ # @param file_path [String] the path for input file
13
+ def initialize(file_path)
14
+ @raw_content = File.read(file_path)
15
+ end
16
+
17
+ # @return [Array<Route>] array of {Route}s
18
+ # @raise [InvalidRailroadInputFormat] if the tuple doesn't match SINGLE_TUPLE_REGEX
19
+ def parse
20
+ clean_string(@raw_content).split(',').map do |route_string|
21
+ matched_route_string = route_string.match(SINGLE_TUPLE_REGEX)
22
+ raise InvalidRailroadInputFormat, route_string if matched_route_string.nil?
23
+
24
+ Route.new(
25
+ from: matched_route_string[:from],
26
+ to: matched_route_string[:to],
27
+ distance: matched_route_string[:distance]
28
+ )
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ # removes special characters from the input except letters, numbers and commas
35
+ # @private
36
+ def clean_string(text)
37
+ text.gsub(/[^0-9A-Za-z\,]/, '')
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,18 @@
1
+ module Trainworks
2
+ class FileParser
3
+ # When parsing the input file, format of the route is not correct
4
+ # InvalidRailroadInputFormat will be raised
5
+ class InvalidRailroadInputFormat < ArgumentError
6
+ # @param [Object] route_string - must respond to `#to_s`
7
+ # @return [InvalidRailroadInputFormat]
8
+ def initialize(route_string)
9
+ @route_string = route_string
10
+ end
11
+
12
+ # Converts the exception into string
13
+ def to_s
14
+ "'#{@route_string}' is not of the form LetterLetterNumber. E.g. AB10"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,149 @@
1
+ # rubocop:disable MethodLength
2
+ # rubocop:disable ParameterLists
3
+
4
+ module Trainworks
5
+ # GraphAlgorithm is used to calculate direct distances,
6
+ # shortest path and other paths between nodes.
7
+ # It assumes graph is a hash of adjacencies of a **directed-positively-weighted-possibly-cyclic-graph**
8
+ # @example Example of a graph
9
+ # 'A' => { 'B' => 5 },
10
+ # 'B' => { 'C' => 5 },
11
+ # 'C' => { 'B' => 4 }
12
+ #
13
+ class GraphAlgorithm
14
+ def initialize(graph)
15
+ @graph = graph
16
+ end
17
+
18
+ # @param [Array] cities is a set of nodes
19
+ # @return [Number] the distance traveled from city to city in cities
20
+ # @return [String] "NO SUCH ROUTE" when one of the citis is not connected to another
21
+ # @example
22
+ # algorithm.distance(['A', 'B', 'C']) => 10
23
+ def distance(cities)
24
+ distance = 0
25
+ begin
26
+ cities.each_cons(2) do |(from, to)|
27
+ distance += go(from: from, to: to)
28
+ end
29
+ rescue NoSuchRoute => e
30
+ distance = e.to_s
31
+ end
32
+
33
+ distance
34
+ end
35
+
36
+ # @param [Object] from the starting point
37
+ # @param [Object] to the goal
38
+ # @param [Number] stops the maximum number of stops between from and to the algorithm is allowed to travel
39
+ # @return [Array<Array>] all possible trips from the starting point to the goal with maximum stops equal to `stops`
40
+ def trips_with_max_stops(from:, to:, stops:, total_paths: [from], solutions: [])
41
+ routes(from).map do |city, _paths|
42
+ return solutions if 0 >= stops
43
+ next_total_paths = [*total_paths, city]
44
+ solutions.push(next_total_paths) if arrived?(city, to)
45
+ trips_with_max_stops(from: city, to: to, stops: stops - 1, total_paths: next_total_paths, solutions: solutions)
46
+ end
47
+ solutions
48
+ end
49
+
50
+ # @param [Object] from the starting point
51
+ # @param [Object] to the goal
52
+ # @param [Number] stops the maximum number of stops between from and to the algorithm is allowed to travel
53
+ # @return [Array<Array>] all possible trips from the starting point to the goal with maximum stops equal to `stops`
54
+ # @see GraphAlgorithm#trips_with_max_stops #trips_with_max_stops
55
+ # it calls {trips_with_max_stops} and filter out the trips that don't have the exact number of stops as `stops`
56
+ def trips_with_exact_stops(from:, to:, stops:)
57
+ total_path_size = stops + 1 # a path includes the stops plus the origin
58
+ trips_with_max_stops(from: from, to: to, stops: stops).select do |path|
59
+ path.size == total_path_size
60
+ end
61
+ end
62
+
63
+ # @param [Object] from the starting point
64
+ # @param [Object] to the goal
65
+ # @param [Number] max_distance the maximum distance between from and to the algorithm is allowed to travel
66
+ # @return [Array<Array>] all trips from the starting point to the goal with maximum stops equal to `max_distance`
67
+ # Since we calculate the distance by adding up the distances between the nodes, the edges must have positive
68
+ # distances otherwise it's not garateed the algorithm will reach a stop.
69
+ def trips_with_max_distance(from:, to:, max_distance:, total_paths: [from], solutions: {}, current_distance: 0)
70
+ routes(from).map do |city, _paths|
71
+ next_current_distance = current_distance + go(from: from, to: city)
72
+ return solutions.keys if next_current_distance >= max_distance
73
+ next_total_paths = [*total_paths, city]
74
+ solutions[next_total_paths] = next_current_distance if arrived?(city, to)
75
+ trips_with_max_distance(
76
+ from: city,
77
+ to: to,
78
+ max_distance: max_distance,
79
+ total_paths: next_total_paths,
80
+ solutions: solutions,
81
+ current_distance: next_current_distance
82
+ )
83
+ end
84
+ solutions.keys
85
+ end
86
+
87
+ # @param [Object] from the starting point
88
+ # @param [Object] to the goal
89
+ # @return [Hash] all possible trips from the starting point to the goal without repeating loops
90
+ def trips(from:, to:, current_distance: 0, current_path: [from], all_paths: {})
91
+ routes(from).map do |city, _paths|
92
+ next_current_path = [*current_path, city]
93
+ next_current_distance = current_distance + go(from: from, to: city)
94
+ all_paths[next_current_path] = next_current_distance if arrived?(city, to)
95
+ next if arrived?(city, to) || already_visited?(next_current_path, city)
96
+ trips(
97
+ from: city,
98
+ to: to,
99
+ current_distance: next_current_distance,
100
+ current_path: next_current_path,
101
+ all_paths: all_paths
102
+ )
103
+ end
104
+ all_paths
105
+ end
106
+
107
+ # @param [Object] from the starting point
108
+ # @param [Object] to the goal
109
+ # @return [Number] the shortest distance from `from` to `to`
110
+ # @see GraphAlgorithm#trips #trips
111
+ # @raise NoSuchRoute
112
+ # It calls {trips} to find all paths between the starting point and the goal and returns
113
+ # the shortest distance found. If there's no path between `from` and `to` it raises {NoSuchRoute}
114
+ def shortest_distance(from:, to:)
115
+ shortest_distance = trips(from: from, to: to).values.min
116
+ raise NoSuchRoute if shortest_distance.nil?
117
+ shortest_distance
118
+ end
119
+
120
+ # NoSuchRoute is raised when there are no direct connection between two cities (nodes)
121
+ class NoSuchRoute < KeyError
122
+ def to_s
123
+ 'NO SUCH ROUTE'
124
+ end
125
+ end
126
+
127
+ private
128
+
129
+ def arrived?(current, goal)
130
+ current == goal
131
+ end
132
+
133
+ # if the current_city can be found more than one time in the path
134
+ # it means we already visited it.
135
+ def already_visited?(path, current_city)
136
+ path.count(current_city) > 1
137
+ end
138
+
139
+ # these are helper methods to deal with finding keys in the graph an its value
140
+ # in case of not finding the keys (`from` and `to`) it raises `NoSuchRoute`
141
+ def go(from:, to:)
142
+ routes(from).fetch(to) { raise NoSuchRoute }
143
+ end
144
+
145
+ def routes(city)
146
+ @graph.fetch(city) { raise NoSuchRoute }
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,31 @@
1
+ module Trainworks
2
+ # GraphBuilder is responsible to transform tuples (in our case Routes)
3
+ # into a Hash which represents a list of adjacencies between the nodes.
4
+ #
5
+ # @todo: encapsulate the idea of a Graph inside a class instead of relying on Hash class.
6
+ module GraphBuilder
7
+ # @param [Array<Route>] routes
8
+ # @return [Hash]
9
+ def self.build(routes)
10
+ routes.reduce({}) do |graph, route|
11
+ add_edge(graph, route.from, route.to, route.distance)
12
+ end
13
+ end
14
+
15
+ # @param [Hash] graph
16
+ # @param [Object] from
17
+ # @param [Object] to
18
+ # @param [Object] distance
19
+ # @return [Hash] graph with the new edge
20
+ # Adds a new edge to the graph.
21
+ # It checks if the key `from` (*node*) is present in the graph and adds to it the `to` with its distance.
22
+ def self.add_edge(graph, from, to, distance)
23
+ if graph.key?(from)
24
+ graph[from][to] = distance
25
+ else
26
+ graph[from] = Hash[to, distance]
27
+ end
28
+ graph
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,53 @@
1
+ module Trainworks
2
+ # Railroad is the entry point for Trainworks gem
3
+ class Railroad
4
+ # @param [String] file_path is the path for the input file containing the graph definition
5
+ # @param [Object] file_parser is the class responsible for parsing the input file and return a set of {Route}s
6
+ # @param [Object] graph_builder receives the set of {Route}s and build a graph for `graph_algorithm`
7
+ # @param [Object] graph_algorithm is the responsible for calculating the distances between nodes, paths, etc.
8
+ def initialize(file_path, file_parser: FileParser, graph_builder: GraphBuilder, graph_algorithm: GraphAlgorithm)
9
+ @file_parser = file_parser.new(file_path)
10
+ @graph = graph_builder.build(@file_parser.parse)
11
+ @algorithm = graph_algorithm.new(@graph)
12
+ end
13
+
14
+ # @param [String] route_string represents the route to be followed. E.g. A-B-C
15
+ # @return [Number] the distance from A to B to C
16
+ # Calculates the distance traveled between cities in the form of `"A-B-C"`
17
+ def distance(route_string)
18
+ @algorithm.distance(route_string.split('-'))
19
+ end
20
+
21
+ # @param [Object] from is the starting point
22
+ # @param [Object] to is the goal
23
+ # @param [Number] with_max_stops how many stops at most, the algorithm is allowed to *travel*.
24
+ # @param [Number] with_exact_stops how many stops exactly, the algorithm is allowed to *travel*.
25
+ # @param [Number] with_max_distance the maximum distance (non inclusive), the algorithm is allowed to *travel*
26
+ # @return [Array<Array>] which represents each path found
27
+ # Notice that only one of the parameters `with_max_stops`, `with_exact_stops` or `with_max_distance` will be taken
28
+ # into account, in the following order:
29
+ #
30
+ # 1. `with_max_stops`
31
+ # 2. `with_exact_stops`
32
+ # 3. `with_max_distance`
33
+ def trips(from:, to:, with_max_stops: nil, with_exact_stops: nil, with_max_distance: nil)
34
+ if with_max_stops
35
+ @algorithm.trips_with_max_stops(from: from, to: to, stops: with_max_stops)
36
+ elsif with_exact_stops
37
+ @algorithm.trips_with_exact_stops(from: from, to: to, stops: with_exact_stops)
38
+ elsif with_max_distance
39
+ @algorithm.trips_with_max_distance(from: from, to: to, max_distance: with_max_distance)
40
+ else
41
+ raise "I don't know how to calculate these routes"
42
+ end
43
+ end
44
+
45
+ # @param [Object] from is the starting point
46
+ # @param [Object] to is the goal
47
+ # @return [Number] the shortest distance between `from` and `to`
48
+ # Calculates the shortest distance between `from` and `to`
49
+ def shortest_distance(from:, to:)
50
+ @algorithm.shortest_distance(from: from, to: to)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,28 @@
1
+ module Trainworks
2
+ # Route is used to group together the information
3
+ # of an edge of a graph. From and To are two nodes
4
+ # and distance is the weight between them
5
+ class Route
6
+ attr_accessor :from, :to, :distance
7
+
8
+ # @param [Object] from is the starting point of the route
9
+ # @param [Object] to is the end point of the route
10
+ # @param [Object] distance also known as *weight* between `from` and `to`
11
+ # @return [Route]
12
+ # `from` and `to` must respond to `#to_s` and `distance` must respond to `#to_f`
13
+ def initialize(from:, to:, distance:)
14
+ self.from = from.to_s
15
+ self.to = to.to_s
16
+ self.distance = distance.to_f
17
+ end
18
+
19
+ # @param [Object] other
20
+ # @return [Boolean]
21
+ # Returns `true` if `other.from`, `other.to` and `other.distance` have the same value as `self`
22
+ def ==(other)
23
+ from == other.from &&
24
+ to == other.to &&
25
+ distance == other.distance
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,4 @@
1
+ module Trainworks
2
+ # Current version
3
+ VERSION = '1.0.0'.freeze
4
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'trainworks/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'trainworks'
9
+ spec.version = Trainworks::VERSION
10
+ spec.authors = ['André Herculano']
11
+ spec.email = ['andresilveirah@gmail.com']
12
+ spec.homepage = 'https://rubygems.org/gems/example'
13
+ spec.summary = 'Models a railroad as a graph and offers some traversing methods.'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(spec)/})
18
+ end
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.13'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'rspec', '~> 3.0'
24
+ spec.add_development_dependency 'rubocop', '~> 0.45.0'
25
+ spec.add_development_dependency 'yard', '~> 0.9'
26
+ spec.add_development_dependency 'redcarpet', '~> 3.3'
27
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trainworks
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - André Herculano
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-10-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.45.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.45.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.9'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: redcarpet
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.3'
97
+ description:
98
+ email:
99
+ - andresilveirah@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - ".rubocop.yml"
107
+ - ".ruby-gemset"
108
+ - ".ruby-version"
109
+ - ".yardopts"
110
+ - Gemfile
111
+ - LICENSE.txt
112
+ - README.md
113
+ - Rakefile
114
+ - examples/input.txt
115
+ - lib/trainworks.rb
116
+ - lib/trainworks/file_parser.rb
117
+ - lib/trainworks/file_parser/invalid_railroad_input_format.rb
118
+ - lib/trainworks/graph_algorithm.rb
119
+ - lib/trainworks/graph_builder.rb
120
+ - lib/trainworks/railroad.rb
121
+ - lib/trainworks/route.rb
122
+ - lib/trainworks/version.rb
123
+ - tmp/.gitkeep
124
+ - trainworks.gemspec
125
+ homepage: https://rubygems.org/gems/example
126
+ licenses:
127
+ - MIT
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.6.11
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Models a railroad as a graph and offers some traversing methods.
149
+ test_files: []