Bu, fonksiyonel programlama ve F # için kesinlikle mükemmel bir seçimdir. Çok sayıda olası yaklaşım var. Pad ile çözüm muhtemelen en direkt olanıdır ve gerçekten iyi bir başlangıç noktasıdır. Eğer daha genel bir şeye ihtiyacınız varsa, o zaman Huusom'un çözümü gayet güzel. Bir dizi içinde kalıpları algılamak için etki alanına özgü bir dilde (DSL) oluşturmak için daha genel bir yaklaşım vardır. Bu daha gelişmiş bir fonksiyonel tekniktir, ancak örneğiniz için gerçekten güzel çalışır. Bunu yaptıysanız, oldukça karmaşık kalıpları gerçekten özlü bir şekilde ifade edebilirsiniz. Bu örnek model bir bildirim özellikleri oluşturmak için çeşitli ilkelleri kullanır
// Create a detector that tests if a location
// contains 1 and returns 'false' when out of range
let one = border false (equals 1)
// A shape detector for your pattern
let pattern =
around (0, 0) one <&> around (1, 0) one <&>
around (-1, 1) one
// Test pattern with any rotation: Combine
// 4 possible rotations with logical or.
let any =
pattern <|> rotate pattern <|>
rotate (rotate pattern) <|>
rotate (rotate (rotate pattern))
: Burada bir örnektir. any
değeri, belirli bir konumda desen olup olmadığını sınamak için çalıştırabileceğiniz bir işlevi temsil eder. Desenin tüm dönüşlerini işler ve ayrıca sınır kontrolleri yapar. Aynca, yansıtılmış desenler eklemeniz gerekir, ancak bu oldukça kolay bir uzantı olacaktır.
uygulanmasını açıklayan muhtemelen tam blog yazısı gerekir, ancak burada oldukça okunaklı olmalıdır yorumladı kaynak kodu olacaktır: Nihayet
/// A type that represents a function that tests
/// whether an array contains some pattern at a
/// specified location. It gets the location to
/// test & the array as arguments and returns bool.
type ShapeDetector = SD of (int -> int -> int[,] -> bool)
/// A primitive that tests whether the value at the
/// current location contains a value 'v'
let equals v = SD (fun x y arr -> arr.[x,y] = v)
/// A combinator that takes 'ShapeDetector' and
/// creates a new one that returns 'def' when
/// accessing outside of the array bounds
let border def (SD f) = SD (fun x y arr ->
if x < 0 || y < 0 || x >= arr.GetLength(0) || y >= arr.GetLength(1)
then def else f x y arr)
/// A combinator that calls a given ShapeDetector
/// at a location specified by offset dx, dy
let around (dx, dy) (SD f) = SD (fun x y arr ->
f (x + dx) (y + dy) arr)
/// A combinator that takes a ShapeDetector and
/// builds a new one, which is rotated by 90 degrees
let rotate (SD f) = SD (fun x y arr ->
f -y x arr)
/// Creates a shape detector that succeeds only
/// when both of the arguments succeed.
let (<&>) (SD f1) (SD f2) = SD (fun x y arr ->
f1 x y arr && f2 x y arr)
/// Creates a shape detector that succeeds
/// when either of the arguments succeed.
let (<|>) (SD f1) (SD f2) = SD (fun x y arr ->
f1 x y arr || f2 x y arr)
, burada örnek bir 2D üzerinde desen dedektör çalışan bir örnektir dizi:
// Create a 2D array as a sample input
let inp =
array2D [ [ 0; 0; 1 ]
[ 0; 1; 0 ]
[ 0; 1; 0 ] ]
// Get the underlying function and run it
// for all possible indices in the array
let (SD f) = any
for x in 0 .. 2 do
for y in 0 .. 2 do
printfn "%A %A" (x, y) (f x y inp)
Eğer bulmaca oyunu için bir sayaç yazıyorsun? – Dmytro
Kesinlikle işlevsel bir dil daha iyi bir uyum gibi geliyor. –