Edit : para as pessoas que lêem isso, que não conhecem o APL, mas querem adotá -lo, o Mastering Dyalog APL é um recurso muito bom.
A avaliação é estritamente da direita para a esquerda. Isso inclui definir variáveis, portanto, tire proveito disso.
2+a, 1+a←1
-> 3 4
a
é definido como 1
, 1+a
avalia 2
, a,2
avalia 1 2
e 2+1 2
avalia como 3 4
.
Como C, ←
pode ser combinado com uma função, ie a +← 3
. Ao contrário de C, isso é genérico: foo F← bar
define foo
como F bar
. De maneira um pouco não intuitiva, como expressão isso retorna bar
, não F bar
.
Também funciona com funções anônimas:
a←0
a+←3 ⋄ a
3
a+←3 ⋄ a
6
a { ⍵/'!' } ←4 ⋄ a
!!!!
Você pode atribuir a uma matriz:, A[3]←8
como seria de esperar. Mas você também pode atribuir vários itens ao mesmo tempo: A[3 5 6]←9 1 4
ou mesmo A[3 5 6]←9
configurá-los para o mesmo item. Você pode, é claro, adicionar uma função ao ←
aqui também. A função será aplicada a cada elemento separadamente, como se você o fizesse F¨
.
⍨
é seu amigo, mesmo que ele não pareça muito feliz com isso.
Se F
for diádico, diádico ⍨
alterna os argumentos: a F b
<-> b F⍨ a
. Isso é útil ao jogar golfe, pois pode evitar que você use chaves:
(F G H x) K y <-> y K⍨ F G H x
Isso altera a ordem de avaliação, pois a mão direita é sempre avaliada antes da mão esquerda.
Se F
é diádico, monádico ⍨
aplica o mesmo argumento aos dois lados da função:
5⍴5
5 5 5 5 5
⍴⍨5
5 5 5 5 5
O argumento é avaliado apenas uma vez. Isso é particularmente útil com produtos externos, ou seja, para comparar cada valor em uma matriz com outros valores na mesma matriz, você pode usar em ∘.=⍨
vez de precisar fazer isso x∘.=x←(whatever)
.
Se F
é monádico, ⍨
não faz nada, mas separa a função do argumento. Portanto, ele ainda pode economizar chaves se a função for complexa:
{⍵+3}⍣5 6
∇{⍵+3}
∇ ⍣ 5 6
({⍵+3}⍣5)6
21
{⍵+3}⍣5⍨6
21
Aprenda os idiomas! Depois golf os idiomas. Por exemplo:
((((1↑⍴X),⍴Y)↑X)^.=Y)⌿X
pode ser transformado mecanicamente em:
X⌿⍨Y^.=⍨X↑⍨(1↑⍴X),⍴Y
e depois para:
X⌿⍨Y^.=⍨X↑⍨(⊃⍴X),⍴Y
⊃
(primeiro) sendo equivalente a 1↑
(pegue um) neste caso. E possivelmente:
X⌿⍨Y^.=⍨X↑⍨(≢X),⍴Y
≢
(registro) sendo equivalente a ⊃⍴
(o primeiro elemento da forma) para todos, exceto os escalares.
Trens
fonte
Truques para lidar com
/
e⌿
em trensAo usar trens, convém usar reduções
f/
como soma+/
ou mesmo replicar a redução//
. No entanto, se o seu trem tiver mais peças à esquerda da redução, você precisará de parênteses para criar um topo. Aqui estão alguns truques para salvar bytes.Use em
1∊
vez de matrizes monádicas∨/
ou∨⌿
booleanasTarefa: Dadas duas seqüências de tamanho igual A e B, retorne 2 se qualquer caractere correspondente de A e B for igual, 0 caso contrário. Por exemplo,
A←'abc'
eB←'def'
dá0
eA←'abc'
eB←'dec'
dá2
.Uma solução dfn pode ser,
A{2×∨/⍺=⍵}B
mas você deseja reduzi-la, tornando-a tácita.A(2×∨/=)B
não vai funcionar porque as regras de formação de trens analisam isso como2 (× ∨/ =)
você deseja2 × (∨/=)
.Observe que
∨/
ou∨⌿
em um vetor booleano (∨/,
ou∨⌿,
para matrizes de classificação mais alta) pergunta se existe algum 1 presente, ou seja1∊
, para que possamos escrever nosso trem como2×1∊=
.Observe que
∊
o argumento correto é desviado, portanto você não pode usá-lo para reduzir cada linha ou coluna separadamente.Use em
1⊥
vez de monádico+/
ou+⌿
Tarefa: Dada uma lista de listas L e um índice N, retorne três vezes a soma da enésima lista. Por exemplo,
L←(3 1 4)(2 7)
eN←1
dá24
.Uma solução dfn pode ser,
N{3×+/⍺⊃⍵}L
mas você deseja reduzi-la, tornando-a tácita.N(3×+/⊃)L
não vai funcionar porque as regras de formação de trens analisam isso como3(× +/ ⊃)
você deseja3 × (+/⊃)
.Observe que avaliar uma lista de números em unário (base 1) é equivalente a somar a lista porque a { a , b , c , d } = a + b + c + d = ( a × 1³) + ( b × 1²) ) + ( c × 1¹) + ( d × 1⁰). Portanto,
+/a b c d
é o mesmo que1⊥a b c d
, e podemos escrever nosso trem como3×1⊥⊃
.Observe que, nos argumentos de classificação mais alta,
1⊥
é equivalente a+⌿
.Use em
f.g
vez def/g
argumentos escalares e / ou vetoriaisTarefa: Dada uma lista L e um número N, retornar o intervalo 1 completa o número de resto mínimos divisão quando os elementos de L são divididos por ELg
L←31 41 59
eN←7
dá1 2 3
.Uma solução dfn pode ser,
N{⍳⌊/⍺|⍵}L
mas você deseja reduzi-la, tornando-a tácita.N(⍳⌊/|)L
não vai funcionar porque as regras de formação de trens analisam isso como⍳ (⌊/) |
você deseja⍳ (⌊/|)
.O produto interno
A f.g B
das duas funções escalares quando os argumentos são escalares e / ou vetores é o mesmo quef/ A g B
ambos são(A[1] g B[1]) f (A[2] g B[2]) f (A[3] g B[3])
etc., para que possamos escrever nosso trem como⍳⌊.|
.Observe que isso não funciona para matrizes de classificação mais alta.
Use em
∊⊆
vez de/
argumentos à esquerda booleanos e à direita de vetor simplesTarefa: Dada uma lista L e um número N, filtre a lista para que apenas números maiores que N permaneçam. Por exemplo,
L←3 1 4
eN←1
dá3 4
.Uma solução dfn pode ser,
N{(⍺<⍵)/⍵}L
mas você deseja reduzi-la, tornando-a tácita.N(</⊢)L
não funcionará porque as regras de ligação analisarão isso como(</) ⊢
mas você deseja/
que a função seja replicada em vez de reduzir o operador .Diádico
⊆
com um argumento à esquerda booleano particiona o argumento à direita de acordo com execuções de 1s no argumento à esquerda, eliminando elementos indicados por 0s. Isso é quase o que queremos, exceto pelo particionamento indesejado. No entanto, podemos nos livrar da partição aplicando monádica∊
. Assim{(⍺<⍵)/⍵}
pode se tornar{∊(⍺<⍵)⊆⍵}
e assim podemos escrever nosso trem como∊<⊆⊢
.Observe que isso não funciona para matrizes de classificação mais alta.
Use em
0⊥
vez de⊢/
ou⊢⌿
com argumentos numéricosTarefa: Dada uma lista L e um número N, multiplique N pelo elemento mais à direita de LEg
L←3 1 4
eN←2
dê8
.Uma solução dfn pode ser,
N{⍺×⊢/⍵}L
mas você deseja reduzi-la, tornando-a tácita.N(⊣×⊢/⊢)L
não vai funcionar porque as regras de formação de trens analisam isso como⊣ (× ⊢/ ⊢)
você deseja⊣ × (⊢/⊢)
.Observe que
0⊥
em uma matriz numérica é o mesmo que⊢⌿
, para que possamos escrever nosso trem como⊣×0⊥⊢
.Observe que isso seleciona a última célula principal de matrizes de classificação mais alta.
fonte
Use
⊥
para combinar multiplicação com adiçãoSuposições:
a
eb
são termos que não exigem parênteses adicionais quando usados como argumento à esquerdaC
é uma expressão que pode precisar de parênteses quando usada como argumento à esquerdaa
b
C
avaliar para escalares numéricosfonte
Números complexos
Muitas vezes esquecidos, eles apresentam oportunidades maravilhosas para encurtar expressões que lidam com grades, labirintos, fractais ou geometria.
fonte
Comprimento do vetor do módulo de indexação
⊃i⌽a
geralmente é mais curto que o ingênuo⊃a[(≢a)|i]
oua⊃⍨i|⍨≢a
(ondea
é um vetor ei
é um número inteiro e⎕io
é 0)Uma variação útil disso (obrigado EriktheOutgolfer por apontar) é:
I↑Y⌽⍨I×X
ondeY
está a concatenação de algunsI
vetores de comprimento eX
é o índice daquele que queremos escolher, por exemplo:3↑'JanFeb...Dec'⌽⍨3×month
fonte
Funções constantes
=⍨
e≠⍨
graças a ngn.Às vezes, você só precisa de um único valor para cada elemento de uma lista. Embora você seja tentado a usar
{value}¨
, é mais curto,value⊣¨
mas para alguns valores comuns, você pode ficar ainda mais baixo (usando⎕IO←0
):¯1
s com⍬⍸list
0
s com⍬⍳list
1
s com⍬⍷list
Observe que eles funcionam apenas em listas (embora possam estar aninhados). Para matrizes de classificação mais alta, você pode usar o seguinte para obter todos os 0s e todos os 1s:
1
s com=⍨
0
s com≠⍨
Se você definir
⎕ML←0
, todos os números podem ser transformados em zeros (como se0×
) com:∊
Se você precisar apenas de um único número, poderá usar monádico
≡
para obter 1 ou 0 em vez de usar1⊣
ou0⊣
.fonte
⊣\
⊣
e⊢
com/
e⌿
mérito um post próprio.Usar
⍨
Evite parênteses
⍨
(Comutar) pode economizar bytes, evitando parênteses. Sempre que você tiver uma função em que o argumento da esquerda precise ser parênteses e o argumento da direita não, você poderá salvar um byte, por exemplo,(A<B)÷C
→C÷⍨A<B
.Matrizes duplas
Para anexar uma cópia de uma matriz ao final, use
,⍨A
ou⍪⍨A
.Números duplos
Em vez de usar
2∘×
para dobrar, você pode usar,+⍨
pois ele adiciona o argumento a si mesmo:1+2∘×
→1++⍨
.Números quadrados
Em vez de usar o
2*⍨Y
quadrado, você pode usar,×⍨Y
pois ele multiplica o argumento consigo mesmo:2*⍨A+B
→×⍨A+B
.Permutação aleatória
?⍨N
lhe dará uma permutação aleatória de comprimentoN
.Auto-classificação
Encontre os índices da primeira ocorrência de cada célula principal com
⍳⍨A
Contagem 1s à direita em um vetor booleano
Em vez de
+/∧\⌽B
contar quantos 1s finais existem,N
você pode usar⊥⍨
.Composição reversa
A f∘g B
éA f g B
, mas se você quiser(g A) f B
, usef⍨∘g⍨
.Redução reversa
f/ a1 a2 a3
éa1 f (a2 f a3)
. Se você quiser(a1 f a2) f a3
, usef⍨/⌽
.Reverse scan
f\ A B C
éA (A f B) (A f (B f C))
.f⍨/∘⌽¨,\ A B C
éA (A f B) ((A f B) f C)
.f⍨\⌽ A B C
é((A f B) f C) (B f C) C
.⌽f/∘⌽¨,\⌽ A B C
. é(A f (B f C)) (B f C) C
.fonte
Enumere os caracteres em uma sequência sem
⍳≢
Tarefa: Dadas duas cadeias, S e T, liste os índices de sua concatenação. Por exemplo,
S←'abcd'
eT←'xyz'
dá1 2 3 4 5 6 7
.Uma solução dfn pode ser,
S{⍳≢⍺,⍵}T
mas você deseja reduzi-la, tornando-a tácita.⍳≢,
não funcionará porque as regras de análise de trem analisarão isso como(⍳)≢(,)
você desejar(⍳≢),
.Diádico
⍋
com um argumento vazio à esquerda classifica matrizes simples de caracteres de acordo com a ordem atual, que é a mesma que⍳≢
. Assim{⍳≢⍺,⍵}
pode se tornar{⍬⍋⍺,⍵}
, para que possamos escrever nosso trem como⍬⍋,
.Observe que isso não funciona para matrizes numéricas ou mistas.
fonte