Советы по игре в гольф в Clojure

16

Каковы ваши советы по игре в гольф с использованием Clojure?

Цель этого вопроса - собрать список техник, которые специфичны для Clojure и могут быть использованы в общих задачах по коду.

mikera
источник
Хм ... не должны ли эти типы постов быть в мета (если я не уверен, что мета существовала 5+ лет назад)
Альберт Реншоу

Ответы:

6

Используйте синтаксис читателя для лямбд.
Так что используйте

#(+ % %2 %3)

вместо того

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

Вы также можете устранить пробелы в некоторых случаях:

#(if (< % 0) (- %) %)
#(if(< % 0)(- %)%)
user2429260
источник
кстати #(+ % %2 %3)эквивалентно +.
bfontaine
4

Где вы можете удалить пробелы:

  • Между строкой и чем-либо еще:

    (println(+"Hello, World!"1))
    
  • Между скобками и прочим:

    (for[x(range 5)](* x x))
    
  • Между числом и всем, кроме встроенных или имен переменных:

    Allowed:
    (+ 1"Example")
    (map{1"-1"2"-2"}[1 2 3])
    
    Not allowed:
    (+1 2)
    
  • Между @(разыменование для атомов) и скобками.

clismique
источник
Также до макроса deref reader@
ASCII-only
1
Также иногда вы можете переставить вещи в letи избавиться от некоторых пробелов.
NikoNyrh
Также перед параметрами в анонимных функциях: #(+ 1(first%))=#(+ 1 (first %))
bfontaine
3

Строки могут рассматриваться как последовательность символов

например, отсортировать символы в строке по алфавиту:

(sort "hello")
=> (\e \h \l \l \o)
mikera
источник
1
Строки по определению являются последовательностью символов почти на каждом языке, но вы не можете применить этот трюк во всех них :-)
mellamokb
3
Вернее, «последовательность» имеет особое значение в Clojure, а не означает, что вы можете применять дополнительные трюки: :-)
mikera
2

Используйте nth ... 0вместоfirst

Чтобы получить первый элемент коллекции, используйте (nth ... 0)over для firstсохранения байта:

(first[2 3 4]): 14 bytes
(nth[2 3 4]0): 13 bytes (saves a byte!)
clismique
источник
то же самое касается second(2 байта)
Уриэль
1
Также вы можете использовать векторы как функции, поэтому ([2 3 4]1)возвращает элемент с индексом 1. Это должно быть полезно, если, например, формат ввода гибкий.
NikoNyrh
1

Используйте применить вместо уменьшения

Например, #(apply + %)на один байт короче #(reduce + %).

NikoNyrh
источник
1

Избегайте, если у вас уже есть для

Например: #(for[a[(sort %)]...)вместо#(let[a(sort %)](for ...)) .

У также есть :letконструкция, но она слишком многословна для кода гольф.

NikoNyrh
источник
1

Используйте +и -вместо incиdec

Это экономит 1 байт, если вы используете inc/ decв выражении с паренами:

(inc(first[1 3 5]))
(+(first[1 3 5])1)
clismique
источник
1

Используйте карты вместо ifs при тестировании на равенство

;; 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
источник
1

Привязать длинные имена функций в let к однобайтовому символу

Например, если вам нужно использовать partitionили frequenciesнесколько раз, было бы полезно связать их с однобайтовым символом в letмакросе. Опять же, это может не стоить того, если вам не нужно letиное, а имя функции относительно короткое.

NikoNyrh
источник
0

Используйте для вместо карты

Например, #(for[i %](Math/abs i))намного короче, чем mapэквивалент.

NikoNyrh
источник