Đây là một bài tập nhỏ được trích dẫn từ Codewars.com
với mục đích chủ yếu là luyện tập xử lý cấu trúc dữ liệu bằng các hàm dựng sẵn trong thư viện tiêu chuẩn của Haskell
.
Yêu cầu
GIả sử chúng ta có một hàm gravityFlip
nhận vào hai tham số là:
direction
- một ký tự đơn'L'
hoặc'R'
, biểu thị hướng của trọng lực trong không gian là: bên tráiL-eft
hoặc bên phảiR-ight
.boxes
- một danh sáchList
hoặc mảngArray
các giá trị số nguyên[Int]
, biểu thị những chiếc hộp có trọng lượng tương ứng với mỗi giá trị số nguyên, giá trị càng lớn thì trọng lượng càng lớn.
Hàm gravityFlip
sẽ sắp xếp danh sách boxes
tùy theo hướng của trọng lực direction
với kết quả dự kiến như sau:
gravityFlip 'R' [3, 2, 1, 4] --> [1, 2, 3, 4]
gravityFlip 'L' [0, 4, 5, 3] --> [5, 4, 3, 0]
Có nghĩa là với direction
trỏ về bên nào thì những chiếc hộp có trọng lượng lớn hơn sẽ bị kéo về phía bên đó nhanh hơn.
Xử lý
Như vậy chúng ta có chữ ký signature
của gravityFlip
như sau:
gravityFlip :: Char -> [Int] -> [Int]
gravityFlip (direction) (boxes) = [...]
Code xử lý chi tiết sẽ có các lựa chọn là:
- Viết hàm
gravityFlip
với các tham số đầu vàodirection
vàboxes
và trả về kết quả là một tập[Int]
đã được sắp xếp. - Hoặc, viết hàm
gravityFlip
với tham số đầu vàodirection
và trả về kết quả là một hàm mới có định kiểu là[Int] -> [Int]
.
Đoạn ánh xạ từ tham số boxes :: [Int]
tới kết quả directedBoxes :: [Int]
đã có trình sắp xếp List.sort
kết hợp với trình nghịch đảo List.reverse
được cung cấp sẵn trong thư viện tiêu chuẩn; Vì vậy nên chúng ta chỉ cần tạo logic điều kiện để trả về trình sắp xếp phù hợp dựa trên tham số đầu tiên direction
.
module GravityFlip (gravityFlip) where import Prelude (Char, Int, error, (.))
import Data.List as List (sort, reverse) gravityFlip :: Char -> [Int] -> [Int]
gravityFlip (direction) = case (direction) of 'R' -> sort 'L' -> reverse . sort _ -> error "Invalid direction."