Dicas para jogar golfe em Clojure

16

Quais são as suas dicas para jogar código com o Clojure?

O objetivo desta pergunta é coletar uma lista de técnicas específicas do Clojure e que podem ser usadas em problemas gerais de golfe com código.

Mikera
fonte
Hmm .. não devem estes tipos de mensagens estar em meta (concedido Eu não tenho certeza meta existia 5+ anos)
Albert Renshaw

Respostas:

6

Use a sintaxe do leitor para lambdas.
Então use

#(+ % %2 %3)

ao invés de

(fn [x y z] (+ x y z))

Você também pode eliminar o espaço em branco algumas vezes:

#(if (< % 0) (- %) %)
#(if(< % 0)(- %)%)
user2429260
fonte
a propósito #(+ % %2 %3)é equivalente a +.
bfontaine
4

Onde você pode remover o espaço em branco:

  • Entre uma string e qualquer outra coisa:

    (println(+"Hello, World!"1))
    
  • Entre colchetes e qualquer outra coisa:

    (for[x(range 5)](* x x))
    
  • Entre um número e tudo que não sejam nomes internos ou variáveis:

    Allowed:
    (+ 1"Example")
    (map{1"-1"2"-2"}[1 2 3])
    
    Not allowed:
    (+1 2)
    
  • Entre @(desreferência para átomos) e colchetes.

clismique
fonte
Também antes da macro deref reader@
somente ASCII
11
Às vezes, você também pode reorganizar as coisas lete se livrar de alguns espaços.
NikoNyrh
Também antes dos parâmetros em funções anônimas: #(+ 1(first%))=#(+ 1 (first %))
bfontaine
3

Strings podem ser tratadas como uma sequência de caracteres

por exemplo, para classificar os caracteres em uma string em ordem alfabética:

(sort "hello")
=> (\e \h \l \l \o)
Mikera
fonte
11
Strings são, por definição, uma sequência de caracteres em quase todas as línguas, mas você não pode aplicar este truque em todos eles :-)
mellamokb
3
Ou melhor, "seqüência" tem um significado especial em Clojure que significa que você pode aplicar truques extras: :-)
mikera
2

Use em nth ... 0vez defirst

Para obter o primeiro elemento de uma coleção, usar (nth ... 0)over firstsalva um byte:

(first[2 3 4]): 14 bytes
(nth[2 3 4]0): 13 bytes (saves a byte!)
clismique
fonte
mesmo se passa para second(2 bytes)
Uriel
11
Além disso, você pode usar vetores como funções, portanto, ([2 3 4]1)retorna o elemento no índice 1. Isso deve ser benéfico se, por exemplo, o formato de entrada for flexível.
NikoNyrh
1

Use aplicar em vez de reduzir

Por exemplo, #(apply + %)um byte é menor que #(reduce + %).

NikoNyrh
fonte
1

Evite deixar se você já tiver um

Por exemplo: em #(for[a[(sort %)]...)vez de#(let[a(sort %)](for ...)) .

Pois também tem uma :letconstrução, mas é muito detalhada para o código de golfe.

NikoNyrh
fonte
1

Use +e em -vez de incedec

Isso economiza 1 byte se você estiver usando inc/ decem uma expressão com parens:

(inc(first[1 3 5]))
(+(first[1 3 5])1)
clismique
fonte
1

Use mapas em vez de ifs ao testar a igualdade

;; if n=3 then A else B
(if (= 3 n) A B) ; (if(=3n)AB)
({3 A} n B)      ; ({3A}nB) -> -3 chars

;; if n=2 or n=3 then A else B
(if (#{2 3} n) A B) ; (if(#{23}n)AB)
({2 A 3 A} n B)     ; ({2A3A}nB) -> -4 chars
bfontaine
fonte
1

Vincule nomes de função longos em let a um símbolo de byte único

Por exemplo, se você precisa usar partitionou frequenciesvárias vezes, poderia ser benéfico para ligá-los a um símbolo de byte único em uma letmacro. Então, novamente, pode não valer a pena se você não precisar do letcontrário, e o nome da função é relativamente curto.

NikoNyrh
fonte
0

Use para em vez de mapa

Por exemplo, #(for[i %](Math/abs i))é muito menor que o mapequivalente.

NikoNyrh
fonte