Suggerimenti per giocare a golf in Swift


24

Quali sono alcuni suggerimenti per giocare a golf in Swift? La sua attenzione alla sicurezza sembra rendere difficile giocare a golf, ma questo rende piccoli consigli e ancora più utili. Esistono funzioni in Swift che possono aiutarlo a eccellere nel code-golf in determinate applicazioni?

Si prega di inviare un suggerimento per risposta.


11
Puoi contare su di noi - se è pensato per essere sicuro, sarà reso goloso!
Conor O'Brien,

9
Eventualmente alcuni buoni consigli arrivano rapidamente.
DJMcMayhem

4
Giocare a golf veloce? Pensavo che il golf doveva essere un gioco lento e calmo ...
Jojodmo,

Risposte:


6

Intervalli

Una cosa che è veramente utile è la creazione di intervalli utilizzando gli operatori ...o..<

Per esempio

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

Quindi, per ottenere i valori dal 2 ° al 4 ° di un array

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

Uso pratico

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

utilizzando

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

È 8 byte più corto di

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

4
... for n in 0...3{print(a[n])}non è valido?
Julian Wolf,

4

chiusure:

L'uso di variabili che contengono una funzione rispetto all'utilizzo di una funzione stessa può aiutare:

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

Piccola differenza qui, ma mostrerà di più in alcuni enigmi.

Funzioni di accorciamento:

Guardare l'esempio precedente mi ricorda qualcosa. A volte, se utilizzerai una funzione abbastanza volte, vale la pena lo spazio per rinominarla:

Questo:

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

A questa:

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

O, in realtà, questo è meglio:

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

In questo modo basta chiamare r("Hello World",8)invece diString(repeating:"Hello World",count:8)

Tralasciando le dichiarazioni di tipo:

Una volta ho creato una chiusura senza impostare il tipo di argomento, creando così una risposta più breve:

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

Il compilatore ha dedotto che iè dentro Int.

Crea array in modo rapido:

Se hai bisogno di un array di Ints, usa a Rangeper crearlo:

Array(0...5)

Questo fa la stessa cosa di:

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

Matrici Invece di Ifo Switch:

Invece di fare questo:

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

Probabilmente puoi farlo:

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

Accorciare i tipi:

Se stai usando molto la conversione di tipo, potresti voler creare un alias di tipo:

typealias f=Float

Carta geografica:

Ricorda che spesso non è necessario utilizzare la returnparola chiave nella mapfunzione.

Esecuzione di Swift Online:

Anche se Provalo online non supporta Swift It adesso !


2
Grazie per il post. Mi ha aiutato molto tio.run/nexus ora funziona con swift :)
palme

3

try

In Swift 2.xe versioni successive, le funzioni che gestivano tradizionalmente gli errori passando un puntatore a un NSErroroggetto come parametro di funzione ora rappresentano il throwloro errore.

Ciò significa che questo:

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

ora sembra:

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

Questo può essere abbreviato usando try?o try!. try?valuterà l'espressione nilse viene generato un errore. try!arresta in modo anomalo il programma se viene generato un errore e deve essere utilizzato solo nei casi in cui non verrà mai generato un errore.

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

try?e try!salva almeno 13 byte dal do-try-catchloop. Si noti che si salva anche almeno un byte in più passando un array vuoto ( []) per le opzioni anziché nil.


3

Matrici di riduzione

Iterando con for-in loopsun array per ottenere un singolo valore come la somma degli elementi all'interno, o il prodotto dei suoi elementi potrebbe essere troppo lungo per quanto sia semplice. Puoi semplicemente usare il reduce()metodo Qualche esempio:

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

Aggiunta degli elementi in un array con for-inloop:

var sum = 0

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

può essere semplificato per:

print(array.reduce(0, +))

E ottenere il prodotto degli elementi all'interno dell'array con loop for-in:

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

può anche essere ridotto a:

print(array.reduce(1, *))

Non perdi più byte dichiarando la **funzione di quanto faresti semplicemente chiamando powmanualmente?
JAL

@JAL sì, ma se chiami pow 10 volte, risparmia una piccola quantità di byte. Non è proprio la migliore tecnica del golf, ma è solo un altro potenziale aiuto. Non è stato pensato specificamente per Pow, ma per altre operazioni come la ricerca di numeri primi, se lo fai 3 volte, risparmia un'enorme quantità di byte
Mr. Xcoder

