Perl, 39 37 35 byte
(Đầu tiên mô tả một phiên bản cũ hơn. Chương trình ngắn hơn mới ở cuối)
Bao gồm +3 cho -alp
Chạy với bộ ký tự trên STDIN, vd perl -alp kleene.pl <<< "a b c"
kleene.pl
(phiên bản này là 34 + 3 byte):
$#a=$"=","}for(@a){push@a,<{@F}$_>
Thêm +2 cho -F
(thả ẩn -a
nếu không có khoảng trắng giữa các ký tự đầu vào hoặc -6 (chỉ@a=""
trước đó }
) nếu chúng tôi đã đặt dấu phẩy giữa các ký tự trên STDIN
Giải trình:
Các -alp
tùy chọn làm cho mã hiệu quả:
BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined($_ = <ARGV>)) {
chomp $_;
our @F = split(' ', $_, 0);
$#a = $" = ',';
}
foreach $_ (@a) {
use File::Glob ();
push @a, glob('{' . join($", @F) . '}' . $_);
}
Bạn có thể thấy <>
trong perl không chỉ được sử dụng cho readline, mà còn có thể thực hiện toàn cầu kiểu vỏ (thực tế trong các perls cổ đại, nó đã được thực hiện bằng cách gọi shell).
Ví dụ <{a,b}{1,2}>
sẽ mở rộng sang"a1","a2","b1","b2"
Vì vậy, nếu chúng ta có các phần tử trong @F
chúng ta chỉ cần thêm dấu phẩy vào giữa. Mặc định giữa các ký tự cho phép nội suy là khoảng trắng, được lưu trữ trong biến đặc biệt $"
. Vì vậy, việc thiết $"
để ,
sẽ biến "{@F}"
thành {a,b}
nếu@F=qw(a b)
(các chuỗi mở rộng dưới dạng chuỗi)
Trong thực tế, tôi thực sự muốn lặp lại với một cái gì đó như glob"{@F}"x$n++
, nhưng tôi tiếp tục gặp phải vấn đề là dòng trống đầu tiên không được tạo và tất cả các cách giải quyết mà tôi tìm thấy đã tạo ra mã quá dài.
Vì vậy, một phần thiết yếu khác của mã này là nếu bạn sử dụng một for
vòng lặp trên một mảng, bạn thực sự có thể đẩy các phần tử bổ sung trên nó trong vòng lặp và vòng lặp cũng sẽ nhận các phần tử mới này. Vì vậy, nếu trong vòng lặp, chúng ta ví dụ như ở phần tử "ab"
, thì nó <{@F}$_>
sẽ mở rộng đến <{a,b}ab>
trong bối cảnh danh sách trở thành ("aab", "bab")
. Vì vậy, nếu tôi đẩy chúng lên @a
thì các chuỗi mở rộng sang bên trái cũng trở nên khả dụng
Tất cả những gì tôi vẫn cần làm là hoàn thành vòng lặp với một chuỗi rỗng. Điều đó được thực hiện bằng cách sử dụng $#a = 0
( ,
trong bối cảnh số trở thành 0
), điều này khiến cho phần tử đầu tiên và duy nhất @a
trở thành undef sẽ hoạt động như thế nào""
khi tôi sử dụng nó
Cải thiện
Trong thực tế bằng cách thực hiện các bài kiểm tra cho lời giải thích này, tôi đã tìm thấy một cách ngắn để sử dụng một quả cầu đang phát triển xử lý đúng mục nhập trống đầu tiên. Chạy dưới dạng perl -ap kleene0.pl <<< "a b"
(vì vậy thêm 2 byte cho -ap
)
kleene0.pl
(phiên bản này là 33 + 2 byte):
$"=",";print<$z,>;$z.="{@F}";redo
Tất cả các giải pháp này sẽ giữ ngày càng nhiều đầu ra trong bộ nhớ và điều đó sẽ khiến chương trình bị lỗi sau một thời gian. Bạn cũng có thể sử dụng perl globs cho thế hệ lười biếng bằng cách sử dụng chúng trong ngữ cảnh vô hướng, nhưng điều đó làm cho các chương trình dài hơn ....