Advertisement
Guest User

Untitled

a guest
Jan 27th, 2020
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 2.91 KB | None | 0 0
  1. def find_ladders(begin_word, end_word, word_list)
  2.   // Return an empty array if the end word isn't in the provided list
  3.  return [] unless (unvisited = word_list.to_set).include?(end_word)
  4.  // Build the words used to transform by using the graph implementation?
  5.  words_by_transform = graph_word_transforms(begin_word, end_word, unvisited)
  6.  // Reverse the path of DFS so you get word -> end word and not end word -> word
  7.  reverse_dfs_paths(begin_word, end_word, words_by_transform)
  8. end
  9. def graph_word_transforms(begin_word, end_word, unvisited)
  10.  // Hash where word is key and potential transformations is value as a set (I think)
  11.  words_by_transform = Hash.new { |h, k| h[k] = Set.new }
  12.  // transformations are each position in the word with all possible changes A-Z?
  13.  transformations = Array(0...begin_word.size).product(Array('a'..'z'))
  14.  unvisited.delete(end_word)
  15.  // Begin layer is a new set, end layer is a set containing the end word
  16.  begin_layer, end_layer = Set.new, Set[end_word]
  17.  // prev is the end layer, curr is the begin (new set), next is a set with begin word?
  18.  prev_layer, curr_layer, next_layer = end_layer, begin_layer, Set[begin_word]
  19.  // next_layer used as stack for DFS? Not sure what's going on here
  20.   until next_layer.empty? || end_layer.any? { |t| words_by_transform[t].intersect?(begin_layer) }
  21.     // layer traversal?
  22.     curr_layer.replace(next_layer)
  23.     // Swap positions of layers?
  24.     curr_layer, prev_layer = prev_layer, curr_layer
  25.     // Remove each layer from unvisted
  26.     unvisited.subtract(prev_layer)
  27.     // Not sure why we clear the next layers set?
  28.     next_layer.clear
  29.     curr_layer.each do |word|
  30.       transformations.each do |i, c|
  31.         // I think this is checking if the word character position transformed at index
  32.         // Is the same as the char from a to z so we don't transform the same twice?
  33.        next if word[i] == c
  34.        // No clue what this is doing?
  35.        transform = word.dup.tap { |w| w[i] = c }
  36.        // Push the transform to the next layer if unvisited includes the transformed
  37.        // word?
  38.        next_layer << transform if (is_neighbor = unvisited.include?(transform))
  39.        // Not sure about this part
  40.        if is_neighbor || prev_layer.include?(transform)
  41.          orig_word, variant = curr_layer.equal?(begin_layer) ? [word, transform] : [transform, word]
  42.          words_by_transform[variant] << orig_word
  43.        end
  44.      end
  45.    end
  46.  end
  47.  words_by_transform
  48. end
  49. // Reverse the DFS path so we go from begin word -> end word rather than end word -> begin?
  50. def reverse_dfs_paths(begin_word, end_word, word_graph)
  51.  paths, path = [], []
  52.  stack = [[end_word, 1]]
  53.  until stack.empty?
  54.    word, lvl = stack.pop
  55.    path.pop until path.size < lvl
  56.    path << word
  57.    if word == begin_word
  58.      paths << path.reverse
  59.    else
  60.      word_graph[word].each { |w| stack << [w, lvl + 1] }
  61.    end
  62.  end
  63.  paths
  64. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement