เคล็ดลับสำหรับการเล่นกอล์ฟใน Swift


24

เคล็ดลับในการเล่นโค้ดใน Swift มีอะไรบ้าง? การมุ่งเน้นไปที่ความปลอดภัยดูเหมือนจะทำให้เล่นกอล์ฟยาก แต่ก็มีเคล็ดลับเล็ก ๆ น้อย ๆ และมีประโยชน์มากกว่า มีคุณสมบัติใด ๆ ใน Swift ที่อาจช่วยให้เก่งใน code-golf ในบางแอพพลิเคชั่นหรือไม่?

กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ


11
คุณสามารถไว้ใจ
Conor O'Brien

9
หวังว่าเคล็ดลับที่ดีบางอย่างเข้ามาอย่างรวดเร็ว
DJMcMayhem

4
เล่นกอล์ฟอย่างรวดเร็วหรือไม่ ผมคิดว่าการเล่นกอล์ฟที่ถูกควรจะเป็นช้าเดินเกมสงบ ...
Jojodmo

คำตอบ:


6

ช่วง

สิ่งหนึ่งที่มีประโยชน์จริงๆคือการสร้างช่วงโดยใช้ตัวดำเนินการ...หรือ..<

ตัวอย่างเช่น

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

ดังนั้นเพื่อรับค่า 2 ถึง 4 ของอาร์เรย์

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

ใช้งานจริง

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

การใช้

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

สั้นกว่า 8 ไบต์

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

4
for n in 0...3{print(a[n])}ไม่ถูกต้อง?
Julian Wolf

4

ปิดกิจการ

การใช้ตัวแปรที่เก็บฟังก์ชันกับการใช้ฟังก์ชันสามารถช่วย:

65 ไบต์:

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

66 ไบต์:

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

ความแตกต่างเล็กน้อยที่นี่ แต่มันจะแสดงเพิ่มเติมในปริศนาบางอย่าง

ฟังก์ชั่นการตัดทอน:

การดูตัวอย่างก่อนหน้าทำให้ฉันนึกถึงบางสิ่ง บางครั้งถ้าคุณจะใช้ฟังก์ชั่นเพียงพอครั้งมันก็คุ้มค่าที่จะเปลี่ยนชื่อ:

นี้:

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

สำหรับสิ่งนี้:

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

หรืออันที่จริงดีกว่า:

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

ด้วยวิธีนี้คุณเพียงแค่โทรหาr("Hello World",8)แทนString(repeating:"Hello World",count:8)

ออกจากการประกาศประเภท:

ฉันเคยสร้างการปิดโดยไม่ตั้งค่าประเภทอาร์กิวเมนต์ดังนั้นการสร้างคำตอบที่สั้นกว่า:

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

คอมไพเลอร์เหมาเอาว่าอยู่ในiInt

สร้างอาร์เรย์อย่างรวดเร็ว:

หากคุณต้องการอาเรย์Intsให้ใช้Rangeเพื่อสร้าง:

Array(0...5)

สิ่งนี้ทำเช่นเดียวกับ:

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

อาร์เรย์แทนIfหรือSwitch:

แทนที่จะทำสิ่งนี้:

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

คุณอาจจะทำสิ่งนี้:

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

ร่นประเภท:

หากคุณใช้การแปลงประเภทมากคุณอาจต้องการสร้างนามแฝงประเภท:

typealias f=Float

แผนที่:

โปรดจำไว้ว่าคุณไม่จำเป็นต้องใช้returnคำหลักในmapฟังก์ชั่น

ใช้งาน Swift Online:

แม้ว่าTry It Onlineไม่รองรับ Swift It now !


2
ขอบคุณสำหรับการโพสต์ ช่วยฉันมาก tio.run/nexus สามารถใช้งานได้กับ swift :)
palme

3

try

ใน Swift 2.x ขึ้นไปฟังก์ชั่นที่จัดการข้อผิดพลาดแบบดั้งเดิมโดยส่งตัวชี้ไปยังNSErrorวัตถุเป็นพารามิเตอร์ฟังก์ชั่นในขณะนี้throwข้อผิดพลาดของพวกเขา

ซึ่งหมายความว่าสิ่งนี้:

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

ตอนนี้ดูเหมือนว่า:

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

