Mẹo chơi gôn trong Perl 6


16

Bạn có lời khuyên chung nào cho việc chơi golf trong Perl 6? Tôi đang tìm kiếm những ý tưởng có thể được áp dụng cho các vấn đề về golf nói chung ít nhất là cụ thể đối với Perl 6 (ví dụ: "xóa bình luận" không phải là một câu trả lời). Xin vui lòng gửi một lời khuyên cho mỗi câu trả lời.

Xin lưu ý rằng Perl 6 không phải là Perl 5, vì vậy câu hỏi này không phải là một bản sao. Hầu hết các mẹo để chơi gôn Perl 5 không áp dụng cho Perl 6.

Câu trả lời:


9

Tránh nghĩa subđen. Trong nhiều trường hợp, bạn chỉ cần sử dụng {}cho các khối mã. Ví dụ: không viết mã sau đây.

sub ($a){$a*2}

Thay vào đó, sử dụng cú pháp khối. Điều này cũng cho phép bạn sử dụng $_, @_%_các biến giữ chỗ, nếu bạn chỉ cần một biến duy nhất. Nếu bạn cần nhiều hơn, bạn có thể sử dụng $^a, $^bcác biến, v.v.

{$_*2}

Ngoài ra, trong một số trường hợp hiếm hoi, có thể sử dụng bất kỳ mã nào (đặc biệt là khi bạn có các biểu thức đơn giản). Các *thay thế đối số giữ chỗ.

* *2

8

Perl 6 có một tính năng thực sự kỳ lạ khi nó cho phép tất cả các ký tự Unicode trong các danh mục Nd , Nl và  No được sử dụng làm chữ số hợp lý. Một số trong số này ngắn hơn so với việc viết các giá trị số của chúng ra trong ASCII:

  • ¼(2 byte) ngắn hơn .25hoặc 1/4(3 byte).
  • ¾(2 byte) ngắn hơn .75hoặc 3/4(3 byte).
  • (3 byte) ngắn hơn 1/16(4 byte).
  • 𐦼(4 byte) ngắn hơn 11/12(5 byte).
  • 𒐲(4 byte) ngắn hơn 216e3(5 byte).
  • 𒐳(4 byte) ngắn hơn 432e3(5 byte).

Để theo dõi điều này, bạn cũng có thể sử dụng số mũ Unicode, ngay cả với nhiều chữ số và / hoặc dấu trừ: say (3² + 4², 2²⁰, 5⁻²)==> (25 1048576 0.04). Danh sách đầy đủ về Unicode mà bạn có thể lạm dụng như thế này có ở đây: docs.perl6.org/lingu/unicode_texas .
Ramillies

8

Tìm hiểu các chức năng để đọc đầu vào. Perl 6 có nhiều chức năng thú vị có thể dễ dàng đọc đầu vào từ ARGV hoặc STDIN (nếu không có gì được chỉ định trên ARGV), có thể rút ngắn mã của bạn nếu được sử dụng đúng cách. Nếu bạn gọi chúng là phương thức filehandle, bạn có thể buộc chúng hoạt động trên filehandle cụ thể (hữu ích nếu bạn đọc ví dụ STDIN, nhưng bạn phải đọc các đối số trên ARGV).

get

Hàm này có một dòng duy nhất và tự động kiểm tra nó, vì vậy bạn không cần phải làm vậy. Điều này rất hữu ích nếu bạn chỉ cần đọc một dòng.

lines

Hàm này nhận tất cả các dòng từ tệp hoặc STDIN. Đây là một danh sách lười biếng, vì vậy nếu bạn sử dụng nó for, nó sẽ chỉ đọc những gì bạn cần. Ví dụ.

say "<$_>"for lines

slurp

Điều này sẽ đọc toàn bộ tệp hoặc STDIN và sẽ trả về kết quả dưới dạng một chuỗi.


Lỗi đó đã được sửa - không biết khi nào, nhưng say "<$_>" for lineshoạt động ngay bây giờ
mèo

5

Cảnh báo : Bức tường của văn bản tiếp cận. Đó là rất nhiều mánh khóe nhỏ tôi đã thu thập theo thời gian.

Viết giải pháp của bạn dưới dạng khối ẩn danh

Điều này đã được đề cập nhưng tôi muốn nhắc lại. Trong TIO, bạn có thể viết my $f =vào tiêu đề, khối vào mã phù hợp và bắt đầu chân trang bằng a ;. Đây dường như là cách ngắn nhất để hoàn thành công việc (vì bạn không cần quan tâm đến việc đọc bất kỳ đầu vào nào, nó được trao cho bạn trong các đối số).

