Swiftでのコードゴルフのヒントは何ですか?安全性に重点を置いているため、ゴルフをするのが難しくなっているように見えますが、ヒントはほとんどなく、さらに便利です。Swiftには、特定のアプリケーションのコードゴルフで優れていると思われる機能がありますか?
回答ごとに1つのヒントを投稿してください。
Swiftでのコードゴルフのヒントは何ですか?安全性に重点を置いているため、ゴルフをするのが難しくなっているように見えますが、ヒントはほとんどなく、さらに便利です。Swiftには、特定のアプリケーションのコードゴルフで優れていると思われる機能がありますか?
回答ごとに1つのヒントを投稿してください。
回答:
本当に役立つのは、...
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)}
for n in 0...3{print(a[n])}
無効ですか?
関数を保持する変数と関数自体を使用する変数を使用すると、次のことができます。
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
。
の配列が必要な場合はInts
、a 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
関数でキーワードを使用する必要はありません。
が、それをオンラインで試してみてくださいスウィフトサポートしていません。 それは今ありません!
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
ます。また[]
、オプションの代わりに空の配列()を渡すことにより、少なくとももう1バイトを節約することに注意してくださいnil
。
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
手動で呼び出すよりも多くのバイトを失いませんか?
スウィフトの三項演算子は非常に簡潔です:condition ? action : other
アクション
条件が真である場合、1つのことを行い、そうでない場合、何か他のことを行います。
textColor = bgIsBlack ? .white : .black
これにより、textColor
背景が黒の場合は白、背景が他の色の場合は黒になります。
nil合体演算子はさらに簡潔です: a ?? b
キーの値をタイトルテキストとして表示できるように、特定のキーのJSONをチェックしているとします。キーが存在しない場合(値がnilの場合)、タイトルのデフォルトテキストを指定します。
title = keysValue ?? "Not Available"
純粋なSwift型を使用する代わりに、Foundation型にフォールバックすることでバイトを節約できる場合があります。のサブストリングとNSString
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以上を節約substringToIndex
取るInt
ためのパラメータとしてNSString
対、Index
構造体(String.CharacterView.Index
スウィフトのための)String
タイプ。
Foundationタイプの可用性は、複数のプラットフォーム(OS X、Linuxなど)によって異なる場合があることに注意してください。ほとんどのFoundationクラスはNSUnimplemented
、Swiftのオープンソースバージョンにあります。
.map()
末尾のクロージャ構文と組み合わせると、forループを強化できます。繰り返したいものを配列に入れて.map()
から、各要素に対して何らかのアクションを実行するために使用できます。
たとえば.map()
、古い栗、Fizzbuzzを1行で書くのに使用できます。
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 }
forEach
2番目の例で使用する方が良いと思いませんか? map
繰り返しのショートカットとしてではなく、配列の内容の変換に実際に使用する必要があります。この場合、結果は破棄されます。
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(repeating:count:)
、残念ながらそれは実際にはゴルフではありません。これら2つのアプローチを比較してください。
var a=String(repeating:"abc",count:3)
そして
var a="";for _ in 0..<3{a+="abc"}
2つ目は数バイト短くなりますが、クロージャーでは使用できません...さらに良いことに、クロージャーでも機能します。
(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"
代わりに。