MATL é uma linguagem de golfe criada por Luis Mendo . O MATL provou ser altamente competitivo, muitas vezes superando envios em outros idiomas de golfe, como Pyth, CJam e Jelly.
Quais são algumas dicas úteis para jogar golfe no MATL? (Como sempre, uma dica por resposta, por favor!)
- Para o registro, o MATL pode ser testado online aqui .
- A documentação pode ser encontrada no Github
accumarray
(XQ
) pode ser bastante poderoso (possivelmente até mais do que no MATLAB / Octave, já que esses identificadores de função de comprimento têm códigos numéricos úteis), mas eu não o conheço o suficiente para ilustrar com bons exemplos. Se for realmente útil, alguém poderia criar uma resposta com idéias sobre como usá-lo?Respostas:
Conheça os literais predefinidos
Embora alguns deles mantenham informações quando copiados para a área de transferência, todos eles têm um valor predefinido.
F
, empurra 0 (na verdade, Falso )T
, empurra 1 (realmente verdadeiro )H
, pressiona 2 (valor predefinido da área de transferência)I
, empurra 3 (valor predefinido da área de transferência)K
, pressiona 4 (valor predefinido da área de transferência)J
, empurra 0 + 1j (valor predefinido da área de transferência)Não tenho certeza se eu cobri todos os valores predefinidos.
fonte
L
também possui um valor predefinido, mas eles se destinam a usos especiais (em vez de valores gerais comuns). Por exemplo,1L
dá[1 0]
(que é usado como índice1:end
),2L
dá[0 -1 1]
(para1:-1:end
). Além disso, funçõesl
eO
assumir 0 entradas por padrão e produtos0
e1
, respectivamente4
?1
, então4
,14
não serve. Você precisaria1 4
. Ou1K
para salvar um byteK
invés de4
útil é:1-4
significa: empurre1
e empurre-4
; Considerando1-K
meios: impulso1
, subtrair o que for abaixo na pilha, em seguida, empurrar4
A
&
Meta-Função (Especificação Alternativa de Entrada / Saída)A maneira tradicional de especificar o número de argumentos de entrada a serem transmitidos para uma função é usar a
$
meta-funçãoDa mesma forma, para especificar o número de argumentos de saída, você pode usar a
#
meta-função que especifica o número de argumentos de saída,ou se você passar um número maior que o número de argumentos de saída definidos para uma função, apenas a
mod(N, numberOfOutputs) + 1
saída será fornecida.Além disso, você pode especificar uma matriz lógica como a entrada
#
para recuperar apenas argumentos de saída específicos.Todas essas especificações de entrada / saída são úteis, mas aumentam sua contagem de bytes muito rapidamente. Para lidar com isso, o MATL introduziu a
&
meta-função na versão 17.0.0 . Essa&
meta-função atua como um atalho para uma especificação de entrada ou saída específica para uma função. Vamos ver o que isso significa.No exemplo acima, queríamos usar a versão de duas entradas
:
(cria um vetor de valores igualmente espaçados). Embora o número padrão de argumentos de entrada:
seja1
(crie uma matriz a partir de[1...N]
), é muito comum que um usuário queira especificar o valor inicial do intervalo que requer a segunda entrada. Então:
, definimos&
como um atalho para2$
.Agora se torna o seguinte, salvando um byte !
Como podemos determinar qual é o número alternativo de argumentos?
A especificação de entrada / saída que é
&
traduzida é específica da função , otimizando a economia de bytes.A seção argumento de entrada / saída da descrição da ajuda para cada função foi atualizada para indicar qual é esse número alternativo de entradas / saídas (se houver). O número possível de argumentos de entrada ou saída é exibido como um intervalo e os valores padrão para cada um são mostrados entre parênteses. A especificação de entrada / saída que pode ser substituída
&
é mostrada após o/
caractere entre parênteses.Aqui está a seção do argumento de entrada / saída da descrição da ajuda para
:
Como você determinou o que
&
significa para cada função?Muito cuidado. Usando a API StackExchange , conseguimos fazer o download de todas as respostas MATL que já foram usadas em um desafio PPCG. Ao analisar cada uma das respostas, conseguimos determinar a frequência com que cada especificação de entrada / saída foi usada para cada função. Usando essas informações, conseguimos identificar objetivamente a especificação de entrada / saída que a
&
meta-função deve representar para cada função. Às vezes, não havia um vencedor claro; muitas funções atualmente não foram&
definidas.Aqui está o script que usamos (infelizmente, está escrito em MATLAB e não em MATL).
E aqui está um exemplo do histograma de
$
/#
usefonte
&
ia significar "aumentar o número de entradas em 1 em relação ao padrão". Sua sugestão acabou por ser muito mais útilFamiliarize-se com as definições de verdade / falsidade do MATL
Enquanto
true
(T
) efalse
(F
) representam claramente a saída verdade e falsidade, respectivamente, a definição amplamente aceita de verdade / falsidade nos dá um pouco mais de flexibilidade no MATL.A definição declara:
Assim, podemos escrever um teste rápido de verdade / falsidade do MATL, que percorrerá todas as entradas e exibirá se elas foram consideradas verdadeiras ou falsas
Aqui está uma versão online.
O que isso significa no MATL
O que isso realmente se traduz em MATL (e, portanto, em MATLAB e Octave) é que uma condição é considerada verdadeira se for um componente não vazio e os componentes reais de todos os seus valores forem diferentes de zero . Há duas partes nisso que devem ser enfatizadas.
Diferente de zero : significa exatamente isso, diferente de zero (
==
). Isso inclui números positivos, números negativos, caracteres não nulos, etc. Você pode verificar facilmente convertendo um determinado valor em umlogical
valor (g
) ou pode usar~~
Todos os valores : normalmente pensamos nos escalares como verdadeiros ou falsos, mas no MATL podemos avaliar escalares, vetores de linhas, vetores de colunas ou mesmo matrizes multidimensionais e eles são considerados verdadeiros se, e somente se, cada valor único for diferente de zero (como definido acima), caso contrário, são falsas. Aqui estão alguns exemplos para demonstrar
O caso de uma aresta, como mencionado acima, é uma matriz vazia
[]
, que sempre é considerada falsa ( exemplo )Como posso usar isso para jogar golfe melhor?
Se o desafio mencionar simplesmente que sua saída deve ser verdadeira ou falsa, você provavelmente poderá explorar a definição acima para economizar alguns bytes da sua resposta. Para economizar confusão, é recomendável que você inclua um link para o teste de verdade / falsidade on-line acima em sua resposta para ajudar a explicar como os valores de verdade / falsidade em MATL funcionam.
Alguns exemplos específicos:
Uma resposta que termina em
A
. Se o desafio exigir uma saída verdadeira ou falsa e você terminar sua resposta emall
(A
) para criar um escalar, poderá remover esse último byte e sua resposta permanecerá correta (a menos que a saída seja[]
uma vez que[]
éfalse
mas[]A
étrue
).Garantir que uma matriz contenha apenas um valor exclusivo : Usa
&=
no lugar deun1=
. Se todos os valores em uma matriz forem iguais, uma comparação de igualdade entre elementos transmitida produzirá umaN x N
matriz de todos. Se todos os valores não forem iguais, essa matriz conterá alguns0
valores e, portanto, será considerada falsa.fonte
Entrada implícita
A maioria das funções aceita algum número de entrada. Essas entradas são retiradas do topo da pilha. Se o topo da pilha não contiver argumentos suficientes, ele extrairá o argumento restante da entrada. (Consulte a Seção 7.3 na documentação). Gostaria de citar a explicação original:
fonte
Matrizes lógicas geralmente podem ser usadas como matrizes numéricas
Você pode usar "
TF
" frequentemente notação em vez de literais de zeros e uns. Por exemplo,FTF
é o mesmo que[0,1,0]
, apenas queFTF
produzlogical
valores, nãodouble
valores. Isso geralmente não é um problema, pois qualquer operação aritmética tratará valores lógicos como números. Por exemplo,FTFQ
dá[1,2,1]
(Q
é "aumentar em 1").Em alguns casos, a conversão de um número em binário pode ser mais curta. Por exemplo,
[1,0,1]
,TFT
e5B
são o mesmo; novamente com o cuidado de que os dois últimos sãological
valores.Um caso em que a diferença entre
TF
(lógico) e[1 0]
(numérico) é importante quando usado como índices. Uma matriz do tipological
usada como índice significa: escolher elementos correspondentes aT
, descartar aqueles correspondentes aF
. Então[10 20]TF)
produz10
(selecione o primeiro elemento), enquanto[10 20][1 0])
produz[10 20]
(o índice[1 0]
tem a interpretação de1:end
, ou seja, escolhe todos os elementos da matriz).fonte
Para loop de tamanho n-1
Considere a substituição
com
para economizar até um byte inteiro ou mais .
fonte
@
/ estáX@
dentro do loop ou não. Talvez você pode simplesmente dizer "para salvar bytes"Mova as coisas depois do loop para dentro do loop, para explorar o fim implícito
As
end
instruções de loop ,,]
podem ser deixadas de fora se não houver código após elas. Eles são preenchidos pelo analisador MATL implicitamente.Portanto, se você puder mover as coisas depois do loop para dentro do loop, poderá salvar a final
]
.Como exemplo específico, o código a seguir localiza quantos zeros à direita existem no fatorial de um número
N
(veja aqui ):1
paraN
.5
está presente.5
aparece (isso funciona porque para cada um5
há pelo menos um2
).A primeira ideia foi
:"@Yf5=]vs
(observe que há instruções após o loop):Como,
v
por padrão, concatena todo o conteúdo da pilha, ele pode ser movido para o loop. E como a adição é associativa, tambéms
pode ser movida. Isso deixa]
no final do código e, portanto, pode ser omitido:"@Yf5=vs
:fonte
Maneira mais curta de definir uma matriz numérica vazia, se a pilha estiver vazia
Para enviar uma matriz numérica vazia, você normalmente usa
[]
. No entanto, se a pilha estiver vazia, você pode salvar um byte usandov
. Esta função, por padrão, concatena todo o conteúdo da pilha verticalmente; portanto, se a pilha estiver vazia, ela produzirá a matriz vazia.Você pode vê-lo em ação, por exemplo, aqui .
fonte
Algumas funções são estendidas em comparação com MATLAB ou Octave
Se você vem do MATLAB ou Octave, encontrará muitas funções do MATL semelhantes às funções desses idiomas. Mas em alguns deles a funcionalidade foi estendida.
Como exemplo, considere a
reshape
função do MATLAB , à qual corresponde em MATLe
. Os trechos de códigoreshape([10 20 30 40 50 60], 2, 3)
e,reshape([10 20 30 40 50 60], 2, [])
respectivamente, significam "remodelar o vetor de linha[10 20 30 40 50 60
em uma matriz 2 × 3" ou "em uma matriz de 2 linhas com quantas colunas forem necessárias". Portanto, o resultado, em ambos os casos, é a matriz 2DAlgo como
reshape([10 20 30 40 50 60], 2, 2)
oureshape([10 20 30 40 50 60], 5, [])
daria um erro por causa de tamanhos incompatíveis. No entanto, o MATL removerá os elementos no primeiro caso ( experimente on-line! ) Ou preencherá com zeros no segundo ( experimente on-line! ) Para produzir, respectivamente,e
Outras funções que possuem funcionalidade estendida em comparação com suas contrapartes do MATLAB são (lista não exaustiva)
S
(sort
),Yb
(strsplit
),m
(ismember
),h
(horzcat
),v
(vertcat
),Zd
(gcd
),Zm
(lcm
),YS
(circshift
),YA
(dec2base
),ZA
(base2dec
),Z"
(blanks
)fonte
Obtenha o índice do primeiro elemento diferente de zero, se houver
A
f
função fornece os índices de todos os elementos diferentes de zero de uma matriz. Muitas vezes você deseja o índice do primeiro elemento diferente de zero. Isso seriaf1)
: apliquef
e escolha seu primeiro elemento. Mas se a matriz original não contiver nenhum valor diferente de zero,f
ela produzirá uma matriz vazia ([]
), e tentar escolher seu primeiro elemento causará um erro.Um comum, a exigência é mais robusto para obter o índice do primeiro elemento se houver pelo menos uma , e
[]
de outra forma. Isso pode ser feito com umaif
ramificação depoisf
, mas é muito caro. Uma maneira melhor éfX<
, ou seja, aplicar a função mínimaX<
à saída def
.X<
retorna uma matriz vazia quando sua entrada é uma matriz vazia.Experimente online! (Observe que uma matriz vazia não é exibida). Ou veja um exemplo disso no trabalho aqui .
fonte
Gere um intervalo desde que uma determinada matriz
TL; WR : use em
f
vez den:
se a matriz tiver apenas elementos diferentes de zero.Geralmente, é necessário gerar uma matriz
[1 2 ... L]
ondeL
está o número de elementos de uma determinada matriz. A maneira padrão de fazer isso én:
. Por exemplo, o códigotn:*
usa um vetor numérico como entrada e calcula cada entrada multiplicada por seu índice.Se for garantido que a matriz fornecida contém apenas entradas diferentes de zero (por exemplo, é formada por números inteiros positivos ou é uma sequência com caracteres imprimíveis),
n:
pode ser substituída porf
, que produz uma matriz com os índices de entradas diferentes de zero. Portanto, o código acima se tornatf*
, o que economiza 1 byte.Alguns exemplos mais elaborados: 1 , 2 , 3 .
fonte
Definição eficiente de literais de array numérico
Aqui estão algumas maneiras que podem ser usadas para salvar bytes ao definir literais de matriz numérica. São fornecidos links para exemplos de respostas que os utilizam. Estes foram obtidos usando o script de análise criado pelo @Suever .
Concatenação e literais predefinidos
Para matrizes com números pequenos às vezes você pode usar concatenação (funções
h
ev
), bem como literais predefinidos para evitar o uso de espaços como separadores: comparar[2 4]
,2 4h
e2Kh
, os quais definem a matriz[2 4]
. Da mesma forma,2K1v
com uma pilha vazia define[2; 4; 1]
. Exemplo .Letras dentro de literais de matriz numérica
Para números um pouco maiores, você pode economizar espaço explorando o fato de que algumas letras têm significados numéricos nos literais da matriz. Então, em vez de
[3 5 2 7;-4 10 12 5]
você pode usar[IAHC;dX12A]
. Exemplo .Especificamente, em literais de matriz,
O
,l
,H
I
K
Têm seus significados usuais0
, ...,4
A
, ...,E
dizer5
, ...,9
X
significa10
a
, ...d
médio-1
, ...,-4
J
eG
mau1j
e-1j
P
significapi
Y
significainf
N
meiosNaN
.Diferenças de sequência e consecutivas
Para números maiores, definir uma string e calcular suas diferenças consecutivas (com
d
) pode ajudar: em vez de[20 10 35 -6]
você pode usar'!5?b\'d
. Isso funciona porqued
usa os pontos de código dos caracteres para calcular as diferenças. Exemplo .fonte