From 297b13ceeb1452a9b7a8877bb36cb69eddc8db5e Mon Sep 17 00:00:00 2001 From: KOTP Date: Fri, 12 Dec 2025 22:55:04 -0500 Subject: [PATCH 1/2] Update supported versions of Ruby - description in README - version for test in CI --- .github/workflows/exercise-tests.yml | 2 +- README.md | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/exercise-tests.yml b/.github/workflows/exercise-tests.yml index 6606205733..1ecb3d4178 100644 --- a/.github/workflows/exercise-tests.yml +++ b/.github/workflows/exercise-tests.yml @@ -16,7 +16,7 @@ jobs: matrix: os: - ubuntu-24.04 - ruby-version: [3.2, 3.3] + ruby-version: [3.3, 3.4] steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 diff --git a/README.md b/README.md index 3f1eb170c5..d758a4e2d5 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,11 @@ Exercism Exercises in Ruby ## Setup -You'll need a recent (2.6+) version of Ruby, but that's it. +You will want a recent (3.4+) version of Ruby, but that's it. Minitest ships with the language, so you're all set. +Older versions of Ruby may work, but are not officially supported. + ## Anatomy of an Exercise The files for an exercise live in `exercises/`. From cd34d916f120c33feabed722b50ed2e74846271a Mon Sep 17 00:00:00 2001 From: KOTP Date: Fri, 18 Sep 2026 03:29:35 -0500 Subject: [PATCH 2/2] =?UTF-8?q?Parallel=20Letter=20Frequency=20performance?= =?UTF-8?q?=20test=203.4=20=E2=9C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../.meta/example.rb | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/exercises/practice/parallel-letter-frequency/.meta/example.rb b/exercises/practice/parallel-letter-frequency/.meta/example.rb index 2c3039eb77..3416b86c6e 100644 --- a/exercises/practice/parallel-letter-frequency/.meta/example.rb +++ b/exercises/practice/parallel-letter-frequency/.meta/example.rb @@ -1,10 +1,34 @@ class ParallelLetterFrequency def self.count(texts) - ractors = (0...texts.length).map do |i| - Ractor.new(texts[i]) do |text| - text.downcase.each_grapheme_cluster.select do |cluster| - cluster.match?(/\p{Alpha}/) - end.tally + return {} if texts.empty? + + ractor_count = [texts.length, 8].min + batch_size = (texts.length.to_f / ractor_count).ceil + ractors = texts.each_slice(batch_size).map do |batch| + Ractor.new(batch) do |batch_texts| + ascii_counts = Array.new(26, 0) + tally = Hash.new(0) + + batch_texts.each do |text| + if text.ascii_only? + text.each_byte do |byte| + case byte + when 65..90 then ascii_counts[byte - 65] += 1 + when 97..122 then ascii_counts[byte - 97] += 1 + end + end + else + text.downcase.each_grapheme_cluster do |cluster| + tally[cluster] += 1 if cluster.match?(/\p{Alpha}/) + end + end + end + + ascii_counts.each_with_index do |count, index| + tally[(index + 97).chr] += count unless count.zero? + end + + tally end end