Mẹo chơi gôn trong Swift


24

Một số mẹo để chơi golf trong Swift là gì? Sự tập trung của nó vào sự an toàn dường như gây khó khăn cho việc chơi gôn, nhưng điều đó tạo ra những mẹo nhỏ và thậm chí còn hữu ích hơn. Có bất kỳ tính năng nào trong Swift có thể giúp nó vượt trội trong môn đánh gôn trong một số ứng dụng nhất định không?

Xin vui lòng gửi một lời khuyên cho mỗi câu trả lời.


11
Bạn có thể tin tưởng vào chúng tôi - nếu điều đó có nghĩa là an toàn, nó sẽ được thực hiện bằng golf!
Conor O'Brien

9
Hy vọng rằng một số lời khuyên tốt đến nhanh chóng.
DJMcMayhem

4
Chơi golf nhanh? Tôi nghĩ rằng golf được coi là một trò chơi có nhịp độ chậm, bình tĩnh ...
Jojodmo

Câu trả lời:


6

Các dãy

Một điều thực sự hữu ích là tạo phạm vi bằng cách sử dụng ...hoặc ..<toán tử

Ví dụ

array[0..<n] //first n elements of array
array[k..<n] //kth through nth elements of array
array[k...n] //kth through n-1 elements of array

Vì vậy, để có được giá trị thứ 2 đến thứ 4 của một mảng

let myArray = ["ab", "cd", "ef", "gh", "ij", "kl", "mn", "op"]
print(myArray[1..<4]) //["cd", "ef", "gh"]

Công dụng thực tế

let a = [3, 1, 4, 1, 5, 9]

Sử dụng

for v in a[0...3]{print(v)}

Có ngắn hơn 8 byte không

for n in 0...3{let v=a[n];print(v)}

4
Sọ for n in 0...3{print(a[n])}không hợp lệ?
Julian Wolf

4

Đóng cửa:

Việc sử dụng các biến giữ một hàm so với sử dụng một hàm có thể giúp:

65 byte:

var r:(String,Int)->String={return String(repeating:$0,count:$1)}

66 byte:

func r(s:String,i:Int)->String{return String(repeating:s,count:i)}

Sự khác biệt nhỏ ở đây, nhưng nó sẽ hiển thị nhiều hơn trong một số câu đố.

Chức năng rút ngắn:

Nhìn vào ví dụ trước làm tôi nhớ đến một cái gì đó. Đôi khi, nếu bạn sẽ sử dụng một hàm đủ số lần, thì đáng để đổi tên nó:

Điều này:

String(repeating:$0,count:$1)

Về điều này:

var r:(String,Int)->String={return String(repeating:$0,count:$1)}

Hoặc, thực sự, điều này là tốt hơn:

var r=String.init(repeating:count:)

Bằng cách đó bạn chỉ cần gọi r("Hello World",8)thay vìString(repeating:"Hello World",count:8)

Rời khỏi Tuyên bố loại:

Tôi đã từng tạo một bao đóng mà không đặt loại đối số, do đó tạo ra một câu trả lời ngắn hơn:

var f={(i)->Int in i-1+i%2*2}

Trình biên dịch suy ra ilà trong Int.

Tạo mảng theo cách nhanh:

Nếu bạn cần một mảng Ints, sử dụng một Rangeđể tạo nó:

Array(0...5)

Điều này thực hiện tương tự như:

[0,1,2,3,4,5]

Mảng thay vì Ifhoặc Switch:

Thay vì làm điều này:

if n==0{return "a"}else if n==1{return "b"}else{return "c"}

Bạn có thể làm điều này:

return ["a","b","c"][n]

Rút ngắn các loại:

Nếu bạn đang sử dụng chuyển đổi loại nhiều, bạn có thể muốn tạo bí danh loại:

typealias f=Float

Bản đồ:

Hãy nhớ rằng bạn thường không cần sử dụng returntừ khóa trong maphàm.

Chạy Swift trực tuyến:

Mặc dù Try It Online không hỗ trợ Swift Nó hiện tại !


2
Cảm ơn vì bài đăng. Giúp tôi rất nhiều. tio.run/nexus hiện hoạt động với swift :)
palme

3

try

Trong Swift 2.x trở lên, các hàm thường xử lý lỗi bằng cách chuyển một con trỏ đến một NSErrorđối tượng làm tham số hàm bây giờ là throwlỗi của chúng.

Điều này có nghĩa là:

var regex = NSRegularExpression(pattern: "\"((http)s?://.*?)\"", options: nil, error: nil)

bây giờ trông như:

