Dicas para jogar golfe em MATL


20

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!)


5
Definitivamente, é uma grande vantagem se você conhece algum Matlab / Octave. Alguns truques de Dicas para jogar golfe no Matlab e Dicas para jogar golfe no Octave também são usados ​​no MATL.
flawr

Sugestão: parece que 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?
sundar - Restabelece Monica

Respostas:


7

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.


Apenas para completar (e no caso de você querer adicionar à sua resposta): cada nível da área de transferência Ltambém possui um valor predefinido, mas eles se destinam a usos especiais (em vez de valores gerais comuns). Por exemplo, 1L[1 0](que é usado como índice 1:end), 2L[0 -1 1](para 1:-1:end). Além disso, funções le Oassumir 0 entradas por padrão e produtos 0e 1, respectivamente
Luis Mendo

Não vejo como isso é útil ... Não consigo escrever 4?
precisa saber é o seguinte

@Cyoce A utilidade é evitar um espaço como separador. Se você quer empurrar 1, então 4, 14não serve. Você precisaria 1 4. Ou 1Kpara salvar um byte
Luis Mendo

@LuisMendo ah, entendo. Eu acho que eu assumi que estava usando o único método número de 1 dígito (não sei porquê)
Cyoce

1
Outro caso em que ao Kinvés de 4útil é: 1-4significa: empurre 1e empurre -4; Considerando 1-Kmeios: impulso 1, subtrair o que for abaixo na pilha, em seguida, empurrar4
Luis Mendo

5

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ção

2$:     % Two-input version of :

Da 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,

2#S     % Two-output version of sort

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) + 1saída será fornecida.

4#S     % Get only the second output of sort

Além disso, você pode especificar uma matriz lógica como a entrada #para recuperar apenas argumentos de saída específicos.

