advent_of_code_cli 0.1.3 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 874bcb2472449a2b367b4276efabaf1c7b15a19857c0e331d16bf3cd6da7e700
4
- data.tar.gz: 36f956b45bb8849b1b17880132842f16194209d3cfaff592be643b98da4d7ca2
3
+ metadata.gz: 975ed7c8275bc2111366961b426b01ba4805835876aa47ada28cb45a8296a56d
4
+ data.tar.gz: e3ecbe525361d68da73e13906adda1594354d9bfc1727a85a752f57114673685
5
5
  SHA512:
6
- metadata.gz: 3387033c1bf3c5f5edd4cd335647c64d3722ba0ffd5a6f716e7ec895d6e789a537d67b181cc44d29d1c99eec79590b3fe69a3627fe4d19e3eeedf180d1b091b1
7
- data.tar.gz: e952fb854364b9bfbcfdd6a84e194476c038ed176fde60903818dce824899c570b84cb256819e46f6afe5438402551adef59bc0825520d85adfce1819c9e8d2a
6
+ metadata.gz: 2bcc6d477acc45cb34b0bbea2c7f2f0cb904b3e76b80847267de80db2d2f5dfcaf96ec0078c080e6de44a4cd45cbe008708199090d4cd0a59fda6147bf2d556e
7
+ data.tar.gz: 7b912eaa46ee7e047aed2bc94ed7997e097317fef923ad4fdbd36d69885ff6be07002cf43ba0409d3b0e0ee916711301a85d1e7775f24c91c349f628dff9f48c
data/.rubocop.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 2.6
3
+ NewCops: enable
3
4
 
4
5
  Style/Documentation:
5
6
  Enabled: false
@@ -14,3 +15,9 @@ Style/StringLiteralsInInterpolation:
14
15
 
15
16
  Layout/LineLength:
16
17
  Max: 120
