advent_of_code_cli 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b2cac14f5226dc5a7c96642991455c2f33c794d2897669393c095ca350cdae2
4
- data.tar.gz: e3d32b4654fc79cfb0fb86e2a33004019142ba6fb523215e2da7692b071879c5
3
+ metadata.gz: 975ed7c8275bc2111366961b426b01ba4805835876aa47ada28cb45a8296a56d
4
+ data.tar.gz: e3ecbe525361d68da73e13906adda1594354d9bfc1727a85a752f57114673685
5
5
  SHA512:
6
- metadata.gz: 2e1723a650da1f128a8f3cae5af52ae0f2e7b04845a883a82181f076d47b14b984a26b3ad6cc79ea4c1ce2272b6232531d2892e8790cd202dbcd053d1ccab98f
7
- data.tar.gz: 71fc3eed81a924700eddb86a9c1f06c2a3ce0c43cbaf09e64f34c6078e3876f6d5409bbfbb4e37952165db444c866e3ebbbd5daaf63a79b7a725402570705f92
6
+ metadata.gz: 2bcc6d477acc45cb34b0bbea2c7f2f0cb904b3e76b80847267de80db2d2f5dfcaf96ec0078c080e6de44a4cd45cbe008708199090d4cd0a59fda6147bf2d556e
7
+ data.tar.gz: 7b912eaa46ee7e047aed2bc94ed7997e097317fef923ad4fdbd36d69885ff6be07002cf43ba0409d3b0e0ee916711301a85d1e7775f24c91c349f628dff9f48c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- advent_of_code_cli (0.1.4)
4
+ advent_of_code_cli (0.1.5)
5
5
  thor (>= 1.2.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -113,6 +113,61 @@ Done!
113
113
 
114
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.
115
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
+
116
171
  ## Contributing
117
172
 
118
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
@@ -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
@@ -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.4"
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.4
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-02 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