Permalink
Browse files

Initial

  • Loading branch information...
0 parents commit 2c13ae0145fa5b5b3ad8b9586c08691ca3c2db95 @joshuaclayton committed Aug 28, 2010
Showing with 125,209 additions and 0 deletions.
  1. +12 −0 .gitignore
  2. +22 −0 MIT-LICENSE
  3. +20 −0 README.markdown
  4. +14 −0 Rakefile
  5. +1 −0 cucumber.yml
  6. +2 −0 ext/sieve/extconf.rb
  7. +44 −0 ext/sieve/sieve.c
  8. +4 −0 ext/sieve/sieve.h
  9. +24 −0 features/sieve.feature
  10. +29 −0 features/step_definitions/sieve_steps.rb
  11. +3 −0 features/support/env.rb
  12. +125,000 −0 features/support/primes.txt
  13. +4 −0 lib/sieve.rb
  14. +30 −0 sieve.gemspec
@@ -0,0 +1,12 @@
+lib/sieve/sieve.bundle
+
+tmp/*
+*.DS_Store
+coverage/*
+*.swp
+*.swo
+rerun.txt
+pkg/*
+*.gem
+
+!.keep
@@ -0,0 +1,22 @@
+Copyright (c) 2010 Josh Clayton
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,20 @@
+# Sieve of Eratosthenes
+
+## A Ruby gem for easy sieving
+
+## Install
+
+Install with Rubygems:
+
+ gem install sieve
+
+## Usage
+
+A method is added to the Numeric class.
+
+ 5.sieve # [2, 3, 5]
+ 20.sieve # [2, 3, 5, 7, 11, 13, 17]
+
+## Author
+
+Written by Josh Clayton
@@ -0,0 +1,14 @@
+require "rubygems"
+require "rake"
+
+require "rake/extensiontask"
+Rake::ExtensionTask.new("sieve") do |extension|
+ extension.lib_dir = "lib/sieve"
+end
+
+require "cucumber/rake/task"
+Cucumber::Rake::Task.new(:cucumber => [:clean, :compile]) do |t|
+ t.rcov = true
+end
+
+task :default => :cucumber
@@ -0,0 +1 @@
+default: features
@@ -0,0 +1,2 @@
+require "mkmf"
+create_makefile("sieve/sieve")
@@ -0,0 +1,44 @@
+#include <ruby.h>
+#include <math.h>
+#include "sieve.h"
+
+void Init_sieve() {
+ VALUE rb_mSieve = rb_define_module("Sieve");
+ VALUE numeric = rb_define_class("Numeric", rb_cObject);
+ rb_define_method(rb_mSieve, "sieve", sieve, 0);
+ rb_include_module(numeric, rb_mSieve);
+}
+
+VALUE sieve(VALUE self) {
+ long number = rb_num2long(self) + 1;
+ long *numbers = malloc(number * sizeof(long));
+
+ if(numbers == NULL) { return Qnil; }
+
+ long i;
+ for(i = 0; i < number; i++) {
+ numbers[i] = i;
+ }
+ numbers[0] = numbers[1] = -1;
+
+ for(i = 0; i < number; i++) {
+ long current_sq = powl(i, 2);
+ if(numbers[i] == -1) { continue; }
+ if(current_sq > number) { break; }
+
+ long n;
+ for(n = current_sq; n < number; n += i) {
+ numbers[n] = -1;
+ }
+ }
+
+ VALUE primes_array = rb_ary_new();
+ for(i = 0; i < number; i++) {
+ if(numbers[i] != -1) {
+ rb_ary_push(primes_array, LONG2FIX(numbers[i]));
+ }
+ }
+
+ free(numbers);
+ return primes_array;
+}
@@ -0,0 +1,4 @@
+#ifndef __sieve_h__
+#define __sieve_h__
+VALUE sieve(VALUE);
+#endif
@@ -0,0 +1,24 @@
+Feature: Sieve of Eratosthenes
+ In order to kick ass at finding primes
+ As a developer
+ I should be able to call a sieve on a numeric to find its primes
+
+ Scenario Outline: Find primes effectively
+ When I run a sieve on <number>
+ Then I should have the primes <primes>
+ Examples:
+ | number | primes |
+ | 2 | 2 |
+ | 3 | 2,3 |
+ | 4 | 2,3 |
+ | 5 | 2,3,5 |
+ | 19 | 2,3,5,7,11,13,17,19 |
+ | 20 | 2,3,5,7,11,13,17,19 |
+ | 29 | 2,3,5,7,11,13,17,19,23,29 |
+ | 30 | 2,3,5,7,11,13,17,19,23,29 |
+ | 110 | 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109 |
+
+ Scenario: Prime tables
+ When I load all the primes from "features/support/primes.txt"
+ And I run a sieve on the last number
+ Then I should have all primes from "features/support/primes.txt"
@@ -0,0 +1,29 @@
+When /^I run a sieve on (\d+)$/ do |number|
+ @result = number.to_i.sieve
+end
+
+Then /^I should have the primes (.*)$/ do |primes|
+ @primes = primes.split(",").map(&:strip).map(&:to_i)
+ @result.should == @primes
+end
+
+When /^I load all the primes from "([^"]*)"$/ do |path|
+ @primes = prime_file_process(path)
+ @primes.should_not be_empty
+end
+
+When /^I run a sieve on the last number$/ do
+ @result = @primes.last.sieve
+end
+
+Then /^I should have all primes from "([^"]*)"$/ do |path|
+ Then %{I should have the primes #{prime_file_process(path).join(",")}}
+end
+
+module PrimeFileProcessor
+ def prime_file_process(path)
+ File.new(path).read.strip.split(/\s+/).map(&:to_i)
+ end
+end
+
+World(PrimeFileProcessor)
@@ -0,0 +1,3 @@
+$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
+require "sieve"
+require "spec/expectations"
Oops, something went wrong. Retry.

0 comments on commit 2c13ae0

Please sign in to comment.