F # golf için ipuçları


21

F # 'da golf oynamak için hangi genel ipuçlarınız var? Genel olarak golf problemlerini kodlamak için uygulanabilecek fikirleri arıyorum, en azından biraz F # 'ya özgü (örneğin "yorumları kaldır" bir cevap değil). Lütfen cevap başına bir ipucu gönderin.

Yanıtlar:


9

Mümkün olduğunda functionyerine kullanın match; 1 karakterlik değişkenler için 6 karakter kaydeder:

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

vs

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

Aynı zamanda 1 karakteri tutarlı bir şekilde kaydetmek için herhangi bir desen eşleşmesinin yerini alabilir:

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

8

Türünü henüz sınırlamadığınız bir değişkende bir yöntem kullanmanız mı gerekiyor? Sadece onu istediğiniz türün değişmezi ile karşılaştırın ve sonra bu değişkenin türünü not almak için sonucu atın.

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

7

Yapabildiğiniz zaman infix operatörleri için önek notasyonunu kullanın - bunları kullanmak için bir fonksiyon tanımlamak zorunda kalmazsınız.

Örneğin, bunu açabilirsiniz:

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

bunun içine:

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

1
Burada kullanıyorum, teşekkürler!
aloisdg diyor

5

Tuple yapısökümü

Değişkenleri kullanmakta başarılı olamamanız durumunda, çoklu izin ifadeleri yerine tuple yapısını kullanın.

let a,b ="",[]

yerine

let a=""
let b=[]

Stdin'den okuma

F # çekirdek kütüphanesi System.Console.Inçağrılan takma adı tanımlar stdin. Bunlar girişi okumanıza izin verir.

// Signature:
stdin<'T> :  TextReader

Msdn'deki TextReader

Olduğundan daha kısa olmasının yanında büyük bir avantaj Console, Sistemi açmak zorunda değilsin.

Dize üzerinde yineleme

dize temel olarak bir a char seq, bu Seq.mapdoğrudan dizelerle kullanmanıza izin verir . Onları anlamada kullanmak da mümkündür.[for c in "" do]

Değişkenler / Referans hücreler

Referans hücrelerin kullanılması, her okuma işlemi hücreyi silmek için ek bir karaktere sahip olduğundan, her zaman kısa değildir.

Genel ipuçları

  • Tam match .. withsatır içi yazmak mümkündür

    function|'a'->()|'b'->()|_->()
    
  • Alfanümerik olmayan karakterlerden önce ve sonra boşluk bırakılmasına gerek yoktur.

    String.replicate 42" "
    if Seq.exists((<>)'@')s then
    if(Seq.exists((<>)'@')s)then
    
  • Boşluk içeren bir dize sola veya sağa kaydırmanız gerekirse, bunun için [s] printf [n] bayraklarını kullanabilirsiniz.

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

    Core.Printf Modülü



3

İşlevler için eta dönüştürme

Çözümlerimden birinde bu ipucu için Laikoni'ye teşekkür ederim .

Örneğin, büyük harfler için 3, diğer tüm karakterler için 1 ile bir dize toplamı için bir işlev düşünün. Yani:

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

By eta-dönüşüm bu şekilde yeniden yazılabilir:

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

ve daha önce olduğu gibi çağrıldı:

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

Fonksiyon ileri kompozisyon operatörü >>

Şimdi, asıl meselemizin, büyük harfler için 3, küçük harfler için 1 ve diğer tüm karakterler hariç tutulacağı bir dize toplamak olduğunu varsayalım.

Bunu şu şekilde yazabiliriz:

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

>>İki işlevi ( Seq.filterve Seq.sumBy) bir araya getirmek için ileri kompozisyon operatörünü ( ) kullanabiliriz . Eta dönüşümü ile işlev tanımı şöyle olacaktır:

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

Chris Smith, >>operatöre MSDN blogunda harika bir yazı yazdı .


2

Mümkün Seqolduğunda şunlardan daha kısadır List:

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

bir karakter daha kısa ...




1

.NET kullanın

.NET, pek çok hoş eklenti sunar. F # onları kullanabilir, bu yüzden onları unutma!

Örnek:

open System.Linq

Yardımcı olabilir!


1

Bir bayt kaydetmek için lambda kullanın. Örneğin, bu:

let f x=x*x

Bu şekilde ifade edilebilir:

fun x->x*x


1

moduleAnahtar kelime tekrar tekrar kullanıldığında modül isimlerini kısaltmak için kullanılabilir. Örneğin:

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

olabilir

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

Bu, modül yöntemlerinin tekrar tekrar kullanıldığı daha uzun programlar için daha faydalıdır (ve her seferinde RequireQualifiedAccessdeğiştiriciye sahip oldukları için tam olarak adlandırılmalıdır ) ve özellikle düzenli bir CLR dizisi (örneğin, değişkenlik) kullanmanın daha yararlı olduğu durumlarda birkaç karakterin tıraş edilmesini sağlar ) bir F # seqveya list.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.