some more ruby exercisms

This commit is contained in:
Ben Harris 2018-03-05 02:08:48 -05:00
parent d8f97adbaf
commit 0420a79060
24 changed files with 1148 additions and 28 deletions

74
ruby/accumulate/README.md Normal file
View File

@ -0,0 +1,74 @@
# Accumulate
Implement the `accumulate` operation, which, given a collection and an
operation to perform on each element of the collection, returns a new
collection containing the result of applying that operation to each element of
the input collection.
Given the collection of numbers:
- 1, 2, 3, 4, 5
And the operation:
- square a number (`x => x * x`)
Your code should be able to produce the collection of squares:
- 1, 4, 9, 16, 25
Check out the test suite to see the expected function signature.
## Restrictions
Keep your hands off that collect/map/fmap/whatchamacallit functionality
provided by your standard library!
Solve this one yourself using other basic tools instead.
## Advanced
It is typical to call [#to_enum](http://ruby-doc.org/core-2.3.1/Object.html#method-i-to_enum) when defining methods for a generic Enumerable, in case no block is passed.
Here is an additional test you could add:
```ruby
def test_accumulate_when_block_is_deferred
skip
accumulate_enumerator = [1, 2, 3].accumulate
accumulated_result = accumulate_enumerator.each do |number|
number * number
end
assert_equal [1, 4, 9], accumulated_result
end
```
* * * *
For installation and learning resources, refer to the
[exercism help page](http://exercism.io/languages/ruby).
For running the tests provided, you will need the Minitest gem. Open a
terminal window and run the following command to install minitest:
gem install minitest
If you would like color output, you can `require 'minitest/pride'` in
the test file, or note the alternative instruction, below, for running
the test file.
Run the tests from the exercise directory using the following command:
ruby accumulate_test.rb
To include color from the command line:
ruby -r minitest/pride accumulate_test.rb
## Source
Conversation with James Edward Gray II [https://twitter.com/jeg2](https://twitter.com/jeg2)
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

View File

@ -0,0 +1,13 @@
class Array
def accumulate(&block)
if block_given?
each_with_object([]) {|elem, out| out << yield(elem)}
else
self.to_enum
end
end
end
module BookKeeping
VERSION = 1
end

View File

@ -0,0 +1,61 @@
require 'minitest/autorun'
require_relative 'accumulate'
class ArrayTest < Minitest::Test
def test_empty_accumulation
assert_equal [], [].accumulate { |e| e * e }
end
def test_accumulate_squares
result = [1, 2, 3].accumulate do |number|
number * number
end
assert_equal [1, 4, 9], result
end
def test_accumulate_upcases
result = %w(hello world).accumulate(&:upcase)
assert_equal %w(HELLO WORLD), result
end
def test_accumulate_reversed_strings
result = %w(the quick brown fox etc).accumulate(&:reverse)
assert_equal %w(eht kciuq nworb xof cte), result
end
def test_accumulate_recursively
result = %w(a b c).accumulate do |char|
%w(1 2 3).accumulate do |digit|
"#{char}#{digit}"
end
end
assert_equal [%w(a1 a2 a3), %w(b1 b2 b3), %w(c1 c2 c3)], result
end
def test_do_not_change_in_place
original = [1, 2, 3]
copy = original.dup
original.accumulate { |n| n * n }
assert_equal copy, original
end
# Problems in exercism evolve over time, as we find better ways to ask
# questions.
# The version number refers to the version of the problem you solved,
# not your solution.
#
# Define a constant named VERSION inside of the top level BookKeeping
# module.
# In your file, it will look like this:
#
# module BookKeeping
# VERSION = 1 # Where the version number matches the one in the test.
# end
#
# If you are curious, read more about constants on RubyDoc:
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
def test_bookkeeping
assert_equal 1, BookKeeping::VERSION
end
end

61
ruby/binary/README.md Normal file
View File

@ -0,0 +1,61 @@
# Binary
Convert a binary number, represented as a string (e.g. '101010'), to its decimal equivalent using first principles.
Implement binary to decimal conversion. Given a binary input
string, your program should produce a decimal output. The
program should handle invalid inputs.
## Note
- Implement the conversion yourself.
Do not use something else to perform the conversion for you.
## About Binary (Base-2)
Decimal is a base-10 system.
A number 23 in base 10 notation can be understood
as a linear combination of powers of 10:
- The rightmost digit gets multiplied by 10^0 = 1
- The next number gets multiplied by 10^1 = 10
- ...
- The *n*th number gets multiplied by 10^*(n-1)*.
- All these values are summed.
So: `23 => 2*10^1 + 3*10^0 => 2*10 + 3*1 = 23 base 10`
Binary is similar, but uses powers of 2 rather than powers of 10.
So: `101 => 1*2^2 + 0*2^1 + 1*2^0 => 1*4 + 0*2 + 1*1 => 4 + 1 => 5 base 10`.
* * * *
For installation and learning resources, refer to the
[exercism help page](http://exercism.io/languages/ruby).
For running the tests provided, you will need the Minitest gem. Open a
terminal window and run the following command to install minitest:
gem install minitest
If you would like color output, you can `require 'minitest/pride'` in
the test file, or note the alternative instruction, below, for running
the test file.
Run the tests from the exercise directory using the following command:
ruby binary_test.rb
To include color from the command line:
ruby -r minitest/pride binary_test.rb
## Source
All of Computer Science [http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-](http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-)
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

12
ruby/binary/binary.rb Normal file
View File

@ -0,0 +1,12 @@
class Binary
def self.to_decimal(num)
raise ArgumentError unless num.chars.all?{|c| /[01]/.match(c)}
num.chars.reverse.each_with_index.reduce(0) do |acc, (elem, i)|
acc += elem.to_i * 2 ** i
end
end
end
module BookKeeping
VERSION = 3
end

View File

@ -0,0 +1,87 @@
require 'minitest/autorun'
require_relative 'binary'
# Common test data version: 1.0.0 969717d
class BinaryTest < Minitest::Test
def test_binary_0_is_decimal_0
# skip
assert_equal 0, Binary.to_decimal('0')
end
def test_binary_1_is_decimal_1
assert_equal 1, Binary.to_decimal('1')
end
def test_binary_10_is_decimal_2
assert_equal 2, Binary.to_decimal('10')
end
def test_binary_11_is_decimal_3
assert_equal 3, Binary.to_decimal('11')
end
def test_binary_100_is_decimal_4
assert_equal 4, Binary.to_decimal('100')
end
def test_binary_1001_is_decimal_9
assert_equal 9, Binary.to_decimal('1001')
end
def test_binary_11010_is_decimal_26
assert_equal 26, Binary.to_decimal('11010')
end
def test_binary_10001101000_is_decimal_1128
assert_equal 1128, Binary.to_decimal('10001101000')
end
def test_binary_ignores_leading_zeros
assert_equal 31, Binary.to_decimal('000011111')
end
def test_2_is_not_a_valid_binary_digit
assert_raises(ArgumentError) { Binary.to_decimal('2') }
end
def test_a_number_containing_a_non_binary_digit_is_invalid
assert_raises(ArgumentError) { Binary.to_decimal('01201') }
end
def test_a_number_with_trailing_non_binary_characters_is_invalid
assert_raises(ArgumentError) { Binary.to_decimal('10nope') }
end
def test_a_number_with_leading_non_binary_characters_is_invalid
assert_raises(ArgumentError) { Binary.to_decimal('nope10') }
end
def test_a_number_with_internal_non_binary_characters_is_invalid
assert_raises(ArgumentError) { Binary.to_decimal('10nope10') }
end
def test_a_number_and_a_word_whitespace_spearated_is_invalid
assert_raises(ArgumentError) { Binary.to_decimal('001 nope') }
end
# Problems in exercism evolve over time, as we find better ways to ask
# questions.
# The version number refers to the version of the problem you solved,
# not your solution.
#
# Define a constant named VERSION inside of the top level BookKeeping
# module, which may be placed near the end of your file.
#
# In your file, it will look like this:
#
# module BookKeeping
# VERSION = 1 # Where the version number matches the one in the test.
# end
#
# If you are curious, read more about constants on RubyDoc:
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
def test_bookkeeping
assert_equal 3, BookKeeping::VERSION
end
end

17
ruby/bob/bob.rb Normal file
View File

@ -0,0 +1,17 @@
class Bob
def self.hey(msg)
if msg.strip == ""
"Fine. Be that way!"
elsif msg.chars.any?{|c| /[a-zA-Z]/.match(c)} || msg.chars.select{|c| /[a-zA-Z]/.match(c)}.all?{|c| /[A-Z]/.match(c)}
"Whoa, chill out!"
elsif msg.strip.end_with?("?")
"Sure."
else
"Whatever."
end
end
end
module BookKeeping
VERSION = 1
end

View File

@ -4,151 +4,151 @@ require_relative 'bob'
# Common test data version: 1.0.0 65756b1
class BobTest < Minitest::Test
def test_stating_something
# skip
#
remark = "Tom-ay-to, tom-aaaah-to."
assert_equal 'Whatever.', Bob.hey(remark), %q{Bob hears "Tom-ay-to, tom-aaaah-to.", and..}
end
def test_shouting
skip
remark = "WATCH OUT!"
assert_equal 'Whoa, chill out!', Bob.hey(remark), %q{Bob hears "WATCH OUT!", and..}
end
def test_shouting_gibberish
skip
remark = "FCECDFCAAB"
assert_equal 'Whoa, chill out!', Bob.hey(remark), %q{Bob hears "FCECDFCAAB", and..}
end
def test_asking_a_question
skip
remark = "Does this cryogenic chamber make me look fat?"
assert_equal 'Sure.', Bob.hey(remark), %q{Bob hears "Does this cryogenic chamber make me look fat?", and..}
end
def test_asking_a_numeric_question
skip
remark = "You are, what, like 15?"
assert_equal 'Sure.', Bob.hey(remark), %q{Bob hears "You are, what, like 15?", and..}
end
def test_asking_gibberish
skip
remark = "fffbbcbeab?"
assert_equal 'Sure.', Bob.hey(remark), %q{Bob hears "fffbbcbeab?", and..}
end
def test_talking_forcefully
skip
remark = "Let's go make out behind the gym!"
assert_equal 'Whatever.', Bob.hey(remark), %q{Bob hears "Let's go make out behind the gym!", and..}
end
def test_using_acronyms_in_regular_speech
skip
remark = "It's OK if you don't want to go to the DMV."
assert_equal 'Whatever.', Bob.hey(remark), %q{Bob hears "It's OK if you don't want to go to the DMV.", and..}
end
def test_forceful_question
skip
remark = "WHAT THE HELL WERE YOU THINKING?"
assert_equal 'Whoa, chill out!', Bob.hey(remark), %q{Bob hears "WHAT THE HELL WERE YOU THINKING?", and..}
end
def test_shouting_numbers
skip
remark = "1, 2, 3 GO!"
assert_equal 'Whoa, chill out!', Bob.hey(remark), %q{Bob hears "1, 2, 3 GO!", and..}
end
def test_only_numbers
skip
remark = "1, 2, 3"
assert_equal 'Whatever.', Bob.hey(remark), %q{Bob hears "1, 2, 3", and..}
end
def test_question_with_only_numbers
skip
remark = "4?"
assert_equal 'Sure.', Bob.hey(remark), %q{Bob hears "4?", and..}
end
def test_shouting_with_special_characters
skip
remark = "ZOMG THE %^*@\#$(*^ ZOMBIES ARE COMING!!11!!1!"
assert_equal 'Whoa, chill out!', Bob.hey(remark), %q{Bob hears "ZOMG THE %^*@\#$(*^ ZOMBIES ARE COMING!!11!!1!", and..}
end
def test_shouting_with_no_exclamation_mark
skip
remark = "I HATE YOU"
assert_equal 'Whoa, chill out!', Bob.hey(remark), %q{Bob hears "I HATE YOU", and..}
end
def test_statement_containing_question_mark
skip
remark = "Ending with ? means a question."
assert_equal 'Whatever.', Bob.hey(remark), %q{Bob hears "Ending with ? means a question.", and..}
end
def test_non_letters_with_question
skip
remark = ":) ?"
assert_equal 'Sure.', Bob.hey(remark), %q{Bob hears ":) ?", and..}
end
def test_prattling_on
skip
remark = "Wait! Hang on. Are you going to be OK?"
assert_equal 'Sure.', Bob.hey(remark), %q{Bob hears "Wait! Hang on. Are you going to be OK?", and..}
end
def test_silence
skip
remark = ""
assert_equal 'Fine. Be that way!', Bob.hey(remark), %q{Bob hears "", and..}
end
def test_prolonged_silence
skip
remark = " "
assert_equal 'Fine. Be that way!', Bob.hey(remark), %q{Bob hears " ", and..}
end
def test_alternate_silence
skip
remark = "\t\t\t\t\t\t\t\t\t\t"
assert_equal 'Fine. Be that way!', Bob.hey(remark), %q{Bob hears "\t\t\t\t\t\t\t\t\t\t", and..}
end
def test_multiple_line_question
skip
remark = "\nDoes this cryogenic chamber make me look fat?\nno"
assert_equal 'Whatever.', Bob.hey(remark), %q{Bob hears "\nDoes this cryogenic chamber make me look fat?\nno", and..}
end
def test_starting_with_whitespace
skip
remark = " hmmmmmmm..."
assert_equal 'Whatever.', Bob.hey(remark), %q{Bob hears " hmmmmmmm...", and..}
end
def test_ending_with_whitespace
skip
remark = "Okay if like my spacebar quite a bit? "
assert_equal 'Sure.', Bob.hey(remark), %q{Bob hears "Okay if like my spacebar quite a bit? ", and..}
end
def test_other_whitespace
skip
remark = "\n\r \t"
assert_equal 'Fine. Be that way!', Bob.hey(remark), %q{Bob hears "\n\r \t", and..}
end
def test_non_question_ending_with_whitespace
skip
remark = "This is a statement ending with whitespace "
assert_equal 'Whatever.', Bob.hey(remark), %q{Bob hears "This is a statement ending with whitespace ", and..}
end
@ -171,7 +171,7 @@ class BobTest < Minitest::Test
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
def test_bookkeeping
skip
assert_equal 1, BookKeeping::VERSION
end
end

View File

@ -0,0 +1,65 @@
# Grade School
Given students' names along with the grade that they are in, create a roster
for the school.
In the end, you should be able to:
- Add a student's name to the roster for a grade
- "Add Jim to grade 2."
- "OK."
- Get a list of all students enrolled in a grade
- "Which students are in grade 2?"
- "We've only got Jim just now."
- Get a sorted list of all students in all grades. Grades should sort
as 1, 2, 3, etc., and students within a grade should be sorted
alphabetically by name.
- "Who all is enrolled in school right now?"
- "Grade 1: Anna, Barb, and Charlie. Grade 2: Alex, Peter, and Zoe.
Grade 3…"
Note that all our students only have one name. (It's a small town, what
do you want?)
## For bonus points
Did you get the tests passing and the code clean? If you want to, these
are some additional things you could try:
- If you're working in a language with mutable data structures and your
implementation allows outside code to mutate the school's internal DB
directly, see if you can prevent this. Feel free to introduce additional
tests.
Then please share your thoughts in a comment on the submission. Did this
experiment make the code better? Worse? Did you learn anything from it?
* * * *
For installation and learning resources, refer to the
[exercism help page](http://exercism.io/languages/ruby).
For running the tests provided, you will need the Minitest gem. Open a
terminal window and run the following command to install minitest:
gem install minitest
If you would like color output, you can `require 'minitest/pride'` in
the test file, or note the alternative instruction, below, for running
the test file.
Run the tests from the exercise directory using the following command:
ruby grade_school_test.rb
To include color from the command line:
ruby -r minitest/pride grade_school_test.rb
## Source
A pairing session with Phil Battos at gSchool [http://gschool.it](http://gschool.it)
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

View File

@ -0,0 +1,23 @@
class School
def initialize
@grades = Hash.new {|h, k| h[k] = [] }
end
def add(name, grade)
@grades[grade] << name
end
def students(grade)
@grades[grade].sort
end
def students_by_grade
@grades.sort.reduce([]) do |memo, (k, _v)|
memo << {grade: k, students: students(k)}
end
end
end
module BookKeeping
VERSION = 3
end

View File

@ -0,0 +1,103 @@
require 'minitest/autorun'
require_relative 'grade_school'
class SchoolTest < Minitest::Test
def test_empty_grade
school = School.new
expected = []
assert_equal expected, school.students(1)
end
def test_add_student
school = School.new
assert school.add('Aimee', 2)
expected = ['Aimee']
assert_equal expected, school.students(2)
end
def test_add_students_to_different_grades
school = School.new
school.add('Aimee', 3)
school.add('Beemee', 7)
assert_equal ['Aimee'], school.students(3)
assert_equal ['Beemee'], school.students(7)
end
def test_grade_with_multiple_students
school = School.new
grade = 6
students = %w(Aimee Beemee Ceemee)
students.each { |student| school.add(student, grade) }
assert_equal students, school.students(grade)
end
def test_grade_with_multiple_students_sorts_correctly
school = School.new
grade = 6
students = %w(Beemee Aimee Ceemee)
students.each { |student| school.add(student, grade) }
expected = students.sort
assert_equal expected, school.students(grade)
end
def test_empty_students_by_grade
school = School.new
expected = []
assert_equal expected, school.students_by_grade
end
def test_students_by_grade
school = School.new
grade = 6
students = %w(Beemee Aimee Ceemee)
students.each { |student| school.add(student, grade) }
expected = [{ grade: grade, students: students.sort }]
assert_equal expected, school.students_by_grade
end
def test_students_by_grade_sorted
school = School.new
everyone.each do |grade|
grade[:students].each { |student| school.add(student, grade[:grade]) }
end
expected = everyone_sorted
assert_equal expected, school.students_by_grade
end
def everyone
[
{ grade: 3, students: %w(Deemee Eeemee) },
{ grade: 1, students: %w(Effmee Geemee) },
{ grade: 2, students: %w(Aimee Beemee Ceemee) }
]
end
def everyone_sorted
[
{ grade: 1, students: %w(Effmee Geemee) },
{ grade: 2, students: %w(Aimee Beemee Ceemee) },
{ grade: 3, students: %w(Deemee Eeemee) }
]
end
# Problems in exercism evolve over time, as we find better ways to ask
# questions.
# The version number refers to the version of the problem you solved,
# not your solution.
#
# Define a constant named VERSION inside of the top level BookKeeping
# module, which may be placed near the end of your file.
#
# In your file, it will look like this:
#
# module BookKeeping
# VERSION = 2 # Where the version number matches the one in the test.
# end
#
# If you are curious, read more about constants on RubyDoc:
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
def test_bookkeeping
assert_equal 3, BookKeeping::VERSION
end
end

View File

@ -0,0 +1,59 @@
# Phone Number
Clean up user-entered phone numbers so that they can be sent SMS messages.
The **North American Numbering Plan (NANP)** is a telephone numbering system used by many countries in North America like the United States, Canada or Bermuda. All NANP-countries share the same international country code: `1`.
NANP numbers are ten-digit numbers consisting of a three-digit Numbering Plan Area code, commonly known as *area code*, followed by a seven-digit local number. The first three digits of the local number represent the *exchange code*, followed by the unique four-digit number which is the *subscriber number*.
The format is usually represented as
```text
(NXX)-NXX-XXXX
```
where `N` is any digit from 2 through 9 and `X` is any digit from 0 through 9.
Your task is to clean up differently formatted telephone numbers by removing punctuation and the country code (1) if present.
For example, the inputs
- `+1 (613)-995-0253`
- `613-995-0253`
- `1 613 995 0253`
- `613.995.0253`
should all produce the output
`6139950253`
**Note:** As this exercise only deals with telephone numbers used in NANP-countries, only 1 is considered a valid country code.
* * * *
For installation and learning resources, refer to the
[exercism help page](http://exercism.io/languages/ruby).
For running the tests provided, you will need the Minitest gem. Open a
terminal window and run the following command to install minitest:
gem install minitest
If you would like color output, you can `require 'minitest/pride'` in
the test file, or note the alternative instruction, below, for running
the test file.
Run the tests from the exercise directory using the following command:
ruby phone_number_test.rb
To include color from the command line:
ruby -r minitest/pride phone_number_test.rb
## Source
Event Manager by JumpstartLab [http://tutorials.jumpstartlab.com/projects/eventmanager.html](http://tutorials.jumpstartlab.com/projects/eventmanager.html)
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

View File

@ -0,0 +1,16 @@
class PhoneNumber
def self.clean(num)
cl = num.scan(/\d/).join
invalid?(num) ? nil : cl
end
def self.invalid?(num)
if num.start_with?("1")
num.size == 11
end
end
end
module BookKeeping
VERSION = 2
end

View File

@ -0,0 +1,75 @@
require 'minitest/autorun'
require_relative 'phone_number'
# Common test data version: 1.2.0 39cba0d
class PhoneNumberTest < Minitest::Test
def test_cleans_the_number
# skip
assert_equal "2234567890", PhoneNumber.clean("(223) 456-7890")
end
def test_cleans_numbers_with_dots
assert_equal "2234567890", PhoneNumber.clean("223.456.7890")
end
def test_cleans_numbers_with_multiple_spaces
assert_equal "2234567890", PhoneNumber.clean("223 456 7890 ")
end
def test_invalid_when_9_digits
assert_nil PhoneNumber.clean("123456789")
end
def test_invalid_when_11_digits_does_not_start_with_a_1
assert_nil PhoneNumber.clean("22234567890")
end
def test_valid_when_11_digits_and_starting_with_1
assert_equal "2234567890", PhoneNumber.clean("12234567890")
end
def test_valid_when_11_digits_and_starting_with_1_even_with_punctuation
assert_equal "2234567890", PhoneNumber.clean("+1 (223) 456-7890")
end
def test_invalid_when_more_than_11_digits
assert_nil PhoneNumber.clean("321234567890")
end
def test_invalid_with_letters
assert_nil PhoneNumber.clean("123-abc-7890")
end
def test_invalid_with_punctuations
assert_nil PhoneNumber.clean("123-@:!-7890")
end
def test_invalid_if_area_code_does_not_start_with_2_9
assert_nil PhoneNumber.clean("(123) 456-7890")
end
def test_invalid_if_exchange_code_does_not_start_with_2_9
assert_nil PhoneNumber.clean("(223) 056-7890")
end
# Problems in exercism evolve over time, as we find better ways to ask
# questions.
# The version number refers to the version of the problem you solved,
# not your solution.
#
# Define a constant named VERSION inside of the top level BookKeeping
# module, which may be placed near the end of your file.
#
# In your file, it will look like this:
#
# module BookKeeping
# VERSION = 1 # Where the version number matches the one in the test.
# end
#
# If you are curious, read more about constants on RubyDoc:
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
def test_bookkeeping
assert_equal 2, BookKeeping::VERSION
end
end

View File

@ -8,8 +8,7 @@ class Complement
def self.of_dna(dna)
dna.each_char.reduce("") do |memo, char|
break "" unless PAIRS.key?(char)
memo + PAIRS[char]
memo << (PAIRS[char] or break "")
end
end
end

View File

@ -0,0 +1,54 @@
# Run Length Encoding
Implement run-length encoding and decoding.
Run-length encoding (RLE) is a simple form of data compression, where runs
(consecutive data elements) are replaced by just one data value and count.
For example we can represent the original 53 characters with only 13.
```text
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" -> "12WB12W3B24WB"
```
RLE allows the original data to be perfectly reconstructed from
the compressed data, which makes it a lossless data compression.
```text
"AABCCCDEEEE" -> "2AB3CD4E" -> "AABCCCDEEEE"
```
For simplicity, you can assume that the unencoded string will only contain
the letters A through Z (either lower or upper case) and whitespace. This way
data to be encoded will never contain any numbers and numbers inside data to
be decoded always represent the count for the following character.
* * * *
For installation and learning resources, refer to the
[exercism help page](http://exercism.io/languages/ruby).
For running the tests provided, you will need the Minitest gem. Open a
terminal window and run the following command to install minitest:
gem install minitest
If you would like color output, you can `require 'minitest/pride'` in
the test file, or note the alternative instruction, below, for running
the test file.
Run the tests from the exercise directory using the following command:
ruby run_length_encoding_test.rb
To include color from the command line:
ruby -r minitest/pride run_length_encoding_test.rb
## Source
Wikipedia [https://en.wikipedia.org/wiki/Run-length_encoding](https://en.wikipedia.org/wiki/Run-length_encoding)
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

View File

@ -0,0 +1,15 @@
class RunLengthEncoding
def self.encode(str)
str.chars.chunk(&:itself).map{|c, a| [a.size > 1 ? a.size : nil, c]}.join
end
def self.decode(str)
str.scan(/(\d*)(\D)/).reduce('') do |res, (n, chr) |
res << (n.empty? ? chr : chr * n.to_i)
end
end
end
module BookKeeping
VERSION = 3
end

View File

@ -0,0 +1,106 @@
require 'minitest/autorun'
require_relative 'run_length_encoding'
# Common test data version: 1.0.0 503a57a
class RunLengthEncodingTest < Minitest::Test
def test_encode_empty_string
# skip
input = ''
output = ''
assert_equal output, RunLengthEncoding.encode(input)
end
def test_encode_single_characters_only_are_encoded_without_count
input = 'XYZ'
output = 'XYZ'
assert_equal output, RunLengthEncoding.encode(input)
end
def test_encode_string_with_no_single_characters
input = 'AABBBCCCC'
output = '2A3B4C'
assert_equal output, RunLengthEncoding.encode(input)
end
def test_encode_single_characters_mixed_with_repeated_characters
input = 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB'
output = '12WB12W3B24WB'
assert_equal output, RunLengthEncoding.encode(input)
end
def test_encode_multiple_whitespace_mixed_in_string
input = ' hsqq qww '
output = '2 hs2q q2w2 '
assert_equal output, RunLengthEncoding.encode(input)
end
def test_encode_lowercase_characters
input = 'aabbbcccc'
output = '2a3b4c'
assert_equal output, RunLengthEncoding.encode(input)
end
def test_decode_empty_string
input = ''
output = ''
assert_equal output, RunLengthEncoding.decode(input)
end
def test_decode_single_characters_only
input = 'XYZ'
output = 'XYZ'
assert_equal output, RunLengthEncoding.decode(input)
end
def test_decode_string_with_no_single_characters
input = '2A3B4C'
output = 'AABBBCCCC'
assert_equal output, RunLengthEncoding.decode(input)
end
def test_decode_single_characters_with_repeated_characters
input = '12WB12W3B24WB'
output = 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB'
assert_equal output, RunLengthEncoding.decode(input)
end
def test_decode_multiple_whitespace_mixed_in_string
input = '2 hs2q q2w2 '
output = ' hsqq qww '
assert_equal output, RunLengthEncoding.decode(input)
end
def test_decode_lower_case_string
input = '2a3b4c'
output = 'aabbbcccc'
assert_equal output, RunLengthEncoding.decode(input)
end
def test_consistency_encode_followed_by_decode_gives_original_string
input = 'zzz ZZ zZ'
output = 'zzz ZZ zZ'
assert_equal output,
RunLengthEncoding.decode(RunLengthEncoding.encode(input))
end
# Problems in exercism evolve over time, as we find better ways to ask
# questions.
# The version number refers to the version of the problem you solved,
# not your solution.
#
# Define a constant named VERSION inside of the top level BookKeeping
# module, which may be placed near the end of your file.
#
# In your file, it will look like this:
#
# module BookKeeping
# VERSION = 1 # Where the version number matches the one in the test.
# end
#
# If you are curious, read more about constants on RubyDoc:
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
def test_bookkeeping
assert_equal 3, BookKeeping::VERSION
end
end

51
ruby/series/README.md Normal file
View File

@ -0,0 +1,51 @@
# Series
Given a string of digits, output all the contiguous substrings of length `n` in
that string.
For example, the string "49142" has the following 3-digit series:
- 491
- 914
- 142
And the following 4-digit series:
- 4914
- 9142
And if you ask for a 6-digit series from a 5-digit string, you deserve
whatever you get.
Note that these series are only required to occupy *adjacent positions*
in the input; the digits need not be *numerically consecutive*.
* * * *
For installation and learning resources, refer to the
[exercism help page](http://exercism.io/languages/ruby).
For running the tests provided, you will need the Minitest gem. Open a
terminal window and run the following command to install minitest:
gem install minitest
If you would like color output, you can `require 'minitest/pride'` in
the test file, or note the alternative instruction, below, for running
the test file.
Run the tests from the exercise directory using the following command:
ruby series_test.rb
To include color from the command line:
ruby -r minitest/pride series_test.rb
## Source
A subset of the Problem 8 at Project Euler [http://projecteuler.net/problem=8](http://projecteuler.net/problem=8)
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

10
ruby/series/series.rb Normal file
View File

@ -0,0 +1,10 @@
class Series
def initialize(series)
@chars = series.chars
end
def slices(num)
raise ArgumentError if num > @chars.size
@chars.each_cons(num).map(&:join)
end
end

View File

@ -0,0 +1,88 @@
require 'minitest/autorun'
require_relative 'series'
class SeriesTest < Minitest::Test
def test_simple_slices_of_one
series = Series.new('01234')
assert_equal ['0', '1', '2', '3', '4'], series.slices(1)
end
def test_simple_slices_of_one_again
series = Series.new('92834')
assert_equal ['9', '2', '8', '3', '4'], series.slices(1)
end
def test_simple_slices_of_two
series = Series.new('01234')
assert_equal ['01', '12', '23', '34'], series.slices(2)
end
def test_other_slices_of_two
series = Series.new('98273463')
expected = ['98', '82', '27', '73', '34', '46', '63']
assert_equal expected, series.slices(2)
end
def test_simple_slices_of_two_again
series = Series.new('37103')
assert_equal ['37', '71', '10', '03'], series.slices(2)
end
def test_simple_slices_of_three
series = Series.new('01234')
assert_equal ['012', '123', '234'], series.slices(3)
end
def test_simple_slices_of_three_again
series = Series.new('31001')
assert_equal ['310', '100', '001'], series.slices(3)
end
def test_other_slices_of_three
series = Series.new('982347')
expected = ['982', '823', '234', '347']
assert_equal expected, series.slices(3)
end
def test_simple_slices_of_four
series = Series.new('01234')
assert_equal ['0123', '1234'], series.slices(4)
end
def test_simple_slices_of_four_again
series = Series.new('91274')
assert_equal ['9127', '1274'], series.slices(4)
end
def test_simple_slices_of_five
series = Series.new('01234')
assert_equal ['01234'], series.slices(5)
end
def test_simple_slices_of_five_again
series = Series.new('81228')
assert_equal ['81228'], series.slices(5)
end
def test_simple_slice_that_blows_up
series = Series.new('01234')
assert_raises ArgumentError do
series.slices(6)
end
end
def test_more_complicated_slice_that_blows_up
slice_string = '01032987583'
series = Series.new(slice_string)
assert_raises ArgumentError do
series.slices(slice_string.length + 1)
end
end
def test_sequential_slices
series = Series.new('1234')
assert_equal ['12', '23', '34'], series.slices(2)
assert_equal ['123', '234'], series.slices(3)
end
end

View File

@ -0,0 +1,39 @@
# Sum Of Multiples
Given a number, find the sum of all the unique multiples of particular numbers up to
but not including that number.
If we list all the natural numbers below 20 that are multiples of 3 or 5,
we get 3, 5, 6, 9, 10, 12, 15, and 18.
The sum of these multiples is 78.
* * * *
For installation and learning resources, refer to the
[exercism help page](http://exercism.io/languages/ruby).
For running the tests provided, you will need the Minitest gem. Open a
terminal window and run the following command to install minitest:
gem install minitest
If you would like color output, you can `require 'minitest/pride'` in
the test file, or note the alternative instruction, below, for running
the test file.
Run the tests from the exercise directory using the following command:
ruby sum_of_multiples_test.rb
To include color from the command line:
ruby -r minitest/pride sum_of_multiples_test.rb
## Source
A variation on Problem 1 at Project Euler [http://projecteuler.net/problem=1](http://projecteuler.net/problem=1)
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

View File

@ -0,0 +1,13 @@
class SumOfMultiples
def initialize(*nums)
@mults = nums
end
def to(max)
(0...max).select{|c| @mults.any?{|m| c % m == 0}}.sum
end
end
module BookKeeping
VERSION = 2
end

View File

@ -0,0 +1,79 @@
require 'minitest/autorun'
require_relative 'sum_of_multiples'
# Common test data version: 1.1.0 df076b2
class SumOfMultiplesTest < Minitest::Test
def test_multiples_of_3_or_5_up_to_1
# skip
assert_equal 0, SumOfMultiples.new(3, 5).to(1)
end
def test_multiples_of_3_or_5_up_to_4
assert_equal 3, SumOfMultiples.new(3, 5).to(4)
end
def test_multiples_of_3_up_to_7
assert_equal 9, SumOfMultiples.new(3).to(7)
end
def test_multiples_of_3_or_5_up_to_10
assert_equal 23, SumOfMultiples.new(3, 5).to(10)
end
def test_multiples_of_3_or_5_up_to_100
assert_equal 2_318, SumOfMultiples.new(3, 5).to(100)
end
def test_multiples_of_3_or_5_up_to_1000
assert_equal 233_168, SumOfMultiples.new(3, 5).to(1000)
end
def test_multiples_of_7_13_or_17_up_to_20
assert_equal 51, SumOfMultiples.new(7, 13, 17).to(20)
end
def test_multiples_of_4_or_6_up_to_15
assert_equal 30, SumOfMultiples.new(4, 6).to(15)
end
def test_multiples_of_5_6_or_8_up_to_150
assert_equal 4_419, SumOfMultiples.new(5, 6, 8).to(150)
end
def test_multiples_of_5_or_25_up_to_51
assert_equal 275, SumOfMultiples.new(5, 25).to(51)
end
def test_multiples_of_43_or_47_up_to_10000
assert_equal 2_203_160, SumOfMultiples.new(43, 47).to(10000)
end
def test_multiples_of_1_up_to_100
assert_equal 4_950, SumOfMultiples.new(1).to(100)
end
def test_multiples_of_an_empty_list_up_to_10000
assert_equal 0, SumOfMultiples.new().to(10000)
end
# Problems in exercism evolve over time, as we find better ways to ask
# questions.
# The version number refers to the version of the problem you solved,
# not your solution.
#
# Define a constant named VERSION inside of the top level BookKeeping
# module, which may be placed near the end of your file.
#
# In your file, it will look like this:
#
# module BookKeeping
# VERSION = 1 # Where the version number matches the one in the test.
# end
#
# If you are curious, read more about constants on RubyDoc:
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
def test_bookkeeping
assert_equal 2, BookKeeping::VERSION
end
end