Browse files

Add some actual functionality.

  • Loading branch information...
1 parent 57dd604 commit f0248a654a115f564362fd2f2c8e1e07bedcea2a @gabebw committed Apr 7, 2012
Showing with 104 additions and 0 deletions.
  1. +2 −0 Gemfile
  2. +12 −0 Gemfile.lock
  3. +6 −0 Rakefile
  4. +17 −0 lib/decoder.rb
  5. +28 −0 lib/encoder.rb
  6. +17 −0 spec/lib/decoder_spec.rb
  7. +17 −0 spec/lib/encoder_spec.rb
  8. +5 −0 spec/spec_helper.rb
View
2 Gemfile
@@ -2,3 +2,5 @@ source :rubygems
gem 'sinatra', '~> 1.3.2'
gem 'redis', '~> 2.2.2'
+gem 'rspec', '~> 2.9.0'
+gem 'rake', '~> 0.9.2'
View
12 Gemfile.lock
@@ -1,10 +1,20 @@
GEM
remote: http://rubygems.org/
specs:
+ diff-lcs (1.1.3)
rack (1.4.1)
rack-protection (1.2.0)
rack
+ rake (0.9.2.2)
redis (2.2.2)
+ rspec (2.9.0)
+ rspec-core (~> 2.9.0)
+ rspec-expectations (~> 2.9.0)
+ rspec-mocks (~> 2.9.0)
+ rspec-core (2.9.0)
+ rspec-expectations (2.9.1)
+ diff-lcs (~> 1.1.3)
+ rspec-mocks (2.9.0)
sinatra (1.3.2)
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)
@@ -15,5 +25,7 @@ PLATFORMS
ruby
DEPENDENCIES
+ rake (~> 0.9.2)
redis (~> 2.2.2)
+ rspec (~> 2.9.0)
sinatra (~> 1.3.2)
View
6 Rakefile
@@ -0,0 +1,6 @@
+require 'bundler/setup'
+require 'rspec/core/rake_task'
+
+RSpec::Core::RakeTask.new
+
+task :default => [:spec]
View
17 lib/decoder.rb
@@ -0,0 +1,17 @@
+# http://stackoverflow.com/questions/742013/how-to-code-a-url-shortener
+class Decoder
+ def initialize(id)
+ @id = id
+ end
+
+ def decode
+ sum = 0
+ @id.split('').map do |chunk|
+ Encoder::CHARS.index(chunk)
+ end.reverse.each_with_index do |chunk, i|
+ sum += chunk * Encoder::BASE ** i
+ end
+
+ sum
+ end
+end
View
28 lib/encoder.rb
@@ -0,0 +1,28 @@
+# http://stackoverflow.com/questions/742013/how-to-code-a-url-shortener
+class Encoder
+ CHARS = ('a'..'z').to_a +
+ ('A'..'Z').to_a +
+ (0..9).to_a.map(&:to_s)
+ BASE = CHARS.size
+
+ def initialize(id)
+ @id = id
+ end
+
+ def encode
+ char_indexes.map { |index| CHARS[index] }.join
+ end
+
+ private
+
+ def char_indexes
+ id = @id
+ digits = []
+ while id > 0
+ remainder = id % BASE
+ digits << remainder
+ id /= BASE
+ end
+ digits.reverse
+ end
+end
View
17 spec/lib/decoder_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe Decoder do
+ it 'transforms alphanumeric hashes into IDs' do
+ Decoder.new('cb').decode.should == 125
+ end
+
+ it 'transforms alphanumeric hashes into large IDs' do
+ large_id = 4 * Encoder::BASE**2 + 61 * Encoder::BASE + 0
+ Decoder.new('e9a').decode.should == large_id
+ end
+
+ it 'returns the same result twice' do
+ Decoder.new('cb').decode
+ Decoder.new('cb').decode.should == 125
+ end
+end
View
17 spec/lib/encoder_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe Encoder do
+ it 'transforms IDs into alphanumeric hashes' do
+ Encoder.new(125).encode.should == 'cb'
+ end
+
+ it 'transforms large IDs into alphanumeric hashes' do
+ large_id = 4 * Encoder::BASE**2 + 61*Encoder::BASE + 0
+ Encoder.new(large_id).encode.should == 'e9a'
+ end
+
+ it 'returns the same result twice' do
+ Encoder.new(125).encode
+ Encoder.new(125).encode.should == 'cb'
+ end
+end
View
5 spec/spec_helper.rb
@@ -0,0 +1,5 @@
+$LOAD_PATH << File.expand_path('../lib', __FILE__)
+
+require 'rspec'
+require 'encoder'
+require 'decoder'

0 comments on commit f0248a6

Please sign in to comment.