TFT#u   % Three output version of unique and discard the second output

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 :seja 1(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 para 2$.

10      % Push 10 to the stack
12      % Push 12 to the stack
2$:     % Create an array: [10, 11, 12] 

Agora se torna o seguinte, salvando um byte !

10 12 &:

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 :

 +- Min-Max range of # of inputs
 |        +----- Alt. Default # of inputs
 |        |
 V        V
1--3 (1 / 2); 1 <--- Possible / Default # of outputs
      ^       
      |       
  Default # of inputs

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 $/ #use


1
Esse recurso foi sugerido por @Suever. Originalmente &ia significar "aumentar o número de entradas em 1 em relação ao padrão". Sua sugestão acabou por ser muito mais útil
Luis Mendo

5

Familiarize-se com as definições de verdade / falsidade do MATL

Enquanto true( T) e false( 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:

if (x)
    disp("x is truthy");
else
    disp("x is falsy");
end

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

` ? 'truthy' } 'falsey' ]DT

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.

  1. 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 um logicalvalor ( g) ou pode usar~~

    F           % Falsy
    T           % Truthy
    0           % Falsy
    1           % Truthy
    2           % Truthy
    -1          % Truthy
    'a'         % Truthy
    ' '         % Truthy (ASCII 32)
    char(0)     % Falsy  (ASCII 0)  
    
  2. 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

    [1, 1, 1]           % Truthy
    [1, 0, 0]           % Falsey
    [1, 1, 1; 1, 1, 1]  % Truthy
    [1, 0, 1; 1, 1, 1]  % Falsey
    'Hello World'       % Truthy
    

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 em all( 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 []é falsemas []Aé true).

  • Garantir que uma matriz contenha apenas um valor exclusivo : Usa &=no lugar de un1=. Se todos os valores em uma matriz forem iguais, uma comparação de igualdade entre elementos transmitida produzirá uma N x Nmatriz de todos. Se todos os valores não forem iguais, essa matriz conterá alguns 0valores e, portanto, será considerada falsa.


4

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:

As entradas implícitas podem ser visualizadas da seguinte forma: a pilha é estendida indefinidamente abaixo da parte inferior, ou seja, nas posições 0, -1, -2, ... com valores que não são definidos inicialmente, mas são resolvidos em tempo real via entrada implícita . Essas entradas são solicitadas ao usuário apenas quando são necessárias, na ordem em que são necessárias. Se várias entradas forem necessárias ao mesmo tempo, elas seguem a ordem normal da pilha, ou seja, a entrada mais profunda na pilha (estendida) é inserida primeiro.


2
Entrada implícita é um recurso que foi sugerido por @flawr
Luis Mendo

6
Flawr @ deve ser um cara muito inteligente. : D
flawr

3

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 que FTFproduz logicalvalores, não doublevalores. Isso geralmente não é um problema, pois qualquer operação aritmética tratará valores lógicos como números. Por exemplo, FTFQ[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], TFTe 5Bsão o mesmo; novamente com o cuidado de que os dois últimos são logicalvalores.


Um caso em que a diferença entre TF(lógico) e [1 0](numérico) é importante quando usado como índices. Uma matriz do tipo logicalusada como índice significa: escolher elementos correspondentes a T, descartar aqueles correspondentes a F. Então [10 20]TF)produz 10(selecione o primeiro elemento), enquanto [10 20][1 0])produz [10 20](o índice [1 0]tem a interpretação de 1:end, ou seja, escolhe todos os elementos da matriz).


3

Para loop de tamanho n-1

Considere a substituição

tnq:"...

com

td"...

para economizar até um byte inteiro ou mais .


@Luis true! Eu pensei que alguém poderia precisar do vetor original que está sendo repetido, mas isso também não é possível na primeira abordagem. Irá remover essa observação.
Sanchises 19/09/16

Mas você não salva necessariamente 1 byte; você salva 1 ou 2, dependendo se você precisa @/ está X@dentro do loop ou não. Talvez você pode simplesmente dizer "para salvar bytes"
Luis Mendo

3

Mova as coisas depois do loop para dentro do loop, para explorar o fim implícito

As endinstruçõ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 ):

  • O código passa de 1para N.
  • Para cada um desses números, ele calcula seus fatores primos e determina quantas vezes 5está presente.
  • A resposta é o número acumulado de vezes que 5aparece (isso funciona porque para cada um 5há pelo menos um 2).

A primeira ideia foi :"@Yf5=]vs(observe que há instruções após o loop):

:      % Range from 1 to implicit input
"      % For each number in that vector
  @    %   Push that number
  Yf   %   Vector of prime factors (with repetitions)
  5=   %   True for entries that equal `5`, and `false` for the rest
]      % End for
v      % Concatenate all vectors as a column vector
s      % Sum. Implicitly display

Como, vpor padrão, concatena todo o conteúdo da pilha, ele pode ser movido para o loop. E como a adição é associativa, também spode ser movida. Isso deixa ]no final do código e, portanto, pode ser omitido :"@Yf5=vs:

:      % Range from 1 to implicit input
"      % For each number in that vector
  @    %   Push that number
  Yf   %   Vector of prime factors (with repetitions)
  5=   %   True for entries that equal `5`, and `false` for the rest
  v    % Concatenate all vectors so far as a column vector
  s    % Sum. Inplicitly end loop and display

não conheço nem um centavo dessa linguagem escrita hieroglífica, mas reservarei grande parte do meu tempo estudando-a nos próximos três meses, talvez.
Abr001am

@ Agawa001 :-) Você verá que é bastante semelhante ao Matlab. Você também pode perguntar ou comentar aqui
Luis Mendo

3

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 usando v. 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 .


2

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 reshapefunção do MATLAB , à qual corresponde em MATL e. Os trechos de código reshape([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 60em 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 2D

10    30    50
20    40    60

Algo como reshape([10 20 30 40 50 60], 2, 2)ou reshape([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,

10 30
20 40 

e

10 60
20  0
30  0
40  0
50  0

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)


1

Obtenha o índice do primeiro elemento diferente de zero, se houver

A ffunçã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 seria f1): aplique fe escolha seu primeiro elemento. Mas se a matriz original não contiver nenhum valor diferente de zero, fela 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 uma iframificação depois f, mas é muito caro. Uma maneira melhor éfX< , ou seja, aplicar a função mínima X<à saída de f. 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 .


1

Gere um intervalo desde que uma determinada matriz

TL; WR : use em fvez den: se a matriz tiver apenas elementos diferentes de zero.


Geralmente, é necessário gerar uma matriz [1 2 ... L]onde Lestá 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 por f, 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 .


1

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 he v), bem como literais predefinidos para evitar o uso de espaços como separadores: comparar [2 4], 2 4he 2Kh, os quais definem a matriz [2 4]. Da mesma forma, 2K1vcom 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 KTêm seus significados usuais 0, ...,4
  • A, ..., Edizer 5, ...,9
  • X significa 10
  • a, ... dmédio -1, ...,-4
  • Je Gmau 1je-1j
  • P significa pi
  • Y significa inf
  • Nmeios NaN.

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 porque dusa os pontos de código dos caracteres para calcular as diferenças. Exemplo .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.