Lời khuyên cho việc chơi golf trong Japt


18

Bây giờ tôi đã hoàn toàn nghiện Code Golf, có lẽ đã đến lúc tôi cố gắng chọn một vài ngôn ngữ chơi gôn.

Cho rằng tôi chơi hầu như chỉ bằng JavaScript, Japt có vẻ như là ngôn ngữ hợp lý để bắt đầu. Tôi sẽ đi sâu vào tài liệu ở cơ hội tiếp theo tôi nhận được, nhưng trong lúc này, xin vui lòng gửi bất kỳ lời khuyên nào bạn có cho Japt trong các câu trả lời dưới đây.

Vì tôi là người mới bắt đầu nói tiếng Japt và chơi golf, nếu bạn có thể "dịch" các mẹo của mình sang JavaScript, nếu có thể, đó sẽ là một trợ giúp lớn trong việc giúp tôi nắm bắt mọi thứ.


Heh, cảm ơn vì đã đăng bài này. Tôi đã không thể làm điều này bởi vì tôi muốn thiết kế lại Japt vào một lúc nào đó, nhưng điều đó sẽ không xảy ra bất cứ lúc nào và có lẽ nó sẽ không làm hỏng nhiều mẹo. Mẹo cho bản thân: viết hướng dẫn: P
Sản phẩm ETH

Đừng quên ghé thăm phòng chat Japt :)
Oliver

Câu trả lời:


11

Chuyển từ JavaScript sang Japt

