2010-03-22 46 views
8

Tôi là một người không thích. Tôi đã quyết định viết một solitaire solitaire solver như là một bài tập đầu tiên để tìm hiểu ngôn ngữ và lập trình chức năng nói chung.Lặp lại một Danh sách ở Scala

Tôi muốn tạo một bộ bài xáo trộn ngẫu nhiên các thẻ chứa 1, 2 hoặc 4 bộ quần áo. Dưới đây là những gì tôi đã đưa ra:

val numberOfSuits = 1 
(List("clubs", "diamonds", "hearts", "spades").take(numberOfSuits) * 4).take(4) 

mà nên trở

List("clubs", "clubs", "clubs", "clubs") 
List("clubs", "diamonds", "clubs", "diamonds") 
List("clubs", "diamonds", "hearts", "spades") 

tùy thuộc vào giá trị của numberOfSuits, ngoại trừ không có List "nhân" hoạt động mà tôi có thể tìm thấy. Tôi đã bỏ lỡ nó? Có cách nào tốt hơn để tạo boong hoàn chỉnh trước khi xáo trộn không?

BTW, tôi dự định sử dụng Bộ đếm cho phù hợp, nhưng sẽ dễ dàng hơn khi nhập câu hỏi của tôi bằng chuỗi. Tôi sẽ lấy Danh sách tạo ra ở trên và sử dụng một cho hiểu, lặp lại trên các bộ quần áo và một danh sách tương tự của thẻ "xếp hạng" để tạo ra một sàn hoàn chỉnh.

+0

Phần thú vị của dự án này sẽ tạo ra các thế hệ bất chính của phong cảnh (bố cục hiện tại của thẻ). Tôi yêu cầu báo cáo hiện tại cho một danh sách các hành động pháp lý, được trả về dưới dạng bộ dữ liệu (cột nguồn, cột đích và vị trí nguồn). Sau đó tôi áp dụng từng tableau hiện tại theo kiểu đệ quy bằng cách sử dụng một số thuật toán mini-max để tìm di chuyển "tốt nhất".Tôi cũng muốn các đối tượng thẻ là bất biến, vì vậy các tableaus ("tableaux") sẽ phải biết nếu một thẻ đang đối mặt. – Ralph

Trả lời

7

Bạn nên tra cứu scaladoc cho đối tượng List. Nó có tất cả cách cư xử của các phương pháp thú vị để tạo danh sách. Ví dụ, sau đây thực hiện chính xác những gì bạn đang cố gắng:

List.flatten(List.make(4, List("clubs", "diamonds", "hearts", "spades").take(numberOfSuits))).take(4) 

Một mã đẹp hơn nhiều, tuy nhiên, sẽ là này (Scala 2.7):

val suits = List("clubs", "diamonds", "hearts", "spades") 
List.tabulate(4, i => suits.apply(i % numberOfSuits)) 

On Scala 2,8 tabulate là cà ri, vì vậy cú pháp chính xác sẽ là:

List.tabulate(4)(i => suits.apply(i % numberOfSuits)) 
+0

Tôi đã thử ví dụ của bạn nhưng gặp lỗi trên 2.8.0.Beta1-prerelease. Trong thực tế, tôi nhận được lỗi này trên hầu hết các mẫu của List.tabulate tôi có thể tìm thấy. Đưa cái gì? scala> List.tabulate (4, i => suits.apply (i% numberOfSuits)) : 5: error: thiếu kiểu tham số List.tabulate (4, i => suits.apply (i% numberOfSuits)) scala> List.tabulate (4, (i: Int) => suits.apply (i% numberOfSuits)) : 7: lỗi: giá trị phương thức quá tải bảng với các lựa chọn thay thế .... không thể áp dụng cho (Int , (Int) => java.lang.String) List.tabulate (4, (i: Int) => suits.apply (i% numberOfSuits)) ^ –

+0

@Adam Cú pháp thay đổi đôi chút từ 2,7 đến 2,8. Xem câu trả lời đã chỉnh sửa. –

+0

Hài hước bạn nên đề cập đến nó. Tôi quên rằng các tài liệu đơn lẻ nằm ở dưới cùng của các trang tài liệu gói. Trong nhận xét tôi đã viết ở trên, tôi đã đưa ra câu trả lời * CHÍNH XÁC * giống như bạn đã cung cấp trước ở trên. – Ralph

16

Flatten một danh sách hữu hạn của danh sách:

scala> List.fill(2)(List(1, 2, 3, 4)).flatten 
res18: List[Int] = List(1, 2, 3, 4, 1, 2, 3, 4) 

Flatten một suối vô hạn của danh sách, lấy các yếu tố N đầu tiên:

scala> Stream.continually(List(1, 2, 3, 4)).flatten.take(8).toList 
res19: List[Int] = List(1, 2, 3, 4, 1, 2, 3, 4) 
+0

Đây có phải là phương pháp mới trong 2.8.0 không? Tôi không thể làm cho nó hoạt động, nhưng điều này đã làm: val suits = List ("club", "diamonds", "hearts", "spades"); List.flatten (List.make (4, suits.take (1))), trong đó "1" là giá trị numberOfSuits. – Ralph

+0

Có, một số trong số này là mới trong phiên bản 2.8. – retronym

6

Bạn có thể mở rộng một chuỗi số và flatMap thay vì nhân.

scala> (1 to 3).flatMap(_=>List(1,2,3,4).take(2)).take(4) 
res1: Seq[Int] = List(1, 2, 1, 2) 

Điều này cũng hoạt động trong 2.7.x.


Chỉnh sửa: vì bạn ít có kinh nghiệm với Scala, bạn có thể chưa gặp mô hình thư viện của tôi. Nếu bạn muốn nhân danh sách của bạn rất nhiều, bạn có thể thêm một lớp chuyển đổi tùy chỉnh:

class MultipliableList[T](l: List[T]) { 
    def *(n: Int) = (1 to n).flatMap(_=>l).toList 
} 
implicit def list2multipliable[T](l: List[T]) = new MultipliableList[T](l) 

và bây giờ bạn có thể

scala> List(1,2,3)*4 
res2: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3) 

(Nói chung, để tái sử dụng implicits như vậy, tuyên bố chúng trong một đối tượng và sau đó nhập MyObject._ để chuyển đổi ẩn và lớp tương ứng trong phạm vi.)

Các vấn đề liên quan