Perl,516504字节
包括2x +1 -p
@l=map{length}/\w+/g;s/\w/$c{$&}++/eg;@h=map{"$_$c{$_}"}keys%c;$_="@h @l";chomp(@w=`cat w.txt`);s/([A-Z])1//;$o=$1;s/(\w)(\d)/$h{$1}=$2,''/eg;@L=/\d/g;$l=shift@L;@O=$_,s/^.//,g([@L],%h)&&last for grep{$l==length&&/^$o/i&&h(\%h,substr$_,1)}@w;$_="@O.";s/^./uc$&/e;sub g{my%g;($R,%g)=@_;my@R=@$R;if($j=shift@R){s/./$g{$&}--/eg;my@C=grep{$j==length&&h(\%g,$_)}@w;push(@O,$_),g([@R],%g)and return 1 or pop@O for@C;0}else{1}}sub h{($y,$z)=@_;my%T;$z=~s/\w/$T{$&}++/eg;$K=1;$K&=$T{$_}<=$y->{$_}for keys%T;$K}
要求w.txt
采用Unix格式(\n
行尾)。用于cat
读取文件;更改type
为Windows。
将上述oneliner保存在中534.pl
并以方式运行echo Test. | perl -p 534.pl
。
很大,但是这是一个开始-很多打高尔夫球的机会,但是我只是想发布它,以使LabVIEW的回答不再那么孤单;-)。我省略了亚秒级执行的优化,节省了30多个字节。
第一个片段(73个字节):
@l=map{length}/\w+/g;s/\w/$c{$&}++/eg;@h=map{"$_$c{$_}"}keys%c;$_="@h @l"
它以紧凑格式生成直方图和单词长度。对于输入,Zulus win.
它将生成不带的2型输出(,)
,这里不需要:
s1 l1 u2 Z1 w1 i1 n1 5 3
这是无高尔夫球的:
sub i{
$_=shift; # get parameter
@l = map{length} /\w+/g; # cound word lengths
s/\w/$c{$&}++/eg; # count letters in hash %c
@h=map{"$_$c{$_}"}keys%c; # construct letter-frequency pairs
"@h @l" # implicit interpolation with $" (space) separator
}
第二段(441字节)
与I / O这主要部分涉及的第一个字母的特殊处理,使用子程序g
和h
下面列出。
sub o {
$_=shift;
chomp(@w=`cat w.txt`); # load the wordlist.
s/([A-Z])1//; $o=$1; # get and remove the uppercase character,
s/(\w)(\d)/$h{$1}=$2,''/eg; # reconstruct histogram in hash %h.
@L=/\d/g; # get the word counts.
$l = shift @L; # get the first word length.
@O = $_, # initialize output with first word,
s/^.//, # strip first char of word
g([@L],%h) && last # call the main algoritm and quit on success
for grep {
$l==length && # check length
/^$o/i && # only match words starting with the uppercase char
h(\%h,substr$_,1) # check if the word satisfies the histogram
} @w; # iterates all words (speedups removed).
$_="@O."; # construct output sentence.
s/^./uc$&/e; # make first char uppercase.
$_
}
此递归函数获取直方图的副本,剩余单词计数的副本以及当前单词。如果字长数组为空,则返回true。否则,它将减少给定单词中字母的直方图计数,获取下一个单词的长度,并从单词列表中找到合适单词的列表。对于每个合适的词,它都会递归。
sub g {
my%g; # local version of histogram
($R,%g)=@_; # get parameters.
my@R=@$R; # dereference arrayref copy of word lengths.
if($j=shift @R) # get the next word-length.
{
s/./$g{$&}--/eg; # update histogram
my @C = # get a list of suitable words.
grep { $j==length && h(\%g,$_) }
@w;
push(@O,$_), # append word to output
g( [@R], %g ) # recurse.
and return 1 # true: append word we're done.
or pop @O # remove word from output
for @C # (for some reason the @C=grep doesn't work here)
;0
} else { 1 } # no more words, done!
}
最后,给该子例程一个单词和一个句子的直方图。它为单词计算一个新的直方图,并检查是否所有字母出现的次数都不超过句子直方图所允许的次数。
# check if first histogram is within bounds of second
sub h{
($y,$z)=@_;
my%T; $z =~ s/\w/$T{$&}++/eg; # calc histogram
$K=1;
$K &= $T{$_} <= $y->{$_}
for keys %T;#$_[0];
$K
}
您可以将取消定位的代码段(sub i/o/g/h
)粘贴到单个文件中,并附加以下测试代码。
sub t {
print $i=i(shift),$/,o($i),$/x2;
%c=%h=@L=@X=@O=();
}
t "Test."; # Test.
t "Zulus win."; # Zulus win.
t "Happy solstice."; # Happy solstice.
t "Abash abel mammal test."; # Abase alms embalm that.
t "Dovecot flagships oleander."; # Dangled horoscope festival.
t 'This code requires further golfing.';# Tech deer fighting ferrous liquors.
- 更新504:保存12个字节,消除
substr
和的参数sub g
。