project_euler_cli 1.1.0 → 1.1.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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/project_euler_cli.rb +1 -0
- data/lib/project_euler_cli/archive_controller.rb +16 -32
- data/lib/project_euler_cli/archive_searcher.rb +3 -33
- data/lib/project_euler_cli/archive_viewer.rb +8 -61
- data/lib/project_euler_cli/cli.rb +1 -1
- data/lib/project_euler_cli/concerns/scraper.rb +78 -0
- data/lib/project_euler_cli/page.rb +2 -4
- data/lib/project_euler_cli/problem.rb +1 -1
- data/lib/project_euler_cli/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0016fc054fcdc5ebc58a58ae77500b6a59776e38a8c2e55c4a6af7b69848007
|
4
|
+
data.tar.gz: dd93295b9e645b7038f8eed4de1ff68f6fce96151530e791d911e9a6cb1c5e86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 775225f6b9fc001b3f5779ed6d1521b01914512d04494bfd2ed9feceafadb17555df1514f27b71039acf08c314f35782d396c5d70bf4485415fc2c8456caff85
|
7
|
+
data.tar.gz: 839bb873d2d478773011d8627ea3dbb57ee18e4e61bef37e6983cc8a17938de7db660e055ca10bbbe841f9b766a7a0a9a1b1db77908e570121a68e9c4c5f8cf1
|
data/Gemfile.lock
CHANGED
data/lib/project_euler_cli.rb
CHANGED
@@ -6,6 +6,7 @@ require 'pry'
|
|
6
6
|
require "project_euler_cli/version"
|
7
7
|
require "project_euler_cli/problem"
|
8
8
|
require "project_euler_cli/page"
|
9
|
+
require "project_euler_cli/concerns/scraper"
|
9
10
|
require "project_euler_cli/archive_controller"
|
10
11
|
require "project_euler_cli/archive_viewer"
|
11
12
|
require "project_euler_cli/archive_searcher"
|
@@ -3,6 +3,7 @@ module ProjectEulerCli
|
|
3
3
|
# Controller class that manages the archive system. It holds the archive data used
|
4
4
|
# by ArchiveViewer and ArchiveSearcher.
|
5
5
|
class ArchiveController
|
6
|
+
include Scraper
|
6
7
|
|
7
8
|
def initialize
|
8
9
|
lookup_totals
|
@@ -13,38 +14,6 @@ class ArchiveController
|
|
13
14
|
@as = ArchiveSearcher.new(@problems)
|
14
15
|
end
|
15
16
|
|
16
|
-
# call-seq:
|
17
|
-
# get_page(id) => page
|
18
|
-
#
|
19
|
-
# Returns page number based on the ID of the problem. The recent page is
|
20
|
-
# considered page 0, invalid pages return -1.
|
21
|
-
def get_page(id)
|
22
|
-
if id.between?(Problem.total - 9, Problem.total)
|
23
|
-
0
|
24
|
-
elsif id.between?(1, Problem.total - 10)
|
25
|
-
(id - 1) / 50 + 1
|
26
|
-
else
|
27
|
-
-1
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# Pulls information from the recent page to determine the total number of problems
|
32
|
-
# and pages.
|
33
|
-
def lookup_totals
|
34
|
-
html = open("https://projecteuler.net/recent")
|
35
|
-
fragment = Nokogiri::HTML(html)
|
36
|
-
|
37
|
-
id_col = fragment.css('#problems_table td.id_column')
|
38
|
-
|
39
|
-
# The newest problem is the first one listed on the recent page. The ID of this
|
40
|
-
# problem will always equal the total number of problems.
|
41
|
-
Problem.total = id_col.first.text.to_i
|
42
|
-
# The last problem on the recent page has an ID that is one larger than the
|
43
|
-
# last problem in the archive pages. The total number of pages can be calculated
|
44
|
-
# from its ID.
|
45
|
-
Page.total = get_page(id_col.last.text.to_i - 1)
|
46
|
-
end
|
47
|
-
|
48
17
|
def searching=(searching)
|
49
18
|
@as.searching = searching
|
50
19
|
end
|
@@ -77,6 +46,21 @@ class ArchiveController
|
|
77
46
|
@av.display_problem(id)
|
78
47
|
end
|
79
48
|
|
49
|
+
# call-seq:
|
50
|
+
# get_page(id) => page
|
51
|
+
#
|
52
|
+
# Returns page number based on the ID of the problem. The recent page is
|
53
|
+
# considered page 0, invalid pages return -1.
|
54
|
+
def get_page(id)
|
55
|
+
if id.between?(Problem.total - 9, Problem.total)
|
56
|
+
0
|
57
|
+
elsif id.between?(1, Problem.total - 10)
|
58
|
+
(id - 1) / Page::PROBLEMS_PER_PAGE + 1
|
59
|
+
else
|
60
|
+
-1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
80
64
|
end
|
81
65
|
|
82
66
|
end
|
@@ -2,6 +2,8 @@ module ProjectEulerCli
|
|
2
2
|
|
3
3
|
# Handles searching the problems
|
4
4
|
class ArchiveSearcher
|
5
|
+
include Scraper
|
6
|
+
|
5
7
|
# Array of IDs corresponding to the problems found in last search
|
6
8
|
attr_reader :results
|
7
9
|
# Tracks whether there is an active search
|
@@ -19,39 +21,7 @@ class ArchiveSearcher
|
|
19
21
|
def load_terms
|
20
22
|
puts "updating keywords..."
|
21
23
|
|
22
|
-
|
23
|
-
1.upto(Page.total) do |page|
|
24
|
-
unless Page.visited.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
|
-
@problems[i].title = link.text
|
33
|
-
i += 1
|
34
|
-
end
|
35
|
-
|
36
|
-
Page.visited << page
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# Loading the recent problems
|
41
|
-
unless Page.visited.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 = Problem.total
|
48
|
-
problem_links.each do |link|
|
49
|
-
@problems[i].title = link.text
|
50
|
-
i -= 1
|
51
|
-
end
|
52
|
-
|
53
|
-
Page.visited << 0
|
54
|
-
end
|
24
|
+
0.upto(Page.total) { |page| load_page(page, @problems) }
|
55
25
|
end
|
56
26
|
|
57
27
|
# Performs a simple search of the problems. It accepts multiple terms. Results
|
@@ -2,82 +2,30 @@ module ProjectEulerCli
|
|
2
2
|
|
3
3
|
# Handles the work of displaying information about the problems.
|
4
4
|
class ArchiveViewer
|
5
|
+
include Scraper
|
5
6
|
|
6
7
|
def initialize(problems)
|
7
8
|
@problems = problems
|
8
9
|
end
|
9
10
|
|
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 = Problem.total
|
18
|
-
problem_links.each do |link|
|
19
|
-
@problems[i].title = link.text
|
20
|
-
i -= 1
|
21
|
-
end
|
22
|
-
|
23
|
-
Page.visited << 0
|
24
|
-
end
|
25
|
-
|
26
11
|
# Displays the 10 most recently added problems.
|
27
12
|
def display_recent
|
28
|
-
load_recent
|
13
|
+
load_recent(@problems)
|
29
14
|
|
30
15
|
puts
|
31
16
|
|
32
|
-
(Problem.total).downto(Problem.total - 9)
|
33
|
-
puts "#{i} - #{@problems[i].title}"
|
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
|
-
@problems[i].title = link.text
|
47
|
-
i += 1
|
48
|
-
end
|
49
|
-
|
50
|
-
Page.visited << page
|
17
|
+
(Problem.total).downto(Problem.total - 9) { |i| puts "#{i} - #{@problems[i].title}" }
|
51
18
|
end
|
52
19
|
|
53
20
|
# Displays the problem numbers and titles for an individual page of the archive.
|
54
21
|
def display_page(page)
|
55
|
-
load_page(page
|
22
|
+
load_page(page, @problems)
|
56
23
|
|
57
24
|
puts
|
58
25
|
|
59
|
-
start = (page - 1) *
|
60
|
-
for i in start...start +
|
61
|
-
unless i >= Problem.total - 9
|
62
|
-
puts "#{i} - #{@problems[i].title}"
|
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
|
-
@problems[id].published = details[0].strip
|
76
|
-
@problems[id].solved_by = details[1].strip
|
77
|
-
|
78
|
-
# recent problems do not have a difficult rating
|
79
|
-
if id < Problem.total - 9
|
80
|
-
@problems[id].difficulty = details[2].strip
|
26
|
+
start = (page - 1) * Page::PROBLEMS_PER_PAGE + 1
|
27
|
+
for i in start...start + Page::PROBLEMS_PER_PAGE
|
28
|
+
puts "#{i} - #{@problems[i].title}" unless i >= Problem.total - 9
|
81
29
|
end
|
82
30
|
end
|
83
31
|
|
@@ -85,7 +33,7 @@ class ArchiveViewer
|
|
85
33
|
#
|
86
34
|
# * +id+ - ID of the problem to be displayed
|
87
35
|
def display_problem(id)
|
88
|
-
load_problem_details(id
|
36
|
+
load_problem_details(id, @problems)
|
89
37
|
|
90
38
|
puts
|
91
39
|
puts "#{@problems[id].title}".upcase
|
@@ -103,7 +51,6 @@ class ArchiveViewer
|
|
103
51
|
# * +list+ - Array of problem IDs
|
104
52
|
def display_custom_page(list)
|
105
53
|
puts
|
106
|
-
|
107
54
|
list.each { |id| puts "#{id} - #{@problems[id].title}" }
|
108
55
|
end
|
109
56
|
|
@@ -76,7 +76,7 @@ class CLI
|
|
76
76
|
|
77
77
|
input = prompt
|
78
78
|
|
79
|
-
if input.to_i.between?(
|
79
|
+
if input.to_i.between?(Page::PROBLEMS_PER_PAGE * (page - 1) + 1, Page::PROBLEMS_PER_PAGE * page)
|
80
80
|
problem_menu(input.to_i)
|
81
81
|
elsif input == 'n'
|
82
82
|
page_menu(page + 1)
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module ProjectEulerCli
|
2
|
+
|
3
|
+
module Scraper
|
4
|
+
|
5
|
+
# Pulls information from the recent page to determine the total number of problems
|
6
|
+
# and pages.
|
7
|
+
def lookup_totals
|
8
|
+
html = open("https://projecteuler.net/recent")
|
9
|
+
fragment = Nokogiri::HTML(html)
|
10
|
+
|
11
|
+
id_col = fragment.css('#problems_table td.id_column')
|
12
|
+
|
13
|
+
# The newest problem is the first one listed on the recent page. The ID of this
|
14
|
+
# problem will always equal the total number of problems.
|
15
|
+
Problem.total = id_col.first.text.to_i
|
16
|
+
# There are ten problems on the recent page, so the last archive problem can be
|
17
|
+
# found by subtracting 10 from the total number of problems. This is used to
|
18
|
+
# calculate the total number of pages.
|
19
|
+
last_archive_id = Problem.total - 10
|
20
|
+
Page.total = (last_archive_id - 1) / Page::PROBLEMS_PER_PAGE + 1
|
21
|
+
end
|
22
|
+
|
23
|
+
# Loads in all of the problem numbers and titles from the recent page.
|
24
|
+
def load_recent(problems)
|
25
|
+
return if Page.visited.include?(0)
|
26
|
+
|
27
|
+
html = open("https://projecteuler.net/recent")
|
28
|
+
fragment = Nokogiri::HTML(html)
|
29
|
+
|
30
|
+
problem_links = fragment.css('#problems_table td a')
|
31
|
+
|
32
|
+
i = Problem.total
|
33
|
+
problem_links.each do |link|
|
34
|
+
problems[i].title = link.text
|
35
|
+
i -= 1
|
36
|
+
end
|
37
|
+
|
38
|
+
Page.visited << 0
|
39
|
+
end
|
40
|
+
|
41
|
+
# Loads the problem numbers and titles for an individual page of the archive.
|
42
|
+
def load_page(page, problems)
|
43
|
+
return if Page.visited.include?(page)
|
44
|
+
|
45
|
+
html = open("https://projecteuler.net/archives;page=#{page}")
|
46
|
+
fragment = Nokogiri::HTML(html)
|
47
|
+
|
48
|
+
problem_links = fragment.css('#problems_table td a')
|
49
|
+
|
50
|
+
i = (page - 1) * Page::PROBLEMS_PER_PAGE + 1
|
51
|
+
problem_links.each do |link|
|
52
|
+
problems[i].title = link.text
|
53
|
+
i += 1
|
54
|
+
end
|
55
|
+
|
56
|
+
Page.visited << page
|
57
|
+
end
|
58
|
+
|
59
|
+
# Loads the details of an individual problem.
|
60
|
+
def load_problem_details(id, problems)
|
61
|
+
return unless problems[id].published.nil?
|
62
|
+
|
63
|
+
html = open("https://projecteuler.net/problem=#{id}")
|
64
|
+
fragment = Nokogiri::HTML(html)
|
65
|
+
|
66
|
+
problem_info = fragment.css('div#problem_info span span')
|
67
|
+
|
68
|
+
details = problem_info.text.split(';')
|
69
|
+
problems[id].published = details[0].strip
|
70
|
+
problems[id].solved_by = details[1].strip
|
71
|
+
|
72
|
+
# recent problems do not have a difficult rating
|
73
|
+
problems[id].difficulty = details[2].strip if id < Problem.total - 9
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: project_euler_cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ecssiah
|
@@ -106,6 +106,7 @@ files:
|
|
106
106
|
- lib/project_euler_cli/archive_searcher.rb
|
107
107
|
- lib/project_euler_cli/archive_viewer.rb
|
108
108
|
- lib/project_euler_cli/cli.rb
|
109
|
+
- lib/project_euler_cli/concerns/scraper.rb
|
109
110
|
- lib/project_euler_cli/page.rb
|
110
111
|
- lib/project_euler_cli/problem.rb
|
111
112
|
- lib/project_euler_cli/version.rb
|