นี่มันคือ นี่เป็นโปรแกรม F # แรกของฉัน หากฉันพลาดคุณสมบัติของภาษาโปรดแจ้งเตือนฉันเมื่อฉันยังเรียนรู้อยู่
นี่คือตัวอย่างอินพุตของฉัน
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . B . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . A . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . C . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . G . . . . .
. . . . . . . D . . . . . . . . . . . . . . . . .
. . . . . . . . F . . . . . . . . . . . . . . . .
. . . . . . . E . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
นี่คือผลลัพธ์
. . . . . . . . . a b . . . . . . . b g . . . . .
. . . . . . . . . a b . B . . . b b b g . . . . .
. . . . . . . . . . a b . . . b c c c g . . . . .
. . . . . . . . A . . a b . b c . . c g . . . . .
. . . . . . . . . . . a b b c . . . c g . . . . .
a a a a a a a a . . . a b c . . C . c g . . . . .
d d d d d d d d a a a a b c . . . c g . . . . . .
. . . . . . . . d d d d b c . . c g . G . . . . .
. . . . . . . D d d d d d c . . c g . . . . . . .
d d d d d d d d f f f f f f c . c g . . . . . . .
e e e e e e e e e e e e e e c . c g . . . . . . .
. . . . . . . . . . . . . e c . c g . . . . . . .
. . . . . . . . . . . . . e c . c g . . . . . . .
. . . . . . . . . . . . . e c . c g . . . . . . .
นี่คือรหัส สนุก.
// The first thing that we need is some data.
let originalData = [
"........................."
"............B............"
"........................."
"........A................"
"........................."
"................C........"
"........................."
"...................G....."
".......D................."
"........F................"
".......E................."
"........................."
"........................."
"........................."
]
ตอนนี้เราจำเป็นต้องแปลงข้อมูลนั้นเป็นอาร์เรย์สองมิติเพื่อให้เราสามารถเข้าถึงได้ผ่านตัวสร้างดัชนี
let dataMatrix =
originalData
|> List.map (fun st -> st.ToCharArray())
|> List.toArray
// We are going to need a concept of ownership for each
// cell.
type Owned =
| Unclaimed
| Owner of char
| Claimed of char
| Boundary of char
ให้เราสร้างเมทริกซ์ที่แสดงถึงความเป็นเจ้าของของแต่ละเซลล์
let claims =
dataMatrix
|> Array.map (fun row ->
row
|> Array.map (function
| '.' -> Owned.Unclaimed
| ch -> Owned.Owner(ch))
)
ให้เรามีวิธีอรรถประโยชน์เพื่อดูสิ่งที่เกิดขึ้น
let printIt () =
printfn ""
claims
|> Array.iter (fun row ->
row |> Array.iter (function
| Owned.Claimed(ch) -> printf " ."
| Owned.Owner(ch) -> printf " %c" ch
| Owned.Boundary(ch) -> printf " %c" ch
| _ -> printf " ." )
printfn "")
ให้เราสร้างบันทึกเพื่อแสดงว่าตัวอักษรตัวใหญ่อยู่ที่ไหน
type CapitalLocation = { X:int; Y:int; Letter:char }
ตอนนี้เราต้องการค้นหาตัวพิมพ์ใหญ่ทั้งหมด
let capitals =
dataMatrix
|> Array.mapi (fun y row ->
row
|> Array.mapi (fun x item ->
match item with
| '.' -> None
| _ -> Some({ X=x; Y=y; Letter=item }))
|> Array.choose id
|> Array.toList
)
|> Array.fold (fun acc item -> item @ acc) List.empty<CapitalLocation>
|> List.sortBy (fun item -> item.Letter)
ขณะที่เราเคลื่อนที่เราต้องการแนวคิดเกี่ยวกับทิศทาง
type Direction =
| Left = 0
| Up = 1
| Right = 2
| Down = 3
// Function gets the coordinates of the adjacent cell.
let getCoordinates (x, y) direction =
match direction with
| Direction.Left -> x-1, y
| Direction.Up -> x, y-1
| Direction.Right -> x+1, y
| Direction.Down -> x, y+1
| _ -> (-1,-1) // TODO: Figure out how to best throw an error here.
ขณะที่เราเคลื่อนที่เราจะต้องรู้ขนาด สิ่งนี้จะช่วยให้เราตรวจสอบว่าเราย้ายออกนอกขอบเขตหรือไม่
type Size = { Width:int; Height: int }
// Get the size of the matrix.
let size = {Width=originalData.Head.Length; Height=originalData.Length}
รูปแบบที่ใช้งานอยู่: ตรงกับเกณฑ์ของเซลล์ที่ระบุ
let (|OutOfBounds|UnclaimedCell|Claimed|Boundary|) (x,y) =
match (x,y) with
| _,_ when x < 0 || y < 0 -> OutOfBounds
| _,_ when x >= size.Width || y >= size.Height -> OutOfBounds
| _ ->
match claims.[y].[x] with
| Owned.Unclaimed -> UnclaimedCell(x,y)
| Owned.Claimed(ch) -> Claimed(x,y,ch)
| Owned.Boundary(ch) -> Boundary(x,y,ch)
| Owned.Owner(ch) -> Claimed(x,y,ch)
ตอนนี้เรากำลังลงภาษีทองเหลือง สิ่งนี้อ้างว่าเซลล์!
let claimCell letter (x, y) =
// Side effect: Change the value of the cell
(claims.[y].[x] <- Owned.Claimed (System.Char.ToLower letter)) |> ignore
ใช้รูปแบบที่ใช้งานอยู่รับสิทธิ์เซลล์นี้หากไม่มีการอ้างสิทธิ์และส่งคืนพิกัดของเซลล์ที่อยู่ติดกัน
let claimAndReturnAdjacentCells (letter, coordinates, direction) =
match coordinates with
| UnclaimedCell (x,y) ->
// Claim it and return the Owned object.
claimCell letter coordinates // meaningful side effect
// use Direction as int to allow math to be performed.
let directionInt = int direction;
Some(
// [counter-clockwise; forward; clockwise]
[(directionInt+3)%4; directionInt; (directionInt+1)%4]
|> List.map enum<Direction>
|> List.map (fun newDirection ->
(
letter,
getCoordinates coordinates newDirection,
newDirection
))
)
| Claimed(cx,cy,cch) when cch <> System.Char.ToLower letter->
// If we find a "Claimed" element that is not our letter, we have
// hit a boundary. Change "Claimed" to "Boundary" and return the
// element that led us to evaluating this element. It is also a
// boundary.
(claims.[cy].[cx] <- Owned.Boundary (System.Char.ToLower cch)) |> ignore
let reverseDirection = enum<Direction>(((int direction)+2)%4)
Some[(
cch,
getCoordinates (cx, cy) reverseDirection,
reverseDirection
)]
| _ -> None
เรากำลังเริ่มสร้างรายการของถุงข้อมูลนี้ให้เราสร้างประเภทเพื่อทำให้สิ่งต่าง ๆ ชัดเจนยิ่งขึ้น
type CellClaimCriteria = (char * (int * int) * Direction)
รับรายการเกณฑ์สำหรับการอ้างสิทธิ์เซลล์เราจะวนซ้ำรายการที่ส่งคืนเซลล์ถัดไปเพื่ออ้างสิทธิ์และรับเงินคืนในรายการนั้น
let rec claimCells (items:CellClaimCriteria list) =
items
|> List.fold (fun acc item ->
let results = claimAndReturnAdjacentCells item
if Option.isSome(results)
then (acc @ Option.get results)
else acc
) List.empty<CellClaimCriteria>
|> (fun l ->
match l with
| [] -> []
| _ -> claimCells l)
สำหรับแต่ละทุนสร้างเกณฑ์การอ้างสิทธิ์ในแต่ละทิศทางจากนั้นเรียกร้องเซลล์เหล่านั้นซ้ำ ๆ
let claimCellsFromCapitalsOut ()=
capitals
|> List.fold (fun acc capital ->
let getCoordinates = getCoordinates (capital.X, capital.Y)
[Direction.Left; Direction.Up; Direction.Right; Direction.Down]
|> List.map (fun direction ->
(
capital.Letter,
getCoordinates direction,
direction
))
|> (fun items -> acc @ items)) List.empty<CellClaimCriteria>
|> claimCells
ทุกโปรแกรมต้องการหลัก
[<EntryPoint>]
let main args =
printIt()
claimCellsFromCapitalsOut()
printIt()
0