do {
    let regex = try NSRegularExpression(pattern: "\"((http)s?://.*?)\"", options: [])
} catch {
    print(error)
}

Điều này có thể được rút ngắn bằng cách sử dụng try?hoặc try!. try?sẽ đánh giá biểu thức nilnếu một lỗi được ném. try!sẽ làm hỏng chương trình của bạn nếu một lỗi bị ném và chỉ nên được sử dụng trong trường hợp sẽ không bao giờ xảy ra lỗi.

let regex = try! NSRegularExpression(pattern: "\"((http)s?://.*?)\"", options: [])

try?try!lưu ít nhất 13 byte từ do-try-catchvòng lặp. Lưu ý rằng bạn cũng lưu ít nhất một byte bằng cách chuyển vào một mảng trống ( []) cho các tùy chọn thay vì nil.


3

Giảm mảng

Lặp lại for-in loopsthông qua một mảng để có được một giá trị duy nhất, chẳng hạn như tổng các phần tử bên trong hoặc sản phẩm của các phần tử của nó có thể quá dài cho việc nó thực sự đơn giản như thế nào. Bạn chỉ có thể sử dụng reduce()phương pháp. Vài ví dụ:

var array = [1,2,3,4,5,6,7]

Thêm các phần tử trong một mảng bằng for-incác vòng lặp:

var sum = 0

for item in array{
    sum += item
}
print(sum)

có thể được đơn giản hóa để:

print(array.reduce(0, +))

Và nhận được sản phẩm của các phần tử bên trong mảng với các vòng lặp for-in:

var multiplier = 1
for item in array{
    multiplier *= item
}
print(multiplier)

cũng có thể được giảm xuống:

print(array.reduce(1, *))

Bạn không mất nhiều byte hơn bằng cách khai báo **hàm hơn bạn chỉ powbằng cách gọi thủ công?
JAL

@JAL có, nhưng nếu bạn gọi pow 10 lần, nó sẽ tiết kiệm được một lượng nhỏ byte. Không thực sự là kỹ thuật chơi golf tốt nhất, nhưng nó chỉ là một trợ giúp tiềm năng khác. Nó không có nghĩa là cụ thể cho pow, nhưng đối với các hoạt động khác như tìm kiếm số nguyên tố, nếu bạn làm như vậy 3 lần, nó sẽ tiết kiệm được một lượng lớn byte
Ông Xcoder

2

Toán tử ternary của Swift rất ngắn gọn: condition ? action : otherhành động

Nếu điều kiện là đúng, hãy làm một việc, nếu không, hãy làm việc khác.

textColor = bgIsBlack ? .white : .black

Điều này làm cho textColormàu trắng nếu nền là màu đen, hoặc màu đen nếu nền là bất kỳ màu nào khác.

Toán tử kết hợp nil thậm chí còn khó hơn: a ?? b

Giả sử bạn đang kiểm tra JSON cho một khóa nhất định để bạn có thể trình bày giá trị của khóa dưới dạng văn bản tiêu đề. Nếu khóa không có mặt (tức là giá trị bằng 0), chúng tôi muốn cung cấp văn bản mặc định tiêu đề.

title = keysValue ?? "Not Available"

2

Bảng liệt kê

Bạn có thể xâu chuỗi forEachtừ enumerated()một loại bộ sưu tập để có được một tham chiếu đến đối tượng (hoặc loại giá trị) trong một bộ sưu tập, cũng như chỉ mục của nó:

[1,2,3,4,5].enumerated().forEach{print($0,$1)}

hoặc là

for (c,i) in [1,2,3,4,5].enumerated(){print(c,i)}

hoặc ( CountableClosedRangecú pháp thậm chí ngắn hơn )

(1...5).enumerated().forEach{print($0,$1)}

Bản in:

0 1
1 2
2 3
3 4
4 5

2

Chuỗi con

Đôi khi, bạn có thể lưu byte bằng cách quay lại các loại Foundation thay vì sử dụng các loại Swift thuần túy. So sánh việc truy cập một chuỗi con của loại NSStringvs vs Swift String:

let x:NSString = "hello world"
x.substringToIndex(5) // "hello"

let y = "hello world"
y.substringToIndex(y.startIndex.advancedBy(5)) // "hello"

Ngay cả với 9 ký tự bị mất bằng cách khai báo xlà một NSString, bạn vẫn tiết kiệm thêm 25 ký tự bằng cách sử dụng loại Foundation, vì substringToIndexlấy Inttham số làm NSString, so với Indexstruct ( String.CharacterView.Index) cho Stringcác loại Swift .

