print_square 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .*.swp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.rvmrc ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
+ # Only full ruby name is supported here, for short names use:
8
+ # echo "rvm use 1.9.3" > .rvmrc
9
+ environment_id="ruby-1.9.3-p286@print_square"
10
+
11
+ # Uncomment the following lines if you want to verify rvm version per project
12
+ # rvmrc_rvm_version="1.16.19 (stable)" # 1.10.1 seams as a safe start
13
+ # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
+ # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
+ # return 1
16
+ # }
17
+
18
+ # First we attempt to load the desired environment directly from the environment
19
+ # file. This is very fast and efficient compared to running through the entire
20
+ # CLI and selector. If you want feedback on which environment was used then
21
+ # insert the word 'use' after --create as this triggers verbose mode.
22
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
+ then
25
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
+ [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
27
+ \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
28
+ if [[ $- == *i* ]] # check for interactive shells
29
+ then echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
30
+ else echo "Using: $GEM_HOME" # don't use colors in non-interactive shells
31
+ fi
32
+ else
33
+ # If the environment file has not yet been created, use the RVM CLI to select.
34
+ rvm --create use "$environment_id" || {
35
+ echo "Failed to create RVM environment '${environment_id}'."
36
+ return 1
37
+ }
38
+ fi
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in print_square.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem 'rspec'
8
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Chris Boertien
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # PrintSquare
2
+
3
+ Prints a square of numbers. The command takes a square number and prints out a pattern, starting with 1 in the middle and spiraling outwards counterclockwise.
4
+
5
+ ## Installation
6
+
7
+ $ gem install print_square
8
+
9
+ ## Usage
10
+
11
+ $ print_square 16
12
+ 16 15 14 13
13
+ 5 4 3 12
14
+ 6 1 2 11
15
+ 7 8 9 10
16
+
17
+ ## Contributing
18
+
19
+ 1. Fork it
20
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
21
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
22
+ 4. Push to the branch (`git push origin my-new-feature`)
23
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/print_square ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'print_square'
4
+
5
+ PrintSquare::CommandRunner.run ARGV
@@ -0,0 +1,83 @@
1
+ module PrintSquare
2
+ class CommandRunner
3
+ class << self
4
+ def run(args)
5
+ validate_args(args)
6
+ print_square(args[0].to_i)
7
+ end
8
+
9
+ def print_square(number)
10
+ size = Math.sqrt(number).to_i
11
+ n = number
12
+ x = PrintSquare::Vector.new size.even? ? 1 : -1, size, size.even? ? 1 : 0
13
+ y = PrintSquare::Vector.new 0, size
14
+ print = PrintSquare::Printer.new size
15
+
16
+ x.turn = proc do
17
+ y.offset += 1 if x.direction == 1
18
+ y.direction = x.direction
19
+ x.direction = 0
20
+ end
21
+
22
+ y.turn = proc do
23
+ if y.direction == -1
24
+ x.size -= 1
25
+ y.size -= 1
26
+ x.offset += 1
27
+ end
28
+ x.direction = y.direction * -1
29
+ y.direction = 0
30
+ end
31
+
32
+ until n == 0
33
+ print.set x, y, n
34
+ y.direction == 0 ? x.next : y.next
35
+ n -= 1
36
+ end
37
+
38
+ print.out
39
+ end
40
+
41
+ def validate_args(args)
42
+ usage(:no_args) if args.count == 0
43
+ usage(:too_many_args) if args.count > 1
44
+ usage(:invalid_arg) unless (Integer(args[0]) rescue false)
45
+ usage(:not_square) unless is_square?(args[0].to_i)
46
+ end
47
+
48
+ def is_square?(number)
49
+ return true if number == 1
50
+ position = 2
51
+ spread = 1
52
+ until spread == 0
53
+ current_square = position*position
54
+ return true if current_square == number
55
+ if number < current_square
56
+ spread >>= 1
57
+ position -= spread
58
+ else
59
+ spread <<= 1
60
+ position += spread
61
+ end
62
+ end
63
+ false
64
+ end
65
+
66
+ def usage(error_type)
67
+ error = case error_type
68
+ when :no_args then 'Missing argument'
69
+ when :invalid_arg then 'Argument must be a number'
70
+ when :too_many_args then 'Too many arguments'
71
+ when :not_square then "Argument is not a square number"
72
+ end
73
+ puts <<-USAGE
74
+ #{error}
75
+
76
+ print_square [square_number]
77
+ USAGE
78
+
79
+ exit(-1)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,18 @@
1
+ module PrintSquare
2
+ class Printer
3
+ def initialize(size)
4
+ @matrix = (1..size).reduce([]) {|matrix,n| matrix + [(1..size).map { 0 }]}
5
+ end
6
+
7
+ def set(x, y, n)
8
+ @matrix[y.position][x.position] = n
9
+ end
10
+
11
+ def out
12
+ column_sizes = @matrix.first.map(&:to_s).map(&:size)
13
+ @matrix.each{|r| r.each_with_index{|c,i| print "#{' ' if i > 0}%#{column_sizes[i]}s" % c}; puts}
14
+ end
15
+ end
16
+
17
+ end
18
+
@@ -0,0 +1,21 @@
1
+ module PrintSquare
2
+ class Vector
3
+ attr_accessor :direction, :position, :offset, :turn, :size
4
+
5
+ def initialize(direction, size, size_offset=1)
6
+ @direction, @size, @size_offset = direction, size, size_offset
7
+ @position = size.even? ? 0 : size - 1
8
+ @offset = 0
9
+ end
10
+
11
+ def next
12
+ @position += @direction
13
+ @turn.call if bounds?
14
+ end
15
+
16
+ def bounds?
17
+ @position == (@direction == 1 ? (@size - @size_offset) : @offset)
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,3 @@
1
+ module PrintSquare
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,10 @@
1
+ require "print_square/version"
2
+ require 'active_support/dependencies/autoload'
3
+
4
+ module PrintSquare
5
+ extend ActiveSupport::Autoload
6
+
7
+ autoload :CommandRunner
8
+ autoload :Printer
9
+ autoload :Vector
10
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'print_square/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "print_square"
8
+ gem.version = PrintSquare::VERSION
9
+ gem.authors = ["Chris Boertien"]
10
+ gem.email = ["chris@aktionlab.com"]
11
+ gem.description = %q{A simple command that validates a square number and prints it in a design}
12
+ gem.summary = %q{Validates squares and prints it in a design}
13
+ gem.homepage = "http://aktionlab.com"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = ["print_square"]
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'activesupport', '~> 3.2.9'
21
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+ require 'stringio'
3
+
4
+ def capture_stdout(&block)
5
+ stdout = $stdout
6
+ out = $stdout = StringIO.new
7
+ begin
8
+ yield
9
+ rescue SystemExit
10
+ end
11
+ $stdout = stdout
12
+ out.seek(0)
13
+ out.read
14
+ end
15
+
16
+ PATTERNS = {
17
+ 1 => "1\n",
18
+ 4 => "4 3\n1 2\n",
19
+ 9 => "5 4 3\n6 1 2\n7 8 9\n",
20
+ 16 => "16 15 14 13\n 5 4 3 12\n 6 1 2 11\n 7 8 9 10\n",
21
+ 25 => "17 16 15 14 13\n18 5 4 3 12\n19 6 1 2 11\n20 7 8 9 10\n21 22 23 24 25\n",
22
+ 36 => "36 35 34 33 32 31\n17 16 15 14 13 30\n18 5 4 3 12 29\n19 6 1 2 11 28\n20 7 8 9 10 27\n21 22 23 24 25 26\n"
23
+ }
24
+
25
+ describe PrintSquare do
26
+ def squares(upto)
27
+ (1..upto).map{|n| n*n}
28
+ end
29
+
30
+ it 'with no args outputs the usage' do
31
+ result = capture_stdout { PrintSquare::CommandRunner.run [] }
32
+ result.should == capture_stdout { PrintSquare::CommandRunner.usage(:no_args) }
33
+ end
34
+
35
+ it 'with multiple args outputs the usage' do
36
+ result = capture_stdout { PrintSquare::CommandRunner.run %w(1 2) }
37
+ result.should == capture_stdout { PrintSquare::CommandRunner.usage(:too_many_args) }
38
+ end
39
+
40
+ it 'with a non integer argument outputs the usage' do
41
+ result = capture_stdout { PrintSquare::CommandRunner.run %w(foo) }
42
+ result.should == capture_stdout { PrintSquare::CommandRunner.usage(:invalid_arg) }
43
+ end
44
+
45
+ it 'outputs an error for non square numbers' do
46
+ ((1..(20*20)).to_a - squares(20)).each do |number|
47
+ result = capture_stdout { PrintSquare::CommandRunner.run [number] }
48
+ result.should == capture_stdout { PrintSquare::CommandRunner.usage(:not_square) }
49
+ end
50
+ end
51
+
52
+ it 'should not output an error for square numbers' do
53
+ squares(20).each do |n|
54
+ result = capture_stdout { PrintSquare::CommandRunner.run [n] }
55
+ result.should_not == capture_stdout { PrintSquare::CommandRunner.usage(:not_square) }
56
+ end
57
+ end
58
+
59
+ it 'should output the proper patterns for each number' do
60
+ squares(6).each do |n|
61
+ result = capture_stdout { PrintSquare::CommandRunner.run [n] }
62
+ result.should == PATTERNS[n]
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,9 @@
1
+ require 'print_square'
2
+
3
+ RSpec.configure do |config|
4
+ config.treat_symbols_as_metadata_keys_with_true_values = true
5
+ config.run_all_when_everything_filtered = true
6
+ config.filter_run :focus
7
+
8
+ config.order = 'random'
9
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: print_square
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris Boertien
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.2.9
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.9
30
+ description: A simple command that validates a square number and prints it in a design
31
+ email:
32
+ - chris@aktionlab.com
33
+ executables:
34
+ - print_square
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - .gitignore
39
+ - .rspec
40
+ - .rvmrc
41
+ - Gemfile
42
+ - LICENSE.txt
43
+ - README.md
44
+ - Rakefile
45
+ - bin/print_square
46
+ - lib/print_square.rb
47
+ - lib/print_square/command_runner.rb
48
+ - lib/print_square/printer.rb
49
+ - lib/print_square/vector.rb
50
+ - lib/print_square/version.rb
51
+ - print_square.gemspec
52
+ - spec/print_square_spec.rb
53
+ - spec/spec_helper.rb
54
+ homepage: http://aktionlab.com
55
+ licenses: []
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 1.8.24
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Validates squares and prints it in a design
78
+ test_files:
79
+ - spec/print_square_spec.rb
80
+ - spec/spec_helper.rb