require_relative 'config'
require_relative 'alphabet'

module Wixy
  class Vigenere
    ENCRYPT = 1
    DECRYPT = -1

    def initialize(config = Config.new)
      @config = config
      @alphabet = Alphabet.new ('A'..'Z')
      @key = @alphabet.sanitized_chars(config.key)
    end

    def encrypt(text)
      cleaned = @alphabet.sanitized_chars(text)
      cleaned.each_with_index.map do |char, i|
        lookup(char, i, ENCRYPT)
      end.compact.join
    end

    def decrypt(text)
      cleaned = @alphabet.sanitized_chars(text)
      cleaned.each_with_index.map do |char, i|
        lookup(char, i, DECRYPT)
      end.compact.join
    end

    def lookup(char, position, direction)
      index = @alphabet.index(char.upcase)
      shift = @alphabet.index(@key[position % @key.length])
      @alphabet[(index + shift * direction)]
    end
  end
end

require_relative 'config'
require_relative 'alphabet'

module Wixy
  class Vigenere
    def initialize(config = Config.new)
      @config = config
      @alphabet = Alphabet.new ('A'..'Z')
      @key = @alphabet.sanitized_chars(config.key)
    end

    def encrypt(text)
      shift = -> (index, offset) { index + offset }
      solve text, shift
      # lookup_with_shift text, shift
    end

    def decrypt(text)
      shift = -> (index, offset) { index - offset }
      solve text, shift
      # lookup_with_shift text, shift
    end

    def lookup_with_shift(text, shift)
      cleaned = @alphabet.sanitized_chars(text)
      cleaned.each_with_index.map do |char, i|
        lookup(char, i, shift)
      end.compact.join
    end

    def solve(text, shift)
      recurse(text.chars, 0, shift).reverse.join
    end

    def recurse(text, i, shift)
      return text if text.empty?
      char = text.shift
      if @alphabet.index(char)
        recurse(text, i + 1, shift) << lookup(char, i, shift)
      else
        recurse(text, i, shift) << char
      end
    end

    def lookup(char, position, shift)
      index = @alphabet.index(char.upcase)
      offset = @alphabet.index(@key[position % @key.length])
      new_index = shift.call(index, offset)
      @alphabet[new_index]
    end
  end
end

Add recursive solver for Vigenere
Add recursive solver for Vigenere
