Hacker News new | past | comments | ask | show | jobs | submit login

Here's < 15 lines, clear, but not functional programming :)

  #!/usr/local/bin/perl
  #borrowed from Nick Holloway <alfie@dcs.warwick.ac.uk>, 27th May 1993.
  my $size=8;my @cols=(0..$size-1);
  sub nextq {
      (print( "@_\n" ),return) if @_ == $size;
      foreach my $col(@cols) {
          next if grep($_ == $col, @_);
          my $row=@_;next if grep ($_ == $col-$row--, @_);
          my $row=@_;next if grep ($_ == $col+$row--, @_);
          nextq(@_,$col);
      }
  }   
  nextq();
Not sure if it's slower or more resource intensive than the Scala solution. I'm sure it could be golfed down to be smaller than the Scala counterpart. It has fewer characters already, even with the comments intact.



Indeed, it has been golfed: http://www.perlmonks.org/?node_id=196582

    -l /.{@ARGV}/?print:map/((.).*)(.)(??{$2!=$3&&length$1!=abs$2-$3&&0})/||do$0,$_.1.."$_@ARGV"


That's frightening. I hate to ask, but is that representative of Perl code?


No. Golf is a game where the winner has the lowest score. It's reused as the term for a programming challenge to implement an algorithm with the fewest number of characters. See https://en.wikipedia.org/wiki/Perl#Perl_pastimes .

This is no more indicative of Perl than the Obfuscated C contest is indicative of C.


Not at all, but it is representative of the best of Perl culture: smart people who enjoy playing with unexpected corners of a complex system, while remembering the difference between "work" and "play." See Ton Hospel's insane Roman numeral calculator: http://perlmonks.org/?node_id=594299


Javascript anyone?

    !function r(y,a,z,b,x){for(x=y--?-1:print(a);++x<n;z&c|b&d||r(y,a+1?a+' '+x:x,z|c,b|d))c=(1|1<<y+9)<<x,d=1<<9+x-y}(n=readline())
http://golf.shinh.org/reveal.rb?N+Queens/murky-satyr_1217229...


It's actually more lines than it appears since the author has concatenated lines with a semi-colon:

   my $size=8;my @cols=(0..$size-1);
   my $row=@_;next if grep ($_ == $col-$row--, @_);
   my $row=@_;next if grep ($_ == $col+$row--, @_);
Strictly speaking that's 6 lines of code concatenated into 3.

But as you said, it would be relatively easy to golf that down and still keep the program logic.


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.


The lack of whitespace is maddening. It contributes to the reputation that Perl is write once read never.

That "print and return with postfix" is the gold star. /s


The context being a deliberate effort to make it compact. You can abuse features in most languages and make it hard to read.


Who cares about "compactness"? You weren't golfing. It just sticks out as bad code.


Not my code, it was copied (note the attribution) from a specific context where somebody cared about compactness.

Edit: Perl's also not the only language that supports the comma operator, predicate if, ternary, and other things that seem to bother you.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: