Permalink
Browse files

Adds some other katas I've tried

  • Loading branch information...
MichaelBaker committed May 6, 2012
1 parent cc020f9 commit e608d56b3acb805111488f19ae734835b94e4d4f
View
@@ -0,0 +1,19 @@
+class Integer
+ def prime_factors
+ x = self
+ divisor = 2
+ primes = []
+ limit = Math.sqrt x
+ while x >= 2
+ if x % divisor == 0
+ primes << divisor
+ x = x / divisor
+ elsif divisor > limit
+ divisor = x
+ else
+ divisor = divisor + 1
+ end
+ end
+ primes
+ end
+end
@@ -0,0 +1,23 @@
+require 'minitest/autorun'
+require './primes'
+
+class PrimesTest < MiniTest::Unit::TestCase
+ def self.test_cases
+ [[0, []],
+ [1, []],
+ [2, [2]],
+ [3, [3]],
+ [4, [2, 2]],
+ [5, [5]],
+ [7, [7]],
+ [8, [2, 2, 2]],
+ [9, [3, 3]],
+ [10, [2, 5]]]
+ end
+
+ test_cases.each do |number, primes|
+ define_method "test_#{number}" do
+ assert_equal(primes, number.prime_factors)
+ end
+ end
+end
@@ -0,0 +1,4 @@
+watch ".*" do |file|
+ system "clear"
+ system "ruby primes_spec.rb"
+end
@@ -0,0 +1,4 @@
+watch ".*" do |filename|
+ system "clear"
+ system "rspec -fdocumentation string_calculator_spec.rb"
+end
@@ -0,0 +1,47 @@
+module StringCalculator
+ DEFAULT_SEPARATOR = /,|\s/
+ MULTI_CHARACTER_SEPARATOR = /\[(.*?)\]/
+ CUSTOM_SEPARATOR_LINE = /^\/\/(.*)\n/
+ VALID_NUMBERS = lambda { |number| 0 <= number && number <= 1000 }
+
+ def self.add(string)
+ numbers = string_to_list string
+ assert_no_negative_numbers numbers
+ numbers.select(&VALID_NUMBERS).reduce &:+
+ end
+
+ private
+
+ def self.string_to_list(string)
+ return [0] if string.empty?
+ string, separator = parse_string_with_separator(string) if contains_custom_separator? string
+ string.split(separator || DEFAULT_SEPARATOR).map &:to_i
+ end
+
+ def self.assert_no_negative_numbers(numbers)
+ negative_numbers = numbers.select { |number| number < 0 }
+ if negative_numbers.any?
+ raise "Negatives not allowed: #{negative_numbers.join(', ')}"
+ end
+ end
+
+ def self.parse_string_with_separator(string)
+ separator = parse_separator string[CUSTOM_SEPARATOR_LINE]
+ [string.sub(CUSTOM_SEPARATOR_LINE, ""), separator]
+ end
+
+ def self.parse_separator(line)
+ if line =~ MULTI_CHARACTER_SEPARATOR
+ Regexp.new line.scan(MULTI_CHARACTER_SEPARATOR)
+ .flatten
+ .map {|separator| Regexp.escape separator}
+ .join("|")
+ else
+ line[2]
+ end
+ end
+
+ def self.contains_custom_separator?(string)
+ string.start_with? "//"
+ end
+end
@@ -0,0 +1,47 @@
+require './string_calculator'
+
+describe StringCalculator do
+ describe ".add" do
+ it "sums a list of numbers separated by commas or newlines" do
+ StringCalculator.add("1,2").should == 3
+ StringCalculator.add("1,2,3").should == 6
+ StringCalculator.add("1,1,1,1").should == 4
+ StringCalculator.add("1,"*100).should == 100
+ StringCalculator.add("1\n2").should == 3
+ StringCalculator.add("1\n2\n2").should == 5
+ StringCalculator.add("1,2\n5").should == 8
+ end
+
+ context "accepts user defined delimiters on the first line of the string" do
+ it "of a single character in the form //<delimiter>" do
+ StringCalculator.add("//;\n1;2").should == 3
+ end
+
+ it "of multiple characters in the form //[<characters>]" do
+ StringCalculator.add("//[***]\n1***2").should == 3
+ end
+
+ it "multiple delimiters in the form //[<delimeter1>][<delimeter2>]" do
+ StringCalculator.add("//[*][%]\n1*2%3").should == 6
+ StringCalculator.add("//[**][%]\n1**2%3").should == 6
+ StringCalculator.add("//[!!!][&*]\n1&*2!!!3").should == 6
+ end
+ end
+
+ it "rejects negative numbers with an exception that includes the offending numbers" do
+ expect { StringCalculator.add("-1").should }.to raise_error /-1/
+ end
+
+ it "ignores numbers greater than 1000" do
+ StringCalculator.add("2,1001").should == 2
+ end
+
+ it "considers the empty string to sum to zero" do
+ StringCalculator.add("").should == 0
+ end
+
+ it "considers a list of one element to sum to itself" do
+ StringCalculator.add("1").should == 1
+ end
+ end
+end
@@ -0,0 +1,4 @@
+watch ".*" do |filename|
+ system "clear"
+ system "rspec -fdocumentation string_calculator_spec.rb"
+end
@@ -0,0 +1,56 @@
+class StringCalculator
+ def initialize(string)
+ self.original_string = string
+ self.string = string.dup
+ extract_separator
+ extract_numbers
+ assert_no_negatives
+ filter_out_large_numbers
+ end
+
+ def add
+ return 0 if string.empty?
+ numbers.reduce &:+
+ end
+
+ private
+
+ attr_accessor :string, :separator, :numbers, :original_string
+
+ def extract_separator
+ self.separator = /,|\n/
+ extract_custom_separator if custom_separator?
+ end
+
+ def extract_custom_separator
+ if string.start_with? "//["
+ self.separator = Regexp.new string.scan(/\[(.+?)\]/)
+ .flatten
+ .map { |separator| Regexp.escape separator }
+ .join("|")
+ else
+ self.separator = string[2]
+ end
+ string.sub!(/\/\/.*\n/, "")
+ end
+
+ def custom_separator?
+ string.start_with? "//"
+ end
+
+ def extract_numbers
+ self.numbers = string.split(separator).map &:to_i
+ end
+
+ def assert_no_negatives
+ raise "No negatives #{negative_numbers.join ', '}" if negative_numbers.any?
+ end
+
+ def filter_out_large_numbers
+ numbers.select! { |number| 0 <= number && number <= 1000 }
+ end
+
+ def negative_numbers
+ numbers.select { |number| number < 0 }
+ end
+end
@@ -0,0 +1,50 @@
+require './string_calculator'
+
+describe StringCalculator do
+ describe "#add sums a stringified list of numbers" do
+ describe "accepts lists separated by" do
+ it "commas" do
+ StringCalculator.new("1,2").add.should == 3
+ StringCalculator.new("1,2,3").add.should == 6
+ StringCalculator.new("1,"*100).add.should == 100
+ end
+
+ it "new-lines" do
+ StringCalculator.new("1\n2").add.should == 3
+ StringCalculator.new("1\n2\n2").add.should == 5
+ StringCalculator.new("1\n"*50).add.should == 50
+ end
+ end
+
+ describe "accepts a custom separator on the first line of the string" do
+ specify "a single character in the form //<separator>" do
+ StringCalculator.new("//;\n1;2").add.should == 3
+ end
+
+ specify "multiple characters in the form //[<characters]" do
+ StringCalculator.new("//[***]\n1***2").add.should == 3
+ end
+
+ specify "multiple separators in the form //[<separator1>][<separator2>]" do
+ StringCalculator.new("//[&][%]\n1&2%3").add.should == 6
+ StringCalculator.new("//[&!][%]\n1&!2%3").add.should == 6
+ end
+ end
+
+ it "ignores numbers greater than 1000" do
+ StringCalculator.new("1,1001").add.should == 1
+ end
+
+ it "raises an error for negative numbers" do
+ expect { StringCalculator.new("-1").add }.to raise_error /-1/
+ end
+
+ it "considers the empty string to be zero" do
+ StringCalculator.new("").add.should == 0
+ end
+
+ it "considers a list of one number to sum to itself" do
+ StringCalculator.new("1").add.should == 1
+ end
+ end
+end
@@ -0,0 +1,4 @@
+watch ".*" do |filename|
+ system "clear"
+ system "rspec -fdocumentation string_calculator_spec.rb"
+end
@@ -0,0 +1,9 @@
+module StringCalculator
+ def self.add(string)
+ return 0 if string.empty?
+ numbers = string.split(/[^-0-9]/).map(&:to_i)
+ negative_numbers = numbers.select {|number| number < 0}
+ raise "No negatives #{negative_numbers.join(", ")}" if negative_numbers.any?
+ numbers.reduce &:+
+ end
+end
@@ -0,0 +1,30 @@
+require './string_calculator'
+
+describe StringCalculator do
+ describe ".add" do
+ context "sums a string of numbers separated by" do
+ it "commas" do
+ StringCalculator.add("1,2").should == 3
+ end
+
+ it "new-lines" do
+ StringCalculator.add("1\n2").should == 3
+ end
+ end
+
+ it "rejects negative numbers with an exception" do
+ expect { StringCalculator.add("-1") }.to raise_error /-1/
+ end
+
+ context "considers" do
+ it "the empty string to be zero" do
+ StringCalculator.add("").should == 0
+ end
+
+ it "a single number to sum to itself" do
+ StringCalculator.add("1").should == 1
+ StringCalculator.add("2").should == 2
+ end
+ end
+ end
+end
@@ -0,0 +1,4 @@
+watch ".*" do |file|
+ system "clear"
+ system "ruby word-morph.rb"
+end
View
@@ -0,0 +1,12 @@
+require "rspec"
+require "./word-morph"
+
+describe "returns a set of steps that morphs the receiver into the argument" do
+ specify "a -> I" do
+ "a".morph_into("I").should == ["a", "I"]
+ end
+
+ specify "ann -> ebb" do
+ "ann".morph_into("ebb").should == ["ann", kkkkkk, "ebb"]
+ end
+end
Oops, something went wrong.

0 comments on commit e608d56

Please sign in to comment.