18
+
19
+ Metrics/AbcSize:
20
+ Enabled: false
21
+
22
+ Metrics/MethodLength:
23
+ Enabled: false
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- advent_of_code_cli (0.1.3)
4
+ advent_of_code_cli (0.1.5)
5
5
  thor (>= 1.2.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > ⚠️ **Note:** This tool is under active development. I built in in a couple hours with no automated tests. Things may change between versions!
4
4
 
5
- A little CLI tool that scaffolds and runs [Advent of Code](https://advent-of-code.com) solutions in Ruby.
5
+ A little CLI tool that scaffolds and runs [Advent of Code](https://adventofcode.com) solutions in Ruby.
6
6
 
7
7
  This project is heavily based on [advent-of-code-rust](https://github.com/arturopala/advent-of-code-rust). Go check it out!
8
8
 
@@ -52,6 +52,8 @@ module Day01
52
52
  end
53
53
  ```
54
54
 
55
+ ...where `input` is an `Array[String]` of all the lines without newlines.
56
+
55
57
  I would love to make this structure configurable in the future.
56
58
 
57
59
  ### Download
@@ -111,6 +113,61 @@ Done!
111
113
 
112
114
  This command expects files to be in the format provided by the `scaffold` command. Once again, I would love to make this configurable but haven't gotten around to it yet.
113
115
 
116
+ ### Examples
117
+
118
+ It is often helpful to run our solutions against example input. The `example` command can help you create and run examples of your own invention.
119
+
120
+ #### Create a new example
121
+
122
+ You can create a new file for example input by running the following command:
123
+
124
+ ```
125
+ bundle exec aoc_cli example new 1 A
126
+ ```
127
+
128
+ The first argument specifies the day, and the second argument is the name of the example. You may choose whatever name you'd like.
129
+
130
+ This will generate the following output:
131
+
132
+ ```
133
+ Creating examples/01/A.txt...
134
+ Creating examples/01/A_expected.yml...
135
+ Done!
136
+ ```
137
+
138
+ - `examples/01/A.txt` is a blank text file where you can enter your own input for the problem.
139
+ - `examples/01/A_expected.yml` is a YAML file with the following content:
140
+
141
+ ```
142
+ part_one: ~
143
+ part_two: ~
144
+ ```
145
+
146
+ Replace the two tildes (`~`) with the expected result of running your solution against the example input provided.
147
+
148
+ #### Running examples
149
+
150
+ You can check your solution against an example with the following command:
151
+
152
+ ```
153
+ bundle exec aoc_cli example solve 1 A
154
+ ```
155
+
156
+ This will output the following:
157
+
158
+ ```
159
+ Reading input...
160
+ Loading solution...
161
+
162
+ Running part one with example A...
163
+ Part one result: 1034 ✅
164
+ Took 0.000259 seconds to solve
165
+
166
+ Running part two with example A...
167
+ Part two result: 7934 ✅
168
+ Took 0.000253 seconds to solve
169
+ ```
170
+
114
171
  ## Contributing
115
172
 
116
173
  Issues and code contributions are welcome! Happy Advent of Code to all who celebrate! 🎁
@@ -25,6 +25,14 @@ module AdventOfCode
25
25
  "inputs/#{day_string}.txt"
26
26
  end
27
27
 
28
+ def example_file_name
29
+ "examples/#{day_string}/#{@name}.txt"
30
+ end
31
+
32
+ def example_expected_file_name
33
+ "examples/#{day_string}/#{@name}_expected.yml"
34
+ end
35
+
28
36
  def create_file(file_name, contents = nil)
29
37
  File.open(file_name, "w") do |file|
30
38
  file.puts contents if contents
@@ -31,7 +31,7 @@ module AdventOfCode
31
31
  private
32
32
 
33
33
  def cookie
34
- @cookie ||= ENV["AOC_COOKIE"]
34
+ @cookie ||= ENV.fetch("AOC_COOKIE", nil)
35
35
  end
36
36
 
37
37
  def cookie_present?
@@ -46,6 +46,9 @@ module AdventOfCode
46
46
 
47
47
  request = Net::HTTP::Get.new(url)
48
48
  request["Cookie"] = "session=#{cookie}"
49
+ # The creator of Advent of Code has requested that automated tools send identifying information
50
+ # when making requests: https://www.reddit.com/r/adventofcode/comments/z9dhtd
51
+ request["User-Agent"] = "github.com/egiurleo/advent_of_code_cli by emily.samp@icloud.com"
49
52
 
50
53
  response = https.request(request)
51
54
  response.read_body
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AdventOfCode
4
+ module Commands
5
+ module Example
6
+ class New < Command
7
+ def initialize(day:, name:)
8
+ @name = name
9
+ super(day: day)
10
+ end
11
+
12
+ def execute
13
+ unless Dir.exist?("examples")
14
+ say("Creating examples directory...")
15
+ Dir.mkdir("examples")
16
+ end
17
+
18
+ unless Dir.exist?("examples/#{day_string}")
19
+ say("Creating examples/#{day_string} directory...")
20
+ Dir.mkdir("examples/#{day_string}")
21
+ end
22
+
23
+ if File.exist?(example_file_name)
24
+ raise ExampleAlreadyExistsError,
25
+ "could not create example file because file #{example_file_name} already exists"
26
+ end
27
+
28
+ say("Creating #{example_file_name}...")
29
+ create_file(example_file_name)
30
+
31
+ say("Creating #{example_expected_file_name}...")
32
+ create_file(example_expected_file_name, expected_file_contents)
33
+
34
+ say "Done!", :green
35
+ end
36
+
37
+ private
38
+
39
+ def expected_file_contents
40
+ <<~RUBY
41
+ part_one: ~
42
+ part_two: ~
43
+ RUBY
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+
5
+ module AdventOfCode
6
+ module Commands
7
+ module Example
8
+ class Solve < Command
9
+ def initialize(day:, name:)
10
+ @name = name
11
+ super(day: day)
12
+ end
13
+
14
+ def execute
15
+ raise MissingExampleError unless File.exist?(example_file_name)
16
+ raise MissingExampleError unless File.exist?(example_expected_file_name)
17
+ raise MissingSolutionError unless File.exist?(solution_file_name)
18
+
19
+ say "Reading input..."
20
+ input = File.readlines(example_file_name, chomp: true)
21
+
22
+ say "Loading solution..."
23
+ load(solution_file_name)
24
+
25
+ module_name = "Day#{day_string}"
26
+
27
+ say "\nRunning part one with example #{@name}..."
28
+ solution(module_name, "one", input)
29
+
30
+ say "\nRunning part two with example #{@name}..."
31
+ solution(module_name, "two", input)
32
+
33
+ say "\nDone!", :green
34
+ end
35
+
36
+ private
37
+
38
+ def solution(module_name, part, input)
39
+ start_time = Time.now
40
+ result = Object.const_get(module_name).send("part_#{part}", input)
41
+ end_time = Time.now
42
+
43
+ expected_result = expected_answers["part_#{part}"]
44
+
45
+ if expected_result.nil?
46
+ say "Part #{part} result: #{result} ⚠️ (no expectation provided)"
47
+ elsif result == expected_result
48
+ say "Part #{part} result: #{result} ✅"
49
+ else
50
+ say "Part #{part} result: #{result} ❌ (expected #{expected_result})"
51
+ end
52
+
53
+ say "Took #{end_time - start_time} seconds to solve"
54
+ end
55
+
56
+ def expected_answers
57
+ @expected_answers ||= YAML.safe_load(File.read(example_expected_file_name))
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "example/new"
4
+ require_relative "example/solve"
5
+
6
+ module AdventOfCode
7
+ module Commands
8
+ module Example
9
+ class CLI < Thor
10
+ desc "new DAY NAME", "creates an example file with name NAME for day DAY"
11
+ def new(day, name)
12
+ New.new(day: day.to_i, name: name).execute
13
+ rescue ExampleAlreadyExistsError => e
14
+ say(e.message, :red)
15
+ rescue InvalidDayError
16
+ rescue_invalid_day_error
17
+ end
18
+
19
+ desc "solve DAY NAME", "runs the example with name NAME for day DAY"
20
+ def solve(day, name)
21
+ Solve.new(day: day.to_i, name: name).execute
22
+ rescue InvalidDayError
23
+ rescue_invalid_day_error
24
+ rescue MissingExampleError
25
+ say "Error: Cannot find example file.", :red
26
+ rescue AdventOfCode::MissingSolutionError
27
+ say "Error: Cannot find solution file.", :red
28
+ end
29
+
30
+ private
31
+
32
+ def rescue_invalid_day_error
33
+ say "Error: The day argument must be an integer between 1 and 25.", :red
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -32,17 +32,17 @@ module AdventOfCode
32
32
 
33
33
  def solution_file_contents
34
34
  <<~RUBY
35
- module Day#{day_string}
36
- class << self
37
- def part_one(input)
38
- raise NotImplementedError
39
- end
40
-
41
- def part_two(input)
42
- raise NotImplementedError
35
+ module Day#{day_string}
36
+ class << self
37
+ def part_one(input)
38
+ raise NotImplementedError
39
+ end
40
+
41
+ def part_two(input)
42
+ raise NotImplementedError
43
+ end
43
44
  end
44
45
  end
45
- end
46
46
  RUBY
47
47
  end
48
48
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'benchmark'
4
-
5
3
  module AdventOfCode
6
4
  module Commands
7
5
  class Solve < Command
@@ -34,7 +32,7 @@ module AdventOfCode
34
32
  end_time = Time.now
35
33
 
36
34
  say "Part #{part} result: #{result}"
37
- say "Took #{end_time-start_time} seconds to solve"
35
+ say "Took #{end_time - start_time} seconds to solve"
38
36
  end
39
37
  end
40
38
  end
@@ -2,5 +2,6 @@
2
2
 
3
3
  require_relative "commands/command"
4
4
  require_relative "commands/download"
5
+ require_relative "commands/example"
5
6
  require_relative "commands/scaffold"
6
7
  require_relative "commands/solve"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AdventOfCode
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.5"
5
5
  end
@@ -7,8 +7,10 @@ require_relative "advent_of_code_cli/commands"
7
7
 
8
8
  module AdventOfCode
9
9
  class Error < StandardError; end
10
+ class ExampleAlreadyExistsError < Error; end
10
11
  class InvalidDayError < Error; end
11
12
  class MissingCookieError < Error; end
13
+ class MissingExampleError < Error; end
12
14
  class MissingInputError < Error; end
13
15
  class MissingSolutionError < Error; end
14
16
 
@@ -41,6 +43,9 @@ module AdventOfCode
41
43
  say "Error: Cannot find solution file.", :red
42
44
  end
43
45
 
46
+ desc "example", "create and run example files"
47
+ subcommand "example", Commands::Example::CLI
48
+
44
49
  private
45
50
 
46
51
  def rescue_invalid_day_error
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: advent_of_code_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emily Samp
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-12-01 00:00:00.000000000 Z
11
+ date: 2022-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -45,6 +45,9 @@ files:
45
45
  - lib/advent_of_code_cli/commands.rb
46
46
  - lib/advent_of_code_cli/commands/command.rb
47
47
  - lib/advent_of_code_cli/commands/download.rb
48
+ - lib/advent_of_code_cli/commands/example.rb
49
+ - lib/advent_of_code_cli/commands/example/new.rb
50
+ - lib/advent_of_code_cli/commands/example/solve.rb
48
51
  - lib/advent_of_code_cli/commands/scaffold.rb
49
52
  - lib/advent_of_code_cli/commands/solve.rb
50
53
  - lib/advent_of_code_cli/version.rb
@@ -54,6 +57,7 @@ licenses:
54
57
  metadata:
55
58
  homepage_uri: https://github.com/egiurleo/advent_of_code_cli
56
59
  source_code_uri: https://github.com/egiurleo/advent_of_code_cli
60
+ rubygems_mfa_required: 'true'
57
61
  post_install_message:
58
62
  rdoc_options: []
59
63
  require_paths:
@@ -69,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
73
  - !ruby/object:Gem::Version
70
74
  version: '0'
71
75
  requirements: []
72
- rubygems_version: 3.3.7
76
+ rubygems_version: 3.3.26
73
77
  signing_key:
74
78
  specification_version: 4
75
79
  summary: A CLI tool to scaffold and run Advent of Code solutions.