class NgLib::Grid(T)

Included Modules

Defined in:

nglib/grid/grid.cr

Constant Summary

DOWN = {1, 0}
DYDX2 = [DOWN, RIGHT]
DYDX4 = [UP, LEFT, DOWN, RIGHT]
DYDX8 = [UP, add(UP, RIGHT), RIGHT, add(DOWN, RIGHT), DOWN, add(DOWN, LEFT), LEFT, add(UP, LEFT)]
LEFT = {0, -1}
RIGHT = {0, 1}
UP = {-1, 0}

Constructors

Class Method Summary

Instance Method Summary

Constructor Detail

def self.new(s : Array(Array(T)), delta : Array(Tuple(Int32, Int32))) #

[View source]
def self.new(h : Int, w : Int, delta : Array(Tuple(Int32, Int32)), &) #

[View source]
def self.new(h : Int, delta : Array(Tuple(Int32, Int32)), &) #

[View source]

Class Method Detail

def self.add(v1 : Tuple(Int, Int), v2 : Tuple(Int, Int)) #

[View source]
def self.dydx2(height : Int, width : Int) #

[View source]
def self.dydx2(s : Array(Array(T))) #

[View source]
def self.dydx2(height : Int, &) #

[View source]
def self.dydx4(s : Array(Array(T))) #

[View source]
def self.dydx4(height : Int, width : Int, &) #

[View source]
def self.dydx4(height : Int, &) #

[View source]
def self.dydx8(s : Array(Array(T))) #

[View source]
def self.dydx8(height : Int, width : Int, &) #

[View source]
def self.dydx8(height : Int, &) #

[View source]
def self.sub(v1 : Tuple(Int, Int), v2 : Tuple(Int, Int)) #

[View source]

Instance Method Detail

def [](y : Int, x : Int) #

[View source]
def [](pos : Tuple(Int, Int)) #

[View source]
def []=(y : Int, x : Int, c : T) #

[View source]
def []=(pos : Tuple(Int, Int), c : T) #

[View source]
def barred?(y : Int, x : Int) : Bool #

位置 $(y, x)$ が進入禁止なら true を返します。

s = [
  "..".chars,
  ".#".chars,
]

grid.barred?(0, 0) # => false
grid.barred?(1, 1) # => true

[View source]
def barred?(pos) : Bool #

位置 pos が進入禁止なら true を返します。

s = [
  "..".chars,
  ".#".chars,
]

grid.barred?({0, 0}) # => false
grid.barred?({1, 1}) # => true

[View source]
def column_walls : Array(Array(Int32)) #

[View source]
def delta : Array(Pos) #

[View source]
def each(& : T -> ) #

グリッドの値を $(0, 0)$ から $(H, W)$ まで順に列挙します。

s = [
  "..#".chars,
  ".#.".chars,
  "##.".chars,
]
grid = Grid(Char).dydx4(s)
gird.each { |c| puts c } # => '.', '.', '#', '.', ..., '.'

[View source]
def each_neighbor(y : Int, x : Int, &) #

位置 $(y, x)$ の近傍で、侵入可能な位置を列挙します。

grid = Grid.dydx([".#.", "...", "..."])

grid.each_neighbor(1, 1) do |ny, nx|
end

[View source]
def each_neighbor_with_direction(y : Int, x : Int, &) #

位置 $(y, x)$ の近傍で、侵入可能な位置を方向とともに列挙します。

grid = Grid.dydx4([".#.", "...", "..."])

grid.each_neighbor(1, 1) do |ny, nx, dir|
end

[View source]
def each_with_coord(&) #

グリッドの値を $(0, 0)$ から $(H, W)$ まで順に座標付きで列挙します。

s = [
  "..#".chars,
  ".#.".chars,
  "##.".chars,
]
grid = Grid(Char).new(s)
gird.each { |c, (i, j)| puts c, {i, j} }

[View source]
def each_with_index(&) #

グリッドの値を $(0, 0)$ から $(H, W)$ まで順に列挙します。

index は $Wi + j$ を返します。通常は #each_with_coord を利用することを推奨します。


[View source]
def fetch(y : Int, x : Int, default : T) #

[View source]
def free?(y : Int, x : Int) : Bool #

位置 $(y, x)$ が通行可能なら true を返します。

s = [
  "..".chars,
  ".#".chars,
]

grid.free?(0, 0) # => true
grid.free?(1, 1) # => false

[View source]
def free?(pos) : Bool #

位置 pos が通行可能なら true を返します。

