스위프트에서의 골프 팁


24

Swift에서 코드 골프에 대한 팁은 무엇입니까? 안전에 중점을두면 골프를 타기가 어려워 지지만 팁이 적고 유용합니다. Swift에는 특정 응용 프로그램에서 코드 골프에 탁월한 기능이 있습니까?

답변 당 하나의 팁을 게시하십시오.


11
당신이 우리를 의지 할 수 있습니다. 만약 그것이 안전하기를 원한다면
Conor O'Brien 1

9
다행히도 좋은 팁이 신속하게 제공되기를 바랍니다.
DJMcMayhem

4
스위프트 골프? 골프가 느리고 차분한 게임 인 줄 알았는데 ...
Jojodmo

답변:


6

범위

정말 유용한 한 가지는 ...or ..<연산자를 사용하여 범위를 만드는 것입니다.

예를 들어

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}

컴파일러 i는에 있음을 유추 했습니다 Int.

빠른 방법으로 배열 만들기 :

의 배열이 필요한 경우 Intsa 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.

스위프트 온라인 실행 :

하지만 것은 온라인으로 시도 스위프트 지원하지 않습니다 그것은 지금 않습니다 !


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?식을 평가합니다 nil. try!오류가 발생하면 프로그램이 중단되며 오류가 발생하지 않는 경우에만 사용해야합니다.

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 루프를 사용하여 배열 내부의 요소 곱을 얻는 방법 :

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

또한 다음과 같이 줄일 수 있습니다.

print(array.reduce(1, *))

수동으로 **호출하는 것보다 함수 를 선언하여 더 많은 바이트를 잃지 pow않습니까?
JAL

@JAL 예. 그러나 pow를 10 번 호출하면 적은 양의 바이트가 절약됩니다. 실제로 최고의 골프 ​​기술은 아니지만 또 다른 잠재적 인 도움 일뿐입니다. 그것은 특별히 펑 의미하지만, 그런 당신이 3 번 할 경우, 소수에 대한 검색과 같은 다른 작업을 위해, 그것은 바이트의 엄청난 금액을 절약 할 한
씨 Xcoder을

2

스위프트의 삼항 연산자는 매우 간결하다 : condition ? action : other행동

조건이 맞으면 한 가지를 수행하고 그렇지 않은 경우 다른 것을 수행하십시오.

textColor = bgIsBlack ? .white : .black

이것은 만드는 textColor배경이 다른 색상의 경우 배경이 검은 색 또는 검은 색이면 흰색을.

무 연합 연산자는 더욱 간결합니다. a ?? b

JSON의 특정 키를 검사하여 키 값을 제목 텍스트로 표시 할 수 있다고 가정 해 보겠습니다. 키가 없으면 (예 : 값이 nil) 제목에 기본 텍스트를 지정하려고합니다.

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 유형 대신 Foundation 유형으로 돌아가 바이트를 절약 할 수 있습니다. NSStringSwift String유형과 Swift 유형 의 하위 문자열 액세스를 비교하십시오 .

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

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

심지어 선언함으로써 손실 9 개 문자로 xint로서 NSString있기 때문에, 당신은, 재단 형식을 사용하여 25 개를 저장 substringToIndex소요 Int에 대한 매개 변수로 NSString대, Index구조체 ( String.CharacterView.Index스위프트에 대한) String유형.

Foundation 유형의 가용성은 여러 플랫폼 (OS X, Linux 등)에 따라 다를 수 있습니다. 대부분의 Foundation 수업은 NSUnimplementedSwift의 오픈 소스 버전에 있습니다.


2

.지도()

.map()후행 클로저 구문과 결합하면 루프를 강화할 수 있습니다. 반복하고자하는 것들을 배열에 넣은 다음 .map()각 요소에 대해 몇 가지 작업을 수행 할 수 있습니다.

예를 들어, 우리는 .map()그 오래된 밤 피즈 버즈를 한 줄에 쓸 수 있습니다 .

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을 true 로 설정할 수 있습니다.

_ = [
        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꽤 흥미로운 부분을 주목하십시오 .


Herman Lauenstein의 답변 중 하나에서 영감을 얻었습니다 .


1

문자열 반복

불행히도 Swift는 *Python 과 마찬가지로 String 곱셈을 지원하지 않습니다 . 대신 사용할 수있는 좋은 방법은 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입니다.
Daniel

1

수입

당신은 대체 할 수 import Foundationimport UIKitUIKit 이미 수입 재단처럼, 5 짧은 바이트.


1
아 맞아. 검토에서 그것을 보지
못했음
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.