Perl being big on "more than one way to do things...", semicolons are easy to discard:
sub nextq {
my $sz=8;
(print("@_\n"),return) if @_ == $sz;
foreach my $col(0..$sz-1) {
my $row;
if (grep($_==$col,@_)) {next} else {$row=@_}
if (grep($_==$col-$row--,@_)) {next} else {$row=@_}
if (grep($_==$col+$row--,@_)) {next} else {$row=@_}
nextq(@_,$col);
}
}
nextq();I still feel that's cheating as you're just replacing the semi-colon with braced blocks; effectively it's still being parsed as multiple lines.
I was thinking more along the lines of using the one line conditional:
condition ? first_expression : second_expression;
eg sub nextq {
(print( "@_\n" ),return) if @_ == (my $size = 8);
foreach my $col(0..$size-1) {
my ($row, $next);
grep ($_ == $col, @_) ? $next=1 : $row=@_;
grep ($_ == $col-$row--, @_) ? $next=1 : $row=@_;
grep ($_ == $col+$row--, @_) ? $next=1 : $row=@_;
nextq(@_,$col) unless $next;
}
}
nextq();
The `$next` ugliness is due to not being allowed to use the `next` inside a one line conditional. There's probably cleaner ways of doing the above though. But that was only a quick hack.It's almost as if "number of lines" isn't particularly meaningful.
I agree but we've already done that argument to death (eg the Plan 9 vs GNU debates about code "complexity")
This sort of line counting is just for fun.
Smaller without being obfuscated:
sub nextq {
my $sz=8;
(print("@_\n"),return) if @_ == $sz;
o: foreach my $col(0..$sz-1) {
my($u,$d)=(scalar(@_),scalar(@_));
for (@_) {next o if($_==$col or $_==$col-$u-- or $_==$col+$d--)}
nextq(@_,$col);
}
}
nextq();Personally I'd consider 1 and 2 character variable names as a form of obfuscation. eg what's the point having a "pseudo-constant" for size if it's named in such a way that isn't immediately obvious that it refers to the size.
Nice code though.
But as you said, it would be relatively easy to golf that down and still keep the program logic.