From 93e8f1156392532f271375903cd74bc38a5273ac Mon Sep 17 00:00:00 2001 From: meatball <69751659+meatball133@users.noreply.github.com> Date: Tue, 1 Oct 2024 19:57:36 +0200 Subject: [PATCH 1/9] Pump ruby vversion (#1719) --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index be94e6f53d..15a2799817 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.2.2 +3.3.0 From 66b1ad4c60acb5df7cf72dc9d345d828594f909e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 14:15:19 -0400 Subject: [PATCH 2/9] Bump actions/checkout from 4.1.7 to 4.2.0 (#1721) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.7 to 4.2.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/692973e3d937129bcbf40652eb9f2f61becf3332...d632683dd7b4114ad314bca15554477dd762a938) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/exercise-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/exercise-tests.yml b/.github/workflows/exercise-tests.yml index 5b3280683d..5a344cd074 100644 --- a/.github/workflows/exercise-tests.yml +++ b/.github/workflows/exercise-tests.yml @@ -19,7 +19,7 @@ jobs: ruby-version: [3.2, 3.3] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - name: Set up Ruby uses: ruby/setup-ruby@52753b7da854d5c07df37391a986c76ab4615999 From fa35ccc41372394db18b4c4a140e27b2597d38d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 14:18:45 -0400 Subject: [PATCH 3/9] Bump ruby/setup-ruby from 1.191.0 to 1.194.0 (#1720) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.191.0 to 1.194.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/52753b7da854d5c07df37391a986c76ab4615999...c04af2bb7258bb6a03df1d3c1865998ac9390972) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/exercise-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/exercise-tests.yml b/.github/workflows/exercise-tests.yml index 5a344cd074..396bfc7300 100644 --- a/.github/workflows/exercise-tests.yml +++ b/.github/workflows/exercise-tests.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - name: Set up Ruby - uses: ruby/setup-ruby@52753b7da854d5c07df37391a986c76ab4615999 + uses: ruby/setup-ruby@c04af2bb7258bb6a03df1d3c1865998ac9390972 with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true From d45740fbf4142fedbf486ee83259a186b14c06a3 Mon Sep 17 00:00:00 2001 From: Dimitar Apostolovski <8737118+themetar@users.noreply.github.com> Date: Wed, 9 Oct 2024 19:00:24 +0200 Subject: [PATCH 4/9] Sync palindrome products (#1722) * [palindrome-products] Add missing tests * [palindrome-products] Update example solution * [palindrome-products] Update config.json * [palindrome-products] Fix formatting (example.rb) --- .../palindrome-products/.meta/config.json | 3 +- .../palindrome-products/.meta/example.rb | 51 +++++++------ .../palindrome-products/.meta/example_2.rb | 47 ------------ .../palindrome-products/.meta/tests.toml | 24 ++++++ .../palindrome_products_test.rb | 74 +++++++++++++++++++ 5 files changed, 125 insertions(+), 74 deletions(-) delete mode 100644 exercises/practice/palindrome-products/.meta/example_2.rb diff --git a/exercises/practice/palindrome-products/.meta/config.json b/exercises/practice/palindrome-products/.meta/config.json index 3c4443e141..c5554bd6a7 100644 --- a/exercises/practice/palindrome-products/.meta/config.json +++ b/exercises/practice/palindrome-products/.meta/config.json @@ -12,7 +12,8 @@ "Insti", "kotp", "markijbema", - "tryantwit" + "tryantwit", + "themetar" ], "files": { "solution": [ diff --git a/exercises/practice/palindrome-products/.meta/example.rb b/exercises/practice/palindrome-products/.meta/example.rb index 2e761d28aa..ef98d0410d 100644 --- a/exercises/practice/palindrome-products/.meta/example.rb +++ b/exercises/practice/palindrome-products/.meta/example.rb @@ -1,43 +1,42 @@ Palindrome = Struct.new(:value, :factors) class Palindromes - attr_reader :range - def initialize(options) - max = options.fetch(:max_factor) - min = options.fetch(:min_factor) { 1 } - @range = (min..max) - end + private - def generate - @palindromes = {} - range.each do |i| - range.each do |j| - product = i * j - if palindrome?(product) - palindrome = @palindromes[product] || Palindrome.new(product, []) - palindrome.factors << [i, j].sort - palindrome.factors.uniq! - @palindromes[product] = palindrome - end - end - end + attr_reader :min, :max + + def initialize(max_factor:, min_factor: 1) + raise ArgumentError, "min must be <= max" unless min_factor <= max_factor + + @min = min_factor + @max = max_factor end def palindrome?(number) number.to_s == number.to_s.reverse end - def sort - @palindromes.sort_by do |key, _palindrome| - key + def factors(palindrome) + (min..Math.sqrt(palindrome)).each_with_object([]) do |number, factors| + div, mod = palindrome.divmod(number) + factors << [number, div] if div.between?(min, max) && mod.zero? end end - def largest - sort.last[1] + def find_palindrome(enum) + enum.lazy. + filter { |number| palindrome? number }. + map { |number| Palindrome.new number, factors(number) }. + find { |palindrome| !palindrome.factors.empty? } end - def smallest - sort.first[1] + public + + attr_reader :smallest, :largest + + def generate + @smallest = find_palindrome(min**2..max**2) || Palindrome.new(nil, []) + + @largest = find_palindrome((max**2..min**2).step(-1)) || Palindrome.new(nil, []) end end diff --git a/exercises/practice/palindrome-products/.meta/example_2.rb b/exercises/practice/palindrome-products/.meta/example_2.rb deleted file mode 100644 index ce989be8d8..0000000000 --- a/exercises/practice/palindrome-products/.meta/example_2.rb +++ /dev/null @@ -1,47 +0,0 @@ -Palindrome = Struct.new(:value, :factors) - -class Palindromes - - private - - attr_reader :range, :candidates - - def initialize(min_factor: 1, max_factor: 9) - @range = (min_factor..max_factor) - end - - def factors(palindrome) - range.each_with_object([]) do |number, factors| - div, mod = palindrome.divmod(number) - if div <= number && range.include?(div) && mod.zero? - factors << [div, number] - end - end - end - - def palindrome_and_factors(palindrome) - Palindrome.new palindrome, factors(palindrome) - end - - public - - def generate - @candidates ||= range.each_with_object([]) do |r1, candidates| - (r1..range.last).each do |r2| - candidate = r1 * r2 - if candidate == candidate.to_s.reverse.to_i - candidates << candidate - end - end - end - end - - def largest - @largest ||= palindrome_and_factors(candidates.max) - end - - def smallest - @smallest ||= palindrome_and_factors(candidates.min) - end - -end diff --git a/exercises/practice/palindrome-products/.meta/tests.toml b/exercises/practice/palindrome-products/.meta/tests.toml index 2f02f4394f..a3bc41750a 100644 --- a/exercises/practice/palindrome-products/.meta/tests.toml +++ b/exercises/practice/palindrome-products/.meta/tests.toml @@ -9,6 +9,9 @@ # As user-added comments (using the # character) will be removed when this file # is regenerated, comments can be added via a `comment` key. +[5cff78fe-cf02-459d-85c2-ce584679f887] +description = "find the smallest palindrome from single digit factors" + [0853f82c-5fc4-44ae-be38-fadb2cced92d] description = "find the largest palindrome from single digit factors" @@ -23,3 +26,24 @@ description = "find the smallest palindrome from triple digit factors" [edab43e1-c35f-4ea3-8c55-2f31dddd92e5] description = "find the largest palindrome from triple digit factors" + +[4f802b5a-9d74-4026-a70f-b53ff9234e4e] +description = "find the smallest palindrome from four digit factors" + +[787525e0-a5f9-40f3-8cb2-23b52cf5d0be] +description = "find the largest palindrome from four digit factors" + +[58fb1d63-fddb-4409-ab84-a7a8e58d9ea0] +description = "empty result for smallest if no palindrome in the range" + +[9de9e9da-f1d9-49a5-8bfc-3d322efbdd02] +description = "empty result for largest if no palindrome in the range" + +[12e73aac-d7ee-4877-b8aa-2aa3dcdb9f8a] +description = "error result for smallest if min is more than max" + +[eeeb5bff-3f47-4b1e-892f-05829277bd74] +description = "error result for largest if min is more than max" + +[16481711-26c4-42e0-9180-e2e4e8b29c23] +description = "smallest product does not use the smallest factor" diff --git a/exercises/practice/palindrome-products/palindrome_products_test.rb b/exercises/practice/palindrome-products/palindrome_products_test.rb index fad80fcf26..c99ac6fadc 100644 --- a/exercises/practice/palindrome-products/palindrome_products_test.rb +++ b/exercises/practice/palindrome-products/palindrome_products_test.rb @@ -2,7 +2,16 @@ require_relative 'palindrome_products' class PalindromesTest < Minitest::Test + def test_smallest_palindrome_from_single_digit_factors + palindromes = Palindromes.new(max_factor: 9) + palindromes.generate + smallest = palindromes.smallest + assert_equal 1, smallest.value + assert_equal [[1, 1]], smallest.factors + end + def test_largest_palindrome_from_single_digit_factors + skip palindromes = Palindromes.new(max_factor: 9) palindromes.generate largest = palindromes.largest @@ -45,4 +54,69 @@ def test_smallest_palindrome_from_triple_digit_factors assert_equal 10_201, smallest.value assert_equal [[101, 101]], smallest.factors end + + def test_smallest_palindrome_from_four_digit_factors + skip + palindromes = Palindromes.new(min_factor: 1000, max_factor: 9999) + palindromes.generate + smallest = palindromes.smallest + assert_equal 1_002_001, smallest.value + assert_equal [[1001, 1001]], smallest.factors + end + + def test_largest_palindrome_from_four_digit_factors + skip + palindromes = Palindromes.new(min_factor: 1000, max_factor: 9999) + palindromes.generate + largest = palindromes.largest + assert_equal 99_000_099, largest.value + assert_equal [[9901, 9999]], largest.factors + end + + def test_empty_for_smallest_if_no_palindrome_in_range + skip + palindromes = Palindromes.new(min_factor: 1002, max_factor: 1003) + palindromes.generate + smallest = palindromes.smallest + assert_nil smallest.value + assert_empty smallest.factors + end + + def test_empty_for_largest_if_no_palindrome_in_range + skip + palindromes = Palindromes.new(min_factor: 15, max_factor: 15) + palindromes.generate + largest = palindromes.largest + assert_nil largest.value + assert_empty largest.factors + end + + def test_error_for_smallest_if_min_more_than_max + skip + error = assert_raises(ArgumentError) do + palindromes = Palindromes.new(min_factor: 10_000, max_factor: 1) + palindromes.generate + palindromes.smallest + end + assert_equal "min must be <= max", error.message + end + + def test_error_for_largest_if_min_more_than_max + skip + error = assert_raises(ArgumentError) do + palindromes = Palindromes.new(min_factor: 2, max_factor: 1) + palindromes.generate + palindromes.smallest + end + assert_equal "min must be <= max", error.message + end + + def test_smallest_palindrome_does_not_use_smallest_factors + skip + palindromes = Palindromes.new(min_factor: 3215, max_factor: 4000) + palindromes.generate + smallest = palindromes.smallest + assert_equal 10_988_901, smallest.value + assert_equal [[3297, 3333]], smallest.factors + end end From 149839fe5296eeff5bed0207f26dbcc816938bfc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 22:19:50 -0400 Subject: [PATCH 5/9] Bump rexml from 3.3.6 to 3.3.9 (#1724) Bumps [rexml](https://github.com/ruby/rexml) from 3.3.6 to 3.3.9. - [Release notes](https://github.com/ruby/rexml/releases) - [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md) - [Commits](https://github.com/ruby/rexml/compare/v3.3.6...v3.3.9) --- updated-dependencies: - dependency-name: rexml dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 86101117a2..73af3549cb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -15,8 +15,7 @@ GEM rainbow (3.1.1) rake (13.2.1) regexp_parser (2.9.0) - rexml (3.3.6) - strscan + rexml (3.3.9) rubocop (1.50.2) json (~> 2.3) parallel (~> 1.10) @@ -42,7 +41,6 @@ GEM simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) simplecov_json_formatter (0.1.4) - strscan (3.1.0) unicode-display_width (2.5.0) PLATFORMS From 42875af51f872bb5d13cc61f82a9bb96882ad847 Mon Sep 17 00:00:00 2001 From: Victor Goff Date: Thu, 31 Oct 2024 14:40:42 -0400 Subject: [PATCH 6/9] Series: Test is not testing for zero length series (#1725) This test now raises if the series is 0 instead of of the slice slice size being larger than the series. This allows one to raise on normalization of user input, the series given, rather than incidentally having the slice size of 1 be larger than the series size from a zero length string. The example solution is updated to raise specifically for a zero length series, rather than the incidental raising when slices are asked for. Note: This should not invalidate current solutions, while allowing solutions that raise in `initialize` for the reason that the series is 0 length will now pass: No need to test current solutions: [no important files changed] --- exercises/practice/series/.meta/example.rb | 1 + exercises/practice/series/series_test.rb | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/practice/series/.meta/example.rb b/exercises/practice/series/.meta/example.rb index d93923d611..dfca6db15a 100644 --- a/exercises/practice/series/.meta/example.rb +++ b/exercises/practice/series/.meta/example.rb @@ -1,5 +1,6 @@ class Series def initialize(series) + raise ArgumentError if series.length.zero? @series = series end def slices(n) diff --git a/exercises/practice/series/series_test.rb b/exercises/practice/series/series_test.rb index 759b5c5288..f93e624068 100644 --- a/exercises/practice/series/series_test.rb +++ b/exercises/practice/series/series_test.rb @@ -68,9 +68,8 @@ def test_slice_length_cannot_be_negative def test_empty_series_is_invalid skip slice_string = "" - series = Series.new(slice_string) assert_raises ArgumentError do - series.slices(1) + Series.new(slice_string) end end end From e4b3329dd5572e32ddf516e8102686c64bd5e65e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:35:27 -0400 Subject: [PATCH 7/9] Bump actions/checkout from 4.2.0 to 4.2.2 (#1726) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.0 to 4.2.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/d632683dd7b4114ad314bca15554477dd762a938...11bd71901bbe5b1630ceea73d27597364c9af683) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/exercise-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/exercise-tests.yml b/.github/workflows/exercise-tests.yml index 396bfc7300..34a7cf8954 100644 --- a/.github/workflows/exercise-tests.yml +++ b/.github/workflows/exercise-tests.yml @@ -19,7 +19,7 @@ jobs: ruby-version: [3.2, 3.3] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Set up Ruby uses: ruby/setup-ruby@c04af2bb7258bb6a03df1d3c1865998ac9390972 From 93a7b1f0d1053a11479dddfdb8d22890fed1b0a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:35:49 -0400 Subject: [PATCH 8/9] Bump ruby/setup-ruby from 1.194.0 to 1.199.0 (#1727) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.194.0 to 1.199.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/c04af2bb7258bb6a03df1d3c1865998ac9390972...7d3497fd78c07c0d84ebafa58d8dac60cd1f0763) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/exercise-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/exercise-tests.yml b/.github/workflows/exercise-tests.yml index 34a7cf8954..e4c9e6e7e5 100644 --- a/.github/workflows/exercise-tests.yml +++ b/.github/workflows/exercise-tests.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Set up Ruby - uses: ruby/setup-ruby@c04af2bb7258bb6a03df1d3c1865998ac9390972 + uses: ruby/setup-ruby@7d3497fd78c07c0d84ebafa58d8dac60cd1f0763 with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true From 1a6a28c7eaf1eb6ad62104b6824c29d1c141039e Mon Sep 17 00:00:00 2001 From: meatball <69751659+meatball133@users.noreply.github.com> Date: Fri, 8 Nov 2024 20:58:26 +0100 Subject: [PATCH 9/9] [New Exercise]: Bottle Song (#1729) * Add bottle-song exercise --- config.json | 14 ++ .../bottle-song/.docs/instructions.md | 57 +++++++ .../practice/bottle-song/.meta/config.json | 17 +++ .../practice/bottle-song/.meta/example.rb | 18 +++ .../practice/bottle-song/.meta/tests.toml | 31 ++++ exercises/practice/bottle-song/bottle_song.rb | 7 + .../practice/bottle-song/bottle_song_test.rb | 141 ++++++++++++++++++ 7 files changed, 285 insertions(+) create mode 100644 exercises/practice/bottle-song/.docs/instructions.md create mode 100644 exercises/practice/bottle-song/.meta/config.json create mode 100644 exercises/practice/bottle-song/.meta/example.rb create mode 100644 exercises/practice/bottle-song/.meta/tests.toml create mode 100644 exercises/practice/bottle-song/bottle_song.rb create mode 100644 exercises/practice/bottle-song/bottle_song_test.rb diff --git a/config.json b/config.json index 5f1e918db3..1b4dbdc4ad 100644 --- a/config.json +++ b/config.json @@ -978,6 +978,20 @@ ], "difficulty": 6 }, + { + "slug": "bottle-song", + "name": "Bottle Song", + "uuid": "fb29b743-0f2d-46fe-8a2a-14973259bb2b", + "practices": [ + "strings" + ], + "prerequisites": [ + "strings", + "numbers", + "loops" + ], + "difficulty": 3 + }, { "slug": "beer-song", "name": "Beer Song", diff --git a/exercises/practice/bottle-song/.docs/instructions.md b/exercises/practice/bottle-song/.docs/instructions.md new file mode 100644 index 0000000000..febdfc8639 --- /dev/null +++ b/exercises/practice/bottle-song/.docs/instructions.md @@ -0,0 +1,57 @@ +# Instructions + +Recite the lyrics to that popular children's repetitive song: Ten Green Bottles. + +Note that not all verses are identical. + +```text +Ten green bottles hanging on the wall, +Ten green bottles hanging on the wall, +And if one green bottle should accidentally fall, +There'll be nine green bottles hanging on the wall. + +Nine green bottles hanging on the wall, +Nine green bottles hanging on the wall, +And if one green bottle should accidentally fall, +There'll be eight green bottles hanging on the wall. + +Eight green bottles hanging on the wall, +Eight green bottles hanging on the wall, +And if one green bottle should accidentally fall, +There'll be seven green bottles hanging on the wall. + +Seven green bottles hanging on the wall, +Seven green bottles hanging on the wall, +And if one green bottle should accidentally fall, +There'll be six green bottles hanging on the wall. + +Six green bottles hanging on the wall, +Six green bottles hanging on the wall, +And if one green bottle should accidentally fall, +There'll be five green bottles hanging on the wall. + +Five green bottles hanging on the wall, +Five green bottles hanging on the wall, +And if one green bottle should accidentally fall, +There'll be four green bottles hanging on the wall. + +Four green bottles hanging on the wall, +Four green bottles hanging on the wall, +And if one green bottle should accidentally fall, +There'll be three green bottles hanging on the wall. + +Three green bottles hanging on the wall, +Three green bottles hanging on the wall, +And if one green bottle should accidentally fall, +There'll be two green bottles hanging on the wall. + +Two green bottles hanging on the wall, +Two green bottles hanging on the wall, +And if one green bottle should accidentally fall, +There'll be one green bottle hanging on the wall. + +One green bottle hanging on the wall, +One green bottle hanging on the wall, +And if one green bottle should accidentally fall, +There'll be no green bottles hanging on the wall. +``` diff --git a/exercises/practice/bottle-song/.meta/config.json b/exercises/practice/bottle-song/.meta/config.json new file mode 100644 index 0000000000..3bfb038776 --- /dev/null +++ b/exercises/practice/bottle-song/.meta/config.json @@ -0,0 +1,17 @@ +{ + "authors": ["meatball133"], + "files": { + "solution": [ + "bottle_song.rb" + ], + "test": [ + "bottle_song_test.rb" + ], + "example": [ + ".meta/example.rb" + ] + }, + "blurb": "Produce the lyrics to the popular children's repetitive song: Ten Green Bottles.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Ten_Green_Bottles" +} diff --git a/exercises/practice/bottle-song/.meta/example.rb b/exercises/practice/bottle-song/.meta/example.rb new file mode 100644 index 0000000000..a318fc81ef --- /dev/null +++ b/exercises/practice/bottle-song/.meta/example.rb @@ -0,0 +1,18 @@ +module BottleSong + + TRANSLATE = { + 0 => "no", 1 => "one", 2 => "two", 3 => "three", 4 => "four", 5 => "five", + 6 => "six", 7 => "seven", 8 => "eight", 9 => "nine", 10 => "ten" + } + + def self.recite(start, amount) + ((start - amount + 1)..(start)).to_a.reverse.map do |current| + <<~TEXT + #{TRANSLATE[current].capitalize} green #{current == 1 ? "bottle" : "bottles"} hanging on the wall, + #{TRANSLATE[current].capitalize} green #{current == 1 ? "bottle" : "bottles"} hanging on the wall, + And if one green bottle should accidentally fall, + There'll be #{TRANSLATE[current - 1]} green #{current - 1 == 1 ? "bottle" : "bottles"} hanging on the wall. + TEXT + end.join("\n") + end +end diff --git a/exercises/practice/bottle-song/.meta/tests.toml b/exercises/practice/bottle-song/.meta/tests.toml new file mode 100644 index 0000000000..1f6e40a37c --- /dev/null +++ b/exercises/practice/bottle-song/.meta/tests.toml @@ -0,0 +1,31 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[d4ccf8fc-01dc-48c0-a201-4fbeb30f2d03] +description = "verse -> single verse -> first generic verse" + +[0f0aded3-472a-4c64-b842-18d4f1f5f030] +description = "verse -> single verse -> last generic verse" + +[f61f3c97-131f-459e-b40a-7428f3ed99d9] +description = "verse -> single verse -> verse with 2 bottles" + +[05eadba9-5dbd-401e-a7e8-d17cc9baa8e0] +description = "verse -> single verse -> verse with 1 bottle" + +[a4a28170-83d6-4dc1-bd8b-319b6abb6a80] +description = "lyrics -> multiple verses -> first two verses" + +[3185d438-c5ac-4ce6-bcd3-02c9ff1ed8db] +description = "lyrics -> multiple verses -> last three verses" + +[28c1584a-0e51-4b65-9ae2-fbc0bf4bbb28] +description = "lyrics -> multiple verses -> all verses" diff --git a/exercises/practice/bottle-song/bottle_song.rb b/exercises/practice/bottle-song/bottle_song.rb new file mode 100644 index 0000000000..b74ea1b720 --- /dev/null +++ b/exercises/practice/bottle-song/bottle_song.rb @@ -0,0 +1,7 @@ +=begin +Write your code for the 'BottleSong' exercise in this file. Make the tests in +`bottle_song_test.rb` pass. + +To get started with TDD, see the `README.md` file in your +`ruby/bottle-song` directory. +=end diff --git a/exercises/practice/bottle-song/bottle_song_test.rb b/exercises/practice/bottle-song/bottle_song_test.rb new file mode 100644 index 0000000000..8eb9bef5e3 --- /dev/null +++ b/exercises/practice/bottle-song/bottle_song_test.rb @@ -0,0 +1,141 @@ +require 'minitest/autorun' +require_relative 'bottle_song' + +class BottleSongTest < Minitest::Test + def test_single_verse + # skip + expected = <<~TEXT + Ten green bottles hanging on the wall, + Ten green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be nine green bottles hanging on the wall. + TEXT + assert_equal expected, BottleSong.recite(10, 1) + end + + def test_last_generic_verse + skip + expected = <<~TEXT + Three green bottles hanging on the wall, + Three green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be two green bottles hanging on the wall. + TEXT + assert_equal expected, BottleSong.recite(3, 1) + end + + def test_verse_with_2_bottles + skip + expected = <<~TEXT + Two green bottles hanging on the wall, + Two green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be one green bottle hanging on the wall. + TEXT + assert_equal expected, BottleSong.recite(2, 1) + end + + def test_verse_with_1_bottle + skip + expected = <<~TEXT + One green bottle hanging on the wall, + One green bottle hanging on the wall, + And if one green bottle should accidentally fall, + There'll be no green bottles hanging on the wall. + TEXT + assert_equal expected, BottleSong.recite(1, 1) + end + + def test_first_two_verses + skip + expected = <<~TEXT + Ten green bottles hanging on the wall, + Ten green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be nine green bottles hanging on the wall. + + Nine green bottles hanging on the wall, + Nine green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be eight green bottles hanging on the wall. + TEXT + assert_equal expected, BottleSong.recite(10, 2) + end + + def test_last_three_verses + skip + expected = <<~TEXT + Three green bottles hanging on the wall, + Three green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be two green bottles hanging on the wall. + + Two green bottles hanging on the wall, + Two green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be one green bottle hanging on the wall. + + One green bottle hanging on the wall, + One green bottle hanging on the wall, + And if one green bottle should accidentally fall, + There'll be no green bottles hanging on the wall. + TEXT + assert_equal expected, BottleSong.recite(3, 3) + end + + def test_all_verses + skip + expected = <<~TEXT + Ten green bottles hanging on the wall, + Ten green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be nine green bottles hanging on the wall. + + Nine green bottles hanging on the wall, + Nine green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be eight green bottles hanging on the wall. + + Eight green bottles hanging on the wall, + Eight green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be seven green bottles hanging on the wall. + + Seven green bottles hanging on the wall, + Seven green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be six green bottles hanging on the wall. + + Six green bottles hanging on the wall, + Six green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be five green bottles hanging on the wall. + + Five green bottles hanging on the wall, + Five green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be four green bottles hanging on the wall. + + Four green bottles hanging on the wall, + Four green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be three green bottles hanging on the wall. + + Three green bottles hanging on the wall, + Three green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be two green bottles hanging on the wall. + + Two green bottles hanging on the wall, + Two green bottles hanging on the wall, + And if one green bottle should accidentally fall, + There'll be one green bottle hanging on the wall. + + One green bottle hanging on the wall, + One green bottle hanging on the wall, + And if one green bottle should accidentally fall, + There'll be no green bottles hanging on the wall. + TEXT + assert_equal expected, BottleSong.recite(10, 10) + end +end