in reply to Golf: Sudoku solving

Mark Byers created a wonderful Shortest Sudoku Solver page, showing shortest Sudoku solvers in many different languages, but the old link seems to be broken now. I remember being amused at the time to notice that several different folks whittled the Perl solution from 188 to 187 to 185 to 184 ... and then along came Ton Hospel and chopped it straight down to around 120! It's sort of deflating when thospel does that to you. :-)

Update: original link courtesy of the Wayback Machine (Aug 2007). The original shortest was based on a version by "Eccles & Toad":

use integer;@A=split//,<>;sub R{for$i(0..80){next if$A[$i];my%t=map{$_ +/9==$i/9||$_%9==$i%9||$_/27==$i/27&&$_%9/3==$i%9/3?$A[$_]:0=>1}0..80; +R($A[$i]=$_)for grep{!$t{$_}}1..9;return$A[$i]=0}die@A}R
Here is the audit trail of shortenings:
* Original Eccles & Toad solution (slightly modified) * Mark Byers reduced it to 187 bytes * Gordon McCreight reduced it to 186 bytes * Pablo Carbonell reduced it to 181 bytes * Simon Stroh changed @A=split//,<> to $/=\1;@A=<> to reduce the prog +ram to 179 bytes * Mitsuru Kariya changed @A[map{ ... }] to map@A[ ... ] to reduce th +e program to 178 bytes * Ton Hospel shortened the program to 121 bytes
Ton Hospel's 121 stroke solver:
$_=$`.$_.$'.<>;split//;${/[@_[map{$i-($i="@-")%9+$_,9*$_+$i%9,9*$_%26+ +$i-$i%27+$i%9-$i%3}0..8]]/o||do$0}for/0/||print..9
which can be reduced to 120 bytes, at the cost of using large amounts of memory:
$_=$`.$_.$'.<>;split//;map{/[@_[map{$i-($i="@-")%9+$_,9*$_+$i%9,9*$_%2 +6+$i-$i%27+$i%9-$i%3}0..8]]/o||do$0}/0/||print..9

Replies are listed 'Best First'.
split//; (Re^2: Golf: Sudoku solving)
by brx (Pilgrim) on Jan 11, 2013 at 08:53 UTC
    $_=$`.$_.$'.<>;split//;${/[@_[map{$i-($i="@-")%9+$_,9*$_+$i%9,9*$_%26+ +$i-$i%27+$i%9-$i%3}0..8]]/o||do$0}for/0/||print..9

    Dear Monks, I need your help

    I don't understand the "split" statement: no return value, apparently no side effect. Reading split was not helpful... :-/

    Another thing: this solver works fine on debian but loop on win xp (strawberryperl

    UPDATE (solved):Thanks to BrowserUk, tobyink and eyepopslikeamosquito. Very clear and fast answers. FYI, in my case, difference between debian and winxp was in fact, between perl 5.8.8 and

    English is not my mother tongue.
    Les tongues de ma mère sont "made in France".

      Perhaps this explains it:

      C:\test>\perl32\bin\perl -wnle"print $]; split; print join '|', @_" Use of implicit split to @_ is deprecated at -e line 1. evry good boy deserves food 5.008009 evry|good|boy|deserves|food C:\test>\perl64\bin\perl -wnle"print $]; split; print join '|', @_" Use of implicit split to @_ is deprecated at -e line 1. the quick brown foox 5.010001 the|quick|brown|foox Terminating on signal SIGINT(2) Terminating on signal SIGINT(2) C:\test>perl -wnle"print $]; split; print join '|', @_" Useless use of split in void context at -e line 1. evry good boy deserves food 5.016001

      As you can see, in 5.8 and 5.10, split in a void context was deprecated, but it put its results into @_;

      Somewhere between 5.10 and 5.16, the deprecation was enforced and that facility was removed. Which mean your golf script no longer works.

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        The @_ feature was removed in Perl 5.12, but was mistakenly omitted from the perl5120delta perldoc page. There's an errata towards the end of perl5140delta.

        This Perl upgrade added three strokes to youreverybody's golf handicap, but in fairness the say feature from Perl 5.10 greatly improved our golfing experience, so we shouldn't be too upset.

        update: didn't mean to imply that BrowserUk in particular was upset by this change.

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      For Perl up to and including 5.10, calling split in scalar or void context had the side-effect of setting @_. This mis-feature was removed in Perl 5.12. That was great news for most Perl programmers because this side-effect "feature" was unnecessary, an ugly wart. It was sad news for golfers though because side-effects are frequently useful in golf. In fact, I recently experienced a similar split annoyance in Compression in Golf: Part III, as described in the "Fun with split" section in that node.

      Simply changing @_ to @z say should fix thospel's original solution at the cost of three strokes:

      $_=$`.$_.$'.<>;@z=split//;${/[@z[map{$i-($i="@-")%9+$_,9*$_+$i%9,9*$_% +26+$i-$i%27+$i%9-$i%3}0..8]]/o||do$0}for/0/||print..9
      I expect you could do better than that, though I haven't tried.