<rss version='2.0'><channel><title>Juho Snellman's Weblog</title><link>http://jsnell.iki.fi/blog/</link><description>Lisp, Perl Golf</description><item><title>Feed moving</title><link>http://jsnell.iki.fi/blog/archive/2006-01-04-feed-moving.html</link><description>

&lt;p&gt;I&#039;ve moved my blog away from the &lt;a href=&quot;http://www.cs.helsinki.fi/&quot;&gt;University of Helsinki Department of Computer Science&lt;/a&gt; servers, where
it&#039;s been living for almost two years. In anticipation of this moment
I originally made all the links to my rss feeds through as
&lt;a href=&quot;http://iki.fi/&quot;&gt;forwarding service&lt;/a&gt;. When the blog moves, just flip the redirector
to point elsewhere, and the users won&#039;t notice a thing!&lt;/p&gt;

&lt;p&gt;At least that was the plan.&lt;/p&gt;

&lt;p&gt;Apparently a lot of people still managed to subscribe with the
target URL of the forwarder
(http://www.cs.helsinki.fi/u/jesnellm/blog/rss-...), instead of
with the forwarder URL (http://www.iki.fi/jsnell/blog/rss-...),
and thus would still be seeing the old feed after the move.&lt;/p&gt;

&lt;p&gt;So now I&#039;ve just set up a HTTP 301 (permanent) redirect on
the old location. Smart RSS aggregators are supposed to update the feed URL
when seeing a permanent redirect, but judging from the access logs
few do this in practice. Instead a 301 is treated the same as a
302 (temporary) redirect.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Which brings me to the actual point&lt;/b&gt;: If you want to keep
on subscribing to this feed indefinitely, please check that you
aren&#039;t using the cs.helsinki.fi URL. I&#039;m hoping to graduate this
year, which might also imply losing the 301 from the old location to the
new one.&lt;/p&gt;

&lt;p&gt;While moving servers, I also took the opportunity to redo the blog as a dynamic
application (using &lt;a href=&quot;http://www.cliki.net/araneida&quot;&gt;Araneida&lt;/a&gt;)
instead of generating static pages. I&#039;ll
see whether I can procrastinate myself into adding comment support
in the future.&lt;/p&gt;
&lt;/p&gt;
</description><author>jsnell@iki.fi</author><category>PERL</category><category>GENERAL</category><category>LISP</category><pubDate>Wed, 04 Jan 2006 05:00:00 GMT</pubDate><guid permaurl='true'>http://www.iki.fi/jsnell/blog/archive/2006-01-04-feed-moving.html</guid></item><item><title>Golf - Deroter</title><link>http://jsnell.iki.fi/blog/archive/2005-07-23.html</link><description>

&lt;p&gt;Long time since the last golf. Inspired by the recent announcement of
a &lt;a href=&quot;http://terje2.perlgolf.org/~golf-info/Book.html&quot;&gt;Perl Golf book&lt;/a&gt; I
took part in a Polish golf that was announced on the mailing list.&lt;/p&gt;

&lt;p&gt;Given a input string that has been &quot;encrypted&quot; with ROT-n on &lt;code&gt;STDIN&lt;/code&gt;
and a dictionary of words (sequences of letters &lt;code&gt;A-Za-z&lt;/code&gt;, not of &lt;code&gt;\w&lt;/code&gt;)
in &lt;code&gt;@ARGV&lt;/code&gt;
the program needs to output to &lt;code&gt;STDOUT&lt;/code&gt; the original plaintext.
(&lt;a href=&quot;http://kernelpanic.pl/perlgolf-view.mx?id=54&quot;&gt;Formal rules&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;My best
solution was 62 characters, but I figured out about an hour before
the golf ended that it was actually broken, and didn&#039;t have time to
figure out anything better than the 65.44 below, which is currently
good for a second place. The apparent winning solution of 63 doesn&#039;t seem to
work either, for unrelated reasons. So the explanation might
be for the winning entry, or it might not.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!perl -p0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You know the drill. &lt;code&gt;-p&lt;/code&gt; handles reading the input and printing
the output. Use &lt;code&gt;-0&lt;/code&gt; to read the input in one go, instead of
a line at a time.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;INIT{%a=map{pop,1}@ARGV}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the &lt;code&gt;INIT&lt;/code&gt; block, pop all command line parameters to make &lt;code&gt;-p&lt;/code&gt;
read from &lt;code&gt;STDIN&lt;/code&gt;. Use the removed arguments as keys in a hash table
for detecting dictionary words. Using the symbol table with
something like &lt;code&gt;$$_=1while$_=pop&lt;/code&gt; would save a few characters, but
that&#039;s incorrect since &lt;code&gt;$ARGV&lt;/code&gt; is automatically set to &lt;code&gt;&#039;-&#039;&lt;/code&gt; on entering
the main loop.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$a{$&amp;amp;}||y/B-ZA-Gb-za/A-z/while/\pL+/g
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;At the start of the main body &lt;code&gt;$_&lt;/code&gt; contains the whole ROT-n text.&lt;/p&gt;

&lt;p&gt;On the first iteration &lt;code&gt;/\pL+/g&lt;/code&gt; will match the first word (letters
only; &lt;code&gt;\pL&lt;/code&gt; is essentially &lt;code&gt;[a-zA-Z]&lt;/code&gt;). &lt;code&gt;//g&lt;/code&gt; works differently in scalar
than in list context: it will only match once per call, but the next call
will start at the location in the string where the last match ended. If
a match was found it returns true, otherwise false.&lt;/p&gt;

&lt;p&gt;In the body of the while we first check if the word we matched
is in the dictionary. If it isn&#039;t (i.e. &lt;code&gt;$a{$&amp;amp;}&lt;/code&gt; is untrue) &lt;code&gt;$_&lt;/code&gt;
obviously isn&#039;t plaintext yet, so we rotate it by one step with
&lt;code&gt;y///&lt;/code&gt;. This contains the only tricky bits in the program:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Changing &lt;code&gt;$_&lt;/code&gt; causes the scalar &lt;code&gt;//g&lt;/code&gt; to be reset, and start
matching from the start of the program.&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Doing the rotation backwards (A -&gt; Z, B -&gt; A, ..., Z -&gt; Y) instead
of the more intuitive direction (A -&gt; B, B -&gt; C, ... Z -&gt; A)
allows writing the transliteration in a way that saves one
character.&lt;/p&gt;

&lt;p&gt;There are six characters (&lt;code&gt;[\+]^_`&lt;/code&gt;) between &lt;code&gt;Z&lt;/code&gt; and &lt;code&gt;a&lt;/code&gt;. By
adding six extra characters into the right place on the left
side of the transliteration operation (with &lt;code&gt;-G&lt;/code&gt;) we can use the
range &lt;code&gt;A-z&lt;/code&gt; on the right side, instead of specifying separate
ranges for upper- and lowercase letters. Compare:&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;pre&gt;&lt;code&gt;y/A-Za-z/B-ZAb-za/
y/B-ZA-Gb-za/A-z/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;FWIW, the 65.48 by Piotr Fusik by far the coolest solution. Wish
I&#039;d thought of that...&lt;/p&gt;
</description><author>jsnell@iki.fi</author><category>PERL</category><pubDate>Sat, 23 Jul 2005 10:00:00 GMT</pubDate><guid permaurl='true'>http://www.iki.fi/jsnell/blog/archive/2005-07-23.html</guid></item><item><title>Golf - Rush Hour</title><link>http://jsnell.iki.fi/blog/archive/2004-07-01.html</link><description>&lt;p&gt;The recent &lt;a href=&#039;http://groups.google.com/groups?selm=cbuda9%24su2%241%40post.home.lunix&#039;&gt;godzillagolf &lt;/a&gt;titled &lt;a href=&#039;http://terje2.perlgolf.org/~pgas/score.pl?func=rules&amp;hole=63&amp;season=1&#039;&gt;Rush Hour&lt;/a&gt; was the first golf in a while where my solution contained anything worth
  explaining. Here&#039;s all 157 characters of the solution:&lt;/p&gt;&lt;pre&gt;#!perl -n0
sub
R{$b&amp;lt;0?reverse:$_}sub
M{/
/?s^\pL^$b=$#A**pos;push@_,&quot;$&amp; $b
&quot;;$c=8*($&amp;lt
Z);s/$&amp;/ /,s/(($&amp;)\C{$c}) /$1$2/&amp;lt;++${$_=R}or&amp;M
for~~R;pop^ge:exit
print@_}M&lt;/pre&gt;&lt;p&gt;The code uses a depth-first search, which can be roughly
  divided into the following steps (the actual code doesn&#039;t
  do things quite in this order):&lt;/p&gt;&lt;ol&gt;&lt;li&gt;If current board has already been visited, backtrack to
     step 4.&lt;/li&gt;&lt;li&gt;Mark current board as visited&lt;/li&gt;&lt;li&gt;If a car is in the target space, print the moves that
     have been accumulated and quit.&lt;/li&gt;&lt;li&gt;Move one of the cars one step in either direction&lt;ul&gt;&lt;li&gt;If no cars can be moved, backtrack&lt;/li&gt;&lt;li&gt; If backtracking to here, try another car/direction&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Go to step 1.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;There are several subproblems that need to be solved to
  implement the algorithm:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Detect whether the win condition has been reached.&lt;/li&gt;&lt;li&gt;Accumulate the moves. (Preferably without using too
     much memory; I have a 149 character solution that uses 200MB,
     which isn&#039;t really justifyable for this problem).&lt;/li&gt;&lt;li&gt;Iterate over all valid moves (car/direction pairs) for a board.&lt;/li&gt;&lt;li&gt;Given a board and a move, generate another board.&lt;/li&gt;&lt;li&gt;Ensure that the backtracking works.&lt;/li&gt;&lt;li&gt;Detect whether the board has already been visited&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The board is of course stored in the original format as a string.
There&#039;s no room for any fancy datastructures... Given that, here
are my solutions to the subproblems:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Just check whether the board contains a space followed by a
     newline:&lt;pre&gt;/ \n/ ? ... : ...  # If the regexp fails, win)&lt;/pre&gt;&lt;li&gt;Keep the moves stored as strings in &lt;code&gt;@_&lt;/code&gt; in the correct order:&lt;pre&gt;push@_,&quot;$&amp; $b\n&quot;; # $&amp; is the current car, $b is either -1 or 1
...   # execute the rest of the algorithm. This quits on success...
pop;  # ... so reaching this line means that we&#039;re backtracking,
      # and need to remove the move&lt;/pre&gt;&lt;li&gt;Given a board, iterate over all valid car-characters in the
     string (I used &lt;code&gt;\pL&lt;/code&gt; here instead of the obvious
     &lt;code&gt;\w&lt;/code&gt; for reasons
     that are still unclear to me). For each character, generate
     a value &lt;code&gt;$b&lt;/code&gt; as either 1 or -1, so that it&#039;s guaranteed that
     for any board both values are generated at least once for
     each car. Since each line is 9 characters long and there
     are at least 2 characters in each car, each car must have
     at least one character in an even and one in an odd position
     in the string. Hence &lt;code&gt;(-1)**pos&lt;/code&gt; generates a proper value.&lt;pre&gt;s^\pL^$b=$#A**pos; ... ^ge&lt;/pre&gt;&lt;code&gt;$#A&lt;/code&gt; is just a shorter way of writing &lt;code&gt;(-1)&lt;/code&gt;.
     Unfortunately the operator precedence of unary &lt;code&gt;-&lt;/code&gt; is
     smaller than that of &lt;code&gt;**&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;First let&#039;s solve the problem only for positive values of
     &lt;code&gt;$b&lt;/code&gt; (i.e. down or up).&lt;pre&gt;$c=8*($&amp;lt Z);  # $c = 8 if car moves up/down, 0 otherwise
s/$&amp;/ /;        # Remove the first character of the car
s/(($&amp;)\C{$c}) /$1$2/
# Find last character of car that&#039;s followed by a space exactly $c
# characters from it, and substitute the space with the character.
# For example &quot;bbcc.&quot; =&gt; &quot;bb.cc&quot;. If this substitution fails,
# the move was impossible and we should backtrack.&lt;/pre&gt;To handle negative values of &lt;code&gt;$b&lt;/code&gt;, just
     conditionally reverse &lt;code&gt;$_&lt;/code&gt; before and after it&#039;s
     modified (nobody else did this in the golf, which I found
     suprising):&lt;/li&gt;&lt;pre&gt;sub R{$b&amp;lt;0?reverse:$_}
$_=R;...;$_=R&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;The backtracking can be implemented just by wrapping the code inside
     a recursive subroutine and restoring the original state if the
     recursive call returns. There are three interesting bits of state:&lt;ul&gt;&lt;li&gt;$_. Saved by binding $_ again with for:&lt;pre&gt;... for&quot;$_&quot;  # Can&#039;t use ... for$_, since that just
               # aliases the current $_ to the new $_&lt;/pre&gt;Since $_ needs to be conditionally reversed in d, we can just
         use the return value of R instead.&lt;pre&gt;... for~~R   # ~~ needed to give scalar context to the reverse&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;The moves that haven&#039;t been tried for this board yet. Since
         these are generated from the substitution in subsolution &lt;b&gt;3&lt;/b&gt;, nothing special needs to be done.&lt;/li&gt;&lt;li&gt;The accumulated moves. This was handled correctly in
           subsolution &lt;b&gt;2&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Mark board visited by incrementing a symbolic reference using
     &lt;code&gt;$_&lt;/code&gt;.&lt;pre&gt;++$$_&lt;/pre&gt;Since &lt;code&gt;$_&lt;/code&gt; needs to be conditionally reversed again,
     the symbolic reference can be made on the value of the assignment
     instead:&lt;pre&gt;++${$_=R}&lt;/pre&gt;The other part of this subproblem is to not recurse if the board
     has already been visited. This can be done by comparing the
     return value of the increment to the final substitution in
     subsolution &lt;b&gt;4&lt;/b&gt;:&lt;pre&gt;s/...//&amp;lt;++${$_=R}or...&lt;/pre&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Mash these ingredients together, and add an &lt;code&gt;exit
print@_&lt;/code&gt; to actually do something with the result, and you get the
solution shown above.&lt;/p&gt;</description><author>jsnell@iki.fi</author><category>PERL</category><pubDate>Thu, 01 Jul 2004 00:00:00 GMT</pubDate><guid permaurl='true'>http://www.iki.fi/jsnell/blog/archive/2004-07-01.html</guid></item><item><title>Golf - Matrix</title><link>http://jsnell.iki.fi/blog/archive/2004-04-13.html</link><description>&lt;p&gt;The &lt;a href=&#039;http://terje2.perlgolf.org/~pgas/score.pl?func=rules&amp;hole=60&amp;season=1&#039;&gt;Matrix&lt;/a&gt; golf had a rather thin field (hopefully only temporary),
    but some really cool code (especially in the post-mortem).&lt;/p&gt;&lt;p&gt;The problem statement was short enough to be quoted here in full:&lt;/p&gt;&lt;blockquote&gt;Let A be an N*N matrix of zeros and ones. A submatrix S of A is any
group of contiguous entries that forms a square or a rectangle.
Write a program that determines the number of elements of the largest submatrix
of ones in A . Largest here is measured by area.&lt;/blockquote&gt;&lt;p&gt;Before going into the details, a brief example of how the algorithm
I used works. Assume the following matrix:&lt;/p&gt;&lt;pre&gt;00011
00110
01110
10110
00010&lt;/pre&gt;&lt;p&gt;The longest string of &lt;code&gt;1&lt;/code&gt;s is the &lt;code&gt;111&lt;/code&gt; on line 3, so that&#039;s the largest submatrix of one line (with an area
of &lt;code&gt;1*3=3&lt;/code&gt;). Then transform the matrix by doing a
stringwise and on each line and the line that follows it. The last
line will be chopped off:&lt;/p&gt;&lt;pre&gt;00010
00110
00110
00010&lt;/pre&gt;&lt;p&gt;Obviously the only way to get a &lt;code&gt;1&lt;/code&gt; on the
   transformed matrix is to have one on the corresponding position in
   two successive lines in the untransformed matrix. So the string &lt;code&gt;11&lt;/code&gt; (found on both lines 2 and 3) corresponds to an area
   of &lt;code&gt;2*2=4&lt;/code&gt; in the original matrix. Repeat the
   transform:&lt;/p&gt;&lt;pre&gt;00010
00110
00010&lt;/pre&gt;&lt;p&gt;Now any 1 is going to be the result of 3 1s on consecutive
        lines, so &lt;code&gt;11&lt;/code&gt; on line two means there was a
        submatrix of area &lt;code&gt;2*3=6&lt;/code&gt; on the original matrix.
        Repeating the whole process two more times would result in
        finding an area of 4 and one of area 5. The answer for this
        matrix would therefore be 6.&lt;/p&gt;&lt;p&gt;My solution (59 characters):&lt;/p&gt;&lt;pre&gt;#!perl -lp0
s/1*/$B[$?*length$&amp;]=$&amp;/ge,/
/,$_&amp;=$&#039;
while++$?;$_=$#B&lt;/pre&gt;&lt;p&gt;As usual, we slurp the whole input into &lt;code&gt;$_&lt;/code&gt; with
&lt;code&gt;-p0&lt;/code&gt; and take care of the trailing newline with &lt;code&gt;-l&lt;/code&gt;. In addition to &lt;code&gt;$_&lt;/code&gt;, a couple of other variables
contain some interesting state. &lt;code&gt;@B&lt;/code&gt; is used for keeping
track of the largest area that&#039;s been found (an old golf trick; we&#039;re
only interested in the size of the array, not the values stored in
it). &lt;code&gt;$?&lt;/code&gt; holds the current iteration (i.e. the multiplier
for the area calculation). &lt;code&gt;$?&lt;/code&gt; is used since it can only
contain an unsigned short (0-65535), and therefore repeatedly
incrementing it in the condition of the &lt;code&gt;while&lt;/code&gt; results in
the variable overflowing to 0 after 65535 iterations. (Another
variable with a similar behaviour is &lt;code&gt;$^C&lt;/code&gt;, which holds
signed chars. I used &lt;code&gt;$?&lt;/code&gt; instead since at some point my
program couldn&#039;t handle negative multipliers)&lt;/p&gt;&lt;p&gt;As mentioned before, the program contains a &lt;code&gt;while&lt;/code&gt;-loop whose condition is just incrementing &lt;code&gt;$?&lt;/code&gt;. The body
of the while implements most of the algorithm. Some code is executed
for each string of &lt;code&gt;1&lt;/code&gt;s with &lt;code&gt;s/1*/.../ge&lt;/code&gt;.
The code in question is &lt;code&gt;$B[$?*length$&amp;]=$&amp;&lt;/code&gt;, which just
calculates the area of the submatrix that the string of &lt;code&gt;1s&lt;/code&gt; represents (by multiplying &lt;code&gt;$?&lt;/code&gt; and the &lt;code&gt;length&lt;/code&gt; of the matched substring, i.e. $&amp;), and stores something
in that index of &lt;code&gt;@B&lt;/code&gt;. In this case, the value being
stored is &lt;code&gt;$&amp;&lt;/code&gt; since (despite using &lt;code&gt;s///&lt;/code&gt;) we
don&#039;t actually want to modify &lt;code&gt;$_&lt;/code&gt; yet. This takes care of
finding the largest area.&lt;/p&gt;&lt;p&gt;To implement the transformation described earlier, a &lt;code&gt;/\n/&lt;/code&gt; is used to find the first newline in $_. After this a
stringwise and of &lt;code&gt;$_&lt;/code&gt; and &lt;code&gt;$&#039;&lt;/code&gt; will have done
the tranformation (including chopping off the last line). Once the
loop ends, we just assign &lt;code&gt;$#B&lt;/code&gt; (the largest index of &lt;code&gt;@B&lt;/code&gt;) to &lt;code&gt;$_&lt;/code&gt;, which is then printed out thanks
to the &lt;code&gt;-p&lt;/code&gt; command line argument.&lt;/p&gt;&lt;p&gt;This was a very cool golf. My only regret is missing a
completely obvious optimization of replacing the &lt;code&gt;s/1*//ge&lt;/code&gt; with a suitable crafted map, which would&#039;ve saved two strokes. Well,
not completely obvious since I only realized that it would&#039;ve been
possible when writing this post. Perhaps I should start writing these
things earlier... ;-)&lt;/p&gt;</description><author>jsnell@iki.fi</author><category>PERL</category><pubDate>Tue, 13 Apr 2004 00:00:00 GMT</pubDate><guid permaurl='true'>http://www.iki.fi/jsnell/blog/archive/2004-04-13.html</guid></item><item><title>Golf - Subproduct</title><link>http://jsnell.iki.fi/blog/archive/2004-03-21.html</link><description>&lt;p&gt;For some reason I usually don&#039;t seem to have time to take part
in golfs that I&#039;ve designed. Almost happened with the badly named (couldn&#039;t
come up with anything better) &lt;a href=&#039;http://terje2.perlgolf.org/~pgas/score.pl?func=rules&amp;hole=58&#039;&gt;Subproduct&lt;/a&gt; too, but in the end I decided that I didn&#039;t
really need to write that seminar report yet...&lt;/p&gt;&lt;p&gt;The problem was simple. Given a string of digits (maximum
length 20) and a maximum substring length N (maximum of 9), find the
largest product of the digits in a substring of 1..N characters. (For
example for the string 0120340 and a N of 5 the correct answer is
3*4=12). The most complex parts about the problem are handling zeros
correctly and keeping track of the maximum value encountered (the
usual golf idiom of using the length of an array for this doesn&#039;t work,
since the maximum value of &lt;code&gt;9**9&lt;/code&gt; would require an array
that&#039;s too large).&lt;/p&gt;&lt;p&gt;Here&#039;s the code (68 characters):&lt;/p&gt;&lt;pre&gt;#!perl
$_=shift;s/./$^=1;($^*=chop)&amp;lt;$\or$\=&quot;$^
&quot;for($`.$&amp;)x&quot;@ARGV&quot;/ge;print&lt;/pre&gt;&lt;p&gt;First we get the first command line parameter into &lt;code&gt;$_&lt;/code&gt;with &lt;code&gt;shift&lt;/code&gt;, and loop over it using  &lt;code&gt;s///&lt;/code&gt;. The answer will be saved into &lt;code&gt;$\&lt;/code&gt; so that we can use
just a print without any arguments to print it. Of course print
without arguments will print &lt;code&gt;$_&lt;/code&gt;too, so we need to empty
&lt;code&gt;$_&lt;/code&gt; somehow. This is the reason for using &lt;code&gt;s/.//&lt;/code&gt;,
while the shorter &lt;code&gt;s///&lt;/code&gt; would otherwise also suffice.&lt;/p&gt;&lt;p&gt;For each position in the input string we&#039;ll first initialize
&lt;code&gt;$^&lt;/code&gt; to one. After that we&#039;ll loop N times through a loop,
where &lt;code&gt;$_&lt;/code&gt; has been initialized to &lt;code&gt;&quot;$`$&amp;&quot;&lt;/code&gt;(that is, all characters up to and including the one that&#039;s currently being
processed by &lt;code&gt;s///&lt;/code&gt;). In the loop, we&#039;ll chop off digits from the end of
the newly constructed &lt;code&gt;$_&lt;/code&gt; and multiply &lt;code&gt;$^&lt;/code&gt; with them. If &lt;code&gt;$^&lt;/code&gt; is larger
then the current value of &lt;code&gt;$\&lt;/code&gt;, set &lt;code&gt;$\&lt;/code&gt; to &lt;code&gt;&quot;$^\n&quot;.&lt;/code&gt;&lt;/p&gt;&lt;p&gt;There are a lot of variations on this theme that are equally
long. I ended up submitting one of the more obfuscated ones, only to
regret it now :-)&lt;/p&gt;</description><author>jsnell@iki.fi</author><category>PERL</category><pubDate>Sun, 21 Mar 2004 00:00:00 GMT</pubDate><guid permaurl='true'>http://www.iki.fi/jsnell/blog/archive/2004-03-21.html</guid></item><item><title>Golf - Card Trick 2</title><link>http://jsnell.iki.fi/blog/archive/2004-03-03.html</link><description>&lt;p&gt;After missing one minigolf, I had some time to take part in &lt;a href=&#039;http://terje2.perlgolf.org/~pgas/score.pl?func=rules&amp;hole=57&#039;&gt;Card Trick 2&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The mission was to determine the result of the &#039;trick&#039; outlined
       below, when getting as input the initial layout of cards and the
       actions of the &#039;audience&#039;.&lt;/p&gt;&lt;blockquote&gt;In my hand I have 21 cards that I deal out face up, one each to 3
spread piles, until there are 3 rows of 7. You silently chose your
card and inform me of which &#039;pile&#039; your card is in (1, 2, or 3). I
then pick up each pile making sure to put the pile with your card
between the two other piles. I deal them out as before, and again you
tell me which pile your card is in. We repeat the process a third
time, and when I again pick up the piles, placing the pile with your
card in the middle, your card will invariably be the center card (11
of 21 in this case).&lt;/blockquote&gt;&lt;p&gt;By the time I&#039;d even read the rules, there was already a mass
of people with a solution of 40-41 (and Ton Hospel at 38, but we all
know that he isn&#039;t human). Given the length of those solutions, it&#039;s
obvious that the solution is going to involve some cute mathematical
formula, instead of directly manipulating the cards to execute the
trick.&lt;/p&gt;&lt;p&gt;The way I thought of the formula was this: Given an index I into the
set of cards (for example with the 21 cards below, 0-20) and the pick
P (1-3) we need a formula for determining from I and P the index which
would get translated to I.&lt;/p&gt;&lt;pre&gt;  0  1  2
  3  4  5
  6  7  8
  9 10 11
 12 13 14
 15 16 17
 18 19 20&lt;/pre&gt;&lt;p&gt;Let&#039;s determine this by hand for for the interesting elements (we&#039;re
only interested in cards that are rearranged into the middle third):&lt;/p&gt;&lt;pre&gt;
    7  8  9 10 11 12 13
 1  0  3  6  9 12 15 18
 2  1  4  7 10 13 16 19
 3  2  5  8 11 14 17 20&lt;/pre&gt;&lt;p&gt;Obviously our formula looks like I&#039; = P + 3I - 22. To generalize this
we just note that 22 is the number of cards + 1 (which happens to be @F-2).
Now, to solve the problem we just need to remember that the card that
we&#039;re interested in ends up in the middlemost position (i.e. for 21 cards
in index 10, @F/2-2), and we can just repeat the formula three times to find
out the original position:&lt;/p&gt;&lt;pre&gt;  I_0    = @F/2-2
  I_1    = P_3 + 3*I_0 - (@F-2)
         = P_3 + 3*(@F/2-2) - @F + 2
         = P_3 + @F/2 - 4
  I_2    = P_2 + 3*I_1 - (@F-2)
         = P_2 + 3*(P_3 + @F/2 - 4) - @F + 2
         = P_2 + 3*P_3 + @F/2 - 10
  I_3    = P_1 + 3*I_2 - (@F-2)
         = P_1 + 3*P_2 + 9*P_3 + @F/2 - 28&lt;/pre&gt;&lt;p&gt;So that&#039;s the theory. In practice few Perl tricks are
needed for this problem. The cards can be accessed from &lt;code&gt;@F&lt;/code&gt; by turning on autosplitting with the &lt;code&gt;-a&lt;/code&gt; switch.
The picks could also be accessed from &lt;code&gt;@F&lt;/code&gt;, but it turns out that it&#039;s easier to access them using
regexps. By crafting a suitable regular expression, we can get the
picks into the special regep variables (&lt;code&gt;$&amp;, $&#039;, $1, etc&lt;/code&gt;). And finally, by using a repeated substitution, we can use the return
value of operation to count the amount of cards in the input (to save one
character when compared to using &lt;code&gt;@F/2&lt;/code&gt;. My final solution
is 39 characters (and a shared second place):&lt;/p&gt;&lt;pre&gt;#!perl -lpa
$_=$F[s/ ..(.)//g-27+9*$&#039;+3*$1+$&amp;]&lt;/pre&gt;</description><author>jsnell@iki.fi</author><category>PERL</category><pubDate>Wed, 03 Mar 2004 00:00:00 GMT</pubDate><guid permaurl='true'>http://www.iki.fi/jsnell/blog/archive/2004-03-03.html</guid></item><item><title>Golf - A1227</title><link>http://jsnell.iki.fi/blog/archive/2004-02-09.html</link><description>&lt;p&gt;The &lt;a href=&#039;http://terje2.perlgolf.org/~pgas/score.pl?func=rules&amp;hole=55&#039;&gt;A1227 golf&lt;/a&gt; that just ended was nominally about printing for each number
from 1 to 99 the amount of different ways that the number could be
represented as the sum of consecutive positive integers. So for
example since the number 9 == 2+3+4 == 4+5, the correct answer for the
number 9 would be 3. I say nominally, since there was actually a
link to the correspoding &lt;a href=&#039;http://www.research.att.com/projects/OEIS?Anum=A001227&#039;&gt;entry&lt;/a&gt; in the On-Line Encyclopedia of Integer Sequences. Amongst
other things, the entry told that another way to generate this
sequence is by determining the number of odd divisors of the number
(including 1).  Unfortunately I missed this bit of information on
the first reading, and only figured this out after drawing rectangles
on graph paper for a couple of hours. I don&#039;t really understand why
the problem statement had to be given in a non-optimal form, with a
link to the better formulation.&lt;/p&gt;&lt;p&gt;Once the problem had been reduced to this form, the solution is
pretty obvious, with just a couple of ways to optimize it for length
(as evidenced by the fact that 12 of 20 participants were in the
39-41 character range). My solution was 40 characters: &lt;code&gt;-l print~~grep$_%2&amp;gt;$&#039;%$_,//..99for 1..99&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Loop for the numbers from 1 to 99. For each of these numbers,
first do a match against the empty regular expression, which stores
the number into $&#039; (so that it can be accessed from inner scopes even
after $_ has been aliased to something else). After that, do a grep
for numbers from 1 to 99, finding all numbers that are both divisible
by two, and which are divisors of the number we stored in $`. Grep
returns a list of the items that satisfied the condition, which we
then need to force to scalar context (done here with ~~) to find out
how many items the list contains.&lt;/p&gt;&lt;p&gt;A nice little golf.&lt;/p&gt;</description><author>jsnell@iki.fi</author><category>PERL</category><pubDate>Mon, 09 Feb 2004 00:00:00 GMT</pubDate><guid permaurl='true'>http://www.iki.fi/jsnell/blog/archive/2004-02-09.html</guid></item><item><title>Golf - Permutations</title><link>http://jsnell.iki.fi/blog/archive/2004-01-30.html</link><description>&lt;div&gt;&lt;p&gt;From now on, I&#039;m archiving explanations of my &lt;a href=&#039;http://perlgolf.sf.net/&#039;&gt;Perl Golf&lt;/a&gt; solutions here. The &lt;a href=&#039;http://terje2.perlgolf.org/~pgas/score.pl?func=rules&amp;hole=54&#039;&gt;latest golf&lt;/a&gt; by Ton Hospel required generating all distinct permutations of
         the letters given as command-line parameters. Here&#039;s my 52
         character entry (which placed second):&lt;/p&gt;&lt;div class=&#039;CODE&#039;&gt;&lt;pre&gt;s/^$/@ARGV
/;s/(.) /${$_=&quot;$1$`$&#039;&quot;}||=do$0/ge||print&lt;/pre&gt;&lt;p&gt;The code uses a simple recursive algorithm for the
        problem:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If there are no input elements, print the accumulated elements&lt;/li&gt;&lt;li&gt;Otherwise, select each of the input elements in turn, and
          recurse with the same parameters, except that the element
          is moved from the input list to the accumulator list&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This being Perl Golf we&#039;ll be using strings
        instead of lists for the input/accumulator. And since
        manipulating any non-$_ variables tends to be bothersome,
        we&#039;ll keep both the input and the accumulator in the same
        string.&lt;/p&gt;&lt;p&gt;The input/accumulator parts of the string need to be
        distinguished somehow. The format I&#039;ve chosen is that
        the accumulated elements come first (unseparated), followed by
        the input elements (all input elements have a trailing space),
        followed by a newline. So for example the string &#039;cba d \n&#039;
        has the elements &#039;c&#039; and &#039;b&#039; accumulated, and the elements
        &#039;a&#039; and &#039;d&#039; are still unprocessed.&lt;/p&gt;&lt;p&gt;The advantage of this format is that it&#039;s easy to initialize,
        thanks to the original input being in @ARGV. The first statement
        of the program (&lt;code&gt;s/^$/@ARGV \n/&lt;/code&gt;) sets $_ to a
        string containing the input elements trailed by a single
        spaces. The substitution will only happen when $_ is empty,
        thanks to the left-hand side of the s///.&lt;/p&gt;&lt;p&gt;After initializing $_, we get to the real meat. The first
        expression of the second statement (&lt;code&gt;s/(.) /${$_=&quot;$1$`$&#039;&quot;}||=do$0/ge&lt;/code&gt;) will match
       all of the still unprocessed characters in the input.
       The right-hand side of the s///ge is evaluated (we don&#039;t
       care about the return value, since the substitution is
       only used as a looping construct here). We first assign
       a new value for $_; basically just move the selected element
       to the start of the string (into the accumulator), and remove
       the trailing space. After that, we do the recursion using &lt;code&gt;do$0&lt;/code&gt;, which basically executes the same program
       with the same enviroment again (this is why the original
       initialization of $_ had to only happen when $_ is empty).&lt;/p&gt;&lt;p&gt;The reason s///g is so useful as a looping construct is that
        it continues to work on the original value of the variable
        that we&#039;re substituting, no matter what&#039;s actually done inside
        the right-hand side. So even though we clobbered the value
        of $_, Perl has saved for us the only piece of context that
        we needed.&lt;/p&gt;&lt;p&gt;Once the second substitution fails, $_ obviously doesn&#039;t
        contain any more input. $_ therefore contains the accumulator
        (in the correct output format), followed by a newline. A
        simple print that&#039;s triggered when the substitution fails
        takes care of the output.&lt;/p&gt;&lt;p&gt;Unfortunately, we still need to filter out duplicate solutions
        since the rules called for printing only the distinct permutations.
        The natural method is marking each printed permutation into
        a hashtable, and only print a permutation if it&#039;s not already
        there.&lt;/p&gt;&lt;p&gt;We use a couple of small optimizations to this scheme. Instead of
        using a hashtable, we use Perls symbol table (well, technically
        it&#039;s a hashtable too). And second, we&#039;ll do the checking and
        incrementing at the same time, using the short-circiting
        ||=-operator. The linenoise-like bits of code in the solution (&lt;code&gt;${...}||=...&lt;/code&gt;) are responsible for this. The left-hand
        side makes a symbolic reference to the value inside the brackets
        (in this case the value that was assigned to $_), and
        the ||= assigns a (true) value to that reference, assuming it&#039;s old
        value was false.&lt;/p&gt;&lt;p&gt;So there you have it. I probably won&#039;t post such a long
        explanation for most future golfs.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</description><author>jsnell@iki.fi</author><category>PERL</category><pubDate>Fri, 30 Jan 2004 00:00:00 GMT</pubDate><guid permaurl='true'>http://www.iki.fi/jsnell/blog/archive/2004-01-30.html</guid></item></channel></rss>