From 27a85f1f9de5519e75fb28b78cb4bf491a0a445d Mon Sep 17 00:00:00 2001 From: Ariejan de Vroom Date: Fri, 15 Nov 2024 09:10:09 +0100 Subject: [PATCH] Initial setup for AoC 2024 Generators galore! --- .gitignore | 19 ++--------------- .gitlab-ci.yml | 0 .rspec | 2 ++ .ruby-version | 1 + Gemfile | 5 +++++ Gemfile.lock | 30 +++++++++++++++++++++++++++ bin/aoc | 13 ++++++++++++ bin/generate | 47 +++++++++++++++++++++++++++++++++++++++++++ lib/application.rb | 24 ++++++++++++++++++++++ spec/spec_helper.rb | 14 +++++++++++++ templates/day.rb | 10 +++++++++ templates/day_spec.rb | 19 +++++++++++++++++ 12 files changed, 167 insertions(+), 17 deletions(-) create mode 100644 .gitlab-ci.yml create mode 100644 .rspec create mode 100644 .ruby-version create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100755 bin/aoc create mode 100755 bin/generate create mode 100644 lib/application.rb create mode 100644 spec/spec_helper.rb create mode 100644 templates/day.rb create mode 100644 templates/day_spec.rb diff --git a/.gitignore b/.gitignore index e3200e0..b923de4 100644 --- a/.gitignore +++ b/.gitignore @@ -11,27 +11,11 @@ /tmp/ # Used by dotenv library to load environment variables. -# .env +.env # Ignore Byebug command history file. .byebug_history -## Specific to RubyMotion: -.dat* -.repl_history -build/ -*.bridgesupport -build-iPhoneOS/ -build-iPhoneSimulator/ - -## Specific to RubyMotion (use of CocoaPods): -# -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control -# -# vendor/Pods/ - ## Documentation cache and generated files: /.yardoc/ /_yardoc/ @@ -42,6 +26,7 @@ build-iPhoneSimulator/ /.bundle/ /vendor/bundle /lib/bundler/man/ +.ruby-lsp # for a library or gem, you might want to ignore these files since the code is # intended to run in multiple environments; otherwise, check them in: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..e69de29 diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..16f9cdb --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--format documentation diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..a0891f5 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +3.3.4 diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..518739f --- /dev/null +++ b/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +ruby '3.3.4' + +gem 'rspec' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..6dcac74 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,30 @@ +GEM + remote: https://rubygems.org/ + specs: + diff-lcs (1.5.1) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.2) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.3) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.1) + +PLATFORMS + arm64-darwin-23 + ruby + +DEPENDENCIES + rspec + +RUBY VERSION + ruby 3.3.4p94 + +BUNDLED WITH + 2.5.22 diff --git a/bin/aoc b/bin/aoc new file mode 100755 index 0000000..a1171ad --- /dev/null +++ b/bin/aoc @@ -0,0 +1,13 @@ +#!/usr/bin/env ruby + +require_relative '../lib/application' + +if ARGV.empty? + puts "Usage: bin/aoc DAY" + puts "Example: bin/aoc 1" + exit 1 +end + +day = ARGV[0].to_i +AdventOfCode2024.run(day) + diff --git a/bin/generate b/bin/generate new file mode 100755 index 0000000..e9e4520 --- /dev/null +++ b/bin/generate @@ -0,0 +1,47 @@ +#!/usr/bin/env ruby + +require 'fileutils' + +def create_day(day) + day_str = day.to_s.rjust(2, '0') + + # Create directories if they don't exist + FileUtils.mkdir_p('lib/solutions') + FileUtils.mkdir_p('lib/input') + FileUtils.mkdir_p('spec/solutions') + FileUtils.mkdir_p('spec/input') + + # Copy solution template + solution_template = File.read('templates/day.rb') + File.write( + "lib/solutions/day_#{day_str}.rb", + solution_template % { day: day_str } + ) + + # Copy test template + test_template = File.read('templates/day_spec.rb') + File.write( + "spec/solutions/day_#{day_str}_spec.rb", + test_template % { day: day_str } + ) + + # Create empty input file + FileUtils.touch("lib/input/day_#{day_str}.txt") + FileUtils.touch("spec/input/day_#{day_str}_test.txt") + + puts "Created files for day #{day_str}:" + puts " - lib/solutions/day_#{day_str}.rb" + puts " - lib/input/day_#{day_str}.txt" + puts " - spec/solutions/day_#{day_str}_spec.rb" + puts " - spec/input/day_#{day_str}_test.txt" +end + +if ARGV.empty? + puts "Usage: bin/generate DAY" + puts "Example: bin/generate 1" + exit 1 +end + +day = ARGV[0].to_i +create_day(day) + diff --git a/lib/application.rb b/lib/application.rb new file mode 100644 index 0000000..88de2f0 --- /dev/null +++ b/lib/application.rb @@ -0,0 +1,24 @@ +require 'fileutils' + +class AdventOfCode2024 + def self.run(day) + day_str = day.to_s.rjust(2, '0') + day_file = File.join(__dir__, 'solutions', "day_#{day_str.downcase}.rb") + + begin + require day_file + solution_class = Object.const_get("Day#{day_str}") + + input = File.read( + File.join(__dir__, 'input', "day_#{day_str}.txt") + ).strip + + puts "Part 1: #{solution_class.new.part_one(input)}" + puts "Part 2: #{solution_class.new.part_two(input)}" + rescue LoadError + puts "Error: Could not find solution file for day #{day_str}" + rescue NameError + puts "Error: Could not find Day#{day_str} class in solution file" + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..075e287 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,14 @@ +require 'rspec/expectations' +require_relative '../lib/application' + +RSpec.configure do |config| + config.expect_with :rspec do |expectations| + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + config.mock_with :rspec do |mocks| + mocks.verify_partial_doubles = true + end + + config.shared_context_metadata_behavior = :apply_to_host_groups +end diff --git a/templates/day.rb b/templates/day.rb new file mode 100644 index 0000000..5bfc7e4 --- /dev/null +++ b/templates/day.rb @@ -0,0 +1,10 @@ +class Day%{day} + def part_one(input) + input.split("\n").map(&:to_i).sum + end + + def part_two(input) + 0 + end +end + diff --git a/templates/day_spec.rb b/templates/day_spec.rb new file mode 100644 index 0000000..f6fa9c9 --- /dev/null +++ b/templates/day_spec.rb @@ -0,0 +1,19 @@ +require "spec_helper" +require "solutions/day_%{day}" + +RSpec.describe Day%{day} do + let(:input) { File.read(File.join(__dir__, '..', '..', 'spec', 'input', 'day_%{day}_test.txt')).strip } + + describe '#part_one' do + it 'calculates the correct solutions for part one' do + expect(subject.part_one(input)).to eq(0) + end + end + + describe '#part_two' do + it 'calculates the correct solutions for part two' do + expect(subject.part_two(input)).to eq(0) + end + end +end +