<commit_before># encoding: utf-8

require 'equalizer'

require_relative 'gaddag/arc'
require_relative 'gaddag/node'
require_relative 'gaddag/path'
require_relative 'gaddag/word'

# Implementation of the GADDAG data structure
class GADDAG
  # The root node
  attr_reader :root

  # Initializes a GADDAG
  # @return [GADDAG]
  def initialize
    @root = Node.new
  end

  # Adds a word to the GADDAG
  # @param word [String] the word to be added
  # @return [GADDAG] the GADDAG instance
  def add(word)
    @root.create_final_path(word.chars.reverse + [Path::DELIMITER])

    Word.new(word.chars).to_delimited_paths.each do |path|
      @root.create_final_path(path)
    end

    self
  end

  # Finds all words that contain the given substring
  # @param substring [String] the substring to search for
  # @return [Array<String>] all matching words
  def find(substring)
    first_letter, second_letter, *last_letters = *substring.chars
    return [] unless @root.path?(last_letters.reverse)

    @root.follow_path(last_letters.reverse).final_paths.select do |path|
      path.start_with?([second_letter, first_letter])
    end.map do |path|
      Path.new(last_letters.reverse + path).to_word.to_s
    end.uniq
  end
end<commit_msg>Revert "Revert "Revert "Utilize #to_ary in GADDAG::Path"""<commit_after># encoding: utf-8

require 'equalizer'

require_relative 'gaddag/arc'
require_relative 'gaddag/node'
require_relative 'gaddag/path'
require_relative 'gaddag/word'

# Implementation of the GADDAG data structure
class GADDAG
  # The root node
  attr_reader :root

  # Initializes a GADDAG
  # @return [GADDAG]
  def initialize
    @root = Node.new
  end

  # Adds a word to the GADDAG
  # @param word [String] the word to be added
  # @return [GADDAG] the GADDAG instance
  def add(word)
    @root.create_final_path(word.chars.reverse + [Path::DELIMITER])

    Word.new(word.chars).to_delimited_paths.each do |path|
      @root.create_final_path(path.letters)
    end

    self
  end

  # Finds all words that contain the given substring
  # @param substring [String] the substring to search for
  # @return [Array<String>] all matching words
  def find(substring)
    first_letter, second_letter, *last_letters = *substring.chars
    return [] unless @root.path?(last_letters.reverse)

    @root.follow_path(last_letters.reverse).final_paths.select do |path|
      path.start_with?([second_letter, first_letter])
    end.map do |path|
      Path.new(last_letters.reverse + path).to_word.to_s
    end.uniq
  end
end
{'fraction_non_alphanumeric': 0.09852999602701629, 'fraction_numerical': 0.0007945967421533572, 'mean_word_length': 3.956692913385827, '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': '1144804', 'n_tokens_mistral': 876, 'n_tokens_neox': 850, 'n_words': 223}