Tôi nên lưu ý rằng tính khả dụng của các loại Foundation có thể khác nhau trên nhiều nền tảng (OS X, Linux, v.v.). Hầu hết các lớp Foundation đều NSUnimplementedở phiên bản mã nguồn mở của Swift.


2

.bản đồ()

Kết hợp .map()với cú pháp đóng dấu có thể thắt chặt các vòng lặp for. Chúng ta có thể đặt những thứ chúng ta muốn lặp lại vào một mảng, sau đó sử dụng .map()để thực hiện một số hành động trên mỗi phần tử.

Ví dụ, chúng ta có thể sử dụng .map()để viết hạt dẻ cũ đó, Fizzbuzz, trong một dòng.

var d: [Int] = Array(1...100)

d.map{$0%15 == 0 ? print("Fizzbuzz") : $0%3 == 0 ? print("Fizz") : $0%5 == 0 ? print("Buzz") : print($0)}

Bên ngoài sân golf, .map()có thể giúp cắt giảm sự lặp lại. Ví dụ: giả sử bạn có một chế độ xem bạn cần định vị theo chương trình. Bạn có thể đặt các neo cho chế độ xem vào một mảng ẩn danh và chạy .map()qua nó để đặt từng ràng buộc .isActivethành đúng, như vậy:

_ = [
        view.topAnchor.constraint(equalTo: view.topAnchor, constant: 40),
        view.widthAnchor.constraint(equalTo: view.widthAnchor),
        view.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
    ].map { $0.isActive = true }

1
Không phải là tốt hơn để sử dụng forEachtrong ví dụ thứ hai của bạn? mapnên thực sự được sử dụng để chuyển đổi nội dung của một mảng và không phải là một phím tắt lặp. Trong trường hợp này, bạn đang loại bỏ kết quả.
JAL

1

Bài tập biến golf trong cấu trúc dòng điều khiển bằng bộ dữ liệu

Xem xét bạn muốn sử dụng một whilevòng lặp và bạn muốn sử dụng cùng một điều kiện trong cả điều kiện và khối để theo dõi. Sau đó, một nhiệm vụ nội tuyến trong một tuple rất có thể sẽ giúp đỡ. Thuộc tính của bạn càng dài thì càng tốt! Hãy xem xét điều này (ngắn hơn 3 byte):

func f(s:[Int]){var k=s,i=0;while(i=k.count,i>0).1{print(i,i+k[i-1]);k.removeLast();}}

về điều này:

func g(s:[Int]){var k=s,i=0;while k.count>0{i=k.count;print(i,i+k[i-1]);k.removeLast();}}

Chú ý (i=k.count,i>0).1một phần, đó là khá thú vị.


Lấy cảm hứng từ một trong những câu trả lời của Herman Lauenstein .


1

Lặp lại chuỗi

Thật không may, Swift không hỗ trợ nhân chuỗi với *, tương tự như Python. Một phương pháp tốt mà bạn có thể sử dụng thay thế là String(repeating:count:), nhưng thật không may, đó không thực sự là golf. So sánh hai cách tiếp cận này:

var a=String(repeating:"abc",count:3)

var a="";for _ in 0..<3{a+="abc"}

Cái thứ hai ngắn hơn một vài byte, nhưng không thể sử dụng trong một bao đóng ... Tốt hơn nữa, và nó cũng hoạt động trong các bao đóng:

(0..<3).map{_ in"abc"}.joined()

Và nếu tôi làm điều đó nhiều lần thì sao? Vâng, bạn có thể sử dụng String.init(). Bây giờ, điều này có thể tiết kiệm rất nhiều byte. Ví dụ: (68 byte):

let k=String.init(repeating:count:)
print(k("abcd",9)+k("XYZxyz",9))

thay vì (74 byte):

print(String(repeating:"abcd",count:9)+String(repeating:"XYZxyz",count:9))

hoặc (70 byte):

var f={String(repeating:$0,count:$1)}
print(f("abcd",9)+f("XYZxyz",9))

Nhưng hãy chắc chắn rằng Chuỗi của bạn đủ dài. Nếu bạn đang sử dụng String(repeating:"abc",3), nó được nhiều tốt hơn để sử dụng "abcabcabc"thay thế.


+1 vì tôi không có biến ý tưởng nào có thể là khởi tạo như thế.
Daniel

1

Nhập khẩu

Bạn có thể thay thế import Foundationbằng import UIKit5 byte ngắn hơn, vì UIKit đã nhập Foundation.


1
À bạn nói đúng. Không thấy điều đó trong đánh giá
mbomb007
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.