Tips untuk bermain golf di MATL

20

MATL adalah bahasa golf yang diciptakan oleh Luis Mendo . MATL telah terbukti sangat kompetitif, seringkali mengalahkan kiriman dalam bahasa golf lainnya seperti Pyth, CJam dan Jelly.

Apa saja tips berguna untuk bermain golf di MATL? (Seperti biasa, satu tip per jawaban, kumohon!)

Stewie Griffin
sumber
5
Ini jelas merupakan keuntungan besar jika Anda tahu beberapa Matlab / Oktaf. Beberapa trik dari Tips untuk bermain golf di Matlab dan Tips untuk bermain golf di Oktaf juga digunakan di MATL.
flawr
Saran: sepertinya accumarray( XQ) bisa sangat kuat (mungkin bahkan lebih daripada di MATLAB / Oktaf karena pegangan fungsi panjang memiliki kode numerik yang berguna), tapi saya tidak cukup tahu untuk menggambarkan dengan contoh yang baik. Jika itu benar-benar berguna, dapatkah seseorang membuat jawaban dengan ide-ide tentang bagaimana menggunakannya?
sundar - Reinstate Monica

Jawaban:

7

Ketahui literal yang telah ditetapkan

Meskipun beberapa dari mereka menyimpan informasi saat disalin ke clipboard, mereka semua memiliki nilai yang telah ditentukan.

  • F, mendorong 0 (sebenarnya Salah )
  • T, mendorong 1 (sebenarnya Benar )
  • H, mendorong 2 (nilai clipboard yang telah ditentukan)
  • I, mendorong 3 (nilai clipboard yang telah ditentukan)
  • K, mendorong 4 (nilai clipboard yang telah ditentukan)
  • J, mendorong 0 + 1j (nilai clipboard yang telah ditentukan)

Tidak yakin apakah saya telah membahas semua nilai yang telah ditentukan sebelumnya.

Adnan
sumber
Hanya untuk kelengkapan (dan jika Anda ingin menambahkan jawaban Anda): setiap tingkat clipboard Ljuga memiliki nilai yang telah ditentukan, tetapi mereka dimaksudkan untuk penggunaan khusus (bukan umum, nilai-nilai umum). Misalnya, 1Lmemberi [1 0](yang digunakan sebagai indeks 1:end), 2Lmemberi [0 -1 1](untuk 1:-1:end). Juga, berfungsi ldan Omengambil 0 input secara default dan menghasilkan 0dan 1masing
Luis Mendo
Saya tidak melihat bagaimana ini berguna ... Tidak bisakah saya menulis 4?
Cyoce
@Cyoce Kegunaannya adalah menghindari spasi sebagai pemisah. Jika Anda ingin mendorong 1, maka 4, 14tidak akan berhasil. Kamu akan membutuhkan 1 4. Atau 1Kuntuk menyimpan satu byte
Luis Mendo
@LuisMendo ah, begitu. Saya kira saya berasumsi itu menggunakan metode angka 1-digit saja (tidak yakin mengapa)
Cyoce
1
Kasus lain ketika Kalih-alih 4berguna adalah: 1-4berarti: mendorong 1, lalu mendorong -4; sedangkan 1-Kartinya: dorong 1, kurangi dari apa pun yang ada di bawah dalam tumpukan, lalu dorong4
Luis Mendo
5

The &Meta-Function (Alternatif Input / Spesifikasi Output)

Cara tradisional untuk menentukan jumlah argumen input untuk diteruskan ke suatu fungsi adalah dengan menggunakan $fungsi-meta

2$:     % Two-input version of :

Demikian pula, untuk menentukan jumlah argumen output, Anda dapat menggunakan #fungsi-meta yang menentukan jumlah argumen output,

2#S     % Two-output version of sort

atau jika Anda melewati nomor yang lebih besar dari jumlah argumen keluaran ditetapkan untuk fungsi, hanya satu mod(N, numberOfOutputs) + 1output disediakan.

4#S     % Get only the second output of sort

Anda juga dapat menentukan array logis sebagai input untuk #hanya mengambil argumen output tertentu.

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