s = [
  "..".chars,
  ".#".chars,
]

grid.free?({0, 0}) # => true
grid.free?({1, 1}) # => false

[View source]
def h : Int32 #

[View source]
def index(offset = {0, 0}, & : T -> ) : Tuple(Int32, Int32) | Nil #
Description copied from module Enumerable(T)

Returns the index of the first element for which the passed block is truthy.

["Alice", "Bob"].index { |name| name.size < 4 } # => 1 (Bob's index)

Returns nil if the block is not truthy for any element.


[View source]
def index(obj, offset = {0, 0}) : Tuple(Int32, Int32) | Nil #
Description copied from module Enumerable(T)

Returns the first index of obj in the collection.

["Alice", "Bob"].index("Alice") # => 0

Returns nil if obj is not in the collection.


[View source]
def index!(offset = {0, 0}, & : T -> ) : Tuple(Int32, Int32) #
Description copied from module Enumerable(T)

Returns the index of the first element for which the passed block is truthy.

["Alice", "Bob"].index! { |name| name.size < 4 } # => 1 (Bob's index)

Raises Enumerable::NotFoundError if there is no element for which the block is truthy.


[View source]
def index!(obj, offset = {0, 0}) : Tuple(Int32, Int32) | Nil #
Description copied from module Enumerable(T)

Returns the first index of obj in the collection.

["Alice", "Bob"].index!("Alice") # => 0

Raises Enumerable::NotFoundError if obj is not in the collection.


[View source]
def label_grid #

連結する free および bar を塗り分けたグリッドを返します。 free のマスは非負整数の連番でラベル付けされ、bar は負の連番でラベル付けされます。 label_grid.max(島の数 - 1) を返すことに注意してください。

s = [
  "..#".chars,
  ".#.".chars,
  "##.".chars,
]
grid = Grid(Char).dydx4(s)
grid.label_grid # => [[0, 0, -1], [0, -2, 1], [-2, -2, 1]]

[View source]
def line_walls : Array(Array(Int32)) #

[View source]
def map(& : T -> U) : Grid(U) forall U #

グリッドの各要素に対して、ブロックを実行した結果に変換したグリッドを返します。


[View source]
def map_with_coord(& : T, Tuple(Int32, Int32) -> U) : Grid(U) forall U #

グリッドの各要素に対して、ブロックを実行した結果に変換したグリッドを返します。


[View source]
def next_coord(pos) #

位置 pos に対して次の座標をタプルで返します。

ここで「次」とは、each_with_coord で走査するときの順と同様です。

次が存在しない場合は nil を返します。

grid.h, grid.w # => 3, 4
grid.next_coord({1, 2}) # => {1, 3}
grid.next_coord({1, 3}) # => {2, 0}
grid.next_coord({2, 3}) # => nil

[View source]
def next_coord!(pos) #

位置 pos に対して次の座標をタプルで返します。

ここで「次」とは、each_with_coord で走査するときの順と同様です。

次が存在しない場合はエラーを送出します。

grid.h, grid.w # => 3, 4
grid.next_coord({1, 2}) # => {1, 3}
grid.next_coord({1, 3}) # => {2, 0}
grid.next_coord({2, 3}) # => nil

[View source]
def node_index(y : Int, x : Int) #

[View source]
def over?(y, x) : Bool #

位置 $(y, x)$ がグリッドの範囲外なら true を返します。

grid.over?(-1, 0)          # => true
grid.over?(h + 10, w + 10) # => true
grid.over?(0, 0)           # => false

[View source]
def over?(pos) : Bool #

位置 pos がグリッドの範囲外なら true を返します。

grid.over?({-1, 0})          # => true
grid.over?({h + 10, w + 10}) # => true
grid.over?({0, 0})           # => false

[View source]
def shortest_path(start_i : Int, start_j : Int) : Array(Array(Int64 | Nil)) #

始点 $(s_i, s_j)$ から各マスへの最短経路長を返します。

到達できない場合は nil が格納されます。

dist = grid.shortest_path(start: {si, sj})
dist[gi][gj] # => 4

[View source]
def shortest_path(start : Tuple, dest : Tuple) : Int64 | Nil #

始点 $(s_i, s_j)$ から終点 $(g_i, g_j)$ への最短経路長を返します。

grid.shortest_path(start: {si, sj}, dest: {gi, gj}) # => 4

[View source]
def shortest_path(start : Tuple) : Array(Array(Int64 | Nil)) #

始点 $(s_i, s_j)$ から各マスへの最短経路長を返します。

到達できない場合は nil が格納されます。

dist = grid.shortest_path(start: {si, sj})
dist[gi][gj] # => 4

[View source]
def shortest_path : Array(Array(Array(Array(Int64 | Nil)))) #

全マス間の最短経路長を返します。

到達できない場合は nil が格納されます。

dist = grid.shortest_path
dist[si][sj][gi][gj] # => 4

[View source]
def shortest_path(start : Tuple, dest : Tuple, tag = :dijkstra, & : Int32, Int32, Int32, Int32 -> U) : Int64 forall U #

始点 $(s_i, s_j)$ から終点 $(g_i, g_j)$ への最短経路長を返します。

内部で利用するアルゴリズムをタグで指定します。

  • :bfs : 侵入不可能な場合は U::MAX を返してください。
  • :binary_bfs : 重みは $0$ または $1$ である必要があります。
  • :dijkstra : デフォルト値です。$\infty = U::MAX$ です。負の数には気をつけてください。

$(i, j)$ から $(i', j')$ への移動時の重みをブロックで指定します。

grid.shortest_path(start: {si, sj}, dest: {gi, gj}) { |i, j, i_adj, j_adj|
  f(i, j, i_adj, j_adj)
} # => 4

[View source]
def shortest_path(start : Tuple, tag = :dijkstra, & : Int32, Int32, Int32, Int32 -> U) : Array(Array(U)) forall U #

始点 $(s_i, s_j)$ から各マスへの最短経路長を返します。

内部で利用するアルゴリズムをタグで指定します。

  • :bfs : 侵入不可能な場合は U::MAX を返してください。
  • :binary_bfs : 重みは $0$ または $1$ である必要があります。
  • :dijkstra : デフォルト値です。$\infty = U::MAX$ です。負の数には気をつけてください。

$(i, j)$ から $(i', j')$ への移動時の重みをブロックで指定します。

dist = grid.shortest_path(start: {0, 0}) { |i, j, i_adj, j_adj| f(i, j, i_adj, j_adj) }
dist[gi][gj] # => 4

ameba:disable Metrics/CyclomaticComplexity


[View source]
def shortest_path(tag = :dijkstra, & : Int32, Int32, Int32, Int32 -> U) : Array(Array(Int64)) forall U #

全マス間の最短経路長を返します。

内部で利用するアルゴリズムをタグで指定します。

  • :bfs : 侵入不可能な場合は U::MAX を返してください。
  • :binary_bfs : 重みは $0$ または $1$ である必要があります。
  • :dijkstra : デフォルト値です。$\infty = U::MAX$ です。負の数には気をつけてください。

$(i, j)$ から $(i', j')$ への移動時の重みをブロックで指定します。

dist = grid.shortest_path { |i, j, i_adj, j_adj| f(i, j, i_adj, j_adj) }
dist[si][sj][gi][gj] # => 4

[View source]
def shortest_path!(start : Tuple, dest : Tuple) : Int64 #

始点 $(s_i, s_j)$ から終点 $(g_i, g_j)$ への最短経路長を返します。

grid.shortest_path(start: {si, sj}, dest: {gi, gj}) # => 4

[View source]
def simulate(si : Int, sj : Int, directions : Enumerable, iterations : Enumerable) : Tuple(Int32, Int32) #

[View source]
def simulate(si : Int, sj : Int, directions : Enumerable) : Tuple(Int32, Int32) #

[View source]
def to_a : Array(Array(T)) #
Description copied from module Enumerable(T)

Returns an Array with all the elements in the collection.

(1..5).to_a # => [1, 2, 3, 4, 5]

[View source]
def to_graph(type = :connect_free) : Array(Array(Int32)) #

グリッドを隣接リスト形式で無向グラフに変換します。

あるマス $(i, j)$ の頂点番号は $Wi + j$ となります。

  • :connect_free : free 同士を結びます(デフォルト)
  • :connect_bar : bar 同士を結びます
  • :connect_same_type : bar 同士、free 同士を結びます
s = [
  "..#".chars,
  ".#.".chars,
  "##.".chars,
]
grid = Grid(Char).dydx4(s)
grid.to_graph # => [[3, 1], [0], [], [0], [], [8], [], [], [5]]

[View source]
def to_s(io : IO) #
Description copied from class Reference

Appends a short String representation of this object which includes its class name and its object address.

class Person
  def initialize(@name : String, @age : Int32)
  end
end

Person.new("John", 32).to_s # => #<Person:0x10a199f20>

[View source]
def w : Int32 #

[View source]