Suggerimenti per giocare a golf in MATL


20

MATL è un linguaggio per il golf creato da Luis Mendo . MATL ha dimostrato di essere altamente competitivo, battendo spesso i contributi in altri linguaggi del golf come Pyth, CJam e Jelly.

Quali sono alcuni consigli utili per giocare a golf in MATL? (Come sempre, un consiglio per risposta, per favore!)


5
È sicuramente un grande vantaggio se conosci Matlab / Octave. Alcuni trucchi da Consigli per giocare a golf in Matlab e Consigli per giocare a golf in Octave usati anche in MATL.
flawr

Suggerimento: sembra che accumarray( XQ) possa essere abbastanza potente (forse anche più che in MATLAB / Octave poiché quelle maniglie delle funzioni di lunghezza hanno pratici codici numerici), ma non lo so abbastanza bene da illustrare con buoni esempi. Se è effettivamente utile, qualcuno potrebbe creare una risposta con idee su come usarlo?
Sundar - Ripristina Monica il

Risposte:


7

Conosci i letterali predefiniti

Sebbene alcuni di essi mantengano informazioni quando vengono copiati negli Appunti, hanno tutti un valore predefinito.

  • F, spinge 0 (in realtà falso )
  • T, spinge 1 (in realtà True )
  • H, spinge 2 (valore di appunti predefinito)
  • I, spinge 3 (valore di appunti predefinito)
  • K, spinge 4 (valore di appunti predefinito)
  • J, spinge 0 + 1j (valore di appunti predefinito)

Non sono sicuro se ho coperto tutti i valori predefiniti però.


Solo per completezza (e nel caso in cui si desideri aggiungere una risposta): ogni livello di appunti Lha anche un valore predefinito, ma sono destinati a usi speciali (piuttosto che a valori generali comuni). Ad esempio, 1L[1 0](che viene utilizzato come indice 1:end), 2L[0 -1 1](per 1:-1:end). Inoltre, funzioni le Oaccetta 0 input per impostazione predefinita e produce 0e 1rispettivamente
Luis Mendo,

Non vedo come sia utile ... Non posso semplicemente scrivere 4?
Cyoce,

@Cyoce L'utilità è di evitare uno spazio come separatore. Se vuoi spingere 1, allora 4, 14non lo farà. Ne avresti bisogno 1 4. O 1Kper salvare un byte
Luis Mendo il

@LuisMendo ah, capisco. Immagino di aver supposto che stesse usando il metodo del solo numero di una cifra (non so perché)
Cyoce

1
Un altro caso in cui Kinvece 4è utile è: 1-4significa: premere 1, quindi premere -4; mentre 1-Ksignifica: spingere 1, sottrarre da tutto ciò che è sotto nello stack, quindi spingere4
Luis Mendo il

5

La &meta-funzione (specifica alternativa input / output)

Il modo tradizionale di specificare il numero di argomenti di input da passare a una funzione è utilizzare la $meta-funzione

2$:     % Two-input version of :

Allo stesso modo, per specificare il numero di argomenti di output è possibile utilizzare la #meta-funzione specificando il numero di argomenti di output,

2#S     % Two-output version of sort

oppure se si passa un numero maggiore del numero di argomenti di output definiti per una funzione, viene fornito solo l' mod(N, numberOfOutputs) + 1output.

4#S     % Get only the second output of sort

È inoltre possibile specificare un array logico come input #per recuperare solo argomenti di output specifici.

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

Tutte queste specifiche di input / output sono utili ma aumentano il conteggio dei byte molto rapidamente. Per far fronte a questo, MATL ha introdotto la &meta-funzione nella versione 17.0.0 . Questa &meta-funzione funge da collegamento per una specifica specifica di input o output per una funzione. Vediamo cosa significa.

Nel nostro esempio sopra, volevamo usare la versione a due input di :(crea un vettore di valori equidistanti). Mentre il numero predefinito di argomenti di input :è 1(crea un array da [1...N]), è molto comune che un utente voglia specificare il valore iniziale dell'intervallo che richiede il secondo input. Quindi :, abbiamo definito &una scorciatoia per 2$.

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

Ora diventa il seguente, salvando un byte !

10 12 &:

Come possiamo determinare qual è il numero alternativo di argomenti?

Le specifiche di input / output che si &traducono in sono specifiche della funzione in modo tale da ottimizzare il risparmio di byte.

La sezione dell'argomento input / output della descrizione della guida per ciascuna funzione è stata aggiornata per indicare qual è questo numero alternativo di input / output (se presente). Il numero possibile di argomenti di input o output viene visualizzato come intervallo e i valori predefiniti per ciascuno sono indicati tra parentesi. Le specifiche di input / output che possono essere sostituite &vengono visualizzate dopo il /carattere tra parentesi.