Như bạn có thể biết, Japt đơn giản là một phiên bản rút gọn, mở rộng của JavaScript. Tôi đã tạo ra Japt vì tôi mệt mỏi với những tên tài sản dài, thích String.fromCharCode(x)Math.floor(x), và sự tẻ nhạt khi làm những việc như tạo ra một phạm vi. Đây là mức tối thiểu bạn cần biết khi chuyển từ JavaScript sang Japt:

  • Japt là một transpiled ngôn ngữ; Đang Japt được transpiled JavaScript và sau đó chạy như JS. (Tôi đoán bạn có thể nói được biên dịch , nhưng phiên âm nghe có vẻ hipster hơn. Tuyên bố miễn trừ trách nhiệm: Tôi hoàn toàn không biết gì về việc trở thành hipster)
  • Tất cả các mục là chương trình đầy đủ theo mặc định. Các đầu vào được ngầm phân tích cú pháp, và sáu đầu vào đầu tiên được đưa vào các biến U, V, W, X, Y, và Z; mảng đầy đủ được lưu trữ trong N. Kết quả của biểu thức cuối cùng được in tự động.
  • Tất cả các chữ cái viết hoa là các biến và giữ nguyên khi được phiên mã. Hầu hết đều có các giá trị đặt trước mà bạn có thể tìm thấy trong phần "Biến" của tài liệu Japt (tại trình thông dịch ).
  • Tất cả các chữ cái thường là các hàm nguyên mẫu hoặc phương thức . Japt thêm các phương thức a- z(và à- ÿ) vào số, chuỗi và mảng. Khi bạn sử dụng một trong những chữ cái này, Japt sẽ điền vào .(; Uctrong Japt tương đương với U.c(JavaScript, có nghĩa là ceil, charCodeAt hoặc concat, tùy thuộc vào loại U. Đây là nơi mà hầu hết sức mạnh của Japt đến từ; bạn có thể tìm thấy danh sách đầy đủ các phương thức này trong phần "Hàm _____" của tài liệu Japt (tại trình thông dịch ).
  • Một không gian đại diện ), và )đại diện )). Điều này là do khi tôi thiết kế Japt lần đầu tiên, tôi muốn lưu càng nhiều byte càng tốt và đó là cách đầu tiên tôi nghĩ đến khi làm điều này. (Mặc dù Us w ntrông có vẻ tốt hơn Us)w)n), IMHO.)
  • Một hàm được ký hiệu là ABC{...}, trong đó ABCcó thể là bất kỳ chuỗi biến nào. Các hàm hoạt động với hầu hết các phần như chúng làm trong JS, sự khác biệt chính là biểu thức cuối cùng được tự động trả về (thay vì phải sử dụng returnhoặc dấu ngoặc đơn ES6 ưa thích).
  • 'biểu thị một chuỗi char duy nhất (nghĩa 'alà giống như "a") và #lấy mã char tiếp theo và trở thành số đó ( #egiống như 101).
  • Bất cứ điều gì giữa các dấu hiệu đồng đô la $vẫn giữ nguyên trong quá trình dịch chuyển. Bạn có thể sử dụng điều này để thực hiện forcác vòng lặp, ví dụ, vì Japt không có những vòng lặp đó, nhưng tôi sẽ đề xuất sử dụng các phương thức khác (chẳng hạn như mtrên chuỗi và mảng hoặc otrên số).
  • Hầu hết các ký tự khác thường được sử dụng trong JS - "", 0-9, (, +, =, vv - giữ nguyên khi transpiled (đối với hầu hết các phần, dù sao).

Và đó là tất cả những gì bạn cần biết để viết mã Japt cơ bản. Để đạt được sức mạnh golf tối đa trong Japt đòi hỏi nhiều kiến ​​thức hơn, nhưng điều đó có thể được tìm thấy trong các câu trả lời khác.


Đây là một ví dụ cơ bản. Giả sử bạn muốn lấy một chuỗi các ký tự ASCII và thay thế từng ký tự bằng mã char thập lục phân của nó. Đây là cách bạn có thể làm điều đó trong JavaScript:

U.split("").map(x=>x.charCodeAt(0).toString(16)).join("")

Bây giờ để chuyển đổi sang Japt. .split("")trong JS tương đương với q""trong Japt, hoặc thậm chí ngắn hơn, chỉ q. .join("")cũng chỉ là q, sự khác biệt là đối tượng là một mảng thay vì một chuỗi. .map(m, .charCodeAt(c, và .toString(s. Vì vậy, mã Japt của chúng tôi có thể trông giống như:

Uq mX{Xc0 s16} q 

Tuy nhiên, trong Japt, mcũng hoạt động tốt trên các chuỗi như trên các mảng, vì vậy chúng ta có thể loại bỏ cả hai qs:

UmX{Xc0 s16}

Kiểm tra nó trực tuyến! Như bạn có thể thấy trong hộp "Mã JS", điều này trực tiếp chuyển đến:

U.m(function(X){return X.c(0).s(16)})

Khi bạn học cách làm việc với Japt, bạn sẽ ngày càng ít tập trung hơn vào việc chuyển đổi qua lại từ JavaScript và có thể viết mã bằng Japt như ngôn ngữ của chính nó. Đây là một lời giải thích bỏ hoàn toàn phần JavaScript:

UmX{Xc0 s16}
               // Implicit: U = input string
UmX{       }   // Take U, and replace each character X with the result of this function:
    Xc0        //   Take the char-code at index 0 in X (the first and only one).
        s16    //   Convert this to a hexadecimal string.
               // Implicit: output result of last expression

Có thể tốt hơn để hiển thị một bước khác: các phím tắt unicode. Trong trường hợp này, chúng tôi nên lưu 2B với họ. Ngoài ra, bạn có thể muốn thêm rằng bạn có thể bỏ qua một số thứ ở cuối. Điều đó sẽ tiết kiệm một byte khác.
Lu-ca

Một mồi tuyệt vời, cảm ơn, ETH. Có đủ ở đó, tôi nghĩ, để giúp tôi bắt đầu với một vài thử thách đơn giản.
Xù xì

Kết hợp điều này với những gì tôi đã lượm lặt được từ README cho đến nay, liệu tôi có đúng không khi ví dụ trên có thể được rút ngắn hơn nữa Um_c s16?
Xù xì

Hoặc, ngắn hơn vẫn còn : ¡Xc s16?
Xù xì

1
@Shaggy Bạn đã đúng! Man, bạn đã tìm ra điều này nhanh chóng ;-) Tôi sẽ thêm một số mẹo chơi gôn Japt cơ bản (như các phím tắt Unicode và như vậy), có thể là các câu trả lời khác.
Sản phẩm ETH

8

Mảng chuỗi nén

CẬP NHẬT: Các công cụ được giới thiệu trong mẹo này đã được viết lại, cải tiến và tích hợp vào trình thông dịch Japt của tôi . Để có kết quả tốt nhất, bạn nên sử dụng máy nén đó hơn bất kỳ liên kết nào dưới đây. Tôi sẽ xem lại mẹo này khi tôi có thêm thời gian và viết lại nó với máy nén mới trong tâm trí.

Giới thiệu

Nếu bạn có một chuỗi các chuỗi trong mã của mình, cách rõ ràng nhất để nén nó là chạy từng chuỗi thông qua từng chuỗiOc . Với mục đích của mẹo này, chúng tôi sẽ làm việc với mảng ["lollipop","marshmallow","nougat","oreo"], có trọng lượng 42 byte ban đầu. Chạy từng chuỗi thông qua Occho chúng ta:

[`lo¥ipop`,`Ú\hÚaow`,`Í`,`eo`]

Đó là 33 byte, một khoản tiết kiệm khá.


Bước 1

Nhưng , chúng ta có thể làm tốt hơn. Nếu chúng ta nối mảng thành một chuỗi phân tách dòng mới, chúng ta có thể thoát khỏi dấu ngoặc, dấu phẩy và backticks bên ngoài và phân chia trên dòng mới để lấy mảng của chúng ta. Áp dụng điều đó vào mảng ví dụ của chúng tôi cung cấp cho chúng tôi như sau:

`lo¥ipop
Ú\hÚaow
Í
eo`·

Xuống tới 26 byte bây giờ.


Bước 2

Nhưng , chúng ta vẫn có thể làm tốt hơn! Chúng ta có thể sử dụng một chữ cái viết thường để phân định các chuỗi thay vì một dòng mới, có thể được bao gồm trong nén. zkhông được sử dụng trong bất kỳ chuỗi nào của chúng tôi, vì vậy hãy bỏ qua và xem cách chúng tôi tiếp tục.

`lo¥ipopzÚ\hÚaowzÍzeo`qz

Ah, các loại hạt - không có cải thiện ở đó; số byte của chúng tôi đã tăng lên một! Có thể có một chữ cái khác bạn có thể sử dụng, nhưng tùy thuộc vào chuỗi của bạn, có thể có một vài chữ để thử - trong ví dụ của chúng tôi có 11 : b,c,d,f,j,k,q,v,x,y,z. Thử từng cái sẽ khá tẻ nhạt, đó là nơi mà công cụ tiện dụng này xuất hiện; cung cấp cho nó các chuỗi phân tách dòng mới của bạn và nó sẽ cố gắng phân định các chuỗi với mỗi chữ cái không có trong bất kỳ chuỗi nào và đầu ra:

  • chuỗi nén ngắn nhất,
  • dấu phân cách mà nó sử dụng và
  • chiều dài của nó.

Chạy các chuỗi mẫu của chúng tôi thông qua nó cho thấy bkết quả tốt nhất:

`lo¥ipáæqrÚaowbÍÞo`qb

Và ở đó bạn có nó, chúng tôi chỉ còn 24 byte.


Bước 3

Nhưng , chúng ta có thể làm thậm chí tốt hơn! Nếu thứ tự các chuỗi trong mảng của bạn không thành vấn đề, có thể có một hoán vị khác kết hợp với một dấu phân cách khác có thể làm việc thậm chí ngắn hơn. Mặc dù vậy, cố gắng từng khả năng sẽ trở nên tẻ nhạt hơn nhiều. Với 4 chuỗi của chúng tôi, có 24 hoán vị khác nhau để thử. Với mỗi trong số 11 chữ cái có thể trở thành 264! Đó là nơi công cụ này phát huy tác dụng. Một lần nữa, hãy cung cấp cho nó chuỗi phân tách dòng mới của bạn và nó sẽ thử mọi kết hợp của mọi hoán vị và mọi chữ cái phân định, xuất ra:

  • thứ tự của các chuỗi trong chuỗi nén ngắn nhất,
  • chuỗi nén,
  • dấu phân cách mà nó sử dụng, và,
  • chiều dài của nó.

Việc chạy các chuỗi mẫu của chúng tôi thông qua nó cho thấy rằng "nougat","oreo","lollipop","marshmallow"với btư cách là một dấu phân cách cho kết quả tốt nhất, với số byte cuối cùng chỉ là 23:

`ÍÞo½o¥ipáæqrÚaow`qb


Tiền thưởng: Nén mảng Integer

Bạn có thể áp dụng nguyên tắc tương tự cho các mảng số nguyên bằng cách trước tiên chuyển đổi từng số sang cơ sở cao hơn. Sử dụng mẫu này, mảng 36 byte:

[588181,156859,595676,475330,680474]

Chúng ta có thể giảm xuống còn 29 byte bằng cách trước tiên chuyển đổi nó thành một chuỗi gồm 32 chuỗi cơ sở và sau đó chạy nó thông qua chương trình nén đầu tiên:

`huclt4p5r5ÛÊg62tkogq`qt mnH

Hoặc thấp tới 27 byte khi sử dụng chương trình thứ hai:

`4p5Ïcl5ÛÊg62tkogq`qt mnH

Bạn có thể lưu một byte hoặc 2 khác trên đó bằng cách di chuyển chuyển đổi số nguyên thành một phương thức bạn đang chạy trên mảng.


Ghi chú

  1. Đừng quên tính đến 1 hoặc 2 byte thêm q<letter>(<space>)chi phí ·. Mặc dù, bạn có thể sử dụng một trong các phím tắt Unicode để lấy lại một byte, tùy thuộc vào dấu phân cách của bạn (chẳng hạn như ql<space>, chẳng hạn như).
  2. Một lời cảnh báo khi sử dụng công cụ cuối cùng: bạn càng có nhiều chuỗi, sẽ càng có nhiều hoán vị và chương trình sẽ chạy chậm hơn, cho đến khi cuối cùng nó thoát ra. Như đã nêu chi tiết ở trên, với 4 chuỗi mẫu của chúng tôi và 11 chữ cái có thể thử, có 264 kết hợp có thể, tăng số chuỗi chỉ bằng 1 với 11 chữ cái giống nhau và chúng tôi đã thử 1320 kết hợp. (Bạn có thể sử dụng công cụ này để đếm số lượng kết hợp, nếu bạn muốn).

Tín dụng

  • Oliver cho cảm hứng để tạo ra các công cụ tìm thấy trong mẹo này.
  • ETHproductions cho hiệu đính.

6

Nén dây

Japt (hiện tại) sử dụng thư viện shoco để nén chuỗi. Bạn có thể nén một chuỗi tùy ý bằng cách sử dụng chuỗi ký tự Ocviết thường:

Oc"Hello, World!"

Đầu ra này HÁM, WŽld! (tốt, về Žmặt kỹ thuật là một ký tự không thể in được). Bạn có thể giải nén điều này bằng cách gói nó trong backticks:

`HÁM, WŽld!`

Kiểm tra nó trực tuyến!

Ngoài ra, bạn có thể sử dụng Odhàm để giải nén một chuỗi tùy ý. Điều này thường không hữu ích, nhưng nó có mục đích của nó ...


Vì vậy, nếu tôi trả lời "Xin chào, thế giới!" thách thức, tôi sẽ sử dụng chỉ HÁM, WŽld!hoặc nó sẽ cần phải được bao bọc trong backticks? Tôi đoán sau.
Xù xì

2
@Shaggy Khi trả lời một câu hỏi bạn cần bao gồm tất cả các mã, vì vậy đó sẽ là `HÁM, WŽld! trong trường hợp này
Martijn Vissers

6

Rút ngắn số với mã Char

Trong Japt, bạn có thể sử dụng #, theo sau là một ký tự để tạo mã char. Điều này có ích khi rút ngắn số dài hơn.

Như @ETHproductions đã đề cập, điều này chỉ hoạt động trên các chữ số ba chữ số trong phạm vi 100-255, trừ khi bạn sẵn sàng chuyển sang UTF-8.

Ví dụ:

123 có thể rút ngắn thành #{

101 có thể rút ngắn thành #e

Bạn thậm chí có thể xâu chuỗi chúng lại với nhau:

123101 có thể rút ngắn thành #{#e

Bạn có thể sử dụng String.fromCharCode(123)trong JavaScript hoặc 123dtrong Japt để tìm ký tự phù hợp.

String.fromCharCode(123) trả lại {


Cảm ơn, @obarakon, mẹo tuyệt vời để có được quả bóng lăn; String.fromCharCode()là một trong những phương thức JS dài (rất nhiều!) có thể chứa số byte của bạn. Có lẽ, những điều này sẽ được coi là số nguyên? tức là, nếu tôi cần số nguyên 123trong một giải pháp, tôi có thể sử dụng #{để lưu một byte.
Xù xì

1
Vâng, đây là những số nguyên. Nếu bạn thêm -Qcờ vào cửa sổ nhập của mình, bạn có thể xem loại đầu ra tốt hơn: dấu ngoặc kép quanh chuỗi , mảng , v.v.
Oliver

1
Bạn nên đề cập rằng nó String.fromCharCode(123)hoạt động trong JavaScript, nhưng bạn có thể làm 123dtrong Japt để có kết quả tương tự ;-) Ngoài ra, điều này chỉ hoạt động trên các chữ số ba chữ số trong phạm vi 100- 255(trừ khi bạn sẵn sàng chuyển sang UTF-8)
Sản phẩm ETH

@ETHproductions Cuộc gọi tốt, cập nhật!
Oliver

5

Mẹo nhanh: Mảng trống []

Japt có một hằng số cho một mảng trống : A. Nhưng, để truy cập nó, bạn phải đăng ký một dấu chấm phẩy ;vào chương trình của bạn để sử dụng các hằng số thay thế của Japt, nếu không thì Asẽ được 10. Vì vậy, việc sử dụng ;Athực sự mang lại khả năng tiết kiệm 0 byte [], nhưng sẽ giúp bạn tiết kiệm byte nếu bạn cần gán mảng của mình cho một biến (ví dụ A=[]:).

Tuy nhiên, nếu (và chỉ nếu) chương trình của bạn không nhận bất kỳ đầu vào nào, bạn có thể truy cập mảng trống chỉ với 1 byte bằng cách sử dụng Nbiến, đó là mảng đầu vào - không có đầu vào, nó sẽ trống. Hãy thử nó ở đây .

Điều này cũng có thêm lợi ích là cho phép bạn sử dụng các giá trị không đổi mặc định trong chương trình của bạn và, trong một số trường hợp, vẫn có thể tiết kiệm byte cho bạn bằng cách sử dụng ;Angay cả khi chương trình của bạn đang nhập liệu nhờ các phím tắt cho s1s2.


2
Wow, tôi đã không nghĩ về việc sử dụng N, ý tưởng tốt đẹp.
Sản phẩm ETH

2
Đẹp đấy, @Shaggy!
Oliver

4

Đánh giá JavaScript

Japt cho phép bạn thực thi JavaScript thô bằng cách gói nó xung quanh $...$.

Ví dụ, $alert("hello world")$

Điều này có thể được rút ngắn bằng cách tận dụng khả năng tự động đóng của Japt $).

$alert("hello world")$ có thể rút ngắn thành $alert("hello world"

Nén JavaScript

Bạn cũng có thể nén JavaScript bằng cách sử dụng Ox.

Nếu có một hàm JavaScript mà bạn muốn sử dụng, giả sử screen.width, bạn có thể nén chuỗi "screen.width"bằng cách sử dụngOc , sau đó chèn kết quả vào giữa Ox` ... `

Lưu ý rằng bạn không cần đóng dấu ngoặc kép trong Japt khi nó không được theo sau bởi bất cứ điều gì khác.


@Shaggy Bạn cần Oxđánh giá chuỗi. Nếu không, bạn sẽ chỉ xuất văn bản "screen.width". Ví dụ
Oliver

4

Biết cờ

Theo sự đồng thuận meta mới nhất (tháng 12 năm 2017) , các cờ dòng lệnh không còn được tính vào byte. Đây thực sự là một tin tuyệt vời cho Japt vì nó có nhiều cờ để xử lý thêm về đầu vào / đầu ra.

Tất cả các cờ có sẵn trong Japt được mô tả dưới đây, theo thứ tự đánh giá . Các cờ trong cùng một nhóm là độc quyền cho nhau. Lưu ý rằng các cờ trong các nhóm khác nhau có thể được sử dụng kết hợp, dẫn đến kết quả như thế này :)

mdefæ

Toàn bộ chương trình được ánh xạ qua đối số đầu tiên ( U).

Nếu có nhiều đối số hơn, chúng được truyền nguyên trạng (nghĩa là không được ánh xạ theo cặp). Mặt khác, đối số thứ hai là chỉ mục và thứ ba là toàn bộ mảng, giống như U.m. Nếu Ulà một số, nó được chuyển đổi thành phạm vi; nếu chuỗi, nó được chuyển đổi thành mảng ký tự và kết quả được nối với nhau.

  • -m: Áp dụng những điều trên và không có gì khác.
  • -d: Trả về truenếu một số kết quả là trung thực, falsenếu không.
  • -e: Trả về truenếu tất cả các kết quả là trung thực, falsenếu không.
  • -f: Trả về mảng các phần tử Ucó kết quả là trung thực.
  • : Áp dụng -fvà trả về phần tử đầu tiên của nó.

gh

Có một yếu tố tại chỉ mục được chỉ định.

  • -g: Lấy phần tử đầu tiên (chỉ số 0).
  • -gX: Lấy phần tử tại chỉ mục X(có thể là bất kỳ số nguyên dương nào).
  • -h: Lấy yếu tố cuối cùng.

Chuyển đổi kết quả sang boolean.

  • -!: Áp dụng boolean không.
  • : Áp dụng boolean không hai lần (trả về tính trung thực).

N

Chuyển đổi kết quả thành số. Cộng unary được sử dụng.

PRSQ

Chuyển đổi thành chuỗi của một số loại.

  • -P: Tham gia mảng với "".
  • -R: Tham gia mảng với "\n".
  • -S: Tham gia mảng với " ".
  • -Q: Áp dụng JSON.stringify(có thể là bất kỳ đối tượng nào, không chỉ là một mảng). Ví dụ .

x

Áp dụng chức năng xcho đầu ra. (Đó là nghĩa đen x, không phải "bất kỳ chức năng bảng chữ cái chữ thường".)

  • Mảng: Tổng.
  • Chuỗi: Cắt từ cả hai đầu.
  • Số: Làm tròn thành số nguyên.

2
Lưu ý rằng việc sử dụng cờ không được tính là một lần gửi Japt, tuy nhiên, nó được tính là một lần gửi ngôn ngữ Japt-with-them-cụ thể-cờ-ngôn ngữ.
Nit

3

Phím tắt Unicode

Có rất nhiều cấu trúc phổ biến ở Japt mà chỉ có thể không được lưu trữ trong một ASCII char duy nhất, chẳng hạn như qS , p2 , mX{, , vv Vì vậy, để làm được việc này, Japt có "Unicode phím tắt", đó là nhân vật trong phạm vi \xA1- \xDE( ¡- Þ) mở rộng ra các cấu trúc phổ biến này. Bạn có thể tìm thấy một danh sách đầy đủ về những điều này trong các tài liệu thông dịch viên .

Ngoài ra, @viết tắt XYZ{_viết tắt của Z{Z, để giúp xây dựng các chức năng. Vì vậy, hãy chơi golf chương trình ví dụ của chúng tôi từ một câu trả lời khác :

UmX{Xc0 s16}

Đầu tiên, chúng ta có thể thay thế X{Xbằng _, điều này mang lại cho chúng ta:

Um_c0 s16}

Sau đó, chúng ta có thể thay thế m_bằng cách ®lưu một byte khác:

U®c0 s16}

Hoặc chúng tôi có thể thay thế X{bằng @, cung cấp cho chúng tôi:

Um@Xc0 s16}

Điều này sau đó cho phép chúng ta sử dụng ¡phím tắt để lưu hai byte:

¡Xc0 s16}

Một trong hai đường dẫn này có thể rút ngắn hơn 1 byte so với đường dẫn còn lại. Bạn có thể tìm ra cái nào?


1
®c s16trong 6 byte - tôi có giành được cookie không?!
Xù xì

@Shaggy Bạn có thể tiết kiệm thêm 1 byte nếu bạn đủ cứng ...;)
Sản phẩm ETH

Nó sẽ là ®c sGgì?
Xù xì

1
Vâng! Tôi nghĩ rằng đó là thấp như bạn có thể đi. Làm tốt! :-)
Sản phẩm ETH

2
Thật ngạc nhiên khi nhìn lại những điều này, thấy sự tiến bộ của Japt trong một vài tháng ngắn ngủi. Điều này bây giờ có thể đạt được với csG.
Xù xì

3

Tận dụng các biến đặt trước

Các biến A- Sđược đặt trước cho các giá trị chung mất nhiều hơn một byte để biểu thị trong Japt:

  • A- G10- 16.
  • H32, I64, J-1, L100.
  • Kđược định nghĩa là new Date(), mà bạn có thể thao tác theo nhiều cách khác nhau.
  • MOlà các đối tượng với các chức năng hữu ích khác nhau. Bạn có thể tìm hiểu thêm trong các tài liệu.
  • Plà chuỗi rỗng, Qlà dấu ngoặc kép, Rlà dòng mới và Slà khoảng trắng .
  • Tđược đặt thành 0, vì vậy bạn có thể sử dụng nó như một bộ tích lũy nếu cần thiết.

Nếu ký tự đầu tiên trong chương trình là dấu chấm phẩy ;, A-Lđược đặt lại như sau:

  • Alà mảng trống [].
  • B"ABCDEFGHIJKLMNOPQRSTUVWXYZ".
  • C"abcdefghijklmnopqrstuvwxyz".
  • D"QWERTYUIOP\nASDFGHJKL\nZXCVBNM".
  • E"[a-z]", và F"[A-Za-z]"(hữu ích trước khi tôi thêm chúng dưới dạng các tính năng regex)
  • G36, H65I91(hữu ích cho phạm vi bảng chữ cái).
  • Jlà một dấu phẩy đơn; L, một khoảng thời gian duy nhất.

Ngày nay chỉ A, B, C, và Dtừ danh sách này là thực sự hữu ích. Tôi dự định thêm một hệ thống tốt hơn cho phép tối đa 256 biến hai byte, sẽ được đặt trước cho các giá trị này và nhiều hơn nữa.


3

Sử dụng chức năng tự động

Bạn rất có thể đã biết điều đó @_là các phím tắt cho XYZ{Z{Z, tương ứng (được nêu trong câu trả lời của các phím tắt Unicode ). Nhưng đôi khi bạn có thể làm cho các chức năng thậm chí ngắn hơn.

Giả sử bạn có một mảng các ký tự và bạn muốn ánh xạ từng ký tự vào mã char của nó. Bạn có thể làm điều này với một trong hai cách sau:

mX{Xc} 
m_c} 

Nhưng có một cách tốt hơn. Nếu một phương thức hoặc toán tử là mục đầu tiên sau một phương thức khác hoặc một (, nó sẽ được chuyển thành một chuỗi. Vì vậy, hai dòng này là tương đương:

r'a'b  // Replace all "a"s with "b"s; transpiles to .r("a","b")
ra'b   // Does the same thing, 1 byte less; transpiles to the same thing

Nhưng làm thế nào để giúp với các chức năng của chúng tôi? Chà, hầu hết các phương thức chấp nhận các hàm, nếu được cung cấp một chuỗi đại diện cho một phương thức hoặc toán tử, sẽ diễn giải nó như là một hàm. Điều đó có nghĩa là bạn cũng có thể làm điều này:

m_c}  // Map each item to its char code
m'c   // Does the same thing, 1 byte less
mc    // Also does the same thing, 2 bytes less

Tôi gọi đây là "chức năng tự động". Có một số giống khác nhau:

  • m@Xc}mc
  • m@Xc1}mc1
  • m@X+1}m+1
  • m@1+X}m!+1
  • m@2pX}m!p2

Hy vọng bạn có được ý tưởng. Để trao đổi các đối số, chỉ cần tiền tố phương thức hoặc toán tử với !.


Điều đáng chú ý ở đây là việc sử dụng các chức năng tự động cũng có thể cho phép tiết kiệm hơn nữa thông qua việc sử dụng các phím tắt? ví dụ: m@2pXÃm!p2<space>m!².
Xù xì

Ái chà! Tôi đã không nghĩ về việc sử dụng một chuỗi trong bản đồ, thậm chí không biết nó có thể. Có lẽ tôi sẽ tiết kiệm được vài byte nhờ vào điều này trong tương lai.
RedClover

Xin chào @Soaku, bằng cách nào đó tôi đã bỏ lỡ rằng bạn đã trả lời bằng Japt, vì vậy hãy cho phép tôi mở rộng lời chào mừng bạn! Hy vọng bạn đã thích sử dụng nó cho đến nay. Nếu bạn có bất kỳ câu hỏi, đề xuất nào hoặc chỉ muốn nói chuyện, vui lòng tham gia với chúng tôi trong phòng chat Japt (Github thường hoạt động tốt cho hai người đầu tiên;))
ETHproductions

3

Nhiệm vụ biến đổi ngầm định

Bất cứ khi nào bạn bắt đầu một dòng mới trong Japt, kết quả của dòng trước đó sẽ tự động được gán cho một trong các biến đầu vào ( U- Z), với dòng đầu tiên là U, thứ hai V, v.v.

Hãy lấy một ví dụ: giả sử bạn muốn tạo 2 mảng để làm việc, một mảng chứa các số 1-10 và cái còn lại chứa các hình vuông của chúng. Con đường dài để làm điều này sẽ như vậy:

U=Aõ V=Um² [do something with the arrays]

Tuy nhiên, sử dụng gán biến tự động có thể rút ngắn thành:

Aõ
Um²
[do something with the arrays]

Chúng tôi đã lưu 4 byte ở đó. Nhưng, trong trường hợp này, chúng ta có thể lưu thêm một byte vì mảng 1-10 được gán cho UUcó thể được bỏ qua trong một số trường hợp nhất định :

Aõ
m²
[do something with the arrays]

Thận trọng

Một điều cần cẩn thận với mẹo này là bạn không ghi đè lên bất kỳ biến đầu vào nào bạn có thể cần sau này trong chương trình của mình. Điều này có thể tránh được bằng cách để lại một hoặc nhiều dòng trống khi bắt đầu nó. Trong ví dụ sau, 2 mảng sẽ được gán cho các biến V& W, thay vì U& V:


Aõ
Vm²
[do something with the arrays]

3

Biết Javascript

Vì bất kỳ mã Japt nào đều chạy dưới dạng mã hóa được mã hóa, nên sự hiểu biết tốt về các toán tử JS và các phương thức tích hợp sẽ giúp ích rất nhiều cho việc chơi các đoạn mã Japt.

Các mẹo liên quan đến JS

[]Vm@...
...
  • Đoản mạch
  • Chia nhỏ với số
    • Điều này có thể được khái quát cho bất kỳ phương thức nào chấp nhận chuỗi nhưng không phải là số. Một số được truyền vào đó sẽ được truyền ngầm thành một chuỗi, thường lưu một byte (ví dụ: 0trên '0).

Các hàm dựng sẵn có liên quan của JS

Xem xét kỹ những tham số nào được truyền cho các đối số hàm.

Đối với các phương thức chuỗi, thật tốt khi biết các hành vi khác nhau như thế nào giữa việc truyền một chuỗi hoặc biểu thức chính quy có hoặc không có gcờ.


3

Sử dụng nhiều dòng khi cần thiết

Đối với hầu hết các thử thách không quá khó, bạn có thể diễn đạt giải pháp chỉ trong một dòng của Japt, như một chuỗi áp dụng các hàm tích hợp. Nhưng những cái phức tạp hơn sẽ yêu cầu sử dụng các cấu trúc lặp, đệ quy hoặc sử dụng lại các đoạn mã lớn. Đây là nơi lập trình đa dòng đến.

Hủy bỏ đóng cửa

Nhiệm vụ : Cho một mảng các số, ghép từng phần tử với chỉ số bình phương và sắp xếp nó theo tổng.

[5,1,17,9,3] => [[5,0],[1,1],[17,4],[9,9],[3,16]] => [[1,1],[5,0],[9,9],[3,16],[17,4]]

Giải pháp một dòng là íUm@Yp2})ñx, nhưng })chi phí hai byte (và không có phím tắt một byte). Bạn có thể loại bỏ })bằng cách di chuyển dấu vết ñxsang dòng tiếp theo, vì vậy mã trông như thế này:

íUm@Yp2
ñx

và JS được phiên mã trở thành:

U = U.í(U.m(function(X, Y, Z) { return Y.p(2) })); U.ñ("x")

Bạn có thể thấy rõ điều này thực hiện tương tự như giải pháp một dòng, chỉ cần gán kết quả trung gian trở lại U.

Tái diễn với các đối số ngầm

Hàm đệ quy ßlấy tất cả UVWXYZlàm tham số ngầm định, nếu không được chỉ định. Urõ ràng là đầu vào chính, nhưng bạn có thể sử dụng bất kỳ VWXYZđể theo dõi các giá trị khác bạn cần. Ví dụ: bạn có thể làm một cái gì đó như sau:

(modify input and implicit assign to U)
(modify V and implicit assign to V)
(test something and call ß without arguments; U and V are passed automatically)

Ngoài ra, nếu tất cả những gì bạn muốn là một biến tạm thời, bạn có thể sử dụng phép gán nội tuyến, như (T=...), vì biến số T(0) hiếm khi được sử dụng nguyên trạng.

Sử dụng lại một chức năng dài

Đối với điều này, tôi không nghĩ rằng tôi có thể đưa ra một nhiệm vụ ví dụ hay, vì vậy tôi sẽ tham khảo giải pháp duy nhất mà mẹo này được sử dụng và chỉ phác thảo một số ý tưởng chung.

  • Để sử dụng lại một chức năng, bạn cần lưu trữ nó trong một biến. Bắt đầu một dòng với chức năng mở {, @hoặc _thực hiện công việc. Ngoài ra, bạn cũng có thể làm một cái gì đó như (T=@...})nhúng phân công hàm bên trong một dòng phức tạp hơn.
  • Thật sự không tầm thường khi gọi hàm được lưu trữ. Giả sử Vlà một hàm và chúng tôi muốn gọi V(U)trong JS. VUkhông hoạt động vì nó đơn giản có nghĩa là V,U. V(Ucũng không; nó V,(U). Ngay cả các phương thức hàm cũng không hữu ích lắm. Cách tốt nhất chúng tôi tìm thấy là:
    • [U]xV (bản đồ và tổng hợp) nếu kết quả là số
    • UmVif Ulà một char duy nhất và Vtrả về một chuỗi, hoặc
    • $V($Uhoặc [U]mV gnói chung.
  • Tuy nhiên, ánh xạ hoặc lặp với nó là khá dễ dàng. Để ánh xạ qua một mảng, sử dụng UmV. Để tìm số nguyên đầu tiên thỏa mãn V, sử dụng Va.

2

Thú vị với chức năng tự động

Là một mẹo tiếp theo của ETH về các chức năng tự động , mẹo này sẽ cung cấp một vài ví dụ cụ thể về các thủ thuật tiết kiệm byte mà bạn có thể đạt được với chúng, mà tôi sẽ thêm vào khi tôi nghĩ thêm.


Lấy số nguyên lớn nhất trong một mảng.

Giả sử chúng ta có mảng [3,1,4,2]được gán cho biến Uvà chúng ta ant để lấy số lớn nhất từ ​​nó. Chúng ta có thể làm điều đó trong 4 byte bằng cách sắp xếp mảng và sau đó bật phần tử cuối cùng:

Un o

Nhược điểm của điều đó là chúng tôi đã sửa đổi mảng ban đầu; Ubây giờ [1,2,3]có thể không phải luôn luôn là mong muốn. May mắn thay, có một cách để làm điều đó mà không sửa đổi mảng cũng ngắn hơn một byte:

Urw

Những gì chúng ta đã làm ở đó là giảm mảng bằng cách sử dụng wphương thức, khi được sử dụng trên một số nguyên sẽ trả về số nguyên lớn hơn và đối số của phương thức (ví dụ: 2w5trả về 5). Vì vậy, ở trên là tương đương với UrÈwYhoặc UrXY{XwY}. Tuy nhiên, xin lưu ý rằng mẹo này sẽ không hoạt động trong trường hợp tất cả các số nguyên trong mảng là âm.


1
Lưu ý bên lề: Tôi dự định thêm các hàm để lấy tối thiểu và tối đa của một mảng, mặc dù có lẽ chỉ trong v2.
Sản xuất ETH

2

Khi không sử dụngí

ílà một tích hợp hữu ích mà cặp (hoặc zips) hai mảng hoặc chuỗi và tùy ý ánh xạ mỗi cặp thông qua một hàm. Tuy nhiên, hiện tại nó có một vài vấn đề nhỏ khi đưa ra các mảng hoặc chuỗi không đồng đều:

  • Nếu mảng thứ nhất có nhiều mục hơn phần thứ hai, các mục không tồn tại trong phần thứ hai sẽ được cung cấp dưới dạng undefined.
  • Nếu mảng thứ hai có nhiều mục hơn mảng thứ nhất, nó sẽ dừng xử lý ở cuối mảng thứ nhất.

Điều này có thể gây khó khăn khi nói, so sánh hai chuỗi không đồng đều và lấy char với điểm mã cao hơn từ mỗi cặp. Ngay cả khi bạn biết rằng Unó sẽ dài hơn, thì vẫn cần nhiều byte để giải quyết nhiệm vụ đơn giản này:

UíUç hV @[XY]n o

Thay vào đó, những gì bạn có thể làm là lấy đầu vào là một mảng gồm hai chuỗi, hoán chuyển mảng với yvà sau đó ánh xạ từng hàng vào kết quả chính xác:

Uy m_q n o

Điều này có lợi thế là luôn luôn đệm chuỗi ngắn hơn với khoảng trắng, làm cho nó trở thành một miếng bánh để đi qua toàn bộ cả hai chuỗi.

Ví dụ thực tế: 1 , 2


2

Tạo phạm vi ASCII

Cập nhật: Japt hiện có một hằng số cho phạm vi ASCII; giá trị thay thế cho E, có thể truy cập bằng ;. Xem mẹo này để biết thêm về hằng số của Japt.

Mặc dù Japt không (chưa) tích hợp sẵn cho phạm vi ASCII, bạn có thể tạo một mảng các ký tự chỉ trong 5 byte:

95odH

Thử nó


Làm thế nào nó hoạt động

95otạo phạm vi [0,95)với mỗi phần tử được truyền qua chức năng tự động d , khi được sử dụng trên một số, sẽ trả về ký tự tại điểm mã đó. Truyền một số làm đối số cho dphương thức, trong trường hợp nàyH , hằng số Japt cho 32 và nó sẽ được thêm vào số ban đầu trước khi được chuyển đổi.

Một giải pháp tương đương trong JavaScript sẽ là:

[...Array(95)].map((_,x)=>String.fromCharCode(x+32))

Nhân vật ngẫu nhiên

Để có được một ký tự ngẫu nhiên trong phạm vi ASCII, hãy sử dụng öthay vào đó, trả về một số ngẫu nhiên từ phạm vi [0,X), trong đó Xsố đó được chạy trên đó.

95ö dH

Hoặc, để có được một mảng gồm nhiều ký tự ngẫu nhiên, hãy chuyển số lượng ký tự bạn cần làm đối số ö. Sau đây sẽ trả về 10 ký tự:

95öA mdH

1

Loại bỏ các ký tự cấu trúc không cần thiết

Bởi chars cấu trúc, ý tôi là {}, (), $, thậm chí "`. Bạn thường có thể xóa các ký tự này bất cứ khi nào chúng xuất hiện ngay khi kết thúc chương trình (ví dụ UmX{Xc +"; "} -> UmX{Xc +"; ).

Ngoài ra, bạn có thể xóa parens hoặc dấu cách bất cứ khi nào chúng xuất hiện ở những nơi sau:

  • Lên một dấu chấm phẩy ;(hoặc kết thúc chương trình);
  • Ở bên phải của {(và bởi phần mở rộng, @) hoặc [, hoặc bên trái của ]hoặc }.

Ngoài ra, dấu phẩy rất hiếm khi cần thiết để tách các đối số. Nếu bạn viết AB, ví dụ, Japt biết bạn có nghĩa ABriêng biệt. Bạn chỉ thực sự cần một dấu phẩy để phân tách hai chữ số, chẳng hạn như Us2,5.

Cuối cùng, nếu có một Ulúc bắt đầu một chương trình hoặc sau một {hay ;, tiếp theo là một cuộc gọi phương pháp (chữ thường hoặc phím tắt Unicode liên quan) hoặc bất kỳ nhà điều hành nhị phân trừ +-( *, &, ==, vv), bạn có thể loại bỏ các Ulưu một byte và Japt sẽ chèn nó cho bạn.


Tôi đã tìm thấy một vài trường hợp khác Ucó thể được thông báo ngay cả khi nó không bắt đầu chương trình.
Xù xì

@Shaggy Oh phải, nó cũng hoạt động sau một {hoặc ;. Có ai khác mà bạn biết? (Đã được một thời gian kể từ khi tôi mã hóa tính năng này: P)
Sản phẩm ETH

Không thể nghĩ về chúng ra khỏi đỉnh đầu của tôi; Tôi sẽ kiểm tra lại khi tôi quay lại máy tính vào ngày mai.
Xù xì

1

Sửa đổi phần tử cuối cùng trong một mảng

Đôi khi bạn có thể cần phải sửa đổi phần tử cuối cùng trong một mảng để đây là lời giải thích về một cách ngắn để làm điều đó. Chúng tôi sẽ làm việc với mảng [2,4,8,32]được gán cho biến đầu vào Uvà chia số nguyên cuối cùng (32 ) cho 2.

Cách rõ ràng để đạt được điều này sẽ là với giải pháp 9 byte này ( Bản trình diễn ):

UhJUgJ /2
  • hnxđặt phần tử tại chỉ mục nthànhx .
  • gn trả về phần tử tại chỉ mục n .
  • J là hằng số Japt cho -1 , nhờ có sự hỗ trợ của Japt cho chỉ số âm, cho phép chúng ta làm việc với phần tử cuối cùng trong một mảng; tiện dụng khi bạn không biết kích thước của mảng.
  • /2chỉ đơn giản là chia cho 2.

Vì vậy, ở trên đặt phần tử tại chỉ mục -1trong mảng thành phần tử tại chỉ mục -1trong mảng chia cho 2. Hoặc trong JavaScript : U[3]=U[3]/2. Khi bạn viết nó ra như thế, có vẻ như là một cách quá dài để đi về nó. May mắn thay, có một cách ngắn hơn; chúng ta có thể bật phần tử cuối cùng từ mảng, sửa đổi nó và đẩy nó trở lại mảng. Việc thực hiện từng thao tác riêng lẻ sẽ mất hơn 9 byte nhưng chúng ta có thể thực hiện tất cả chúng cùng một lúc chỉ với 7 byte, tiết kiệm 2 byte ( Bản trình diễn )

UpUo /2

Được dịch sang JS, nó tương đương với:

U.push(U.pop()/2)&&U
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.