Skip to content

Instantly share code, notes, and snippets.

@rpbaptist
Last active February 21, 2020 13:09
Show Gist options
  • Save rpbaptist/e99a53d1c0c9c5d64a74cc9a042fd01f to your computer and use it in GitHub Desktop.
Save rpbaptist/e99a53d1c0c9c5d64a74cc9a042fd01f to your computer and use it in GitHub Desktop.
Spreadsheet column calculation in Ruby
# frozen_string_literal: true
class XlsxColumns
attr_reader :position
ALPHABET = ("A".."Z").to_a
class << self
def column(position)
if position > max_position
raise ArgumentError, "Position must be #{max_position} or lower"
elsif position <= ALPHABET.length
letter_from_position(position)
else
letter_with_prefix(position)
end
end
private
def letter_with_prefix(position)
prefix_index = position / letter_count
adjusted_position = position % letter_count
prefix = letter_from_position(prefix_index)
letter = letter_from_position(adjusted_position)
prefix + letter
end
# It would be possible to make this recursive, but not really necessary.
def max_position
letter_count * letter_count
end
def letter_from_position(position)
ALPHABET[position - 1]
end
def letter_count
ALPHABET.length
end
end
end
# frozen_string_literal: true
require "spec_helper"
require "xlsx_columns"
RSpec.describe XlsxColumns do
describe "#column" do
context "when position below 26" do
it "returns the corresponding letter" do
expect(described_class.column(3)).to eql("C")
expect(described_class.column(26)).to eql("Z")
end
end
context "when position is above 26" do
it "returns a combination of letters" do
expect(described_class.column(27)).to eql("AA")
expect(described_class.column(56)).to eql("BD")
expect(described_class.column(456)).to eql("QN")
expect(described_class.column(676)).to eql("ZZ")
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment