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 ]