Một cách hay khác là sử dụng -nhoặc công -ptắc, nhưng tôi không tìm ra cách nào để nó hoạt động trong TIO.

Sử dụng cú pháp dấu hai chấm để truyền đối số

Đó là, thay vì thing.method(foo,bar), bạn có thể làm thing.method:foo,barvà lưu 1 ký tự. Thật không may, bạn không thể gọi một phương thức khác trên kết quả vì những lý do rõ ràng, do đó, chỉ nên sử dụng cho phương pháp cuối cùng trong một khối.

Sử dụng $_càng nhiều càng tốt

Đôi khi, tốt hơn là lấy một đối số danh sách hơn là một số đối số riêng biệt vì điều này. Khi truy cập $_, bạn có thể gọi các phương thức trên đó chỉ bằng cách bắt đầu bằng dấu chấm: eg .sortbằng $_.sort.

Tuy nhiên, hãy nhớ rằng mỗi khối sẽ có một khối riêng $_, vì vậy các tham số của khối bên ngoài sẽ không truyền vào bên trong. Nếu bạn cần truy cập các tham số của chức năng chính từ một khối bên trong, ...

Sử dụng các ^biến nếu bạn không thể sử dụng$_

Chèn một ^giữa sigil và tên biến, như thế này : $^a. Những công việc này chỉ trong một khối. Trình biên dịch trước tiên sẽ đếm xem bạn có bao nhiêu trong số này trong khối, sắp xếp chúng theo từ vựng và sau đó gán đối số đầu tiên cho đối số thứ nhất, thứ hai cho thứ hai, v.v. Các ^nhu cầu chỉ được sử dụng trong lần xuất hiện đầu tiên của biến. Vì vậy, {$^a - $^b}mất 2 vô hướng và trừ chúng. Điều duy nhất quan trọng là thứ tự chữ cái, {-$^b + $^a}cũng làm điều tương tự.

Nếu bạn từng cảm thấy muốn sử dụng cú pháp khối nhọn (như ->$a,$b {$a.map:{$_+$b}}), thì tốt hơn hết bạn nên viết câu lệnh không có thật khi bắt đầu khối bằng cách sử dụng ^cho mỗi đối số bạn sẽ không sử dụng trong khối chính (như {$^b;$^a.map:{$_+$b}}) đó là cách tốt hơn để chơi gôn {$^a.map(*+$^b)}. Tôi chỉ muốn thể hiện khái niệm này.)

Đọc kỹ tài liệu vận hành

Các nhà khai thác rất mạnh mẽ và thường là cách ngắn nhất để hoàn thành công việc. Đặc biệt là meta-nhà khai thác (nhà khai thác mà phải mất nhà khai thác như một cuộc tranh cãi) [], [\], X, <</ >>Zcó giá trị của sự chú ý của bạn. Đừng quên rằng một meta-op có thể lấy một meta-op khác làm đối số (như XZ%%tôi đã quản lý để sử dụng ở đây ). Bạn cũng có thể sử dụng >>cho một cuộc gọi phương thức, có thể rẻ hơn rất nhiều so với bản đồ ( @list>>.methodthay vì @list.map(*.method), nhưng hãy cẩn thận, chúng không giống nhau! ). Và cuối cùng, trước khi bạn sử dụng nhị phân << >>, hãy nhớ rằng Zthường sẽ làm điều tương tự với ít ký tự hơn nhiều.

Nếu bạn chồng nhiều meta vào nhau, bạn có thể chỉ định mức độ ưu tiên bằng dấu ngoặc vuông []. Điều đó sẽ giúp bạn tiết kiệm khi bạn chồng quá nhiều toán tử đến nỗi nó làm cho trình biên dịch bối rối. (Điều đó không xảy ra rất thường xuyên.)

Cuối cùng, nếu bạn cần ép buộc mọi thứ vào Bool, Int hoặc Str, đừng sử dụng các phương thức .Bool, .Int.Str, thay vào đó là các toán tử ?, +~. Hoặc thậm chí tốt hơn, chỉ cần đặt chúng vào một biểu thức số học để buộc chúng vào Int và cứ thế. Cách ngắn nhất để có được độ dài của danh sách là +@list. Nếu bạn muốn tính 2 với sức mạnh của độ dài của một danh sách, chỉ cần nói 2**@listvà nó sẽ thực hiện Điều đúng.

Sử dụng các biến trạng thái tự do $, @%