2

L'operatore ternario di Swift è molto conciso: l' condition ? action : otherazione

Se la condizione è vera, fare una cosa, in caso contrario, fare qualcos'altro.

textColor = bgIsBlack ? .white : .black

Questo rende il textColorbianco se lo sfondo è nero o nero se lo sfondo è di qualsiasi altro colore.

L'operatore a coalescenza zero è ancora più terser: a ?? b

Supponiamo che tu stia controllando JSON per una determinata chiave in modo da poter presentare il valore della chiave come testo del titolo. Se la chiave non è presente (ovvero il valore è zero), vogliamo dare al titolo il testo predefinito.

title = keysValue ?? "Not Available"

2

Enumerazione

È possibile eseguire la catena forEachda enumerated()un tipo di raccolta per ottenere un riferimento all'oggetto (o al tipo di valore) in una raccolta, nonché al suo indice:

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

o

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

o ( CountableClosedRangesintassi ancora più breve )

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

stampe:

0 1
1 2
2 3
3 4
4 5

2

substring

A volte, è possibile salvare byte ricadendo sui tipi di Foundation anziché utilizzare i tipi Swift puri. Confronta l'accesso a una sottostringa di un tipo NSStringvs un Swift String:

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

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

Anche con i 9 caratteri persi dichiarandoli xcome NSString, si risparmiano altri 25 usando il tipo Foundation, poiché substringToIndexprende un Intparametro come NSString, vs an Indexstruct ( String.CharacterView.Index) per i Stringtipi Swift .

Devo notare che la disponibilità dei tipi di Foundation può variare su più piattaforme (OS X, Linux, ecc.). La maggior parte delle lezioni della Fondazione sono NSUnimplementednella versione open source di Swift.


2

.carta geografica()

La combinazione .map()con la sintassi della chiusura finale può restringere i for-loop. Possiamo mettere le cose su cui vogliamo iterare in un array, quindi usare .map()per eseguire alcune azioni su ciascun elemento.

Ad esempio, possiamo usare .map()per scrivere quella vecchia castagna, Fizzbuzz, in una riga.

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

Al di fuori del golf, .map()può aiutare a ridurre la ripetizione. Ad esempio, supponiamo di avere una vista che è necessario posizionare a livello di codice. È possibile inserire le ancore per la vista in un array anonimo e passarci .map()sopra per impostare ogni vincolo .isActivesu true, in questo modo:

_ = [
        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
Non è meglio usare forEachnel tuo secondo esempio? mapdovrebbe davvero essere usato per trasformare il contenuto di un array e non come scorciatoia di iterazione. In questo caso, stai scartando il risultato.
JAL

1

Assegnare variabili golf nelle strutture di flusso di controllo usando le tuple

Considera di voler utilizzare un whileciclo e di voler usare la stessa cosa sia nella condizione che nel blocco da seguire. Quindi, un compito inline in una tupla sarebbe molto probabilmente di aiuto. Più lungo è il tuo attributo, meglio è! Considera questo (3 byte più corto):

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

oltre questo:

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

Notare la (i=k.count,i>0).1parte, che è piuttosto interessante.


Ispirato da una delle risposte di Herman Lauenstein .


1

Ripetendo le stringhe

Sfortunatamente, Swift non supporta la moltiplicazione di stringhe con *, allo stesso modo Python. Un buon metodo che puoi usare invece è String(repeating:count:), ma sfortunatamente non è davvero da golf. Confronta questi due approcci:

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

e

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

Il secondo è più corto di un paio di byte, ma non può essere utilizzato in una chiusura ... Meglio ancora, e funziona anche nelle chiusure:

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

E se lo facessi più volte? Bene, puoi usare String.init(). Ora, questo può salvare molti byte. Ad esempio (68 byte):

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

anziché (74 byte):

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

o (70 byte):

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

Ma assicurati che la tua stringa sia abbastanza lunga. Se stai usando String(repeating:"abc",3), è molto meglio usare "abcabcabc"invece.


+1 perché non avevo idea che le variabili potessero essere inizializzatori del genere.
Daniel,

1

Importare

Puoi sostituirlo import Foundationcon import UIKit5 byte in meno, poiché UIKit importa già Foundation.


1
Ah hai ragione. Non l'ho visto nella recensione
mbomb007 il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.