นี้สามารถจะสั้นลงโดยใช้หรือ try? จะประเมินนิพจน์หากมีข้อผิดพลาดเกิดขึ้น จะทำให้โปรแกรมของคุณพังถ้าเกิดข้อผิดพลาดและควรใช้เฉพาะในกรณีที่ไม่มีข้อผิดพลาดเกิดขึ้นtry!try?niltry!

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

try?และtry!บันทึกอย่างน้อย 13 ไบต์จากdo-try-catchลูป โปรดทราบว่าคุณได้บันทึกอย่างน้อยหนึ่งไบต์อีกด้วยโดยส่งผ่านอาร์เรย์ที่ว่างเปล่า ( []) สำหรับตัวเลือกแทนnilเช่นกัน


3

ลดอาร์เรย์

การวนซ้ำfor-in loopsผ่านอาร์เรย์เพื่อรับค่าเดียวเช่นผลรวมขององค์ประกอบภายในหรือผลคูณขององค์ประกอบอาจยาวเกินไปสำหรับความเรียบง่ายของมัน คุณสามารถใช้reduce()วิธีนี้ได้ ตัวอย่างบางส่วน:

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

การเพิ่มองค์ประกอบในอาร์เรย์ด้วยfor-inลูป:

var sum = 0

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

สามารถทำให้เป็น:

print(array.reduce(0, +))

และรับผลคูณขององค์ประกอบภายในอาร์เรย์ด้วย for-in loops:

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

สามารถลดลงเป็น:

print(array.reduce(1, *))

คุณไม่สูญเสียไบต์มากขึ้นโดยการประกาศ**ฟังก์ชั่นมากกว่าที่คุณต้องการเพียงแค่เรียกpowด้วยตนเอง
JAL

@JAL ใช่ แต่ถ้าคุณโทรหา pow 10 ครั้งจะช่วยประหยัดจำนวนไบต์เล็กน้อย ไม่ใช่เทคนิคการเล่นกอล์ฟที่ดีที่สุด แต่เป็นอีกความช่วยเหลือที่มีศักยภาพ มันไม่ได้มีไว้สำหรับคนที่มีนิสัยเฉยๆ แต่สำหรับคนอื่น ๆ เช่นการค้นหาหมายเลขเฉพาะถ้าคุณทำอย่างนั้น 3 ครั้งมันจะช่วยประหยัดจำนวนไบต์ได้มาก
Mr. Xcoder

2

ผู้ประกอบการที่ประกอบไปด้วย Swift สั้นมาก: condition ? action : otherการกระทำ

หากเงื่อนไขเป็นจริงให้ทำสิ่งหนึ่งถ้าไม่ทำอย่างอื่น

textColor = bgIsBlack ? .white : .black

สิ่งนี้ทำให้textColorสีขาวถ้าพื้นหลังเป็นสีดำหรือสีดำถ้าพื้นหลังเป็นสีอื่น

ผู้ประกอบการศูนย์รวมตัวกันเป็น terser: a ?? b

สมมติว่าคุณกำลังตรวจสอบ JSON สำหรับคีย์ที่แน่นอนเพื่อให้คุณสามารถแสดงค่าของคีย์เป็นข้อความชื่อ หากไม่มีคีย์ (เช่นค่าเป็นศูนย์) เราต้องการให้ข้อความชื่อเริ่มต้น

title = keysValue ?? "Not Available"

2

การนับ

คุณสามารถโยงforEachจากenumerated()ประเภทคอลเลกชันเพื่อรับการอ้างอิงไปยังวัตถุ (หรือประเภทค่า) ในคอลเลกชันเช่นเดียวกับดัชนี:

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

หรือ

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

หรือ (แม้แต่CountableClosedRangeไวยากรณ์ที่สั้นลง)

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

พิมพ์:

0 1
1 2
2 3
3 4
4 5

2

สตริงย่อย

บางครั้งคุณสามารถบันทึกไบต์ด้วยการถอยกลับไปยังประเภทของมูลนิธิแทนที่จะใช้ประเภท Swift ที่บริสุทธิ์ เปรียบเทียบการเข้าถึงสตริงย่อยของประเภทNSStringvs a Swift String:

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

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

แม้ว่าจะมีอักขระ 9 ตัวที่หายไปจากการประกาศxเป็นNSStringแต่คุณก็ประหยัดได้อีก 25 ตัวโดยใช้ประเภท Foundation เนื่องจากsubstringToIndexใช้Intเป็นพารามิเตอร์สำหรับNSStringvs an Indexstruct ( String.CharacterView.Index) สำหรับStringประเภทSwift

