Mẹo chơi gôn trong MATL


20

MATL là một ngôn ngữ chơi gôn được tạo bởi Luis Mendo . MATL đã được chứng minh là có tính cạnh tranh cao, thường đánh bại các bài nộp trong các ngôn ngữ chơi gôn khác như Pyth, CJam và Jelly.

Một số lời khuyên hữu ích cho việc chơi golf trong MATL là gì? (Như mọi khi, một mẹo cho mỗi câu trả lời, xin vui lòng!)


5
Nó chắc chắn là một lợi thế lớn nếu bạn biết một số Matlab / Octave. Một số mẹo từ Mẹo chơi gôn trong MatlabMẹo chơi gôn trong Octave cũng được sử dụng trong MATL.
flawr

Gợi ý: có vẻ như accumarray( XQ) có thể khá mạnh (thậm chí có thể nhiều hơn trong MATLAB / Octave vì các tay cầm hàm độ dài này có mã số tiện dụng), nhưng tôi không biết nó đủ rõ để minh họa bằng các ví dụ hay. Nếu nó thực sự hữu ích, ai đó có thể tạo ra một câu trả lời với ý tưởng về cách sử dụng nó không?
- Phục hồi lại

Câu trả lời:


7

Biết các chữ được xác định trước

Mặc dù một số trong số chúng giữ thông tin khi được sao chép vào bảng tạm, tất cả chúng đều có giá trị được xác định trước.

  • F, đẩy 0 (thực tế là sai )
  • T, đẩy 1 (thực sự đúng )
  • H, đẩy 2 (giá trị clipboard được xác định trước)
  • I, đẩy 3 (giá trị clipboard được xác định trước)
  • K, đẩy 4 (giá trị clipboard được xác định trước)
  • J, đẩy 0 + 1j (giá trị clipboard được xác định trước)

Không chắc chắn nếu tôi đã bao gồm tất cả các giá trị được xác định trước mặc dù.


Chỉ để hoàn thiện (và trong trường hợp bạn muốn thêm vào câu trả lời của mình): mỗi cấp độ của bảng tạm Lcũng có một giá trị được xác định trước, nhưng chúng được dành cho sử dụng đặc biệt (thay vì giá trị chung, chung). Ví dụ: 1Lgive [1 0](được sử dụng làm chỉ mục 1:end), 2Lgive [0 -1 1](for 1:-1:end). Ngoài ra, các chức năng lOlấy 0 đầu vào theo mặc định và sản xuất 01tương ứng
Luis Mendo

Tôi không thấy nó hữu ích như thế nào ... Tôi không thể viết 4?
Cyoce

@Cyoce Tính hữu dụng là tránh một khoảng trắng làm dấu phân cách. Nếu bạn muốn đẩy 1, sau đó 4, 14sẽ không làm. Bạn sẽ cần 1 4. Hoặc 1Kđể lưu một byte
Luis Mendo

@LuisMendo ah, tôi hiểu rồi. Tôi đoán tôi đã giả sử nó sử dụng phương thức chỉ có 1 chữ số (không rõ tại sao)
Cyoce

1
Một trường hợp khác khi Kthay vì 4tiện dụng là: 1-4có nghĩa là: đẩy 1, sau đó đẩy -4; trong khi đó 1-Kcó nghĩa là: đẩy 1, trừ đi bất cứ thứ gì bên dưới trong ngăn xếp, sau đó đẩy4
Luis Mendo

5

Hàm &Meta (Đặc tả đầu vào / đầu ra thay thế)

Cách truyền thống để xác định số lượng đối số đầu vào để truyền cho hàm là sử dụng hàm $meta

2$:     % Two-input version of :

Tương tự, để chỉ định số lượng đối số đầu ra, bạn có thể sử dụng hàm #meta chỉ định số lượng đối số đầu ra,

2#S     % Two-output version of sort

hoặc nếu bạn vượt qua một số đó là lớn hơn số lượng các đối số đầu ra định nghĩa cho một chức năng, chỉ các mod(N, numberOfOutputs) + 1đầu ra được cung cấp.

4#S     % Get only the second output of sort

Bạn cũng có thể chỉ định một mảng logic làm đầu vào để #chỉ truy xuất các đối số đầu ra cụ thể.

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

Tất cả các thông số kỹ thuật đầu vào / đầu ra này đều tiện dụng nhưng chúng tăng tốc độ đếm byte của bạn rất nhanh. Để giải quyết vấn đề này, MATL đã giới thiệu &chức năng meta trong phiên bản 17.0.0 . Hàm &meta này hoạt động như một lối tắt cho một đặc tả đầu vào hoặc đầu ra cụ thể cho một chức năng. Hãy xem điều đó có nghĩa là gì.

Trong ví dụ của chúng tôi ở trên, chúng tôi muốn sử dụng phiên bản hai đầu vào của :(tạo ra một vectơ các giá trị cách đều nhau). Mặc dù số lượng đối số đầu vào mặc định :1(tạo một mảng từ [1...N]), nhưng rất phổ biến là người dùng sẽ muốn chỉ định giá trị bắt đầu của phạm vi yêu cầu đầu vào thứ hai. Vì vậy :, chúng tôi đã xác định &là một phím tắt cho 2$.

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

Bây giờ trở thành như sau, tiết kiệm một byte !

10 12 &:

Làm thế nào chúng ta có thể xác định số lượng đối số thay thế là gì?

Đặc tả đầu vào / đầu ra &chuyển thành chức năng cụ thể để chúng tôi tối ưu hóa tiết kiệm byte.

Phần đối số đầu vào / đầu ra của mô tả trợ giúp cho từng chức năng đã được cập nhật để cho biết số lượng đầu vào / đầu ra thay thế này là gì (nếu có). Số lượng đối số đầu vào hoặc đầu ra có thể được hiển thị dưới dạng phạm vi và các giá trị mặc định cho từng đối số được hiển thị trong ngoặc đơn. Thông số đầu vào / đầu ra có thể được thay thế bằng &được hiển thị sau /ký tự trong ngoặc đơn.

Đây là phần đối số đầu vào / đầu ra của mô tả trợ giúp cho :

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

Làm thế nào bạn xác định được ý &nghĩa của từng chức năng?

Rất cẩn thận. Sử dụng API StackExchange , chúng tôi có thể tải xuống tất cả các câu trả lời MATL đã từng được sử dụng trong thử thách PPCG. Bằng cách phân tích từng câu trả lời, sau đó chúng tôi có thể xác định tần suất mà mỗi thông số đầu vào / đầu ra được sử dụng cho từng chức năng. Sau đó, sử dụng thông tin này, chúng tôi có thể xác định một cách khách quan đặc tả đầu vào / đầu ra mà hàm &meta sẽ đại diện cho từng chức năng. Đôi khi không có người chiến thắng rõ ràng, rất nhiều chức năng hiện chưa &được xác định.

Đây là kịch bản chúng tôi đã sử dụng (không may là nó được viết bằng MATLAB chứ không phải MATL).

Và đây là một ví dụ về biểu đồ của $/ #sử dụng


1
Tính năng này được đề xuất bởi @Suever. Ban đầu &sẽ có nghĩa là "tăng số lượng đầu vào lên 1 so với mặc định". Gợi ý của anh ấy trở nên hữu ích hơn nhiều
Luis Mendo

5

Làm quen với các định nghĩa trung thực / giả dối của MATL

Mặc dù true( T) và false( F) đại diện rõ ràng cho đầu ra trung thực và giả, tương ứng, định nghĩa được thống nhất rộng rãi về tính trung thực / giả mạo cho chúng ta linh hoạt hơn một chút trong MATL.

Định nghĩa nêu:

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

Vì vậy, chúng tôi có thể viết một bài kiểm tra MATL thật / giả nhanh chóng, nó sẽ lặp qua tất cả các đầu vào và hiển thị xem chúng được coi là trung thực hay giả