Semua spesifikasi input / output ini berguna tetapi mereka menaikkan byte-count Anda dengan sangat cepat. Untuk mengatasinya, MATL memperkenalkan &fungsi-meta di rilis 17.0.0 . &Fungsi-meta ini bertindak sebagai pintasan untuk spesifikasi input atau output tertentu untuk suatu fungsi. Mari kita lihat apa artinya itu.

Dalam contoh kami di atas, kami ingin menggunakan versi dua-input dari :(membuat vektor dengan nilai spasi sama). Sementara jumlah default argumen input :adalah 1(membuat array dari [1...N]), sangat umum bahwa pengguna ingin menentukan nilai awal rentang yang membutuhkan input kedua. Jadi untuk :, kami telah menetapkan &sebagai jalan pintas untuk 2$.

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

Sekarang menjadi yang berikut, menghemat satu byte !

10 12 &:

Bagaimana kita bisa menentukan berapa jumlah alternatif argumen?

Spesifikasi input / output yang &diterjemahkan adalah fungsi spesifik sehingga kami mengoptimalkan penghematan byte.

Bagian argumen input / output dari deskripsi bantuan untuk setiap fungsi telah diperbarui untuk menunjukkan apa jumlah input / output alternatif ini (jika ada). Jumlah argumen input atau output yang mungkin ditampilkan sebagai rentang dan nilai default untuk masing-masing ditampilkan dalam tanda kurung. Input / output spec yang dapat diganti dengan &ditampilkan setelah /karakter dalam tanda kurung.

Berikut adalah bagian argumen input / output dari deskripsi bantuan untuk :

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

Bagaimana Anda menentukan apa &artinya untuk setiap fungsi?

Dengan sangat hati-hati. Dengan menggunakan StackExchange API , kami dapat mengunduh semua jawaban MATL yang pernah digunakan dalam tantangan PPCG. Dengan menguraikan masing-masing jawaban, kami kemudian dapat menentukan frekuensi penggunaan setiap spesifikasi input / output untuk setiap fungsi. Dengan menggunakan informasi ini, kami kemudian dapat mengidentifikasi secara objektif spesifikasi input / output yang &harus mewakili fungsi-meta untuk setiap fungsi. Terkadang tidak ada pemenang yang jelas, begitu banyak fungsi saat ini tidak &didefinisikan.

Berikut ini skrip yang kami gunakan (sayangnya ditulis dalam MATLAB dan bukan MATL).

Dan di sini adalah contoh dari histogram dari $/ #penggunaan

Suever
sumber
1
Fitur ini disarankan oleh @Suever. Awalnya &akan berarti "menambah jumlah input dengan 1 sehubungan dengan default". Sarannya ternyata jauh lebih berguna
Luis Mendo
5

Biasakan diri dengan definisi kebenaran / kepalsuan MATL

Sementara true( T) dan false( F) masing-masing secara jelas mewakili keluaran yang benar dan salah, definisi yang disepakati secara luas tentang kebenaran / kepalsuan memberi kita sedikit lebih banyak fleksibilitas dalam MATL.

Definisi tersebut menyatakan:

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

Jadi kita dapat menulis tes MATL truthy / falsy cepat yang akan mengulang semua input dan menampilkan apakah mereka dianggap benar atau salah

` ? 'truthy' } 'falsey' ]DT

Ini adalah versi online.

Apa artinya ini di MATL

Apa ini sebenarnya diterjemahkan ke dalam MATL (dan karena itu dalam MATLAB dan Oktaf) adalah bahwa suatu kondisi dianggap benar jika jika tidak kosong dan komponen nyata dari semua nilainya tidak nol . Ada dua bagian untuk ini yang harus ditekankan.

  1. Non-nol : Ini berarti persis seperti itu, tidak sama dengan nol ( ==). Ini termasuk angka positif, angka negatif, karakter non-null, dll. Anda dapat dengan mudah memeriksa dengan mengonversi nilai yang diberikan ke logicalnilai ( g) atau Anda dapat menggunakan~~

    F           % Falsy
    T           % Truthy
    0           % Falsy
    1           % Truthy
    2           % Truthy
    -1          % Truthy
    'a'         % Truthy
    ' '         % Truthy (ASCII 32)
    char(0)     % Falsy  (ASCII 0)  
    
  2. Semua nilai : Biasanya kita menganggap skalar sebagai benar atau salah, tetapi dalam MATL, kita dapat mengevaluasi skalar, vektor baris, vektor kolom, atau bahkan matriks multi-dimensi dan mereka dianggap benar jika dan hanya jika setiap nilai tunggal adalah bukan nol (seperti didefinisikan di atas), kalau tidak mereka palsu. Berikut adalah beberapa contoh untuk ditunjukkan

    [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
    

Kasing satu tepi, seperti yang disebutkan di atas, adalah array kosong [], yang selalu dianggap palsu ( contoh )

Bagaimana saya bisa menggunakan ini untuk bermain golf yang lebih baik?

Jika tantangan hanya menyebutkan bahwa output Anda harus benar atau salah, Anda mungkin dapat mengeksploitasi definisi di atas untuk memotong beberapa byte dari jawaban Anda. Untuk menyimpan kebingungan, Anda disarankan untuk menyertakan tautan ke tes kebenaran / kepalsuan online di atas dalam jawaban Anda untuk membantu menjelaskan bagaimana nilai kebenaran / kepalsuan MATL bekerja.

Beberapa contoh spesifik:

  • Sebuah jawaban yang berakhir dengan A. Jika tantangan membutuhkan truthy atau output falsy dan Anda berakhir jawaban Anda di all( A) untuk membuat skalar, Anda dapat menghapus byte terakhir ini dan jawaban Anda akan tetap benar (kecuali output adalah []karena []adalah falsetetapi []Aadalah true).

  • Memastikan bahwa array hanya berisi satu nilai unik : Menggunakan &=menggantikan un1=. Jika semua nilai dalam array sama, perbandingan kesetaraan elemen-bijaksana yang disiarkan akan menghasilkan N x Nmatriks semua nilai. Jika semua nilai tidak sama, matriks ini akan berisi beberapa 0nilai dan karenanya dianggap palsu.

Suever
sumber
4

Masukan Tersirat

Sebagian besar fungsi menerima sejumlah input. Input ini diambil dari bagian atas tumpukan. Jika bagian atas tumpukan tidak mengandung cukup argumen, itu akan menarik argumen yang tersisa dari input. (Lihat Bagian 7.3 dalam dokumentasi) Saya ingin mengutip penjelasan asli:

Input implisit dapat dilihat sebagai berikut: tumpukan diperpanjang tanpa batas di bawah bagian bawah, yaitu, pada posisi 0, −1, −2, ... dengan nilai yang awalnya tidak ditentukan, tetapi diselesaikan dengan cepat melalui input implisit . Input-input ini diminta dari pengguna hanya saat dibutuhkan, sesuai dengan urutannya. Jika beberapa input diperlukan pada saat yang sama mereka mengikuti urutan tumpukan normal, yaitu, input yang paling dalam di tumpukan (diperpanjang) dimasukkan terlebih dahulu.

cacat
sumber
2
Input implisit adalah fitur yang disarankan oleh @ flawr
Luis Mendo
6
@ flawr pasti pria yang sangat pintar. : D
flawr
3

Array logis sering dapat digunakan sebagai array numerik

Anda sering dapat menggunakan TFnotasi " " alih-alih array literal dari nol dan satu. Misalnya, FTFsama dengan [0,1,0], hanya yang FTFmenghasilkan logicalnilai, bukan doublenilai. Ini biasanya bukan masalah, karena operasi aritmatika akan memperlakukan nilai logis sebagai angka. Misalnya, FTFQmemberi [1,2,1]( Qadalah "meningkat sebesar 1").

Dalam beberapa kasus, konversi angka menjadi biner mungkin lebih pendek. Sebagai contoh, [1,0,1], TFTdan 5Badalah sama; lagi dengan hati-hati bahwa dua yang terakhir adalah logicalnilai.


Suatu kasus di mana perbedaan antara TF(logis) dan [1 0](numerik) penting adalah ketika digunakan sebagai indeks. Array tipe yang logicaldigunakan sebagai indeks berarti: pilih elemen yang sesuai T, buang elemen yang terkait dengannya F. Jadi [10 20]TF)menghasilkan 10(pilih elemen pertama), sedangkan [10 20][1 0])menghasilkan [10 20](indeks [1 0]memiliki interpretasi 1:end, yaitu, pilih semua elemen array).

Luis Mendo
sumber
3

Untuk lilitan ukuran n-1

Pertimbangkan untuk mengganti

tnq:"...

dengan

td"...

untuk menyimpan hingga satu byte atau lebih .

Sanchises
sumber
@Buat benar! Saya pikir seseorang mungkin membutuhkan vektor asli yang sedang diulang, tetapi itu juga tidak mungkin dalam pendekatan pertama. Akan menghapus komentar itu.
Sanchises
Tetapi Anda tidak perlu menyimpan 1 byte; Anda menyimpan 1 atau 2 tergantung pada apakah Anda memerlukan @/ X@dalam loop atau tidak. Mungkin Anda bisa mengatakan "untuk menyimpan byte"
Luis Mendo
3

Pindahkan hal-hal dari setelah loop ke dalam loop, untuk mengeksploitasi ujung implisit

endPernyataan loop ],, dapat ditinggalkan jika tidak ada kode setelahnya. Mereka diisi oleh parser MATL secara implisit.

Jadi, jika Anda bisa memindahkan sesuatu dari setelah loop ke dalam loop Anda bisa menyimpan final ].

Sebagai contoh khusus, kode berikut ini menemukan berapa banyak nol yang ada di dalam faktorial suatu angka N(lihat di sini ):

  • Kode dilingkarkan dari 1ke N.
  • Untuk masing-masing angka itu menghitung faktor prima, dan menentukan berapa kali 5hadir.
  • Jawabannya adalah akumulasi jumlah kali yang 5muncul (ini berhasil karena masing-masing 5setidaknya ada satu 2).

Ide pertama adalah :"@Yf5=]vs(perhatikan bahwa ada pernyataan setelah 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

Karena vsecara default menggabungkan semua konten stack, itu dapat dipindahkan ke loop. Dan karena penambahan itu asosiatif, sbisa dipindahkan juga. Yang tersisa ]di akhir kode, dan karenanya dapat dihilangkan :"@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
Luis Mendo
sumber
saya tidak tahu sepeser pun dari bahasa tertulis yang hieroglif-sama ini tetapi saya akan memesan sebagian besar waktu saya mempelajarinya tiga bulan ke depan mungkin.
Abr001am
@ Agawa001 :-) Anda akan menemukan itu sangat mirip dengan Matlab. Anda juga dapat bertanya atau berkomentar di sini
Luis Mendo
3

Cara yang lebih pendek untuk mendefinisikan array numerik kosong, jika tumpukan kosong

Untuk mendorong array numerik kosong yang biasa Anda gunakan []. Namun, jika stack kosong, Anda dapat menyimpan byte menggunakan v. Fungsi ini secara default menggabungkan semua konten stack secara vertikal, jadi jika stack kosong, itu menghasilkan array kosong.

Anda dapat melihatnya beraksi misalnya di sini .

Luis Mendo
sumber
2

Beberapa fungsi diperluas dibandingkan dengan MATLAB atau Oktaf

Jika Anda berasal dari MATLAB atau Oktaf, Anda akan menemukan banyak fungsi MATL mirip dengan fungsi dalam bahasa tersebut. Tetapi dalam beberapa dari mereka fungsionalitas telah diperluas.

Sebagai contoh, pertimbangkan reshapefungsi MATLAB , yang sesuai dengan MATL e. Cuplikan kode reshape([10 20 30 40 50 60], 2, 3)dan reshape([10 20 30 40 50 60], 2, [])masing-masing berarti "membentuk kembali vektor baris [10 20 30 40 50 60menjadi matriks 2 × 3", atau "menjadi matriks 2 baris dengan kolom sebanyak yang diperlukan". Jadi hasilnya, dalam kedua kasus, adalah array 2D

10    30    50
20    40    60

Sesuatu seperti reshape([10 20 30 40 50 60], 2, 2)atau reshape([10 20 30 40 50 60], 5, [])akan memberikan kesalahan karena ukuran yang tidak kompatibel. Namun, MATL akan menghapus elemen dalam kasus pertama ( coba online! ) Atau isi dengan nol di kedua ( coba online! ) Untuk menghasilkan, masing-masing,

10 30
20 40 

dan

10 60
20  0
30  0
40  0
50  0

Fungsi lain yang memiliki fungsionalitas diperluas dibandingkan dengan rekan-rekan MATLAB mereka adalah (daftar non-lengkap) S( sort), Yb(strsplit ), m( ismember), h( horzcat), v( vertcat), Zd( gcd), Zm( lcm), YS( circshift), YA( dec2base), ZA( base2dec), Z"( ), ( blanks).

Luis Mendo
sumber
1

Dapatkan indeks elemen non-nol pertama, jika ada

The fFungsi memberikan indeks dari semua non zero-elemen array. Seringkali Anda menginginkan indeks dari elemen bukan nol pertama . Itu akan menjadi f1): menerapkan fdan memilih elemen pertama. Tetapi jika array asli tidak mengandung nilai bukan nol fakan menghasilkan array kosong ( []), dan mencoba untuk memilih elemen pertamanya akan memberikan kesalahan.

Persyaratan umum yang lebih kuat adalah mendapatkan indeks elemen pertama jika setidaknya ada satu , dan []sebaliknya. Ini bisa dilakukan dengan ifcabang setelah f, tapi itu mahal byte. Cara yang lebih baik adalah fX<, yaitu, menerapkan fungsi minimum X<ke output f. X<mengembalikan array kosong ketika inputnya adalah array kosong.

Cobalah online! (Perhatikan bahwa array kosong tidak ditampilkan sama sekali). Atau lihat contoh ini bekerja di sini .

Luis Mendo
sumber
1

Hasilkan rentang selama array yang diberikan

TL; WR : gunakan fsebagai gantin: jika array hanya memiliki elemen bukan nol.


Hal ini sering terjadi bahwa salah satu kebutuhan untuk menghasilkan sebuah array [1 2 ... L]di mana Ladalah jumlah elemen dari array yang diberikan. Cara standar untuk melakukannya adalah n:. Misalnya kodenyatn:* mengambil vektor numerik sebagai input dan menghitung setiap entri dikalikan dengan indeksnya.

Jika array yang diberikan dijamin hanya berisi entri bukan nol (misalnya, itu dibentuk oleh bilangan bulat positif, atau string dengan karakter yang dapat dicetak), n:dapat diganti dengan f, yang menghasilkan array dengan indeks entri bukan nol. Jadi kode di atas menjadi tf*, yang menghemat 1 byte.

Beberapa contoh yang lebih rumit: 1 , 2 , 3 .

Luis Mendo
sumber
1

Mendefinisikan literal array numerik secara efisien

Berikut adalah beberapa cara yang dapat digunakan untuk menyimpan byte saat mendefinisikan literal array numerik. Tautan diberikan sebagai contoh jawaban yang menggunakannya. Ini telah diperoleh dengan menggunakan skrip analitik yang dibuat oleh @Suever .

Rangkaian dan literasi yang telah ditentukan sebelumnya

Untuk array dengan angka kecil Anda kadang-kadang dapat menggunakan gabungan (fungsi hdan v), serta liter yang telah ditentukan untuk menghindari menggunakan spasi sebagai pemisah: bandingkan [2 4], 2 4hdan 2Kh, yang semuanya mendefinisikan array [2 4]. Demikian pula, 2K1vdengan mendefinisikan tumpukan kosong [2; 4; 1]. Contoh .

Huruf dalam literal array numerik

Untuk angka yang sedikit lebih besar, Anda dapat menghemat ruang dengan mengeksploitasi fakta bahwa beberapa huruf memiliki makna angka dalam literal array. Jadi alih-alih [3 5 2 7;-4 10 12 5]Anda bisa menggunakan [IAHC;dX12A]. Contoh .

Secara khusus, dalam literal array,

  • O, l, H I KMemiliki makna yang biasa mereka 0, ...,4
  • A, ..., Eberarti 5, ...,9
  • X cara 10
  • a, ... dberarti -1, ...,-4
  • Jdan Gberarti 1jdan-1j
  • P cara pi
  • Y cara inf
  • Nberarti NaN.

Perbedaan string dan berturut-turut

Untuk angka yang lebih besar, mendefinisikan string dan menghitung perbedaan berurutannya (dengan d) dapat membantu: alih-alih [20 10 35 -6]Anda dapat menggunakannya '!5?b\'d. Ini berfungsi karena dmenggunakan titik kode karakter untuk menghitung perbedaan. Contoh .

Luis Mendo
sumber