Finding minimum steps required to traverse from source to terminal Hello everyone this is my first post here so please do critique my post if there's anything.
I have made a program intended to pass a programming challenge on open.kattis.com, here.
It should do as title says, but with the conditions that each traversal follows the rules of a &quot;Knight&quot; from chess, that being plus/minus two columns/rows and plus/minus one column/row.

_read method:
I attempted to solve this making a Node class and passing coordinate and char data into each instance of a Node object for each coordinate.

_adjacencify method:
Thereafter, I found adjacencies (neighbours) of all Node objects, with the aforementioned condition of a chess Knight.

_jump method:
Lastly, I used a BFS implementation in order to find the shortest path from the source (root) to the terminal (here represented as 'K').

find_path:
Wraps everything up.


Here's the code I ended up with:
class Nite
  #attr_accessor :char, :col, :row
  class Node
    attr_accessor :char, :col, :row, :disc, :parent
    attr_reader :adjies
    def initialize(char, col, row)
      @char = char
      @col = col
      @row = row
      @adjies = [] # adjacencies
      @disc = false
      @parent = nil
    end
    def add(value)
      @adjies &lt;&lt; value
    end
  end

  def _read
    # assign each coord. to a Node-object
    n = gets.to_i
    nodes = Array.new
    n.times do |x|
      temp = gets.strip.to_s
      temp.size.times do |y|
        node = Node.new(temp[y], x, y)
        nodes &lt;&lt; node
      end
    end

    nodes
  end

  def _adjacencify(nodes)

    nodes.each do |x|
      nodes.each do |y|
        if y.col == x.col &amp;&amp; y.row == x.row || y.char == '#'
          next
        end

        # logic

        if x.row == (y.row - 1) # y.row + 1

          if x.col == (y.col - 2) # y.col + 2
            x.add(y) # (col+2, row+1)
          elsif x.col == (y.col + 2) # y.col - 2
            x.add(y) # (col-2, row+1)
          end
    
        elsif x.row == (y.row + 1) # y.row - 1

          if x.col == (y.col - 2) # y.col + 2
            x.add(y) # (col+2, row-1)
          elsif x.col == (y.col + 2) # y.col - 2)
            x.add(y) # (col-2, row-1)
          end
    
        end

        if x.row == (y.row - 2) # y.row + 2

          if x.col == (y.col - 1) # y.col + 1
            x.add(y) # (col+1, row+2)
          elsif x.col == (y.col + 1) # y.col - 1
            x.add(y) # (col-1, row+2)
          end
    
        elsif x.row == (y.row + 2) # y.row - 2

          if x.col == (y.col - 1) # y.col + 1
            x.add(y) # (col+1, row-2)
          elsif x.col == (y.col + 1) # y.col - 1
            x.add(y) # (col-1, row-2)
          end

        end

      end
    end

    nodes
  end

  def _jump(nodes)

    nodes = _adjacencify(nodes)

    q = Queue.new
    root = nodes[0]
    root.disc = true
    q &lt;&lt; root

    while !q.empty? do
      v = q.pop
      if v.char == 'K'
        steps = 0
        until v.parent == nil do
          if !v.nil?
          end
          steps += 1
          v.parent = v.parent.parent
        end
        return steps
      end
      v.adjies.each do |w|
        if w.disc == false
          w.parent = v
          w.disc = true
          q &lt;&lt; w
        end
      end
    end
    return -1

  end

  def find_path
    _jump(_read)
  end

end

nite = Nite.new
puts nite.find_path

I suspect of course that the _adjacencify method is super time consuming, and that some loops are way too time consuming.
I failed the &lt;1.00s time requirement in order to pass the challenge.
I want all types of criticism on my code, and I want tips and also, if anyone wants, different implementations that perform better.
Especially Ruby convention is something I want critique on, considering I am coming from a Java and Python background and I'm fairly fresh in Ruby.
Please tell me if I should edit anything in this post to make anything clearer.
and welcome!
Things I really like

Using standard Ruby indention (2 spaces)
Using the attr_accessor and attr_reader helpers instead of hand-rolling these methods
Using n.times do to loop.
Using next at the top of a loop body instead of a nested if
Short, focused methods
Great use of functional decomposition (goes along with the focused methods)

There's a lot of nit-picky things to follow, so don't be discouraged.  Many of these things are minor, and I'm mostly pointing out Ruby idioms or practices you have no way to know yet.  Due to time constraints, I am not going to address the algorithm itself, nor look for any major improvements.  I will mostly point out the things that catch my eye as a Ruby programmer.
Naming things
  def _read
    # assign each coord. to a Node-object

Does the comment indicate that &quot;read&quot; could use a better name?
    nodes.each do |x|
      nodes.each do |y|

x and y are frequently used as coordinate names for a Cartesian grid, which a chessboard is.  Here, x and y are nodes, not coordinates.  Better names would be a and b, or perhaps origin and destination.
@adjies = [] # adjacencies

Probably just name the variable @adjacencies so you can lose the comment, and the code will be clearer throughout.  Someone reading the code who hasn't seen this comment yet will be confused.
Formatting
    end
    def add(value)
      @adjies &lt;&lt; value
    end
  end

Standard Ruby formatting separates methods with a blank line.  I also prefer a blank line between a method and the end of the class:
    end

    def add(value)
      @adjies &lt;&lt; value
    end

  end

but the more common practice is to have no blank line after the last method in a class:
    end

    def add(value)
      @adjies &lt;&lt; value
    end
  end

Idiomatic private methods in Ruby
def _jump(nodes)

Standard Ruby does not use the underscore conversion for private methods.  Instead, private methods can follow the private keyword:

private

def jump(nodes)

Note that all methods that follow &quot;private&quot; will be private, so you don't have to use it before every private method.  Standard Ruby practice is to just give the &quot;private&quot; keyword once, and then follow that with all of the private methods.
Omit the &quot;return&quot; keyword in the last expression in a method.
   return -1

The result of a Ruby method is the value of the last expression in the method.  So unless returning early, we usually omit the &quot;return&quot; keyword when it's on the last line:
    -1

You omit the &quot;return&quot; keyword elsewhere, so I assume this is just an oversight.
Don't compare to true or false
if w.disc == false

In Ruby, true and false are a little different than in Java.  Ruby considers anything that is either nil or false to be &quot;falsey&quot;, and everything else is &quot;truthy&quot;.  Therefore, it is bad practice to compare a value with false, since this comparison will fail if the value is actually nil.
So instead of comparing with false, do this:
if !w.disc

But even better, Ruby has a negating form of &quot;if&quot; called &quot;unless&quot;.  Idiomatic Ruby would be:
unless w.disc

Getting the first element of an array or enumeration
root = nodes[0]

This is fine, but this also works:
root = nodes.first

Ruby likes you to have multiple ways to do a thing, a philosophical shift from Python.
Redundant #to_s
     temp = gets.strip.to_s

The result of String#strip is a String, so there's no need for .to_s here.
Use Array instead of Queue (for this application)
q = Queue.new

Queue is intended for multi-threaded applications; it includes locking to prevent race conditions.  For a single-threaded application, you can and should just use Array.  The minor reason is performance (avoid the locking).  The major reason is communication: A Ruby programmer seeing Queue is going to start looking for the threading in your program.
Since the methods you are calling on q (&lt;&lt; and pop) are also implement on Array and have the same meaning, you can do this instead:
q = []

Create empty arrays with []
nodes = Array.new

There's nothing wrong with this, but you will more often see a new, empty array created using the array literal syntax:
nodes = []