Suggerimenti per giocare a golf in F #


21

Quali consigli generali hai per giocare a golf in F #? Sto cercando idee che possano essere applicate ai problemi del codice golf in generale che siano almeno in qualche modo specifiche per F # (ad esempio "rimuovere i commenti" non è una risposta). Si prega di inviare un suggerimento per risposta.

Risposte:


9

Utilizzare functioninvece di matchquando possibile; salverà 6 caratteri per variabili di 1 carattere:

let f=function // ... (14 chars)

vs

let f x=match x with // ... (20 chars)

Può anche sostituire qualsiasi corrispondenza di modello per salvare costantemente 1 carattere:

match a with|          // ... (13 chars)
a|>function|           // ... (12 chars)
(function| (* ... *))a // (12 chars)

8

Devi utilizzare un metodo su variabile per il quale non hai ancora vincolato il tipo? Basta confrontarlo con un letterale del tipo che si desidera che sia, quindi gettare via il risultato per annotare il tipo di quella variabile:

let f (x:string)=x.Length
let f x=x="";x.Length

7

Usa la notazione del prefisso per gli operatori infix quando puoi: ti salverà dal dover definire una funzione per usarli.

Ad esempio, puoi girare questo:

List.map(fun i->i+2)[1;1;2;3;5;8]

in questo:

List.map((+)2)[1;1;2;3;5;8]


5

Decostruzione delle tuple

Nel caso in cui non si riesca ad usare le variabili, utilizzare la decostruzione della tupla invece delle espressioni let multiple

let a,b ="",[]

invece di

let a=""
let b=[]

Lettura da stdin

La libreria core F # definisce un alias per System.Console.Inchiamato stdin. Questi ti consentono di leggere l'input.

// Signature:
stdin<'T> :  TextReader

TextReader su msdn

Il grande vantaggio a parte il fatto che è più corto di quello che Consoleè, non è nemmeno necessario aprire il sistema

Iterazione su stringa

string è fondamentalmente un char seq, questo ti permette di usare Seq.mapdirettamente con le stringhe. È anche possibile usarli per comprendere[for c in "" do]

Mutabili / Celle di riferimento

L'uso delle celle di riferimento non è sempre più breve poiché ogni operazione di lettura viene fornita con un carattere aggiuntivo per eliminare la cella.

Suggerimenti generali

  • È possibile scrivere l' match .. withinline completo

    function|'a'->()|'b'->()|_->()
    
  • Non sono necessari spazi vuoti prima e dopo i caratteri non alfanumerici.

    String.replicate 42" "
    if Seq.exists((<>)'@')s then
    if(Seq.exists((<>)'@')s)then
    
  • Nel caso in cui sia necessario riempire a sinistra oa destra una stringa con spazi, è possibile utilizzare i flag [s] printf [n] per questo.

    > sprintf "%20s" "Hello, World!";;
    val it : string = "       Hello, World!"
    

    Modulo Core.Printf


4

Usa id invece di x-> x

id è un operatore che rappresenta la funzione identità.

let u x=x|>Seq.countBy (fun x->x)

può essere scritto

let u x=x|>Seq.countBy id

fonte

Lo uso qui


3

Eta-conversione per funzioni

Mille grazie a Laikoni per questo suggerimento in una delle mie soluzioni .

Considera una funzione, per esempio, sommando una stringa con 3 per le lettere maiuscole e 1 per tutti gli altri caratteri. Così:

let counter input = Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1) input

Per eta-conversione questo può essere riscritto come:

let counter = Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1)

e chiamato come prima:

counter "Hello world!" |> printfn "%i"

L'operatore di composizione diretta in avanti >>

Supponiamo ora che la nostra sfida originale sarebbe quella di sommare una stringa con 3 per lettere maiuscole e 1 per lettere minuscole e tutti gli altri caratteri sono esclusi.

Potremmo scrivere questo come:

let counter input = Seq.filter Char.IsLetter input |> Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1)

Possiamo usare l'operatore di composizione diretta ( >>) per concatenare le due funzioni ( Seq.filtere Seq.sumBy) insieme. Con la conversione eta la definizione della funzione diventerebbe:

let counter = Seq.filter Char.IsLetter >> Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1)

Chris Smith ha scritto alla grande l' >>operatore sul suo blog MSDN .


2

Quando possibile Seqè più breve di List:

[[1];[2;3];[4];[5]|>List.collect
[[1];[2;3];[4];[5]|>Seq.collect

è un carattere più corto ...



2

Preferisci la nuova stringa di riga rispetto a "\ n"

Questo inizierà a pagare anche con un singolo carattere di nuova riga nel tuo codice. Un caso d'uso potrebbe essere:

(18 byte)

string.Concat"\n"

(17 byte)

string.Concat"
"

Ispirato dalla risposta di Chiru per es6 .

Usato qui



1

Usa lambdas per salvare un byte. Ad esempio, questo:

let f x=x*x

Può essere espresso come questo:

fun x->x*x


1

La moduleparola chiave può essere utilizzata per abbreviare i nomi dei moduli se utilizzata più volte. Per esempio:

Array.fold ...
Seq.iter ...
List.map ...

può diventare

module A=Array
A.fold ...
module S=Seq
S.iter ...
module L=List
L.map ...

Ciò è più utile per i programmi più lunghi in cui i metodi del modulo vengono utilizzati ripetutamente (e devono essere nominati ogni volta perché hanno il RequireQualifiedAccessmodificatore) e consente di radere alcuni caratteri, soprattutto quando è più utile utilizzare un array CLR normale (ad esempio, la mutabilità ) di un F # seqo list.

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.