project_euler_cli 1.0.1
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 +7 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +45 -0
- data/LICENSE.txt +21 -0
- data/README.md +58 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/project-euler-cli +6 -0
- data/bin/setup +6 -0
- data/lib/project_euler_cli.rb +10 -0
- data/lib/project_euler_cli/archive_controller.rb +94 -0
- data/lib/project_euler_cli/archive_searcher.rb +82 -0
- data/lib/project_euler_cli/archive_viewer.rb +118 -0
- data/lib/project_euler_cli/cli.rb +146 -0
- data/lib/project_euler_cli/version.rb +3 -0
- data/project_euler_cli.gemspec +39 -0
- data/spec.md +6 -0
- metadata +137 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 49c120e27b54ecb70be7838b2ff12a1908b0fe4324a34489502dab2a6c1c2477
|
4
|
+
data.tar.gz: eef16492a89722e73afa03a5cc090c5792e0623d88a02e0ef6993601c2b472cd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c01e65d898c336d7de472afc46ce60fe5f3dc20f9ac7233828c21ed30a4696eaf77231abf6e967330929eb65cd2107176ea41bbca12d766a0351c0c879228a01
|
7
|
+
data.tar.gz: a81c4f77115407f9ceff0c3caaae1e7315deca93e6600b3aff3656b2b1f579cdcd99a43f782df63e6b9b20ca7e1afb167263b96ca94233a8be3dac0cec967fbb
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
project_euler_cli (1.0.1)
|
5
|
+
nokogiri (~> 1.8)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
coderay (1.1.2)
|
11
|
+
diff-lcs (1.3)
|
12
|
+
method_source (0.9.0)
|
13
|
+
mini_portile2 (2.3.0)
|
14
|
+
nokogiri (1.8.2)
|
15
|
+
mini_portile2 (~> 2.3.0)
|
16
|
+
pry (0.11.3)
|
17
|
+
coderay (~> 1.1.0)
|
18
|
+
method_source (~> 0.9.0)
|
19
|
+
rake (10.5.0)
|
20
|
+
rspec (3.7.0)
|
21
|
+
rspec-core (~> 3.7.0)
|
22
|
+
rspec-expectations (~> 3.7.0)
|
23
|
+
rspec-mocks (~> 3.7.0)
|
24
|
+
rspec-core (3.7.1)
|
25
|
+
rspec-support (~> 3.7.0)
|
26
|
+
rspec-expectations (3.7.0)
|
27
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
+
rspec-support (~> 3.7.0)
|
29
|
+
rspec-mocks (3.7.0)
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
+
rspec-support (~> 3.7.0)
|
32
|
+
rspec-support (3.7.1)
|
33
|
+
|
34
|
+
PLATFORMS
|
35
|
+
ruby
|
36
|
+
|
37
|
+
DEPENDENCIES
|
38
|
+
bundler (~> 1.16)
|
39
|
+
project_euler_cli!
|
40
|
+
pry (~> 0.11)
|
41
|
+
rake (~> 10.0)
|
42
|
+
rspec (~> 3.0)
|
43
|
+
|
44
|
+
BUNDLED WITH
|
45
|
+
1.16.1
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 ecssiah
|
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,58 @@
|
|
1
|
+
# Project Euler CLI
|
2
|
+
|
3
|
+
This is a command line interface for browsing the problems archived by Project Euler.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'project_euler_cli'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install project_euler_cli
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Main Menu:
|
24
|
+
- List recent problems (r)
|
25
|
+
- List archived problems (l)
|
26
|
+
- Search problems (s)
|
27
|
+
- Exit program (x)
|
28
|
+
|
29
|
+
Page Menu:
|
30
|
+
- View problem 314 (314)
|
31
|
+
- Next page (n)
|
32
|
+
- Previous page (p)
|
33
|
+
- Go to page 4 (g4)
|
34
|
+
- Exit to main menu (x)
|
35
|
+
|
36
|
+
Problem Menu:
|
37
|
+
- Back to current page (b)
|
38
|
+
- Exit to main menu (x)
|
39
|
+
|
40
|
+
Search Menu:
|
41
|
+
- View problem 217 (217)
|
42
|
+
- Back to search results (b)
|
43
|
+
- Search again (s)
|
44
|
+
- Exit to main menu (x)
|
45
|
+
|
46
|
+
## Development
|
47
|
+
|
48
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
49
|
+
|
50
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
51
|
+
|
52
|
+
## Contributing
|
53
|
+
|
54
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ecssiah/project_euler_cli.
|
55
|
+
|
56
|
+
## License
|
57
|
+
|
58
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "project_euler_cli"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
require "project_euler_cli/version"
|
7
|
+
require "project_euler_cli/archive_controller"
|
8
|
+
require "project_euler_cli/archive_viewer"
|
9
|
+
require "project_euler_cli/archive_searcher"
|
10
|
+
require "project_euler_cli/cli"
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module ProjectEulerCli
|
2
|
+
|
3
|
+
# Controller class that manages the archive system. It holds the archive data used
|
4
|
+
# by ArchiveViewer and ArchiveSearcher.
|
5
|
+
class ArchiveController
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@archive_data = {}
|
9
|
+
|
10
|
+
lookup_totals
|
11
|
+
|
12
|
+
@av = ArchiveViewer.new(@archive_data)
|
13
|
+
@as = ArchiveSearcher.new(@archive_data)
|
14
|
+
|
15
|
+
@archive_data[:visited_pages] = []
|
16
|
+
@archive_data[:problems] = Array.new(@archive_data[:num_problems] + 1, "")
|
17
|
+
@archive_data[:problem_details] = Array.new(@archive_data[:num_problems] + 1) { {} }
|
18
|
+
end
|
19
|
+
|
20
|
+
# call-seq:
|
21
|
+
# get_page(id) => page
|
22
|
+
#
|
23
|
+
# Returns page number based on the ID of the problem. The recent page is
|
24
|
+
# considered page 0, invalid pages return -1.
|
25
|
+
def get_page(id)
|
26
|
+
if id.between?(@archive_data[:num_problems] - 9, @archive_data[:num_problems])
|
27
|
+
0
|
28
|
+
elsif id.between?(1, @archive_data[:num_problems] - 10)
|
29
|
+
(id - 1) / 50 + 1
|
30
|
+
else
|
31
|
+
-1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Pulls information from the recent page to determine the total number of problems
|
36
|
+
# and pages.
|
37
|
+
def lookup_totals
|
38
|
+
html = open("https://projecteuler.net/recent")
|
39
|
+
fragment = Nokogiri::HTML(html)
|
40
|
+
|
41
|
+
id_col = fragment.css('#problems_table td.id_column')
|
42
|
+
|
43
|
+
# The newest problem is the first one listed on the recent page. The ID of this
|
44
|
+
# problem will always equal the total number of problems.
|
45
|
+
@archive_data[:num_problems] = id_col.first.text.to_i
|
46
|
+
# The last problem on the recent page has an ID that is one larger than the
|
47
|
+
# last problem in the archive pages. The total number of pages can be calculated
|
48
|
+
# from its ID.
|
49
|
+
@archive_data[:num_pages] = get_page(id_col.last.text.to_i - 1)
|
50
|
+
end
|
51
|
+
|
52
|
+
def num_pages
|
53
|
+
@archive_data[:num_pages]
|
54
|
+
end
|
55
|
+
|
56
|
+
def num_problems
|
57
|
+
@archive_data[:num_problems]
|
58
|
+
end
|
59
|
+
|
60
|
+
def searching=(searching)
|
61
|
+
@as.searching = searching
|
62
|
+
end
|
63
|
+
|
64
|
+
def searching
|
65
|
+
@as.searching
|
66
|
+
end
|
67
|
+
|
68
|
+
def search(terms)
|
69
|
+
@as.search(terms)
|
70
|
+
end
|
71
|
+
|
72
|
+
def results_include?(id)
|
73
|
+
@as.results.include?(id)
|
74
|
+
end
|
75
|
+
|
76
|
+
def display_recent
|
77
|
+
@av.display_recent
|
78
|
+
end
|
79
|
+
|
80
|
+
def display_page(page)
|
81
|
+
@av.display_page(page)
|
82
|
+
end
|
83
|
+
|
84
|
+
def display_results
|
85
|
+
@av.display_custom_page(@as.results)
|
86
|
+
end
|
87
|
+
|
88
|
+
def display_problem(id)
|
89
|
+
@av.display_problem(id)
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module ProjectEulerCli
|
2
|
+
|
3
|
+
# Handles searching the problems
|
4
|
+
class ArchiveSearcher
|
5
|
+
# Array of IDs corresponding to the problems found in last search
|
6
|
+
attr_reader :results
|
7
|
+
# Tracks whether there is an active search
|
8
|
+
attr_accessor :searching
|
9
|
+
|
10
|
+
def initialize(archive_data)
|
11
|
+
@archive_data = archive_data
|
12
|
+
|
13
|
+
@results = []
|
14
|
+
@searching = false
|
15
|
+
@initial_search = true
|
16
|
+
end
|
17
|
+
|
18
|
+
# Loads the problem numbers and titles for every page that is not loaded.
|
19
|
+
def load_terms
|
20
|
+
puts "updating keywords..."
|
21
|
+
|
22
|
+
# Loading each archive page
|
23
|
+
1.upto(@archive_data[:num_pages]) do |page|
|
24
|
+
unless @archive_data[:visited_pages].include?(page)
|
25
|
+
html = open("https://projecteuler.net/archives;page=#{page}")
|
26
|
+
fragment = Nokogiri::HTML(html)
|
27
|
+
|
28
|
+
problem_links = fragment.css('#problems_table td a')
|
29
|
+
|
30
|
+
i = (page - 1) * 50 + 1
|
31
|
+
problem_links.each do |link|
|
32
|
+
@archive_data[:problems][i] = link.text
|
33
|
+
i += 1
|
34
|
+
end
|
35
|
+
|
36
|
+
@archive_data[:visited_pages] << page
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Loading the recent problems
|
41
|
+
unless @archive_data[:visited_pages].include?(0)
|
42
|
+
html = open("https://projecteuler.net/recent")
|
43
|
+
fragment = Nokogiri::HTML(html)
|
44
|
+
|
45
|
+
problem_links = fragment.css('#problems_table td a')
|
46
|
+
|
47
|
+
i = @archive_data[:num_problems]
|
48
|
+
problem_links.each do |link|
|
49
|
+
@archive_data[:problems][i] = link.text
|
50
|
+
i -= 1
|
51
|
+
end
|
52
|
+
|
53
|
+
@archive_data[:visited_pages] << 0
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Performs a simple search of the problems. It accepts multiple terms. Results
|
58
|
+
# will contain *any* of the terms
|
59
|
+
#
|
60
|
+
# * +terms+ - String of search terms
|
61
|
+
def search(terms)
|
62
|
+
if @initial_search
|
63
|
+
@initial_search = false
|
64
|
+
load_terms
|
65
|
+
end
|
66
|
+
|
67
|
+
puts "searching..."
|
68
|
+
@results.clear
|
69
|
+
@searching = true
|
70
|
+
|
71
|
+
terms.downcase.split(' ').each do |term|
|
72
|
+
for i in 1..@archive_data[:num_problems]
|
73
|
+
if @archive_data[:problems][i].downcase.include?(term.downcase)
|
74
|
+
@results << i
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module ProjectEulerCli
|
2
|
+
|
3
|
+
# Handles the work of displaying information about the problems.
|
4
|
+
class ArchiveViewer
|
5
|
+
|
6
|
+
def initialize(archive_data)
|
7
|
+
@archive_data = archive_data
|
8
|
+
end
|
9
|
+
|
10
|
+
# Loads in all of the problem numbers and titles from the recent page.
|
11
|
+
def load_recent
|
12
|
+
html = open("https://projecteuler.net/recent")
|
13
|
+
fragment = Nokogiri::HTML(html)
|
14
|
+
|
15
|
+
problem_links = fragment.css('#problems_table td a')
|
16
|
+
|
17
|
+
i = @archive_data[:num_problems]
|
18
|
+
problem_links.each do |link|
|
19
|
+
@archive_data[:problems][i] = link.text
|
20
|
+
i -= 1
|
21
|
+
end
|
22
|
+
|
23
|
+
@archive_data[:visited_pages] << 0
|
24
|
+
end
|
25
|
+
|
26
|
+
# Displays the 10 most recently added problems.
|
27
|
+
def display_recent
|
28
|
+
load_recent unless @archive_data[:visited_pages].include?(0)
|
29
|
+
|
30
|
+
puts
|
31
|
+
|
32
|
+
(@archive_data[:num_problems]).downto(@archive_data[:num_problems] - 9) do |i|
|
33
|
+
puts "#{i} - #{@archive_data[:problems][i]}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Loads the problem numbers and titles for an individual page of the archive.
|
38
|
+
def load_page(page)
|
39
|
+
html = open("https://projecteuler.net/archives;page=#{page}")
|
40
|
+
fragment = Nokogiri::HTML(html)
|
41
|
+
|
42
|
+
problem_links = fragment.css('#problems_table td a')
|
43
|
+
|
44
|
+
i = (page - 1) * 50 + 1
|
45
|
+
problem_links.each do |link|
|
46
|
+
@archive_data[:problems][i] = link.text
|
47
|
+
i += 1
|
48
|
+
end
|
49
|
+
|
50
|
+
@archive_data[:visited_pages] << page
|
51
|
+
end
|
52
|
+
|
53
|
+
# Displays the problem numbers and titles for an individual page of the archive.
|
54
|
+
def display_page(page)
|
55
|
+
load_page(page) unless @archive_data[:visited_pages].include?(page)
|
56
|
+
|
57
|
+
puts
|
58
|
+
|
59
|
+
start = (page - 1) * 50 + 1
|
60
|
+
for i in start...start + 50
|
61
|
+
unless i >= @archive_data[:num_problems] - 9
|
62
|
+
puts "#{i} - #{@archive_data[:problems][i]}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Loads the details of an individual problem.
|
68
|
+
def load_problem_details(id)
|
69
|
+
html = open("https://projecteuler.net/problem=#{id}")
|
70
|
+
fragment = Nokogiri::HTML(html)
|
71
|
+
|
72
|
+
problem_info = fragment.css('div#problem_info span span')
|
73
|
+
|
74
|
+
details = problem_info.text.split(';')
|
75
|
+
@archive_data[:problem_details][id][:published] = details[0].strip
|
76
|
+
@archive_data[:problem_details][id][:solved_by] = details[1].strip
|
77
|
+
|
78
|
+
# recent problems do not have a difficult rating
|
79
|
+
if id < @archive_data[:num_problems] - 9
|
80
|
+
@archive_data[:problem_details][id][:difficulty] = details[2].strip
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Displays the details of an individual problem.
|
85
|
+
#
|
86
|
+
# * +id+ - ID of the problem to be displayed
|
87
|
+
def display_problem(id)
|
88
|
+
load_problem_details(id) if @archive_data[:problem_details][id].empty?
|
89
|
+
|
90
|
+
puts
|
91
|
+
puts "#{@archive_data[:problems][id]}".upcase
|
92
|
+
puts "Problem #{id}"
|
93
|
+
puts
|
94
|
+
puts @archive_data[:problem_details][id][:published]
|
95
|
+
puts @archive_data[:problem_details][id][:solved_by]
|
96
|
+
|
97
|
+
if id < @archive_data[:num_problems] - 9
|
98
|
+
puts @archive_data[:problem_details][id][:difficulty]
|
99
|
+
end
|
100
|
+
|
101
|
+
puts
|
102
|
+
puts "https://projecteuler.net/problem=#{id}"
|
103
|
+
end
|
104
|
+
|
105
|
+
# Displays a custom page of problems given by an array of IDs.
|
106
|
+
#
|
107
|
+
# * +list+ - Array of problem IDs
|
108
|
+
def display_custom_page(list)
|
109
|
+
puts
|
110
|
+
|
111
|
+
list.each do |id|
|
112
|
+
puts "#{id} - #{@archive_data[:problems][id]}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module ProjectEulerCli #:nodoc:
|
2
|
+
|
3
|
+
# Manages the command line interface for the program. It uses the ArchiveController
|
4
|
+
# to access the site data.
|
5
|
+
class CLI
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@ac = ArchiveController.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def start
|
12
|
+
banner
|
13
|
+
main_menu
|
14
|
+
end
|
15
|
+
|
16
|
+
def prompt
|
17
|
+
print "e: "
|
18
|
+
gets.strip
|
19
|
+
end
|
20
|
+
|
21
|
+
def banner
|
22
|
+
puts
|
23
|
+
puts " ---------------------------------- "
|
24
|
+
puts " [ Project Euler ]"
|
25
|
+
puts " [ e^iπ = -1 ]"
|
26
|
+
puts " ---------------------------------- "
|
27
|
+
end
|
28
|
+
|
29
|
+
def main_menu
|
30
|
+
puts " - List recent problems (r) -"
|
31
|
+
puts " - List archived problems (l) -"
|
32
|
+
puts " - Search (s) -"
|
33
|
+
puts " - Exit (x) -"
|
34
|
+
|
35
|
+
input = prompt
|
36
|
+
|
37
|
+
if input == 'r'
|
38
|
+
recent_menu
|
39
|
+
main_menu
|
40
|
+
elsif input == 'l'
|
41
|
+
page_menu(1)
|
42
|
+
main_menu
|
43
|
+
elsif input == 's'
|
44
|
+
search_menu
|
45
|
+
main_menu
|
46
|
+
elsif input == 'x'
|
47
|
+
return
|
48
|
+
else
|
49
|
+
main_menu
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def recent_menu
|
54
|
+
@ac.display_recent
|
55
|
+
|
56
|
+
puts
|
57
|
+
puts "e(x)it"
|
58
|
+
|
59
|
+
input = prompt
|
60
|
+
|
61
|
+
if input.to_i.between?(@ac.num_problems - 9, @ac.num_problems)
|
62
|
+
problem_menu(input.to_i)
|
63
|
+
elsif input == 'x'
|
64
|
+
return
|
65
|
+
else
|
66
|
+
recent_menu
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def page_menu(page)
|
71
|
+
page = [1, page, @ac.num_pages].sort[1] #clamp
|
72
|
+
@ac.display_page(page)
|
73
|
+
|
74
|
+
puts
|
75
|
+
puts "[#{page}/#{@ac.num_pages}] (n)ext (p)rev (g)oto e(x)it"
|
76
|
+
|
77
|
+
input = prompt
|
78
|
+
|
79
|
+
if input.to_i.between?(50 * (page - 1) + 1, 50 * page)
|
80
|
+
problem_menu(input.to_i)
|
81
|
+
elsif input == 'n'
|
82
|
+
page_menu(page + 1)
|
83
|
+
elsif input == 'p'
|
84
|
+
page_menu(page - 1)
|
85
|
+
elsif input.start_with?('g')
|
86
|
+
page_menu(input.gsub('g', '').to_i)
|
87
|
+
elsif input == 'x'
|
88
|
+
return
|
89
|
+
else
|
90
|
+
page_menu(page)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def problem_menu(id)
|
95
|
+
@ac.display_problem(id)
|
96
|
+
|
97
|
+
puts
|
98
|
+
puts "(b)ack e(x)it"
|
99
|
+
|
100
|
+
input = prompt
|
101
|
+
|
102
|
+
if input == 'b'
|
103
|
+
if @ac.searching
|
104
|
+
search_results_menu
|
105
|
+
else
|
106
|
+
page = @ac.get_page(id)
|
107
|
+
page == 0 ? recent_menu : page_menu(page)
|
108
|
+
end
|
109
|
+
elsif input == 'x'
|
110
|
+
return
|
111
|
+
else
|
112
|
+
problem_menu(id)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def search_results_menu
|
117
|
+
@ac.display_results
|
118
|
+
|
119
|
+
puts
|
120
|
+
puts "(s)earch e(x)it"
|
121
|
+
|
122
|
+
input = prompt
|
123
|
+
|
124
|
+
if @ac.results_include?(input.to_i)
|
125
|
+
problem_menu(input.to_i)
|
126
|
+
elsif input == 's'
|
127
|
+
search_menu
|
128
|
+
elsif input == 'x'
|
129
|
+
@ac.searching = false
|
130
|
+
return
|
131
|
+
else
|
132
|
+
search_results_menu
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def search_menu
|
137
|
+
print "search: "
|
138
|
+
|
139
|
+
search_terms = gets.strip
|
140
|
+
@ac.search(search_terms)
|
141
|
+
search_results_menu
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "project_euler_cli/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "project_euler_cli"
|
8
|
+
spec.version = ProjectEulerCli::VERSION
|
9
|
+
spec.authors = ["ecssiah"]
|
10
|
+
spec.email = ["ecssiah@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{This is a command line interface for browsing Project Euler.}
|
13
|
+
spec.description = %q{This is a basic command line interface that allows the user to browse through the archive of problems maintained by Project Euler. It also offers a search feature to quickly locate relevant problems.}
|
14
|
+
spec.homepage = "https://github.com/ecssiah/project-euler-cli"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
21
|
+
else
|
22
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
23
|
+
"public gem pushes."
|
24
|
+
end
|
25
|
+
|
26
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
|
+
f.match(%r{^(test|spec|features)/})
|
28
|
+
end
|
29
|
+
spec.bindir = 'bin'
|
30
|
+
spec.executables << 'project-euler-cli'
|
31
|
+
spec.require_paths = ["lib"]
|
32
|
+
|
33
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
34
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
35
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
36
|
+
spec.add_development_dependency "pry", "~> 0.11"
|
37
|
+
|
38
|
+
spec.add_dependency "nokogiri", "~> 1.8"
|
39
|
+
end
|
data/spec.md
ADDED
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: project_euler_cli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ecssiah
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-04-20 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.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
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: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.11'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.11'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: nokogiri
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.8'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.8'
|
83
|
+
description: This is a basic command line interface that allows the user to browse
|
84
|
+
through the archive of problems maintained by Project Euler. It also offers a search
|
85
|
+
feature to quickly locate relevant problems.
|
86
|
+
email:
|
87
|
+
- ecssiah@gmail.com
|
88
|
+
executables:
|
89
|
+
- project-euler-cli
|
90
|
+
extensions: []
|
91
|
+
extra_rdoc_files: []
|
92
|
+
files:
|
93
|
+
- ".gitignore"
|
94
|
+
- ".rspec"
|
95
|
+
- ".travis.yml"
|
96
|
+
- Gemfile
|
97
|
+
- Gemfile.lock
|
98
|
+
- LICENSE.txt
|
99
|
+
- README.md
|
100
|
+
- Rakefile
|
101
|
+
- bin/console
|
102
|
+
- bin/project-euler-cli
|
103
|
+
- bin/setup
|
104
|
+
- lib/project_euler_cli.rb
|
105
|
+
- lib/project_euler_cli/archive_controller.rb
|
106
|
+
- lib/project_euler_cli/archive_searcher.rb
|
107
|
+
- lib/project_euler_cli/archive_viewer.rb
|
108
|
+
- lib/project_euler_cli/cli.rb
|
109
|
+
- lib/project_euler_cli/version.rb
|
110
|
+
- project_euler_cli.gemspec
|
111
|
+
- spec.md
|
112
|
+
homepage: https://github.com/ecssiah/project-euler-cli
|
113
|
+
licenses:
|
114
|
+
- MIT
|
115
|
+
metadata:
|
116
|
+
allowed_push_host: https://rubygems.org
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
requirements: []
|
132
|
+
rubyforge_project:
|
133
|
+
rubygems_version: 2.7.6
|
134
|
+
signing_key:
|
135
|
+
specification_version: 4
|
136
|
+
summary: This is a command line interface for browsing Project Euler.
|
137
|
+
test_files: []
|