ฉันควรทราบว่าความพร้อมใช้งานของประเภท Foundation อาจแตกต่างกันในหลายแพลตฟอร์ม (OS X, Linux, ฯลฯ ) คลาส Foundation ส่วนใหญ่อยู่NSUnimplementedใน Swift เวอร์ชันโอเพ่นซอร์ส


2

.แผนที่()

การรวม.map()กับไวยากรณ์การปิดท้ายสามารถกระชับขึ้นสำหรับลูป เราสามารถใส่สิ่งที่เราต้องการย้ำเข้าไปในอาร์เรย์จากนั้นใช้.map()เพื่อดำเนินการบางอย่างในแต่ละองค์ประกอบ

ตัวอย่างเช่นเราสามารถใช้.map()ในการเขียนเกาลัดเก่านั่น Fizzbuzz ในหนึ่งบรรทัด

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)}

นอกสนามกอล์ฟ.map()สามารถช่วยลดการซ้ำซ้อน ตัวอย่างเช่นสมมติว่าคุณมีมุมมองที่คุณต้องการกำหนดตำแหน่งโดยทางโปรแกรม คุณสามารถใส่จุดยึดสำหรับมุมมองลงในอาร์เรย์ที่ไม่ระบุชื่อและใช้งาน.map()มันเพื่อตั้งค่าข้อ จำกัด แต่ละข้อ.isActiveให้เป็นจริงเช่น:

_ = [
        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
มันจะไม่ดีกว่าที่จะใช้forEachในตัวอย่างที่สองของคุณ? mapควรนำมาใช้เพื่อแปลงเนื้อหาของอาร์เรย์และไม่ใช่ทางลัดซ้ำ ในกรณีนี้คุณจะละทิ้งผลลัพธ์
JAL

1

การกำหนดตัวแปรกอล์ฟในโครงสร้างการควบคุมการไหลโดยใช้สิ่งอันดับ

พิจารณาว่าคุณต้องการใช้การwhileวนซ้ำและคุณต้องการใช้สิ่งเดียวกันทั้งในสภาพและบล็อกที่จะติดตาม จากนั้นการมอบหมายแบบอินไลน์ในทูเปิลจะช่วยได้มากที่สุด คุณลักษณะของคุณอีกต่อไปดีกว่า! พิจารณาสิ่งนี้ (สั้นกว่า 3 ไบต์):

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

มากกว่านี้:

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

สังเกตุ(i=k.count,i>0).1ส่วนที่ค่อนข้างน่าสนใจ


แรงบันดาลใจจากเฮอร์แมน Lauenstein ของ คำตอบ


1

ทำซ้ำเงื่อนไข

น่าเสียดายที่ Swift ไม่รองรับการคูณสตริงด้วย*เช่นเดียวกันกับ Python วิธีการที่ดีที่คุณสามารถใช้แทนได้String(repeating:count:)แต่น่าเสียดายที่นั่นไม่ใช่กอล์ฟ เปรียบเทียบสองแนวทางนี้:

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

และ

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

ตัวที่สองสั้นกว่าสองไบต์ แต่มันไม่สามารถใช้ในการปิดได้ดีกว่า แต่ยังใช้งานได้ในการปิด:

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

และถ้าฉันทำหลายครั้งล่ะ String.init()ดีที่คุณสามารถใช้ ตอนนี้อาจบันทึกจำนวนมาก ตัวอย่างเช่น (68 ไบต์):

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

แทน (74 ไบต์):

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

หรือ (70 ไบต์):

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

แต่ให้แน่ใจว่าสายของคุณยาวพอ หากคุณใช้String(repeating:"abc",3)มันเป็นมากดีกว่าที่จะใช้"abcabcabc"แทน


+1 เพราะฉันไม่มีตัวแปรความคิดสามารถเป็นตัวเริ่มต้นได้
แดเนียล

1

นำเข้า

คุณสามารถแทนที่import Foundationด้วยความยาวได้import UIKit5 ไบต์เนื่องจาก UIKit นำเข้ารากฐานแล้ว


1
อาคุณพูดถูก ไม่เห็นว่าในการตรวจสอบ
mbomb007
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.