<commit_before>class Alphabet
  # chars is an array of character strings, like ["A", "B", "C" ...]
  def initialize(chars, options = {})
    @chars = chars.to_a.rotate(options[:shift] || 0)
    @index = Hash[@chars.each_with_index.to_a]
  end

  def [](index)
    @chars[index]
  end

  def index(char)
    i = @index[char]
  end

  def sanitized_chars(text)
    text.upcase.chars.map { |c| char_if_present(c) }.compact
  end

  def substitute(char, other_alphabet)
    other_alphabet[index(char)]
  end

  def to_s
    "<Alphabet '#{@chars.join}'>"
  end

  private
  def char_if_present(char)
    char if index(char)
  end
end


class Caesar
  def initialize(shift)
    @text_alphabet = Alphabet.new ("A".."Z")
    @cipher_alphabet = Alphabet.new ("A".."Z"), shift: shift
    puts "text: #{@text_alphabet}"
    puts "text: #{@cipher_alphabet}"
  end


  def encrypt(text)
    substitute(text, @text_alphabet, @cipher_alphabet)
  end

  def decrypt(text)
    substitute(text, @cipher_alphabet, @text_alphabet)
  end

  private
  def substitute(text, source_alphabet, target_alphabet)
    source_alphabet.sanitized_chars(text).map do |char|
      source_alphabet.substitute(char, target_alphabet)
    end.join
  end
end<commit_msg>Make substitution a method of *target* alphabet.<commit_after>class Alphabet
  # chars is an array of character strings, like ["A", "B", "C" ...]
  def initialize(chars, options = {})
    @chars = chars.to_a.rotate(options[:shift] || 0)
    @index = Hash[@chars.each_with_index.to_a]
  end

  def [](index)
    @chars[index]
  end

  def index(char)
    i = @index[char]
  end

  def sanitized_chars(text)
    text.upcase.chars.map { |c| char_if_present(c) }.compact
  end

  # Given a char and another alphabet, find the char in this alphabet
  # at the corresponding index in this alphabet
  def char(char, other_alphabet)
    self[other_alphabet.index(char)]
  end

  def to_s
    "<Alphabet:[#{@chars.join}]>"
  end

  private
  def char_if_present(char)
    char if index(char)
  end
end


class Caesar
  def initialize(shift)
    @text_alphabet = Alphabet.new ("A".."Z")
    @cipher_alphabet = Alphabet.new ("A".."Z"), shift: shift
  end


  def encrypt(text)
    substitute(text, @text_alphabet, @cipher_alphabet)
  end

  def decrypt(text)
    substitute(text, @cipher_alphabet, @text_alphabet)
  end

  private
  def substitute(text, source_alphabet, target_alphabet)
    source_alphabet.sanitized_chars(text).map do |char|
      target_alphabet.char(char, source_alphabet)
    end.join
  end
end
{'fraction_non_alphanumeric': 0.12381703470031545, 'fraction_numerical': 0.0007886435331230284, 'mean_word_length': 3.6380255941499087, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7168554', 'n_tokens_mistral': 940, 'n_tokens_neox': 896, 'n_words': 217}