Brainflak Nhân Metagolf


17

Câu hỏi này là câu hỏi đầu tiên trong số những thử thách sinh nhật Brain-flak được thiết kế để chúc mừng sinh nhật đầu tiên của Brain-Flak! Bạn có thể tìm thêm thông tin về Sinh nhật của Brain-Flak tại đây

Mùa hè năm ngoái chúng tôi đã có Integer Metagolf Brain-flak và câu trả lời mà nó tạo ra rất hữu ích cho cộng đồng Brain-Flak kể từ đó. Điều chính làm cho Integer Metagolf trở nên hiệu quả là một kỹ thuật gọi là mã hóa nhân.

Trong phép nhân thời gian chạy Brain-Flak là cực kỳ tốn kém. Đoạn nhân ngắn nhất được biết đến là:

({}<>)({<({}[()])><>({})<>}{}<><{}>)

Được phát hiện bởi Megatom

Tuy nhiên, có một cách rất đơn giản để tạo phép nhân thời gian biên dịch. Ví dụ: đoạn mã sau sẽ nhân với 5:

 (({})({})({})({}){})

Hãy thử trực tuyến!

Điều này hoạt động vì các biểu thức liên tiếp được thêm vào với nhau. Mỗi cái ({})không làm gì với ngăn xếp ( {}bật và (..)đẩy nó trở lại ngay) và đánh giá bất cứ thứ gì ở trên cùng của ngăn xếp. Tất cả các biểu thức này cùng nhau tổng hợp tới năm lần bất cứ thứ gì nằm trên đỉnh của ngăn xếp.

Đối với bất kỳ nbiểu thức chuỗi nào sau đây sẽ tạo một đoạn mã sẽ nhân số đỉnh của ngăn xếp bằng cách n:

"("+"({})"*(n-1)+"{})"

Điều này hoạt động bằng cách thực nhiện các biểu thức mà tất cả đánh giá lên đầu ngăn xếp. Cái đầu tiên n-1không thực sự thay đổi bất cứ thứ gì và cái cuối cùng sẽ loại bỏ đỉnh của ngăn xếp trước khi đẩy.

Đối với các số tổng hợp, bạn có thể xâu chuỗi nhiều biểu thức nhỏ hơn lại với nhau để lưu byte. Ví dụ: bạn có thể nhân với 25 bằng cách nhân 5 lần:

(({})({})({})({}){})(({})({})({})({}){})

Điều này khá đơn giản, và đối với một số con số, nó hoạt động khá tốt tuy nhiên có nhiều cách tốt hơn để làm điều này. Ví dụ, một phương pháp tôi đã đưa ra sử dụng biểu diễn nhị phân của số. ( Đây là một triển khai python ) Phương pháp mới này hiệu quả hơn nhiều so với biểu thức chuỗi đơn giản được hiển thị trước đó, nhưng nó không phải là kết thúc, có tất cả các cách thú vị để nhân mã hóa cứng và có lẽ là một tấn mà chưa ai phát hiện ra.

Vì vậy, tôi nghĩ rằng đã đến lúc để xem chúng ta có thể nhận được tốt như thế nào.

Tổng quan ngắn gọn về Brain-Flak

Dưới đây là một mô tả về tất cả mọi thứ bạn sẽ cần biết về Brain-Flak cho thử thách này.

Brain-Flak có "nilads" và "monads". Nilads là dấu ngoặc đơn không có gì bên trong chúng. Mỗi nilad làm một điều và trả về một giá trị. Đối với thử thách này, hai nilad chúng tôi quan tâm là {}<>. {}bật lên trên cùng của ngăn xếp hoạt động và trả về giá trị của nó. <>chuyển ngăn xếp hoạt động và ngăn xếp hoạt động, để ngăn xếp hoạt động trở thành không hoạt động và ngăn xếp không hoạt động trở thành hoạt động, nó trả về không.

Monads là dấu ngoặc đơn với những thứ bên trong chúng. Họ lấy một đối số duy nhất, tổng của tất cả mọi thứ bên trong họ, đôi khi thực hiện một hành động và sau đó trả về một giá trị. Ba trong số chúng tôi quan tâm là (...), <...>[...]. Đơn vị quan trọng nhất cho thử thách (...)này lấy giá trị của bên trong và đẩy nó vào ngăn xếp hoạt động. Sau đó nó trả về đối số. <...>[...]cả hai đơn nguyên "trơ", nghĩa là chúng không thực hiện bất kỳ hành động nào mà thay đổi giá trị mà chúng được thông qua. <...>luôn trả về 0 bất kể đối số được thông qua. Trong khi đó [...]luôn trả về thời gian đối số -1.


