<h1> Thông dịch viên tích phân lambda nhị phân </ h1>
Hình bên trên bạn có thể nhìn thấy bên trái trình tự giải mã nhị phân lambda nhị phân 206 bit (bcc) trong ký hiệu đồ hoạ, và ở bên phải một chương trình số nguyên 167 bit, trong cả ký hiệu nhị phân và đồ thị, cùng với 300 bit đầu tiên của đầu ra. Bạn có thể chạy ngay lập tức bằng cách cho con số primes. blc vào trình thông dịch blc nhỏ trong perl với (Xuất ra nhiều hơn 300 bit trong Perl sẽ hạ cánh máy tính của bạn trong địa ngục trao đổi.) Hoặc vào thông dịch viên blc trong C với Option - b biểu thị bit - oriented IO chứ không phải là chế độ theo định dạng byte mặc định. Phiên bản thông dịch của người phiên dịch này đã bị đánh bại vì hầu hết các chức năng trong cuộc thi C Code Obfuscated C Code 2012.
Giải tích nhị phân lambda được giải thích chi tiết trong bài báo mới nhất của tôi có sẵn trong PostScript và PDF, và phần nào ít chi tiết hơn trong mục nhập Wikipedia trước đây.
Lấy cảm hứng từ một blog FP Lunch vào ngày 13 tháng 4 năm 2008 của Thorsten Altenkirch, tôi đã có thể cải tiến sự liên tục trong định lý đối xứng-thông tin từ năm 1876 đến năm 1636, và một lần nữa vào ngày 3 tháng 3 năm 2009 xuống còn 1388. Vào ngày 3 tháng 9, 2011, Bertram Felgenhauer đã đưa ra một bộ đánh giá đơn nguyên cho phép chúng ta theo dõi các bit đầu vào được đọc cho đến nay, tránh được sự cần thiết phải giảm tượng trưng, và cắt giảm hằng số xuống đến 667 bit. Bertram cũng cải thiện thông dịch viên brainfuck bằng 64 bit.
Vào ngày 10 tháng 3 năm 2009, tôi xác định 4 bit đầu tiên của xác suất bị chặn: .0001. Vào ngày 17 tháng 6 năm 2011, theo đề xuất của Chris Hendrie, tôi đã thay đổi số nguyên / chuỗi tương ứng để tránh đảo chiều. Đại diện đại diện của đại đa số này làm cho thứ tự lexicographic trên các số được phân định trùng với thứ tự số.
Vào tháng 3 năm 2012 tôi đã tính ra bộ giảm thiểu tính toán lambda stepwise đơn giản nhất, một thành phần cần thiết trong một bằng chứng của Định lý đối xứng của Thông tin.
Thiết kế của một máy tính phổ thông tối thiểu được thúc đẩy bởi mong muốn của tôi để đưa ra một định nghĩa cụ thể của Kolmogorov phức tạp, trong đó nghiên cứu ngẫu nhiên của các đối tượng cá nhân. Tất cả các ý tưởng trong bài báo đã được thực hiện bằng ngôn ngữ Haskell thanh lịch tuyệt vời, về cơ bản đã được đánh máy lambda calculus với rất nhiều cú pháp đường trên đầu trang. Một ví dụ: hiển thị một chương trình 10 byte cho `` nói lắp '', một chương trình 21 byte cho số nguyên tố, và thông dịch 104 byte Brainfuck.
Khóa học trực tuyến tại Oberlin College cung cấp một bài giới thiệu rất dễ hiểu đối với bộ tổ hợp. Colin Taylor đã viết một thông dịch tương tự cho Lambda Calculus, trong khi Gregory Chaitin, người thúc đẩy lý thuyết thông tin thuật toán, đã viết một cho LISP. Ngôn ngữ Lập trình Unlambda là một ngôn ngữ dựa trên tổ hợp với đầu vào, đầu ra, đánh giá bị chậm trễ, và cuộc gọi với hiện tại-sự tiếp nối. Phiên dịch đã được viết bằng nhiều ngôn ngữ, bao gồm c, java, perl, đề án, SMLNJ, CAML, và ngay cả trong bản thân unlambda! Gần đây, Ben Rudiak-Gould (benrgATdarkDOTdarkwebDOTcom) đã cung cấp một thông dịch logic kết hợp toàn diện nhất, sử dụng các mã của Nhà thờ để mã hóa ký tự. Bằng cách buộc mã combinator vào đầu vào / đầu ra chuẩn, ngôn ngữ Lazy K của nó hỗ trợ các tiện ích quen thuộc như sắp xếp! Để đưa nó lên, anh ta cung cấp một trình biên dịch (được viết bằng Scheme) từ (một tập hợp) của Đề án vào Lazy K. Chris Barker cũng có một số trang quan tâm, bao gồm hướng dẫn Lambda và một số ngôn ngữ tối giản.
Trước khi khám phá ra làm thế nào để giải thích toán tử lambda trong nhị phân, tôi đã tìm ra làm thế nào để làm cho một máy phổ quát trong logic nhị phân combinatory. Cái đầu tiên hóa ra rất nhiều mô tả hơn, nghĩa là nhìn chung cần ít bit hơn. Nhưng vì lợi ích lịch sử, tôi giữ applet cũ này ở đây: Trên thực tế, nó làm chậm trang tải quá nhiều, vì vậy tôi bình luận nó.
Chương trình này là một thông dịch viên cho ngôn ngữ đơn giản nhất có thể: cả hai chức năng và dữ liệu được biểu diễn bởi bộ tổ hợp, được xây dựng từ S và K theo ứng dụng. Các bộ tổ hợp nguyên thủy được định nghĩa bởi các mã nhận diện Combinator Kxy = x Sxyz = xz (yz) là tất cả các ký tự. Ngoài các bộ tổ hợp nguyên thủy S và K, thông dịch viên có các bộ tổ hợp được xác định trước sau: I = SKK Y = SSK (S (K (SS (S (SSK)))) K) Pxyz = zxy 0xy = x 1xy = y? = 0? (Pxy) = 1 Trong trường nhập văn bản, bạn có thể nhập các định nghĩa như ở trên, hoặc kết hợp để được đánh giá. Trong trường hợp kết quả quá lớn để được hiển thị cụ thể, phần của nó được hiển thị dưới dạng dấu hoa thị. Nếu kết quả có thể được giải thích như là một danh sách, điều này được hiển thị như là một chuỗi đầu ra với các bit 0,1 và một lần nữa dấu sao cho thấy các phần tử không bit. Một ví dụ là (các dòng đầu vào được hiển thị với một dấu nhắc):
Lambda the Ultimate.
Dẫn đường.
Hệ số nhị phân Lambda và luận điểm phức hợp.
Trong khi Anton đang bập bẹ về Giáo hội & amp; Turing, tôi đã tìm ra Razor của Occam sẽ là kiểu chứng minh mà người ta sẽ đưa ra khi đưa ra Lambda Calculus qua Universal Turing Machines. Điều này dẫn đến câu hỏi của những gì là nhỏ nhất (như được đo bằng nhị phân) Turing Machine có thể được xây dựng. John Tromp cung cấp một câu trả lời cho câu hỏi này trong Luôn luôn luôn vui vẻ Lambda Calculus và Combinatory Logic Playground:
Hình ảnh bạn có thể thấy thông dịch viên tự giải tích lambda nhị phân 210 bit và trình tự thông dịch logic nhị phân 272 bit. Cả hai đều được giải thích chi tiết trong bài báo mới nhất của tôi có sẵn trong PostScript và PDF. Thiết kế của một máy tính phổ quát tối giản được thúc đẩy bởi mong muốn của tôi để đưa ra một định nghĩa cụ thể của Kolmogorov phức tạp, trong đó nghiên cứu ngẫu nhiên của các đối tượng cá nhân. Tất cả các ý tưởng trong bài báo đã được thực hiện bằng ngôn ngữ Haskell thanh lịch tuyệt vời, về cơ bản đã được đánh máy lambda calculus với rất nhiều cú pháp đường trên đầu trang.
Thật thú vị, phiên bản dựa trên Lambda Calculus nhỏ hơn so với trên Combinator. Một tuyên bố tôi tìm thấy quan tâm đến bài báo về PL:
Mặc dù nội dung thông tin dường như phụ thuộc nhiều vào việc lựa chọn ngôn ngữ lập trình, khái niệm này thực sự không thay đổi đối với một hằng số cộng.
Bạn không chắc chắn nếu tuyên bố đó có nghĩa là nghiên cứu PL cuối cùng là doomed. :-)
<h1> Thông dịch viên tích phân lambda nhị phân </ h1>
Tải qua App Store Đọc bài đăng này trong ứng dụng của chúng tôi!
Làm thế nào để mô hình đầu ra của các tích phân lambda nhị phân?
Tôi đã viết mã để làm như sau:
Phân tích cú pháp nhập dữ liệu nhị phân vào một số cấu trúc dữ liệu đại diện cho phép tính lambda không được định dạng thông thường Beta - giảm thuật ngữ này.
Chuyện gì xảy ra sau đó?
Làm thế nào là "đầu ra" giải nghĩa? Là đầu ra a) kết quả được dịch trở lại vào nhị phân thông qua cùng một mã hóa, hoặc b) bitstream mã hoá bởi một danh sách các phép toán luận kết cuối sai? (Và điều gì sẽ xảy ra nếu đầu ra không tạo thành một danh sách như vậy?)
Hay tôi hiểu nhầm cách BLC hoạt động?
Tôi muốn đề nghị sử dụng http://www. ioccc. org/2012/tromp/hint. html làm tài liệu tham khảo chính của bạn. Trang Wikipedia có thể là tốt, nhưng những ghi chép ban đầu của ông về BLC khá tốt.
Về chủ đề đầu vào và đầu ra, ông có điều này để nói:
Cụ thể hơn, nó định nghĩa một máy phổ quát, từ một luồng đầu vào của các bit, phân tích cú pháp nhị phân của thuật toán lambda, áp dụng cho phần còn lại của đầu vào (được dịch sang một danh sách lười biếng của các phép toán luận, trong đó có một biểu diễn tiêu chuẩn trong lambda calculus), và dịch kết quả đánh giá trở lại vào một dòng bit để được đầu ra.
<h1> Thông dịch viên tích phân lambda nhị phân </ h1>
Chúng tôi khuyên bạn nên nâng cấp lên Safari, Google Chrome hoặc Firefox mới nhất.
Kéo yêu cầu 0.
GitHub là nhà của hơn 20 triệu nhà phát triển làm việc cùng nhau để lưu trữ và xem xét mã, quản lý các dự án, và cùng nhau xây dựng phần mềm.
Sử dụng Git hoặc thanh toán với SVN bằng cách sử dụng URL web.
Thông dịch viên Lambda trong PHP.
Lambda calculus là một ngôn ngữ lập trình rất tối thiểu được sáng tạo vào năm 1936 bởi Nhà thờ Alonzo. Đó là chức năng tương đương của Máy Turing.
Giải tích Lambda chỉ có ba khái niệm: Các định nghĩa hàm, các biến khai lexically, ứng dụng chức năng.
Một ví dụ sẽ là chức năng nhận diện:
Phần đầu tiên λx định nghĩa một hàm mà mất một x, the. biểu thị rằng phần sau đây là cơ thể chức năng. Cơ thể chỉ trả về x.
Trong PHP, bạn sẽ viết tương tự như sau:
Bạn có thể tổ chức các định nghĩa chức năng. Đây là một hàm trả về một hàm:
Và bạn cũng có thể áp dụng một hàm cho một đối số, mà chỉ có nghĩa là gọi hàm.
Đây là dạng viết tay ngắn (kết hợp trái).
Cuộc gọi lồng nhau như:
Được hiểu là:
Nếu bạn muốn thay đổi nhóm để kết hợp phải, bạn cần phải nhóm chúng một cách rõ ràng trong dấu ngoặc đơn:
Thật thú vị, tính toán lambda là turing đầy đủ. Chỉ sử dụng ba khái niệm này, bạn có thể biểu diễn bất kỳ tính toán nào.
Kiểm tra các liên kết ở phía dưới để biết thêm chi tiết về làm thế nào để làm công cụ trong lambda calculus.
Dự án này bao gồm một bộ phân tích cú pháp biểu thức lambda bằng cách sử dụng phẩy, và một thông dịch eval áp dụng dựa trên việc thực hiện của Matt Might trong kế hoạch.
Thông dịch viên là call-by-value, nghĩa là các cuộc gọi đệ quy cần phải được bao bọc trong một chức năng để ngăn họ không được đánh giá một cách háo hức.
Ví dụ về làm thế nào để làm con số (mã hóa nhà thờ), booleans, số học, boolean logic, looping (đệ quy), vv xem example. php.
Dự án này vận chuyển với một vòng lặp đọc-eval-in mà bạn có thể sử dụng để đánh giá các biểu thức tính toán lambda:
Theo mặc định, nó là ở chế độ int, mong rằng kết quả của biểu thức là một số mã hoá của nhà thờ. Thí dụ:
Bạn có thể chuyển sang chế độ bool bằng cách gửi lệnh b:
Hoặc r cho chế độ thô:
Một vài điều vẫn đang được tiến hành:
Máy Krivine: Trình thông dịch thay thế này sẽ cho phép gọi theo nhu cầu và lập chỉ mục vào các chỉ số de-bruijn, điều này là cần thiết.
Giải tích lambda nhị phân: Cho phép mã hoá các chương trình tính toán lambda dưới dạng nhị phân tạo ra các chương trình rất nhỏ. Điều này cũng định nghĩa một cơ chế I / O.
Bạn không thể thực hiện hành động đó vào lúc này.
Bạn đăng nhập bằng tab hoặc cửa sổ khác. Tải lại để làm mới phiên của bạn. Bạn đã đăng xuất trong tab hoặc cửa sổ khác. Tải lại để làm mới phiên của bạn.
Hệ số nhị phân Lambda và luận điểm phức hợp.
Trong phần đầu tiên, chúng tôi giới thiệu các biểu diễn nhị phân của cả hai phép toán lambda và các thuật ngữ logic kết hợp, và chứng minh sự đơn giản của chúng bằng cách cung cấp các trình dịch thông dịch cú phân tử rất nhỏ gọn cho những ngôn ngữ nhị phân này. Dọc theo cách chúng tôi cũng trình bày các kết quả mới trên danh sách các đại diện, khung trừu tượng, và các bộ kết hợp fixpoint. Trong phần thứ hai chúng tôi xem lại Lý thuyết Thông tin Thuật toán, trong đó các thông dịch viên cung cấp một phương tiện thuận tiện. Chúng tôi chứng minh điều này với một số giới hạn trên cụ thể về độ phức tạp của chương trình, bao gồm mã vạch phân tách tự động cho các chuỗi nhị phân.
Nếu bạn có đăng ký cá nhân cho ấn phẩm này hoặc nếu bạn đã mua quyền truy cập Pay Per Article trong vòng 24 giờ qua, bạn có thể truy cập bằng cách đăng nhập bằng tên người dùng và mật khẩu của mình ở đây:
Bản quyền & bản sao; 2017 Công ty TNHH Xuất bản Khoa học Thế giới • Chính sách Bảo mật.
Cú pháp.
Có ba loại biểu thức sau đây:
Một biểu thức lambda có dạng (λ x. E) trong đó x có thể là bất kỳ tên biến pháp lý nào và e bất kỳ biểu thức pháp lý nào. Ở đây x được gọi là tham số và e được gọi là thân hàm.
Để đơn giản, chúng ta thêm một hạn chế nữa là không phải có một biến có cùng tên với x hiện đang ở trong phạm vi. Một biến bắt đầu nằm trong phạm vi khi tên của nó xuất hiện giữa (λ và. Và dừng ở trong phạm vi tương ứng).
Một chức năng được áp dụng bằng cách thay thế mỗi lần xuất hiện của tham số trong cơ thể chức năng với đối số của nó. Biểu thức của form ((λ x. E) a), trong đó x là một tên biến và e và a là các biểu thức, đánh giá (hoặc giảm) với biểu thức e 'trong đó e' là kết quả của việc thay thế mỗi lần xuất hiện của x trong e với a.
Một dạng bình thường là một biểu hiện không thể đánh giá được nữa.
Nhiệm vụ của bạn, nếu bạn chọn chấp nhận nó, là viết một thông dịch viên lấy dữ liệu đầu vào của nó là biểu hiện của phép toán lambda không có chứa giá trị không chứa các biến tự do và tạo ra dạng xuất hiện của biểu thức (hoặc một biểu thức alpha-đồng nhất với nó) . Nếu biểu thức không có hình thức bình thường hoặc nó không phải là một biểu hiện hợp lệ, hành vi đó là không xác định.
Giải pháp với số lượng ký tự nhỏ nhất thắng.
Một vài ghi chú:
Đầu vào có thể được đọc từ stdin hoặc từ một tên tập tin được đưa ra như một đối số dòng lệnh (bạn chỉ cần thực hiện một hoặc khác - không phải cả hai). Đầu ra đi vào thiết bị xuất chuẩn. Ngoài ra, bạn có thể định nghĩa một hàm lấy input như một chuỗi và trả về kết quả dưới dạng một chuỗi. Nếu các ký tự không phải ASCII là vấn đề đối với bạn, bạn có thể sử dụng dấu gạch chéo ngược (\) thay vì λ. Chúng tôi đếm số ký tự chứ không phải byte, vì vậy ngay cả khi tệp nguồn của bạn được mã hoá dưới dạng số ký tự unicode λ là một ký tự. Tên biến pháp luật bao gồm một hoặc nhiều chữ thường, nghĩa là các ký tự giữa a và z (không cần hỗ trợ tên chữ số, chữ hoa hay chữ cái không phải la tinh). Đối với thách thức này, không có dấu ngoặc đơn là tùy chọn. Mỗi biểu thức lambda và mỗi ứng dụng chức năng sẽ được bao quanh bởi chính xác một cặp ngoặc đơn. Không có tên biến nào sẽ được bao quanh bởi dấu ngoặc đơn. Không giống như cách viết đường như cú pháp (λ x y. E) cho (λ x. (Λ y. E)) không cần phải hỗ trợ. Nếu yêu cầu chiều sâu đệ quy đến hơn 100 là cần thiết để đánh giá một hàm, hành vi đó sẽ không được xác định. Điều này cần phải được thực hiện mà không có tối ưu hóa ở tất cả các ngôn ngữ và vẫn đủ lớn để có thể thực hiện hầu hết các biểu thức. Bạn cũng có thể cho rằng khoảng cách sẽ như trong các ví dụ, tức là không có dấu cách ở đầu và cuối của đầu vào hoặc trước một λ hoặc. và chính xác một không gian sau khi a. và giữa một hàm và đối số của nó và sau một λ.
Mẫu đầu vào và đầu ra.
Đầu vào: ((x, x) (λ y (λ z. Z)))
Đầu ra: (λ y (λ z. Z))
Đầu vào: (λ x. ((Λ y. Y) x))
Đầu vào: ((λ x. (Λ y. X)) (λ a. A))
Đầu ra: (λ y. (Λ a. A))
Dữ liệu đầu vào: (((λ x. (Λ y. X)) (λ a. A)) (λ b. B)
Đầu vào: ((λ x. (Λ y. Y)) (λ a. A))
Đầu vào: ((λ x. (Λ y.)) (Λ a. A)) (λ b.)
Đầu ra: bất cứ điều gì (Đây là một ví dụ về một biểu thức không có hình thức bình thường)
Dữ liệu đầu vào: ((λ x. (Λ y. X)) (λ a. A)) ((λx. (X x)) (λx. (X x))))
Output: (λ a. A) (Đây là một ví dụ về một biểu thức không bình thường nếu bạn đánh giá các đối số trước khi gọi hàm, và thật đáng tiếc là một ví dụ mà giải pháp đã cố gắng của tôi không thành công)
Dữ liệu đầu vào: ((λ a. (Λ b. (A (a (a b))))) (λ c (λ d. (C (c d)))))
Kết quả: `(λ a. (Λ b. (A (a (a (a (a (a (a (a (a b)))))))))) Tính toán 2 ^ 3 trong các chữ số của Nhà thờ.
Python - 321 320.
Đây là nỗ lực (cố định) của tôi:
Tôi đã vắt nó xuống 644 ký tự, tôi phần yếu tố của cEll vào cOpy và Par; lưu trữ các cuộc gọi đến cell và cdr thành các biến địa phương tạm thời, và chuyển các biến địa phương sang globals trong các hàm "terminal" (tức không đệ quy).Ngoài ra, các hằng số thập phân ngắn hơn literals ký tự và điều này kinh doanh khó chịu.
. xác định chính xác chữ thường (giả sử ASCII), nhưng cũng chấp nhận bất kỳ `
. (Sự quan sát tương tự về ASCII được thực hiện trong video tuyệt vời này về UTF-8.)
Tôi có thể nhận được một vài phiếu bầu cho nỗ lực? Tôi đã làm việc trong ngày và đêm này trong một tuần. Tôi đã khám phá ra bản gốc của bài báo McCarthy và bị một lỗi trong bản thân nó cho đến khi tôi đọc phần phụ lục của The Roots of Lisp của Paul Graham. Tôi đã bị phân tâm đến nỗi tôi tự nhốt mình trong căn nhà của mình, rồi hoàn toàn quên mất khi về đến nhà vào lúc 12 giờ 30 (chậm trễ để gọi người quản lý tòa nhà đang sống ở quận hạt) và phải chi tiêu đêm ở bà tôi (hacking cho đến khi pin máy tính xách tay của tôi là khô).
Và sau tất cả những điều đó, nó thậm chí không gần với mục nhập chiến thắng!
Tôi không chắc làm thế nào để làm cho bất kỳ điều này ngắn hơn; và tôi đã sử dụng tất cả các thủ đoạn bẩn tôi có thể nghĩ đến! Có lẽ nó không thể được thực hiện trong C.
Với một số lượng quảng đại trong đếm (đoạn đầu tiên lấy một chuỗi và in ra kết quả), đó là 778 770 709 694 ký tự. Nhưng để làm cho nó độc lập, nó phải có cuộc gọi sbrk. Và để xử lý các biểu thức phức tạp hơn, nó cũng cần xử lý tín hiệu. Và tất nhiên nó không thể được thực hiện thành một mô-đun với bất kỳ mã mà cố gắng sử dụng malloc.
Vì vậy, than ôi, đây là:
Đây là khối ngay trước khi cắt giảm cuối cùng. Các thủ thuật ở đây là các con trỏ số nguyên thay vì con trỏ (lợi dụng hành vi 'implicit int'), và việc sử dụng 'bộ nhớ đầu': char * n là con trỏ 'mới' hoặc 'tiếp theo' vào không gian trống. Nhưng đôi khi tôi viết một chuỗi vào bộ nhớ, sau đó gọi strlen và tăng n; hiệu quả sử dụng bộ nhớ và sau đó phân bổ nó, sau khi kích thước được dễ dàng hơn để tính toán. Bạn có thể thấy nó khá thẳng thắn từ bài báo McCarthy, ngoại trừ tế bào () có giao diện giữa các hàm và biểu diễn chuỗi dữ liệu.
Hệ số nhị phân Lambda 186.
Chương trình được hiển thị trong bãi chứa hex bên dưới.
không chấp nhận định dạng bạn đề xuất. Thay vào đó, nó mong đợi một thuật ngữ lambda trong định dạng lambda nhị phân (blc) nhị phân. Tuy nhiên, nó cho thấy tất cả các bước đơn giản trong việc giảm dạng bình thường, sử dụng dấu ngoặc đơn tối thiểu.
Ví dụ: tính toán 2 ^ 3 trong các chữ số của Nhà thờ.
Lưu dữ liệu trên hex với xxd - r> symbolic. Blc.
Lấy một thông dịch viên blc từ http://www. cwi. nl/
Kể từ hexdump là khá không thể đọc được, đây là một phiên bản "tháo rời".
thay thế 00 (lambda) bằng \ và 01 (ứng dụng) với @ Bây giờ nó gần như có thể đọc được như là brainfuck :-)
Haskell, 342 323 317 305 ký tự.
Khi viết bài này, đây là giải pháp duy nhất đánh giá ((λ f. (Λ x. (Fx))) (λ y. (Λ x. Y)) đến kết quả chính xác (λ x. (Λ z. x)) thay vì (λ x. (λ x. x)). Việc thực hiện đúng phép toán lambda đòi hỏi sự thay thế tránh chụp, ngay cả dưới sự đảm bảo đơn giản của vấn đề này, rằng không có biến nào làm biến đổi một biến khác trong phạm vi của nó. (Chương trình của tôi xảy ra để làm việc thậm chí không có đảm bảo này.)
Điều này chạy trong GHC 7.0, theo yêu cầu vì thử thách này đã được thiết lập vào tháng 1 năm 2011. Nó sẽ ngắn hơn 13 ký tự nếu tôi được phép thừa nhận GHC 7.10.
Nó có thể được sử dụng như.
Giải pháp chưa hoàn toàn được chơi golf nhưng đã gần như không thể đọc được.
Chỉnh sửa: kiểm tra câu trả lời của tôi dưới đây cho 250 theo nguyên bản JavaScript.
2852 243 ký tự sử dụng LiveScript (Không Regex Không chơi golf hoàn toàn - có thể được cải thiện)
Đó là 3 ^ 2 = 9, như đã nêu trên OP.
Nếu có ai tò mò, đây là một phiên bản mở rộng với một số ý kiến:
Waterhouse Arc - 140 ký tự.
Nó có thể được ngắn hơn nhiều nếu tính năng đánh giá lười biếng của Haskell được sử dụng đầy đủ. Đáng buồn, tôi không biết làm thế nào để làm điều đó.
Ngoài ra, nhiều nhân vật bị lãng phí trong bước phân tích cú pháp.
Các biến cho phép nhập dữ liệu bằng chữ thường [từ a..z] sys có thể tạo ra các biến bằng chữ hoa [từ A..Z] nếu cần ở đầu ra. Giả sử cấu hình ký tự ascii.
Got 231 với JavaScript / không Regex.
Nhận mảng 2 phần tử. 1 là viết tắt của λ và 2 là viết tắt của một biến chỉ số bruijn.
Phiên bản này không sử dụng các biến phụ (vì thế không theo 100% kết luận của lambda) như nhiều phiên bản khác ở đây. Mỗi biến phải dài 1 chararcter (như một số khác ở đây). Mã kiểm tra:
Nhị phân lambda tích phân.
. dự kiến ký hiệu bằng nhau: lô = y, hoặc âm mưu = tháng 5 năm 2007.
Lý lịch.
BLC được thiết kế để cung cấp một định nghĩa bê tông đơn giản và thanh lịch của phức tạp mô tả (Kolmogorov phức tạp).
Nói chung, sự phức tạp của một đối tượng là độ dài của mô tả ngắn nhất của nó.
Để làm cho chính xác, chúng tôi đưa mô tả được bitstrings, và xác định một phương pháp mô tả với một số thiết bị tính toán, hoặc máy tính, mà biến đổi các mô tả thành các đối tượng. Các đối tượng thường chỉ là bitstrings, nhưng cũng có thể có cấu trúc bổ sung, ví dụ như, các cặp dây.
Ban đầu, các máy Turing, một chế độ chính thức nổi tiếng nhất để tính toán, được sử dụng cho mục đích này. Nhưng họ đang thiếu một chút trong xây dựng và composability. Một hình thức tính toán cổ điển khác, tích phân tích Lambda, mang lại những ưu điểm khác biệt trong việc dễ sử dụng. Các tính toán lambda không kết hợp bất kỳ khái niệm về I / O mặc dù, vì vậy một trong những cần phải được thiết kế.
Việc thêm một hàm đọc sơ khai để tích phân lambda, như Chaitin đã làm cho LISP, sẽ phá huỷ sự minh bạch tham chiếu, trừ khi nó phân biệt giữa hành động I / O và kết quả của nó, như Haskell làm với I / O đơn nguyên của nó. Nhưng điều đó đòi hỏi một hệ thống kiểu, một biến chứng không cần thiết.
Thay vào đó, BLC yêu cầu dịch bitstrings thành các thuật ngữ lambda, mà máy tính (bản thân một thuật ngữ lambda) có thể được áp dụng dễ dàng.
có thể được nhìn thấy để trực tiếp thực hiện các nhà điều hành if-then-else.
Bây giờ hãy xem xét chức năng ghép nối.
áp dụng cho hai thuật ngữ M và N.
Áp dụng điều này cho một boolean sản lượng thành phần mong muốn của sự lựa chọn.
được biểu thị là.
Z hoạt động như một sự tiếp tục của danh sách, có thể là một danh sách không (để kết thúc chuỗi) hoặc một chuỗi khác (sẽ được nối vào chuỗi ban đầu).
Phân cách với giới hạn chưa được định.
Độ phức tạp mô tả thực sự có hai hương vị riêng biệt, tùy thuộc vào việc đầu vào được xem là giới hạn hay không.
Hiểu được sự kết thúc của đầu vào giúp bạn mô tả các vật thể dễ dàng hơn. Ví dụ, bạn chỉ có thể sao chép toàn bộ đầu vào để đầu ra. Hương vị này được gọi là phức hợp đơn giản hoặc đơn giản.
Nhưng theo một nghĩa nào đó là thông tin bổ sung. Một hệ thống tập tin ví dụ cần lưu trữ riêng biệt chiều dài của các tập tin. Ngôn ngữ C sử dụng ký tự null để biểu thị sự kết thúc của một chuỗi nhưng điều này xảy ra với chi phí không có ký tự đó trong các chuỗi.
Các hương vị khác được gọi là phức tạp tiền tố, được đặt tên theo mã tiền tố, nơi máy tính cần phải tìm ra, từ đầu vào đọc cho đến nay, cho dù nó cần phải đọc thêm bit. Chúng tôi nói rằng đầu vào là tự giới hạn. Điều này hoạt động tốt hơn cho các kênh truyền thông, vì người ta có thể gửi nhiều mô tả, cái này đến cái khác, và vẫn nói với họ cách nhau.
Trong mô hình I / O của BLC, hương vị được quyết định bởi sự lựa chọn của z. Nếu chúng ta giữ nó như là một biến tự do, và yêu cầu nó xuất hiện như là một phần của đầu ra, sau đó máy phải được làm việc trong một cách tự giới hạn. Nếu mặt khác chúng tôi sử dụng một thuật ngữ lambda được thiết kế đặc biệt để dễ dàng phân biệt với bất kỳ ghép nối nào thì đầu vào sẽ trở thành giới hạn. BLC chọn False cho mục đích này nhưng cho nó một cái tên khác thay thế mang tính mô tả của Nil. Đối phó với các danh sách có thể là Nil là đơn giản: kể từ.
người ta có thể viết các hàm M và N để đối phó với hai trường hợp, điều duy nhất là N sẽ được truyền cho M như là đối số thứ ba của nó.
Chúng ta có thể tìm thấy một phương pháp mô tả U như vậy đối với bất kỳ phương pháp mô tả D nào, có một hằng c (chỉ phụ thuộc vào D) sao cho không đối tượng nào có nhiều hơn c bit thêm để mô tả bằng phương pháp U so với phương pháp D. Và BLC được thiết kế để làm cho các hằng số này tương đối nhỏ. Trong thực tế hằng sẽ là chiều dài của một mã hóa nhị phân của một D-trình biên dịch viết bằng BLC, và U sẽ là một thuật ngữ lambda phân tích mã hoá này và chạy thông dịch giải mã này trên phần còn lại của đầu vào. U thậm chí không cần biết liệu mô tả có bị giới hạn hay không; nó hoạt động cùng một trong hai cách.
Có đã giải quyết được vấn đề dịch bitstrings thành toán tử lambda, bây giờ chúng ta phải đối mặt với những vấn đề đối diện: làm thế nào để mã hóa điều khoản lambda thành bitstrings?
Đầu tiên chúng ta cần phải viết các thuật ngữ lambda của chúng ta trong một ký hiệu đặc biệt bằng cách sử dụng các chỉ số De Bruijn. Mã hóa của chúng tôi sau đó được định nghĩa đệ quy như sau.
Ví dụ, chức năng ghép nối được viết bằng định dạng De Bruijn, có mã hóa.
Thuật ngữ lambda đóng là một trong đó tất cả các biến đều bị ràng buộc, nghĩa là không có bất kỳ biến số miễn phí. Trong định dạng De Bruijn, điều này có nghĩa là chỉ mục i chỉ có thể xuất hiện trong ít nhất lambdas lồng nhau. Số lượng các điều khoản khép kín có kích thước n bit được cho bởi trình tự OEIS A114852 của Bộ bách khoa toàn thư On-Line của chuỗi số nguyên.
Thuật ngữ đóng ngắn nhất có thể là chức năng nhận dạng. Trong chế độ phân cách, máy này chỉ sao chép đầu vào của nó vào đầu ra của nó.
Vậy máy U này là gì? Ở đây, ở định dạng De Bruijn (tất cả các chỉ số có một chữ số):
Đây là trong nhị phân:
0101000110100000000101011000000000011110000101111110011110 0001011100111100000011110000101101101110011111000011111000 0101111010011101001011001110000110110000101111100001111100 0011100110111101111100111101110110000110010001101000011010 (chỉ dài 232 bít (29 byte))
Một phân tích chi tiết về máy U có thể được tìm thấy ở đây. [1]
Phức tạp, cụ thể.
Nói chung, chúng ta có thể làm cho phức tạp của một đối tượng điều kiện trên một số đối tượng khác được cung cấp như là đối số bổ sung cho máy phổ quát. Tính phức tạp đơn giản (hoặc đơn giản) KS và phức tạp tiền tố KP được xác định bởi.
Chương trình nhận dạng chứng minh điều đó.
Chương trình chứng minh điều đó.
ở đâu là mã Levenstein cho x được định nghĩa bởi. trong đó chúng tôi xác định số và bitstrings theo thứ tự lexicographic. Mã này có thuộc tính tốt đẹp cho tất cả các k,
Hơn nữa, nó làm cho thứ tự lexicographic của con số giới hạn trùng với thứ tự số.
Sự phức tạp của một tập hợp các số tự nhiên là sự phức tạp của chuỗi đặc trưng của nó, một thuật ngữ lambda vô hạn trong Calculus Lambda Vô hạn.
có 100 bit đầu ra đầu tiên.
trong khi một biến thể đơn giản chứng minh.
Điều này thậm chí còn ngắn hơn 23 byte của Haskell.
Tính đối xứng của thông tin.
là một chương trình ngắn nhất cho x.
Bất bình đẳng này là một nửa dễ dàng của một sự bình đẳng (lên đến một hằng số) được gọi là đối xứng của thông tin. Chứng minh cuộc trò chuyện.
liên quan đến việc mô phỏng vô số các chương trình theo thời trang, nhìn thấy những gì ngăn chặn và xuất ra cặp x (cho một chương trình ngắn nhất được đưa ra) và bất kỳ y, và cho mỗi chương trình như vậy p, yêu cầu một codeword mới cho y của chiều dài. Sự bất bình đẳng Kraft đảm bảo rằng việc liệt kê vô hạn các yêu cầu này có thể được hoàn thành và trong thực tế các từ mã cho y có thể được giải mã ngay lập tức, song song với bảng liệt kê ở trên. Chi tiết về kết quả cơ bản của Chaitin có thể được tìm thấy ở đây. [2]
Thuật ngữ nối hai bản sao của đầu vào, chứng minh điều đó.
Áp dụng nó để mã hóa riêng của nó cho một quine 132 bit:
Cho đến nay, chúng ta đã thấy một chút đáng ngạc nhiên trong cách thực sự nén một đối tượng vào một mô tả ngắn hơn; trong ví dụ cuối cùng, chúng tôi đã chỉ phá vỡ ngay cả. Mặc dù, chúng ta thực sự nén theo từng bit.
Những gì có thể là chương trình ngắn nhất sản xuất một sản lượng lớn hơn? Sau đây là một ứng cử viên tốt: chương trình, kích thước 55 bit, sử dụng các chữ số của Nhà thờ để xuất ra chính xác những người. Nhịp đập đó cả hai gzip và bzip2, máy nén cần 344 và 352 bit tương ứng, để mô tả cùng một đầu ra (như một tập tin 8192 byte với một tên chữ cái).
Xác suất dừng của máy phổ quát tiền tố được định nghĩa là xác suất nó sẽ xuất ra bất kỳ thuật ngữ nào có dạng đóng kín (bao gồm tất cả các chuỗi được dịch):
Với một số nỗ lực, chúng ta có thể xác định 4 bit đầu tiên của số trí tuệ đặc biệt này:
nơi xác suất .0001 2 = 2 -4 đã được đóng góp bởi các chương trình 00100 và 00101 cho các thuật ngữ Đúng và Sai.
Trong khi các luồng bit là tốt đẹp trên lý thuyết, họ giá vé thấp trong interfacing với thế giới thực. Ngôn ngữ BLC8 là một biến thể thực tế hơn về BLC, trong đó các chương trình hoạt động trên một dòng byte, trong đó mỗi byte được biểu diễn như là một danh sách được phân cách của 8 bit theo thứ tự big-endian.
BLC8 đòi hỏi một máy tính phức tạp hơn:
Bộ phân tích cú pháp trong U8 theo dõi cả hai byte còn lại, và các bit còn lại trong byte hiện tại, loại bỏ sau khi phân tích cú pháp đã hoàn tất. Do đó, kích thước của U8, mà là 355 bit như là một chương trình BLC, là 45 byte trong BLC8.
Chương trình BLC8 sau đây.
là một thông dịch băng không giới hạn Brainfuck trong 829 bit (dưới 104 byte). Định dạng che dấu sự xuất hiện của các chỉ số hai con số: 10 trên dòng 1, 15 trên dòng 2, và 11 và 3 giây 12 trên dòng 3. Các chỉ số này được đánh dấu bằng dấu gạch dưới để phân biệt chúng với chỉ số một chữ số.
Điều này cung cấp một ví dụ tốt đẹp về tài sản mà các phương pháp mô tả phổ quát khác nhau ở mức độ phức tạp nhất. Viết một thông dịch viên BLC8 trong Brainfuck, mà sẽ cung cấp một kết hợp trên ràng buộc theo hướng khác, được để lại như là một tập thể dục cho die-cứng Brainfuck lập trình viên.
Thông dịch viên dự kiến đầu vào của nó để bao gồm một chương trình Brainfuck theo sau là một] theo sau là đầu vào cho chương trình Brainfuck. Trình thông dịch chỉ nhìn vào các bit 0,1,4 của mỗi ký tự để xác định đó, -. + & Lt; & lt; & gt ;, nghĩa là bất kỳ ký tự nào khác ngoài 8 phải được loại bỏ khỏi chương trình Brainfuck. Tiêu thụ nhiều đầu vào hơn là kết quả sẵn có trong một lỗi (kết quả không phải là danh sách).
Thông dịch viên này là bản dịch thô của phiên bản sau đây được viết bằng Haskell.
Nhị phân lambda tích phân.
Lý lịch.
BLC được thiết kế để cung cấp một định nghĩa bê tông đơn giản và thanh lịch của độ phức tạp mô tả (phức tạp Kolmogorov), trong đó phức tạp của một đối tượng là độ dài mô tả ngắn nhất của nó.
Điều này được thực hiện chính xác bằng cách xác định một phương pháp mô tả với một hàm tính toán biến đổi bitstrings (mô tả) thành các đối tượng. Các đối tượng thường chỉ là bitstrings, nhưng cũng có thể có cấu trúc bổ sung, ví dụ như, các cặp dây.
Ban đầu, các máy Turing, một chế độ chính thức nổi tiếng nhất để tính toán, được sử dụng cho mục đích này. Nhưng họ đang thiếu một chút trong xây dựng và composability. Một hình thức tính toán cổ điển khác, tích phân tích Lambda, mang lại những ưu điểm khác biệt trong việc dễ sử dụng. BLC là kết quả của việc kết hợp một khái niệm của I / O nhị phân vào lambda calculus, để biến nó thành một phương pháp mô tả hiệu quả.
Chuỗi nhị phân trong BLC.
True = & lt; math & gt; \ lambda x \, \ lambda y. \, X & lt; / math & gt; Sai = & lt; toán học & gt; \ lambda x \, \ lambda y.\, y & lt; / math & gt;
có thể được nhìn thấy để trực tiếp thực hiện các nhà điều hành if-then-else.
Chức năng ghép nối tiêu chuẩn.
& lt; math & gt; \ langle, \ rangle = \ lambda x \, \ lambda y \, \ lambda z. \, z xy & lt; / math & gt;
áp dụng cho hai thuật ngữ M và N.
& lt; math & gt; \ langle M, N \ rangle = \ lambda z. \, z M N & lt; / math & gt;
có thể được áp dụng cho một boolean để tạo thành phần mong muốn của sự lựa chọn.
& lt; toán học & gt; \ langle B_, \ langle B_ \ ldots \ langle B_>, z \ rangle \ ldots \ rangle rangle & lt; / math & gt; được biểu thị là & lt; toán & gt; s: z \ & lt; / math & gt ;.
Z hoạt động như một sự tiếp tục của danh sách, có thể là một danh sách không (để kết thúc chuỗi) hoặc một chuỗi khác (sẽ được nối vào chuỗi ban đầu).
Phân cách với giới hạn chưa được định.
Độ phức tạp mô tả có hai hương vị riêng biệt, tùy thuộc vào việc đầu vào được xem là giới hạn hay không.
Hiểu được sự kết thúc của đầu vào giúp bạn mô tả các vật thể dễ dàng hơn. Ví dụ, bạn chỉ có thể sao chép toàn bộ đầu vào để đầu ra. Hương vị này được gọi là phức hợp đơn giản hoặc đơn giản.
Nhưng theo một nghĩa nào đó là thông tin bổ sung. Một hệ thống tập tin ví dụ cần lưu trữ riêng biệt chiều dài của các tập tin. Ngôn ngữ C sử dụng ký tự null để biểu thị sự kết thúc của một chuỗi nhưng điều này xảy ra với chi phí không có ký tự đó trong các chuỗi.
Các hương vị khác được gọi là phức tạp tiền tố, được đặt tên theo mã tiền tố, nơi máy tính cần phải tìm ra, từ đầu vào đọc cho đến nay, cho dù nó cần phải đọc thêm bit. Chúng tôi nói rằng đầu vào là tự giới hạn. Điều này hoạt động tốt hơn cho các kênh truyền thông, vì người ta có thể gửi nhiều mô tả, cái này đến cái khác, và vẫn nói với họ cách nhau.
Trong mô hình I / O của BLC, hương vị được quyết định bởi sự lựa chọn của z. Khi được giữ như là một biến tự do, và bắt buộc phải xuất hiện như một phần của đầu ra, thì máy phải làm việc theo cách tự giới hạn. Nếu mặt khác z là một thuật ngữ lambda được thiết kế đặc biệt để dễ dàng phân biệt với bất kỳ ghép nối nào thì đầu vào sẽ trở thành giới hạn. BLC chọn False cho mục đích này nhưng cho nó một cái tên khác thay thế mang tính mô tả của Nil. Đối phó với các danh sách có thể là Nil là đơn giản: kể từ.
& lt; math & gt; \ langle x, y rangle \ M \ N = M \ x \ y \ N & lt; / math & gt; & & lt; math & gt; Nil \ M \ N = N & lt; / math & gt;
người ta có thể viết các hàm M và N để đối phó với hai trường hợp, điều duy nhất là N sẽ được truyền cho M như là đối số thứ ba của nó.
Người ta có thể tìm thấy một phương pháp mô tả U sao cho bất kỳ phương pháp mô tả nào khác D, có một hằng c (chỉ phụ thuộc vào D) sao cho không đối tượng nào có nhiều hơn c bit thêm để mô tả bằng phương pháp U so với phương pháp D. BLC được thiết kế để làm cho các hằng số này tương đối nhỏ. Trong thực tế hằng sẽ là chiều dài của một mã hóa nhị phân của một D-trình biên dịch viết bằng BLC, và U sẽ là một thuật ngữ lambda phân tích mã hoá này và chạy thông dịch giải mã này trên phần còn lại của đầu vào. U thậm chí không cần biết liệu mô tả có bị giới hạn hay không; nó hoạt động cùng một trong hai cách.
BLC không chỉ đại diện cho bitstrings như thuật toán lambda, nhưng theo cách khác xung quanh là tốt.
Thứ nhất, các thuật ngữ lambda được viết bằng một ký hiệu cụ thể sử dụng các chỉ số được gọi là De Bruijn. Việc mã hóa sau đó được định nghĩa đệ quy như sau.
Ví dụ: chức năng ghép nối & lt; math & gt; \ lambda x \ lambda y \ lambda z. x z y & lt; / math & gt; được viết & lt; math & gt; \ lambda \ lambda \ lambda. 1 3 2 & lt; / math & gt; ở định dạng De Bruijn, có mã hóa & lt; math & gt; 00 \ 00 \ 00 \ 01 \ 01 \ 1010111 & lt; / math & gt ;.
Thuật ngữ lambda đóng là một trong đó tất cả các biến đều bị ràng buộc, nghĩa là không có bất kỳ biến số miễn phí. Trong định dạng De Bruijn, điều này có nghĩa là chỉ mục i chỉ có thể xuất hiện trong ít nhất lambdas lồng nhau. Số lượng các điều khoản khép kín có kích thước n bit được cho bởi trình tự Bản mẫu: OEIS2C của On-Line Encyclopedia of Integer Sequences.
Thuật ngữ đóng ngắn nhất có thể là chức năng nhận dạng & lt; math & gt; \ widehat = 0010 & lt; / math & gt ;. Trong chế độ phân cách, máy này chỉ sao chép đầu vào của nó vào đầu ra của nó.
Sau đó, máy phổ quát U trong BLC, ở định dạng De Bruijn (tất cả các chỉ số là một chữ số):
& lt; math & gt; (\ lambda 1 1) (\ lambda \ lambda \ lambda 1 (\ lambda \ lambda \ lambda \ lambda 3 (\ lambda 5 (3 (\ lambda 2 (3 (\ lambda \ lambda 3 (\ lambda 1 (1 (2 (lambda 1 2)) (4 (\ lambda 4 (\ lambda 3 1 (2 1))))) & lt; / math & gt; & gt; \ lambda 4 (\ lambda 2 (1 4))) 5)))) (3 3) 2) (\ lambda 1 ((\ lambda 1 1) (\ lambda 1 1))) & lt; / math & gt;
Đây là trong nhị phân:
0101000110100000000101011000000000011110000101111110011110 0001011100111100000011110000101101101110011111000011111000 0101111010011101001011001110000110110000101111100001111100 0011100110111101111100111101110110000110010001101000011010 (chỉ dài 232 bít (29 byte))
Một phân tích chi tiết về máy U có thể được tìm thấy ở đây. [1]
Nói chung, phức tạp của một đối tượng có thể có điều kiện trên một số đối tượng khác được cung cấp như một đối số bổ sung cho máy phổ quát. BLC định nghĩa độ phức tạp Plain (hoặc đơn giản) KS và phức tạp tiền tố KP bởi. Chương trình nhận dạng & lt; toán học & gt; \ lambda 1 & lt; / math & gt; chứng minh rằng.
Chương trình & lt; math & gt; \ lambda \ lambda 1 ((\ lambda 1 1) (\ lambda \ lambda \ lambda \ lambda 2 (4 4) (\ lambda \ lambda 3 2 (3 2 (2 (5 1 (2 1 ))) () \ lambda \ lambda 1) (\ lambda \ lambda \ lambda 1 (\ lambda 4 (\ lambda 4 (\ lambda 1 3 2)))) (\ lambda \ lambda \ lambda 1 (3 (\ lambda \ lambda 1)) 2) (\ lambda 1) 2 & lt; / math & gt; chứng minh rằng.
& lt; math & gt; (\ lambda 1 1) (\ lambda \ lambda \ lambda 1) (4 4 (lambda 4 (\ lambda \ lambda \ lambda 5 2 (5 2 (3 1 (2 1)))))) 4 (\ lambda 1))))) (\ lambda \ lambda \ lambda 1 (3 ((lambda 1 1) & lt; / math & gt; & lt; math & gt; (\ lambda \ lambda \ lambda \ lambda 1 (\ lambda 5 5 (\ lambda \ lambda 3 () \ lambda \ lambda 6 1 2) 3)) (\ lambda \ lambda 5 (\ lambda 1 4 3))) (3 1)) (\ lambda \ lambda 1 (\ lambda \ lambda 2) 2) (\ lambda 1)) (\ lambda \ lambda 1)) 2) & lt ; / math & gt;
\ overline & amp; = 0 \\ \ overline & amp; = 1 \ overline \ n \\ \ end & lt; / math & gt; trong đó chúng tôi xác định số và bitstrings theo thứ tự lexicographic. Mã này có thuộc tính tốt đẹp cho tất cả các k,
Hơn nữa, nó làm cho thứ tự lexicographic của con số giới hạn trùng với thứ tự số.
Xác suất dừng của máy phổ quát tiền tố được định nghĩa là xác suất nó sẽ xuất ra bất kỳ thuật ngữ nào có dạng đóng kín (bao gồm tất cả các chuỗi được dịch):
Với một số nỗ lực, chúng ta có thể xác định 4 bit đầu tiên của số trí tuệ đặc biệt này:
nơi mà xác suất Bản mẫu: Math đã được đóng góp bởi các chương trình Mẫu: Mono và Bản mẫu: Mono cho các thuật ngữ Đúng và Sai.
Trong khi các luồng bit là tốt đẹp trên lý thuyết, họ giá vé thấp trong interfacing với thế giới thực. Ngôn ngữ BLC8 là một biến thể thực tế hơn về BLC, trong đó các chương trình hoạt động trên một dòng byte, trong đó mỗi byte được biểu diễn như là một danh sách được phân cách của 8 bit theo thứ tự big-endian.
BLC trong IOCCC 2012.
Việc thực hiện cả hai BLC và BLC8 trong ngôn ngữ lập trình C đã giành được giải thưởng "Hầu hết các chức năng" trong phiên bản 2012 của Cuộc thi mã C ác Quốc tế.
<h1> Thông dịch viên tích phân lambda nhị phân </ h1>
Tải qua App Store Đọc bài đăng này trong ứng dụng của chúng tôi!
Làm thế nào để mô hình đầu ra của các tích phân lambda nhị phân?
Tôi đã viết mã để làm như sau:
Phân tích cú pháp nhập dữ liệu nhị phân vào một số cấu trúc dữ liệu đại diện cho phép tính lambda không được định dạng thông thường Beta - giảm thuật ngữ này.
Chuyện gì xảy ra sau đó?
Làm thế nào là "đầu ra" giải nghĩa? Là đầu ra a) kết quả được dịch trở lại thành nhị phân thông qua cùng một mã hóa, hoặc b) bitstream mã hoá bởi một danh sách các phép toán luận kết cuối sai? (Và điều gì sẽ xảy ra nếu đầu ra không tạo thành một danh sách như vậy?)
Hay tôi hiểu nhầm cách BLC hoạt động?
Tôi muốn đề nghị sử dụng http://www. ioccc. org/2012/tromp/hint. html làm tài liệu tham khảo chính của bạn. Trang Wikipedia có thể là tốt, nhưng những ghi chép ban đầu của ông về BLC khá tốt.
Về chủ đề đầu vào và đầu ra, ông có điều này để nói:
Cụ thể hơn, nó định nghĩa một máy phổ quát, từ một luồng đầu vào của các bit, phân tích mã nhị phân của thuật toán lambda, áp dụng cho phần còn lại của đầu vào (được dịch sang một danh sách lười biếng của các phép toán luận, trong đó có một biểu diễn tiêu chuẩn trong lambda calculus), và dịch kết quả đánh giá trở lại vào một dòng bit để được đầu ra.
Cú pháp.
Có ba loại biểu thức sau đây:
Một biểu thức lambda có dạng (λ x. E) trong đó x có thể là bất kỳ tên biến pháp lý nào và e bất kỳ biểu thức pháp lý nào. Ở đây x được gọi là tham số và e được gọi là thân hàm.
Để đơn giản, chúng ta thêm một hạn chế nữa là không phải có một biến có cùng tên với x hiện đang ở trong phạm vi. Một biến bắt đầu nằm trong phạm vi khi tên của nó xuất hiện giữa (λ và. Và dừng ở trong phạm vi tương ứng).
Một chức năng được áp dụng bằng cách thay thế mỗi lần xuất hiện của tham số trong cơ thể chức năng với đối số của nó. Biểu thức của form ((λ x. E) a), trong đó x là một tên biến và e và a là các biểu thức, đánh giá (hoặc giảm) với biểu thức e 'trong đó e' là kết quả của việc thay thế mỗi lần xuất hiện của x trong e với a.
Một dạng bình thường là một biểu hiện không thể đánh giá được nữa.
Nhiệm vụ của bạn, nếu bạn chọn chấp nhận nó, là viết một thông dịch viên lấy dữ liệu đầu vào của nó là biểu hiện của phép toán lambda không có chứa giá trị không chứa các biến tự do và tạo ra dạng xuất hiện của biểu thức (hoặc một biểu thức alpha-đồng nhất với nó) . Nếu biểu thức không có hình thức bình thường hoặc nó không phải là một biểu hiện hợp lệ, hành vi đó là không xác định.
Giải pháp với số lượng ký tự nhỏ nhất thắng.
Một vài ghi chú:
Đầu vào có thể được đọc từ stdin hoặc từ một tên tập tin được đưa ra như một đối số dòng lệnh (bạn chỉ cần thực hiện một hoặc khác - không phải cả hai). Đầu ra đi vào thiết bị xuất chuẩn. Ngoài ra, bạn có thể định nghĩa một hàm lấy input như một chuỗi và trả về kết quả dưới dạng một chuỗi. Nếu các ký tự không phải ASCII là vấn đề đối với bạn, bạn có thể sử dụng dấu gạch chéo ngược (\) thay vì λ. Chúng tôi đếm số ký tự chứ không phải byte, vì vậy ngay cả khi tệp nguồn của bạn được mã hoá dưới dạng số ký tự unicode λ là một ký tự. Tên biến pháp luật bao gồm một hoặc nhiều chữ thường, nghĩa là các ký tự giữa a và z (không cần hỗ trợ tên chữ số, chữ hoa hay chữ cái không phải la tinh). Đối với thách thức này, không có dấu ngoặc đơn là tùy chọn. Mỗi biểu thức lambda và mỗi ứng dụng chức năng sẽ được bao quanh bởi chính xác một cặp ngoặc đơn. Không có tên biến nào sẽ được bao quanh bởi dấu ngoặc đơn. Không giống như cách viết đường như cú pháp (λ x y. E) cho (λ x. (Λ y. E)) không cần phải hỗ trợ. Nếu yêu cầu chiều sâu đệ quy đến hơn 100 là cần thiết để đánh giá một hàm, hành vi đó sẽ không được xác định. Điều này cần phải được thực hiện mà không có tối ưu hóa ở tất cả các ngôn ngữ và vẫn đủ lớn để có thể thực hiện hầu hết các biểu thức. Bạn cũng có thể cho rằng khoảng cách sẽ như trong các ví dụ, tức là không có dấu cách ở đầu và cuối của đầu vào hoặc trước một λ hoặc. và chính xác một không gian sau khi a. và giữa một hàm và đối số của nó và sau một λ.
Mẫu đầu vào và đầu ra.
Đầu vào: ((x, x) (λ y (λ z. Z)))
Đầu ra: (λ y (λ z. Z))
Đầu vào: (λ x. ((Λ y. Y) x))
Đầu vào: ((λ x. (Λ y. X)) (λ a. A))
Đầu ra: (λ y. (Λ a. A))
Dữ liệu đầu vào: (((λ x. (Λ y. X)) (λ a. A)) (λ b. B)
Đầu vào: ((λ x. (Λ y. Y)) (λ a. A))
Đầu vào: ((λ x. (Λ y.)) (Λ a. A)) (λ b.)
Đầu ra: bất cứ điều gì (Đây là một ví dụ về một biểu thức không có hình thức bình thường)
Dữ liệu đầu vào: ((λ x. (Λ y. X)) (λ a. A)) ((λx. (X x)) (λx. (X x))))
Output: (λ a. A) (Đây là một ví dụ về một biểu thức không bình thường nếu bạn đánh giá các đối số trước khi gọi hàm, và thật đáng tiếc là một ví dụ mà giải pháp đã cố gắng của tôi không thành công)
Dữ liệu đầu vào: ((λ a. (Λ b. (A (a (a b))))) (λ c (λ d. (C (c d)))))
Kết quả: `(λ a. (Λ b. (A (a (a (a (a (a (a (a (a b)))))))))) Tính toán 2 ^ 3 trong các chữ số của Nhà thờ.
Python - 321 320.
Đây là nỗ lực (cố định) của tôi:
Tôi đã vắt nó xuống 644 ký tự, tôi phần yếu tố của cEll vào cOpy và Par; lưu trữ các cuộc gọi đến cell và cdr thành các biến địa phương tạm thời, và chuyển các biến địa phương sang globals trong các hàm "terminal" (tức không đệ quy). Ngoài ra, các hằng số thập phân ngắn hơn literals ký tự và điều này kinh doanh khó chịu.
. xác định chính xác chữ thường (giả sử ASCII), nhưng cũng chấp nhận bất kỳ `
. (Sự quan sát tương tự về ASCII được thực hiện trong video tuyệt vời này về UTF-8.)
Tôi có thể nhận được một vài phiếu bầu cho nỗ lực? Tôi đã làm việc trong ngày và đêm này trong một tuần. Tôi đã khám phá ra bản gốc của bài báo McCarthy và bị một lỗi trong bản thân nó cho đến khi tôi đọc phần phụ lục của The Roots of Lisp của Paul Graham. Tôi đã bị phân tâm đến nỗi tôi tự nhốt mình trong căn nhà của mình, rồi hoàn toàn quên mất khi về đến nhà vào lúc 12 giờ 30 (chậm trễ để gọi người quản lý tòa nhà đang sống ở quận hạt) và phải chi tiêu đêm ở bà tôi (hacking cho đến khi pin máy tính xách tay của tôi là khô).
Và sau tất cả những điều đó, nó thậm chí không gần với mục nhập chiến thắng!
Tôi không chắc làm thế nào để làm cho bất kỳ điều này ngắn hơn; và tôi đã sử dụng tất cả các thủ đoạn bẩn tôi có thể nghĩ đến! Có lẽ nó không thể được thực hiện trong C.
Với một số lượng quảng đại trong đếm (đoạn đầu tiên lấy một chuỗi và in ra kết quả), đó là 778 770 709 694 ký tự. Nhưng để làm cho nó độc lập, nó phải có cuộc gọi sbrk. Và để xử lý các biểu thức phức tạp hơn, nó cũng cần xử lý tín hiệu. Và tất nhiên nó không thể được thực hiện thành một mô-đun với bất kỳ mã mà cố gắng sử dụng malloc.
Vì vậy, than ôi, đây là:
Đây là khối ngay trước khi cắt giảm cuối cùng. Các thủ thuật ở đây là các con trỏ số nguyên thay vì con trỏ (lợi dụng hành vi 'implicit int'), và việc sử dụng 'bộ nhớ đầu': char * n là con trỏ 'mới' hoặc 'tiếp theo' vào không gian trống. Nhưng đôi khi tôi viết một chuỗi vào bộ nhớ, sau đó gọi strlen và tăng n; hiệu quả sử dụng bộ nhớ và sau đó phân bổ nó, sau khi kích thước được dễ dàng hơn để tính toán. Bạn có thể thấy nó khá thẳng thắn từ bài báo McCarthy, ngoại trừ tế bào () có giao diện giữa các hàm và biểu diễn chuỗi dữ liệu.
Hệ số nhị phân Lambda 186.
Chương trình được hiển thị trong bãi chứa hex bên dưới.
không chấp nhận định dạng bạn đề xuất. Thay vào đó, nó mong đợi một thuật ngữ lambda trong định dạng lambda nhị phân (blc) nhị phân. Tuy nhiên, nó cho thấy tất cả các bước đơn giản trong việc giảm dạng bình thường, sử dụng dấu ngoặc đơn tối thiểu.
Ví dụ: tính toán 2 ^ 3 trong các chữ số của Nhà thờ.
Lưu dữ liệu trên hex với xxd - r> symbolic. Blc.
Lấy một thông dịch viên blc từ http://www. cwi. nl/
Kể từ hexdump là khá không thể đọc được, đây là một phiên bản "tháo rời".
thay thế 00 (lambda) bằng \ và 01 (ứng dụng) với @ Bây giờ nó gần như có thể đọc được như là brainfuck :-)
Haskell, 342 323 317 305 ký tự. Khi viết bài này, đây là giải pháp duy nhất đánh giá ((λ f. (Λ x. (Fx))) (λ y. (Λ x. Y)) đến kết quả chính xác (λ x. (Λ z. x)) thay vì (λ x. (λ x. x)). Việc thực hiện đúng phép toán lambda đòi hỏi sự thay thế tránh chụp, ngay cả dưới sự đảm bảo đơn giản của vấn đề này, rằng không có biến nào làm biến đổi một biến khác trong phạm vi của nó. (Chương trình của tôi xảy ra để làm việc thậm chí không có đảm bảo này.)
Điều này chạy trong GHC 7.0, theo yêu cầu vì thử thách này đã được thiết lập vào tháng 1 năm 2011. Nó sẽ ngắn hơn 13 ký tự nếu tôi được phép thừa nhận GHC 7.10.
Nó có thể được sử dụng như.
Giải pháp chưa hoàn toàn được chơi golf nhưng đã gần như không thể đọc được.
Chỉnh sửa: kiểm tra câu trả lời của tôi dưới đây cho 250 theo nguyên bản JavaScript.
2852 243 ký tự sử dụng LiveScript (Không Regex Không chơi golf hoàn toàn - có thể được cải thiện)
Đó là 3 ^ 2 = 9, như đã nêu trên OP.
Nếu có ai tò mò, đây là một phiên bản mở rộng với một số ý kiến:
Waterhouse Arc - 140 ký tự.
Nó có thể được ngắn hơn nhiều nếu tính năng đánh giá lười biếng của Haskell được sử dụng đầy đủ. Đáng buồn, tôi không biết làm thế nào để làm điều đó.
Ngoài ra, nhiều nhân vật bị lãng phí trong bước phân tích cú pháp.
Các biến cho phép nhập dữ liệu bằng chữ thường [từ a..z] sys có thể tạo ra các biến bằng chữ hoa [từ A..Z] nếu cần ở đầu ra. Giả sử cấu hình ký tự ascii.
Got 231 với JavaScript / không Regex.
Nhận mảng 2 phần tử. 1 là viết tắt của λ và 2 là viết tắt của một biến chỉ số bruijn.
Phiên bản này không sử dụng các biến phụ (vì thế không theo 100% kết luận của lambda) như nhiều phiên bản khác ở đây. Mỗi biến phải dài 1 chararcter (như một số khác ở đây). Mã kiểm tra:
Không có nhận xét nào:
Đăng nhận xét
Lưu ý: Chỉ thành viên của blog này mới được đăng nhận xét.