Ecco la sezione dell'argomento input / output della descrizione della guida per :

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

Come hai determinato cosa &significa per ciascuna funzione?

Molto attentamente. Utilizzando l' API StackExchange , siamo stati in grado di scaricare tutte le risposte MATL che siano mai state utilizzate in una sfida PPCG. Analizzando ciascuna delle risposte, siamo stati quindi in grado di determinare la frequenza con cui ogni specifica di input / output è stata utilizzata per ciascuna funzione. Usando queste informazioni siamo stati quindi in grado di identificare oggettivamente le specifiche di input / output che la &meta-funzione dovrebbe rappresentare per ciascuna funzione. A volte non c'era un vincitore chiaro, quindi molte funzioni al momento non sono state &definite.

Ecco lo script che abbiamo usato (purtroppo è scritto in MATLAB e non in MATL).

Ed ecco un esempio dell'istogramma di $/ #use


1
Questa funzione è stata suggerita da @Suever. Inizialmente &intendeva "aumentare il numero di input di 1 rispetto al valore predefinito". Il suo suggerimento si rivelò molto più utile
Luis Mendo,

5

Acquisire familiarità con le definizioni di verità / falsità di MATL

Mentre true( T) e false( F) rappresentano chiaramente l'output di verità e falsità, rispettivamente, la definizione ampiamente condivisa di verità / falsità ci dà un po 'più di flessibilità in MATL.

La definizione afferma:

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

Quindi possiamo scrivere un rapido test di verità / falsità MATL che scorrerà attraverso tutti gli input e mostrerà se sono stati considerati come veri o falsi

` ? 'truthy' } 'falsey' ]DT

Ecco una versione online.

Cosa significa questo in MATL

Ciò che ciò si traduce in MATL (e quindi in MATLAB e Octave) è che una condizione è considerata vera se è vuota e le componenti reali di tutti i suoi valori sono diverse da zero . Ci sono due parti da sottolineare.

  1. Non zero : significa esattamente che, non uguale a zero ( ==). Ciò include numeri positivi, numeri negativi, caratteri non nulli, ecc. Puoi facilmente verificare convertendo un dato valore in un logicalvalore ( g) oppure puoi usare~~

    F           % Falsy
    T           % Truthy
    0           % Falsy
    1           % Truthy
    2           % Truthy
    -1          % Truthy
    'a'         % Truthy
    ' '         % Truthy (ASCII 32)
    char(0)     % Falsy  (ASCII 0)  
    
  2. Tutti i valori : in genere pensiamo agli scalari come veri o falsi, ma in MATL possiamo valutare scalari, vettori di riga, vettori di colonna o persino matrici multidimensionali e sono considerati veritieri se e solo se ogni singolo valore è diverso da zero (come definito sopra), altrimenti sono falsi. Ecco alcuni esempi da dimostrare

    [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
    

Il caso a un bordo, come menzionato sopra, è un array vuoto [], che è sempre considerato falso ( esempio )

Come posso usarlo per giocare meglio a golf?

Se la sfida menziona semplicemente che il tuo output deve essere veritiero o falso, puoi probabilmente sfruttare la definizione sopra per radere qualche byte dalla tua risposta. Per evitare confusione, si consiglia di includere un collegamento al test di verità / falsità online sopra nella risposta per aiutare a spiegare come funzionano i valori di verità / falsità MATL.

Un paio di esempi specifici:

  • Una risposta che termina con A. Se la sfida richiede un output veritiero o falso e si termina la risposta in all( A) per creare uno scalare, è possibile rimuovere quest'ultimo byte e la risposta rimarrà corretta (a meno che l'output sia []poiché []è falsema []Aè true).

  • Garantire che un array contenga un solo valore univoco : utilizza &=al posto di un1=. Se tutti i valori in un array sono uguali, un confronto di uguaglianza trasmessa in base agli elementi produrrà una N x Nmatrice di tutti. Se tutti i valori non sono uguali, questa matrice conterrà alcuni 0valori e pertanto sarà considerata falsa.


4

Input implicito

La maggior parte delle funzioni accetta un certo numero di input. Questi input sono presi dalla cima dello stack. Se la parte superiore dello stack non contiene argomenti sufficienti, trarrà l'argomento rimanente dall'input. (Vedi la Sezione 7.3 nella documentazione) Vorrei citare la spiegazione originale:

Gli input impliciti possono essere visualizzati come segue: lo stack viene esteso indefinitamente sotto il fondo, ovvero nelle posizioni 0, −1, −2, ... con valori che non sono inizialmente definiti, ma che vengono risolti al volo tramite input implicito . Questi input vengono richiesti all'utente solo quando sono necessari, nell'ordine in cui sono necessari. Se sono necessari più input contemporaneamente, seguono l'ordine normale dello stack, ovvero l'input più profondo nello stack (esteso) viene inserito per primo.


2
L'input implicito è una funzionalità suggerita da @flawr
Luis Mendo il

6
@flawr deve essere un ragazzo davvero intelligente. : D
flawr

3

Le matrici logiche possono spesso essere usate come matrici numeriche

Spesso è possibile utilizzare la " TF" notazione anziché i letterali array di zero e uno. Ad esempio, FTFè lo stesso [0,1,0]che FTFproduce solo logicalvalori, non doublevalori. Questo di solito non è un problema, poiché qualsiasi operazione aritmetica tratterà i valori logici come numeri. Ad esempio, FTFQ[1,2,1]( Qè "aumenta di 1").

In alcuni casi, la conversione di un numero in binario può essere più breve. Ad esempio, [1,0,1], TFTe 5Bsono le stesse; di nuovo con la cautela che questi ultimi due sono logicalvalori.


Un caso in cui la differenza tra questioni TF(logiche) e [1 0](numeriche) è quando usato come indici. Una matrice di tipo logicalusata come indice significa: selezionare gli elementi corrispondenti a T, scartare quelli corrispondenti a F. Quindi [10 20]TF)produce 10(seleziona il primo elemento), mentre [10 20][1 0])produce [10 20](l'indice [1 0]ha l'interpretazione di 1:end, cioè, seleziona tutti gli elementi dell'array).


3

Per anello di dimensioni n-1

Considerare la sostituzione

tnq:"...

con

td"...

per salvare fino a un intero byte o più .


@Luis true! Ho pensato che uno potrebbe aver bisogno del vettore originale che è in loop, ma neanche questo è possibile nel primo approccio. Rimuoverà tale osservazione.
Sanchises,

Ma non devi necessariamente salvare 1 byte; si salva 1 o 2 a seconda che sia necessario @/ X@all'interno del ciclo o meno. Forse puoi semplicemente dire "per salvare i byte"
Luis Mendo,

3

Sposta le cose da dopo il loop all'interno del loop, per sfruttare la fine implicita

Le endistruzioni del ciclo ], possono essere tralasciate se non c'è codice dopo di esse. Vengono compilati implicitamente dal parser MATL.

Quindi, se riesci a spostare le cose da dopo il loop all'interno del loop, puoi salvare la finale ] .

Come esempio specifico, il codice seguente trova quanti zeri finali ci sono nel fattoriale di un numero N(vedi qui ):

  • Il codice scorre da 1aN .
  • Per ciascuno di quei numeri calcola i suoi fattori primi e determina quante volte 5è presente.
  • La risposta è il numero accumulato di volte che 5appare (questo funziona perché per ognuno 5ce n'è almeno uno 2).

La prima idea è stata :"@Yf5=]vs(nota che ci sono dichiarazioni dopo il ciclo):

:      % 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

Poiché vper impostazione predefinita concatena tutti i contenuti dello stack, può essere spostato nel ciclo. E poiché l'aggiunta è associativa, spuò anche essere spostata. Ciò lascia ]alla fine del codice e quindi può essere omesso :"@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

non conosco un centesimo di questa lingua scritta geroglifica ma mi riserverò gran parte del mio tempo a studiarlo nei prossimi tre mesi forse.
Abr001,

@ Agawa001 :-) Scoprirai che è abbastanza simile a Matlab. Puoi anche chiedere o commentare qui
Luis Mendo,

3

Modo più breve per definire un array numerico vuoto, se lo stack è vuoto

Per eseguire il push di una matrice numerica vuota normalmente utilizzata []. Tuttavia, se lo stack è vuoto, è possibile salvare un byte utilizzandov . Questa funzione di default concatena verticalmente tutti i contenuti dello stack, quindi se lo stack è vuoto produce l'array vuoto.

Puoi vederlo in azione per esempio qui .


2

Alcune funzioni sono estese rispetto a MATLAB o Octave

Se vieni da MATLAB o Octave, scoprirai che molte funzioni MATL sono simili a quelle in quelle lingue. Ma in alcuni di essi la funzionalità è stata estesa.

Ad esempio, considera la reshapefunzione di MATLAB , che in MATL corrisponde e. I frammenti di codice reshape([10 20 30 40 50 60], 2, 3)e reshape([10 20 30 40 50 60], 2, [])rispettivamente medio "rimodellare il vettore riga [10 20 30 40 50 60in una matrice 2 × 3", o "in una matrice 2-riga con altrettante colonne come necessario". Quindi il risultato, in entrambi i casi, è l'array 2D

10    30    50
20    40    60

Qualcosa di simile reshape([10 20 30 40 50 60], 2, 2)o reshape([10 20 30 40 50 60], 5, [])darebbe un errore a causa di dimensioni incompatibili. Tuttavia, MATL rimuoverà gli elementi nel primo caso ( provalo online! ) O riempirà con zeri nel secondo ( provalo online! ) Per produrre, rispettivamente,

10 30
20 40 

e

10 60
20  0
30  0
40  0
50  0

Altre funzioni che hanno funzionalità estese rispetto alle loro controparti MATLAB sono (elenco non esaustivo) S( sort), Yb( strsplit), m( ismember), h( horzcat), v( vertcat), Zd( gcd), Zm( lcm), YS( circshift), YA( dec2base), ZA( base2dec), Z"( blanks).


1

Ottieni l'indice del primo elemento diverso da zero, se presente

La ffunzione fornisce gli indici di tutti gli elementi diversi da zero di un array. Spesso si desidera l'indice del primo elemento diverso da zero. Sarebbe f1): applica fe scegli il suo primo elemento. Ma se l'array originale non contiene alcun valore diverso da zero, fverrà generato un array vuoto ( []) e provare a selezionare il suo primo elemento genererà un errore.

Un requisito comune e più solido è quello di ottenere l'indice del primo elemento se ne esiste almeno uno e in caso []contrario. Questo potrebbe essere fatto con un iframo dopo f, ma è costoso per byte. Un modo migliore è fX<, cioè, applicare la funzione minima X<all'output di f. X<restituisce un array vuoto quando il suo input è un array vuoto.

Provalo online! (Si noti che un array vuoto non viene visualizzato affatto). O vedi un esempio di questo al lavoro qui .


1

Genera un intervallo lungo quanto un determinato array

TL; WR : utilizzare finvece n:se l'array ha solo elementi diversi da zero.


Spesso è necessario generare un array in [1 2 ... L]cui si Ltrova il numero di elementi di un determinato array. Il modo standard per farlo è n:. Ad esempio, il codice tn:*accetta un vettore numerico come input e calcola ciascuna voce moltiplicata per il suo indice.

Se si garantisce che l'array specificato contenga solo voci diverse da zero (ad esempio, è formato da numeri interi positivi o è una stringa con caratteri stampabili), n:può essere sostituito da f, che produce un array con gli indici delle voci diverse da zero. Quindi diventa il codice sopra tf*, che salva 1 byte.

Alcuni esempi più elaborati: 1 , 2 , 3 .


1

Definizione efficiente di valori letterali di array numerici

Ecco alcuni modi che possono essere utilizzati per salvare byte quando si definiscono valori letterali di array numerici. Vengono forniti collegamenti a risposte di esempio che li utilizzano. Questi sono stati ottenuti utilizzando lo script di analisi creato da @Suever .

Concatenazione e letterali predefiniti

Per array con piccoli numeri a volte è possibile utilizzare concatenazione (funzioni he v), nonché letterali predefinite per evitare di usare gli spazi come separatori: confronta [2 4], 2 4he 2Kh, i quali definiscono la matrice [2 4]. Allo stesso modo, 2K1vcon uno stack vuoto definisce [2; 4; 1]. Esempio .

Lettere all'interno di letterali array numerici

Per numeri leggermente più grandi è possibile salvare spazi sfruttando il fatto che alcune lettere hanno significati numerici all'interno di valori letterali array. Quindi invece di [3 5 2 7;-4 10 12 5]te puoi usare [IAHC;dX12A]. Esempio .

Nello specifico, all'interno di array letterali,

  • O, l, H I KHanno i loro significati consueti 0, ...,4
  • A, ..., Emedia 5, ...,9
  • X si intende 10
  • a, ... dsignifica -1, ...,-4
  • Je Gmedio 1je-1j
  • P si intende pi
  • Y si intende inf
  • Nsignifica NaN.

Stringa e differenze consecutive

Per numeri più grandi, definire una stringa e calcolare le sue differenze consecutive (con d) può aiutare: invece di [20 10 35 -6]usare '!5?b\'d. Questo funziona perché dutilizza i punti di codice dei caratteri per calcolare le differenze. Esempio .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.