Chương trình mẫu với lời giải thích

Nếu bạn chưa bao giờ lập trình trong Brain-Flak, có thể nên xem xét một số chương trình ví dụ sử dụng các thao tác được mô tả

({}{})

Điều này thêm hai số hàng đầu trên ngăn xếp. Mỗi {}giá trị bật ra khỏi ngăn xếp và (...)đẩy tổng của chúng trở lại.

({}[{}])

Tương tự, điều này sẽ trừ mục thứ hai trên ngăn xếp từ mục đầu tiên. Giống như trước mỗi {}giá trị bật lên nhưng giá trị [..]thứ hai khiến nó được thêm vào. Một lần nữa (...)đẩy tổng.

({}<{}>)

Điều này loại bỏ giá trị thứ hai trên ngăn xếp giữ nguyên giá trị hàng đầu. Nó hoạt động giống như hai lần cuối ngoại trừ giá trị thứ hai bị tắt tiếng do <...>đó việc đẩy chỉ đẩy giá trị đầu tiên trở lại.

(({}))

Điều này tạo ra một bản sao thứ hai của giá trị trên đỉnh của ngăn xếp. Nó thực hiện điều này bằng cách bật đỉnh của ngăn xếp với {}giá trị của nó, đầu tiên (..)sau đó đẩy nó trở lại đánh giá về giá trị của nó. Cái thứ hai (...)lấy giá trị được trả về bởi cái thứ nhất và cũng đẩy nó vào stack. tạo một bản sao thứ hai.

Bài tập

Cho một số nguyên ntạo một đoạn mã Brain-Flak ngăn xếp nhân lên gấp bội số đỉnh của ngăn xếp hiện tại n.

Bạn được phép sử dụng các hoạt động Brain-Flak sau đây

(...) -> Push Monad, Pushes the result of its contents
<...> -> Zero Monad, Returns zero
[...] -> Negative Monad, Returns the opposite of its contents result
{}    -> Pop nilad, Pops the TOS and returns its value
<>    -> Switch nilad, Switches the active and inactive stack

Các hoạt động khác bị cấm cho mục đích của thách thức.

Chấm điểm

Điểm của bạn sẽ là độ dài tích lũy của tất cả các chương trình từ n=2đến n=10000. Hãy chắc chắn bao gồm một liên kết đến đầu ra của chương trình của bạn để xác minh.


1
Không quan tâm, tại sao các hoạt động 1 và vòng lặp bị cấm?
Neil

@Neil Toán tử chiều cao ngăn xếp cũng bị cấm.
Erik the Outgolfer

1
@EriktheOutgolfer Tôi đã cấm cái đó trong metagolf số nguyên.
Neil

7
Các nhà khoa học máy tính thật kỳ lạ. Họ phát minh ra các ngôn ngữ lập trình không thể sử dụng, vốn dĩ là chống golf và sau đó thách thức nhau viết mã golf để giải quyết các vấn đề đơn giản trong ngôn ngữ này. Không có gì bí truyền hơn thế này. +1 tốt thưa ngài.
Draco18

1
@ Qwerp-Derp Tôi đã xem xét tối ưu hóa đầu ra của chương trình Python được liên kết (điểm hiện tại 681950) và thấy tiết kiệm không đáng kể 4492 bằng cách sử dụng [...], vì vậy đó là một sự khởi đầu.
Neil

Câu trả lời:


2

Ruby, 669856

$answers = Hash.new{|hash,n|
  valid = []
  2.upto(n**0.5){|i|
    valid.push("("+hash[n/i]+")"+"({})"*(i-2)+"{}") if n%i == 0
  }
  valid.push("({})"+hash[n-1])
  (hash[n] = valid.min_by{|s| s.length})
}
$answers[1] = "{}"

def full_answer n
  "("+$answers[n]+")"
end

Đây là một câu trả lời cơ bản nhanh chóng. 1000 chương trình đầu tiên được tìm thấy ở đây . (Tôi đã cố gắng đăng tất cả chúng, nhưng điều đó làm quá tải kích thước pastebin tối đa.) Tôi có thể thêm một lời giải thích mã sau.

Ví dụ:

360:    ((((((({})(({}){}){})({}){})({}){}){}){}){})
4608:   (((((((((((({})({}){})({}){}){}){}){}){}){}){}){}){}){})
9991:   (({})((({})(((((((({})((({})({}){}){}){}){}){}){}){}){}){}){})({}){}){})
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.