Thách thức là viết một trình thông dịch cho phép tính lambda chưa được gõ trong càng ít ký tự càng tốt. Chúng tôi xác định phép tính lambda chưa được xử lý như sau:
Cú pháp
Có ba loại biểu thức sau:
Một biểu thức lambda có dạng
(λ x. e)
nơix
có thể là bất kỳ tên biến pháp luật vàe
bất kỳ biểu hiện quy phạm pháp luật. Ở đâyx
được gọi là tham số vàe
được gọi là thân hàm.Để đơn giản, chúng tôi thêm một hạn chế nữa là không được có một biến có cùng tên như
x
hiện tại trong phạm vi. Một biến bắt đầu được trong phạm vi khi tên của nó xuất hiện ở giữa(λ
và.
và dừng lại được trong phạm vi ở tương ứng)
.- Ứng dụng chức năng có dạng
(f a)
nơif
vàa
là biểu pháp lý. Ở đâyf
được gọi là hàm vàa
được gọi là đối số. - Một biến có dạng
x
trong đóx
là một tên biến hợp pháp.
Ngữ nghĩa
Một hàm được áp dụng bằng cách thay thế từng lần xuất hiện của tham số trong thân hàm bằng đối số của nó. Chính thức hơn một biểu hiện của hình thức ((λ x. e) a)
, nơi x
là một tên biến và e
và a
là những biểu hiện, đánh giá lại (hoặc giảm) để biểu thức e'
mà e'
là kết quả của việc thay thế từng xảy ra x
trong e
với a
.
Một hình thức bình thường là một biểu thức không thể được đánh giá thêm.
Các thách thức
Nhiệm vụ của bạn, nếu bạn chọn chấp nhận nó, là viết một trình thông dịch lấy đầu vào là biểu thức của phép tính lambda chưa được xử lý không chứa biến tự do và tạo ra dạng đầu ra của biểu thức (hoặc biểu thức alpha đồng dạng với biểu thức) . Nếu biểu thức không có dạng bình thường hoặc nó không phải là biểu thức hợp lệ, hành vi không được xác định.
Giải pháp với số lượng ký tự nhỏ nhất sẽ thắng.
Một vài lưu ý:
- Đầu vào có thể được đọc từ stdin hoặc từ tên tệp được cung cấp dưới dạng đối số dòng lệnh (bạn chỉ cần thực hiện cái này hoặc cái kia - không phải cả hai). Đầu ra đi đến thiết bị xuất chuẩn.
- Ngoài ra, bạn có thể định nghĩa một hàm lấy đầu vào là một chuỗi và trả về đầu ra dưới dạng một chuỗi.
- Nếu các ký tự không phải ASCII có vấn đề với bạn, bạn có thể sử dụng
\
ký tự dấu gạch chéo ngược ( ) thay vì. - Chúng tôi đếm số lượng ký tự, không phải byte, vì vậy ngay cả khi tệp nguồn của bạn được mã hóa dưới dạng unicode λ tính là một ký tự.
- Tên biến hợp pháp bao gồm một hoặc nhiều chữ cái viết thường, tức là các ký tự giữa a và z (không cần hỗ trợ tên chữ và số, chữ in hoa hoặc chữ cái không phải là chữ Latinh - tất nhiên, mặc dù vậy sẽ không làm mất hiệu lực giải pháp của bạn).
- Theo như 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 dấu ngoặc đơn. Không có tên biến sẽ được bao quanh bởi dấu ngoặc đơn.
- Đường cú pháp như viết
(λ x y. e)
cho(λ x. (λ y. e))
không cần phải được hỗ trợ. - Nếu độ sâu đệ quy hơn 100 được yêu cầu để đánh giá một hàm, hành vi không được xác định. Điều đó phải đủ thấp hơn đủ để được thực hiện mà không cần tối ưu hóa trong 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ể giả định rằng khoảng cách sẽ như trong các ví dụ, nghĩa là không có khoảng trắng ở đầu và cuối của đầu vào hoặc trước một
λ
hoặc.
chính xác một khoảng trắng sau một.
và giữa một hàm và đối số của nó và sau aλ
.
Đầu vào và đầu ra mẫu
Đầu vào:
((λ x. x) (λ y. (λ z. z)))
Đầu ra:
(λ y. (λ z. z))
Đầu vào:
(λ x. ((λ y. y) x))
Đầu ra:
(λ x. x)
Đầu vào:
((λ x. (λ y. x)) (λ a. a))
Đầu ra:
(λ y. (λ a. a))
Đầu vào:
(((λ x. (λ y. x)) (λ a. a)) (λ b. b))
Đầu ra:
(λ a. a)
Đầu vào:
((λ x. (λ y. y)) (λ a. a))
Đầu ra:
(λ y. y)
Đầu vào:
(((λ x. (λ y. y)) (λ a. a)) (λ b. b))
Đầu ra:
(λ b. b)
Đầu vào:
((λx. (x x)) (λx. (x x)))
Đầu ra: bất cứ điều gì (Đây là một ví dụ về biểu thức không có dạng bình thường)
Đầu vào:
(((λ x. (λ y. x)) (λ a. a)) ((λx. (x x)) (λx. (x x))))
Đầu ra:
(λ a. a)
(Đây là một ví dụ về biểu thức không bình thường hóa nếu bạn đánh giá các đối số trước lệnh gọi hàm và đáng buồn là một ví dụ về giải pháp đã thử của tôi không thành công)Đầu vào:
((λ a. (λ b. (a (a (a b))))) (λ c. (λ d. (c (c d)))))
Đầu ra:
`(λ a. (λ b. (a (a (a (a (a (a (a (a b))))))))))
Điều này tính 2 ^ 3 bằng chữ số Church.
(\y. a)
.