Trong mỗi khối, mỗi sự xuất hiện của $(hay @hay %) đề cập đến một biến trạng thái sáng bóng vô hướng mới (hoặc mảng, hoặc băm) (một biến mà vẫn tồn tại giá trị trên cuộc gọi đến các khối). Nếu bạn cần một biến trạng thái chỉ cần được tham chiếu một lần trong mã nguồn, thì ba người này là những người bạn lớn của bạn. (Thường xuyên nhất là $.) Ví dụ, trong thử thách Reverse Math C chu kỳ , nó có thể được sử dụng để chọn các toán tử theo chu kỳ từ một mảng, được lập chỉ mục bởi $++%6.

Sử dụng các hình thức phụ của map, grepet al.

Điều đó có nghĩa là: làm hơn map {my block},listlist.map({my block}). Ngay cả khi bạn quản lý để sử dụng list.map:{my block}, hai cách tiếp cận này xuất hiện ở cùng một số byte. Và thông thường, bạn sẽ cần phải ngoặc đơn danh sách khi gọi một phương thức, nhưng không phải khi gọi một phụ. Vì vậy, cách tiếp cận phụ xuất hiện luôn tốt hơn hoặc ít nhất giống như phương pháp một.

Ngoại lệ duy nhất ở đây là khi đối tượng là mapped, grepped và vân vân $_. Sau đó .map:{}rõ ràng là nhịp đập map {},$_.

Sử dụng các mối nối ( &|) thay vì &&||.

Rõ ràng, chúng ngắn hơn 1 byte. Mặt khác, chúng phải được thu gọn bằng cách bị buộc vào một bối cảnh boolean. Điều này có thể luôn luôn được thực hiện với a ?. Ở đây bạn nên biết về một meta-op !opbuộc bối cảnh bool, sử dụng opvà phủ nhận kết quả.

Nếu bạn có một danh sách và bạn muốn biến nó thành một ngã ba, đừng sử dụng [&][|]. Thay vào đó sử dụng .any.all. Cũng có .nonenhững thứ không thể dễ dàng bắt chước bởi các ngã ba.


1
Tôi nghĩ &&||vẫn còn hữu ích cho ngắn mạch?
ASCII-chỉ

@ Chỉ ASCII: Có, chắc chắn là có.
Ramillies

4

Giảm không gian sử dụng cho các biến

Có một vài phần cho việc này.

Xóa khoảng trắng

Các biến được khai báo sử dụng mythường có thể được khai báo mà không có khoảng trắng giữa myvà tên biến. my @atương đương với my@a.

Sử dụng các biến ít sigil

Bạn có thể khai báo các biến bằng cách sử dụng dấu gạch chéo ngược để loại bỏ sigil trước tên biến, như vậy:

my \a=1;

(tiếc là bạn không thể xóa khoảng trắng :()

Điều này rất hữu ích vì sau đó bạn có thể gọi chúng là tên biến trần sau này.

 a=5;
 a.say

Về cơ bản, điều này sẽ tiết kiệm byte nếu bạn sử dụng biến nhiều lần ở nơi khác trong mã của mình. Nhược điểm là biến cần phải được khởi tạo.

Sử dụng $!$/

Các biến được khai báo trước này thường được sử dụng cho các trường hợp ngoại lệ và biểu thức khớp tương ứng, nhưng không cần xác định bằng cách sử dụng my.

$!=1;
$/=5;

Đặc biệt hữu ích là sử dụng $/như một mảng và sử dụng các phím tắt $theo sau là một số để truy cập vào phần tử đó của $/mảng;

$/=100..200;
say $5;  #105
say $99; #199

2

Sử dụng ...thay vìfirst

Thông thường, nếu bạn muốn tìm số đầu tiên phù hợp với một số điều kiện &f, bạn có thể biểu thị nó như sau:

first &f,1..*

Tuy nhiên, thay vào đó bạn có thể sử dụng ...toán tử:

+(1...&f)

Nếu bạn phải bắt đầu từ 0, bạn có thể có -1sau đó thay vì +.

Nếu bạn muốn chỉ mục của phần tử đầu tiên trong danh sách @acó điều kiện &f, thông thường bạn làm:

first &f,@a,:k

Thay thế:

(@a...&f)-1

(hoặc ngược lại nếu bạn muốn 0 được lập chỉ mục). Theo cùng một cách, bạn có thể nhận được tất cả các yếu tố cho đến yếu tố đầu tiên vượt qua điều kiện.

Nhược điểm này là danh sách để vượt qua tình trạng này tại một số điểm, nếu không ...điều hành sẽ cố gắng suy luận ra khỏi cuối của danh sách, và nhiều khả năng ném một lỗi. Bạn cũng không thể sử dụng bất kỳ mã nào ở phía bên trái, vì nó sẽ được hiểu là một phần của chuỗi.

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.