` ? 'truthy' } 'falsey' ]DT

Đây là một phiên bản trực tuyến.

Điều này có nghĩa là gì trong MATL

Điều này thực sự chuyển thành MATL (và do đó trong MATLAB và Octave) là một điều kiện được coi là đúng nếu nó không rỗng và các thành phần thực của tất cả các giá trị của nó là khác không . Có hai phần này cần được nhấn mạnh.

  1. Non-zero : Điều này có nghĩa chính xác là như vậy, không bằng zero ( ==). Điều này bao gồm số dương, số âm, ký tự không null, v.v. Bạn có thể dễ dàng kiểm tra bằng cách chuyển đổi một giá trị đã cho thành logicalgiá trị ( g) hoặc bạn có thể sử dụng~~

    F           % Falsy
    T           % Truthy
    0           % Falsy
    1           % Truthy
    2           % Truthy
    -1          % Truthy
    'a'         % Truthy
    ' '         % Truthy (ASCII 32)
    char(0)     % Falsy  (ASCII 0)  
    
  2. Tất cả các giá trị : Thông thường chúng ta nghĩ rằng vô hướng là đúng hoặc sai, nhưng trong MATL, chúng ta có thể đánh giá vô hướng, vectơ hàng, vectơ cột hoặc thậm chí ma trận đa chiều và chúng được coi là trung thực nếu và chỉ khi mỗi giá trị là khác không (như được định nghĩa ở trên), nếu không chúng là giả. Dưới đây là một vài ví dụ để chứng minh

    [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
    

Trường hợp một cạnh, như đã đề cập ở trên, là một mảng trống [], luôn được coi là sai lệch ( ví dụ )

Làm thế nào tôi có thể sử dụng điều này để chơi golf tốt hơn?

Nếu thử thách chỉ đề cập rằng đầu ra của bạn phải trung thực hoặc sai lệch, bạn có thể khai thác định nghĩa ở trên để loại bỏ một vài byte khỏi câu trả lời của bạn. Để tránh nhầm lẫn, bạn nên bao gồm một liên kết đến bài kiểm tra trung thực / giả mạo trực tuyến ở trên trong câu trả lời của bạn để giúp giải thích cách hoạt động của các giá trị MATL thật / giả.

Một vài ví dụ cụ thể:

  • Một câu trả lời kết thúc bằng A. Nếu thách thức đòi hỏi một truthy hoặc đầu ra falsy và bạn kết thúc câu trả lời trong all( A) để tạo ra một đại lượng vô hướng, bạn có thể xóa byte cuối cùng này và câu trả lời của bạn sẽ vẫn chính xác (trừ đầu ra là []kể từ khi []falsenhưng []Atrue).

  • Đảm bảo rằng một mảng chỉ chứa một giá trị duy nhất : Sử dụng &=thay cho un1=. Nếu tất cả các giá trị trong một mảng bằng nhau, một phép so sánh đẳng thức phần tử được phát sóng sẽ tạo ra một N x Nma trận của tất cả các giá trị. Nếu tất cả các giá trị không bằng nhau, ma trận này sẽ chứa một số 0giá trị và do đó được coi là giả.


4

Đầu vào tiềm ẩn

Hầu hết các chức năng chấp nhận một số lượng đầu vào. Những đầu vào này được lấy từ đầu ngăn xếp. Nếu đỉnh của ngăn xếp không chứa đủ đối số, nó sẽ rút ra đối số còn lại từ đầu vào. (Xem Phần 7.3 trong tài liệu) Tôi muốn trích dẫn lời giải thích ban đầu:

Các đầu vào tiềm ẩn có thể được xem như sau: ngăn xếp được kéo dài vô tận bên dưới đáy, nghĩa là, tại các vị trí 0, −1, 2, ... với các giá trị không được xác định ban đầu, nhưng được giải quyết nhanh chóng thông qua đầu vào ẩn . Những đầu vào này được yêu cầu từ người dùng chỉ khi họ cần, theo thứ tự mà họ cần. Nếu một số đầu vào được yêu cầu đồng thời chúng tuân theo thứ tự ngăn xếp thông thường, nghĩa là đầu vào sâu nhất trong ngăn xếp (mở rộng) được nhập trước tiên.


2
Nhập liệu tiềm ẩn là một tính năng được đề xuất bởi @flawr
Luis Mendo

6
@flawr phải là một chàng trai thực sự thông minh. : D
flawr

3

Mảng logic thường có thể được sử dụng như mảng số

Bạn thường có thể sử dụng TFký hiệu "" thay vì các ký tự bằng số và số không. Ví dụ, FTFgiống như [0,1,0], chỉ FTFtạo ra logicalcác giá trị, không phải doublegiá trị. Điều này thường không phải là một vấn đề, vì bất kỳ hoạt động đối xứng sẽ coi các giá trị logic là số. Ví dụ: FTFQcho [1,2,1]( Qlà "tăng thêm 1").

Trong một số trường hợp, việc chuyển đổi một số thành nhị phân có thể ngắn hơn. Ví dụ, [1,0,1], TFT5Bđều giống nhau; một lần nữa với sự thận trọng rằng hai cái sau là logicalgiá trị.


Một trường hợp trong đó sự khác biệt giữa các vấn đề TF(logic) và [1 0](số) là khi được sử dụng như các chỉ số. Một mảng kiểu logicalđược sử dụng làm chỉ mục có nghĩa là: chọn các phần tử tương ứng T, loại bỏ các phần tử tương ứng với F. Vì vậy, [10 20]TF)sản xuất 10(chọn phần tử đầu tiên), trong khi [10 20][1 0])sản xuất [10 20](chỉ mục [1 0]có giải thích 1:end, nghĩa là chọn tất cả các phần tử của mảng).


3

Đối với vòng có kích thước n-1

Xem xét việc thay thế

tnq:"...

với

td"...

để lưu tối đa toàn bộ byte trở lên .


@Luis đúng! Tôi nghĩ rằng người ta có thể cần vectơ gốc đang được lặp, nhưng điều đó cũng không thể thực hiện được trong cách tiếp cận đầu tiên. Sẽ loại bỏ nhận xét đó.
Sanchise

Nhưng bạn không nhất thiết phải tiết kiệm 1 byte; bạn lưu 1 hoặc 2 tùy thuộc vào việc bạn có cần @/ X@trong vòng lặp hay không. Có lẽ bạn chỉ có thể nói "để lưu byte"
Luis Mendo

3

Di chuyển mọi thứ từ sau vòng lặp sang trong vòng lặp, để khai thác kết thúc ngầm

Các endcâu lệnh lặp ], có thể bị bỏ qua nếu không có mã nào sau chúng. Chúng được điền bởi trình phân tích cú pháp MATL ngầm.

Vì vậy, nếu bạn có thể di chuyển mọi thứ từ sau vòng lặp sang trong vòng lặp, bạn có thể lưu trận chung kết ].

Như một ví dụ cụ thể, đoạn mã sau đây tìm thấy có bao nhiêu số 0 ở cuối giai thừa của một số N(xem nó ở đây ):

  • Các vòng lặp mã từ 1đến N.
  • Đối với mỗi số đó, nó tính các thừa số nguyên tố của nó và xác định số lần 5xuất hiện.
  • Câu trả lời là số lần tích lũy 5xuất hiện (điều này hoạt động vì với mỗi lần 5có ít nhất một lần 2).

Ý tưởng đầu tiên là :"@Yf5=]vs(lưu ý rằng có các câu lệnh sau vòng lặp):

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

vtheo mặc định nối tất cả các nội dung ngăn xếp, nó có thể được di chuyển vào vòng lặp. Và vì bổ sung là kết hợp, scó thể được di chuyển quá. Điều đó để lại ]ở cuối mã, và do đó nó có thể được bỏ qua :"@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

tôi không biết một xu của ngôn ngữ viết chữ tượng hình này nhưng tôi sẽ dành phần lớn thời gian để nghiên cứu nó trong ba tháng tới.
Abr001am

@ Agawa001 :-) Bạn sẽ thấy nó khá giống với Matlab. Bạn cũng có thể hỏi hoặc bình luận tại đây
Luis Mendo

3

Cách ngắn hơn để xác định một mảng số trống, nếu ngăn xếp trống

Để đẩy một mảng số trống bạn thường sử dụng []. Tuy nhiên, nếu ngăn xếp trống, bạn có thể lưu một byte bằng cách sử dụng v. Hàm này theo mặc định nối tất cả các nội dung ngăn xếp theo chiều dọc, vì vậy nếu ngăn xếp trống, nó tạo ra mảng trống.

Bạn có thể thấy nó trong hành động ví dụ ở đây .


2

Một số chức năng được mở rộng so với MATLAB hoặc Octave

Nếu bạn đến từ MATLAB hoặc Octave, bạn sẽ thấy nhiều hàm MATL tương tự như các hàm trong các ngôn ngữ đó. Nhưng trong một vài trong số họ chức năng đã được mở rộng.

Ví dụ, hãy xem xét reshapehàm MATLAB , trong MATL tương ứng với e. Đoạn mã reshape([10 20 30 40 50 60], 2, 3)reshape([10 20 30 40 50 60], 2, [])tương ứng có nghĩa là "định hình lại vectơ hàng [10 20 30 40 50 60thành ma trận 2 × 3" hoặc "thành ma trận 2 hàng với càng nhiều cột nếu cần". Vì vậy, kết quả, trong cả hai trường hợp, là mảng 2D

10    30    50
20    40    60

Một cái gì đó như reshape([10 20 30 40 50 60], 2, 2)hoặc reshape([10 20 30 40 50 60], 5, [])sẽ đưa ra một lỗi vì kích thước không tương thích. Tuy nhiên, MATL sẽ loại bỏ các phần tử trong trường hợp đầu tiên ( thử trực tuyến! ) Hoặc điền vào các số 0 trong phần thứ hai ( thử trực tuyến! ) Để tạo ra, tương ứng,

10 30
20 40 

10 60
20  0
30  0
40  0
50  0

Các hàm khác có chức năng mở rộng so với các đối tác MATLAB của chúng là (danh sách không đầy đủ) S( sort), Yb( strsplit), m( ismember), h( horzcat), v( vertcat), Zd( gcd), Zm( lcm), YS( circshift), YA( dec2base), ZA( base2dec), Z"( blanks).


1

Lấy chỉ mục của phần tử khác không đầu tiên, nếu có

Các fchức năng cung cấp cho các chỉ số của tất cả các yếu tố khác không của một mảng. Thường thì bạn muốn chỉ số của phần tử khác không đầu tiên . Đó sẽ là f1): áp dụng fvà chọn yếu tố đầu tiên của nó. Nhưng nếu mảng ban đầu không chứa bất kỳ giá trị khác không nào fsẽ tạo ra một mảng trống ( []) và cố gắng chọn phần tử đầu tiên của nó sẽ báo lỗi.

Một yêu cầu phổ biến, mạnh mẽ hơn là lấy chỉ số của phần tử đầu tiên nếu có ít nhất một , và []nếu không. Điều này có thể được thực hiện với một ifnhánh sau f, nhưng nó rất đắt. Một cách tốt hơn fX<là, áp dụng hàm tối thiểu X<cho đầu ra của f. X<trả về một mảng trống khi đầu vào của nó là một mảng trống.

Hãy thử trực tuyến! (Lưu ý rằng một mảng trống hoàn toàn không hiển thị). Hoặc xem một ví dụ về điều này tại nơi làm việc ở đây .


1

Tạo một phạm vi miễn là một mảng nhất định

TL; WR : sử dụng fthay vì n:nếu mảng chỉ có các phần tử khác.


Nó thường là trường hợp người ta cần tạo ra một mảng [1 2 ... L]trong đó Lsố lượng phần tử của một mảng nhất định. Cách tiêu chuẩn để làm điều đó là n:. Ví dụ, mã tn:*lấy một vectơ số làm đầu vào và tính toán từng mục nhập nhân với chỉ số của nó.

Nếu mảng đã cho được đảm bảo chỉ chứa các mục nhập khác (ví dụ: nó được hình thành bởi các số nguyên dương hoặc là một chuỗi có các ký tự có thể in được), n:có thể được thay thế bằng f, tạo ra một mảng với các chỉ mục của các mục nhập khác. Vì vậy, đoạn mã trên trở thành tf*, giúp tiết kiệm 1 byte.

Một số ví dụ chi tiết hơn: 1 , 2 , 3 .


1

Xác định hiệu quả các mảng số

Dưới đây là một vài cách có thể được sử dụng để lưu byte khi xác định nghĩa đen của mảng số. Liên kết được đưa ra để trả lời ví dụ sử dụng chúng. Chúng được lấy bằng cách sử dụng tập lệnh phân tích được tạo bởi @Suever .

Ghép và chữ được xác định trước

Đối với các mảng có số lượng nhỏ, đôi khi bạn có thể sử dụng phép nối (hàm hv ), cũng như chữ được xác định trước để tránh sử dụng không gian như tách: so sánh [2 4], 2 4h2Kh, tất cả đều xác định mảng [2 4]. Tương tự, 2K1vvới một ngăn xếp trống xác định [2; 4; 1]. Ví dụ .

Các chữ cái trong mảng chữ số

Đối với các số lớn hơn một chút, bạn có thể lưu các không gian khai thác thực tế là một số chữ cái có ý nghĩa số trong phạm vi mảng. Vì vậy, thay vì [3 5 2 7;-4 10 12 5]bạn có thể sử dụng [IAHC;dX12A]. Ví dụ .

Cụ thể, trong phạm vi chữ,

  • O, l,H I K Có ý nghĩa thông thường của họ 0, ...,4
  • A, ..., Ecó nghĩa là 5, ...,9
  • X có nghĩa 10
  • a, ... d có nghĩa là -1, ...,-4
  • JG có nghĩa là 1j-1j
  • P có nghĩa pi
  • Y có nghĩa inf
  • N có nghĩa NaN .

Chuỗi và sự khác biệt liên tiếp

Đối với các số lớn hơn, việc xác định một chuỗi và tính toán các khác biệt liên tiếp của nó (với d) có thể giúp: thay vì [20 10 35 -6]bạn có thể sử dụng '!5?b\'d. Điều này hoạt động vì dsử dụng các điểm mã của ký tự để tính toán sự khác biệt. Ví dụ .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.