<?xml version="1.0"?>
<rss version="2.0.">
  <channel>
    <title>Advogato blog for brlewis</title>
    <link>http://www.advogato.org/person/brlewis/</link>
    <description>Advogato blog for brlewis</description>
    <language>en-us</language>
    <generator>mod_virgule</generator>
    <pubDate>Thu, 24 Jul 2008 19:55:54 GMT</pubDate>
    <item>
      <pubDate>Fri, 19 Nov 2004 14:52:44 GMT</pubDate>
      <title>19 Nov 2004</title>
      <link>http://www.advogato.org/person/brlewis/diary.html?start=8</link>
      <guid>http://www.advogato.org/person/brlewis/diary.html?start=8</guid>
      <description>&lt;p&gt;In &lt;a href="http://advogato.org/article/804.html" &gt;Coding Challenge:
Increment a date/timestamp string&lt;/a&gt;, &lt;a href="http://www.advogato.org/person/ncm/" &gt;ncm&lt;/a&gt; challenges
us to "consider the string as a pure 14-digit number, with digits that
have very odd add-with-carry relationships."  Then think of a
fun-to-code way to write a function that could be "a &lt;em&gt;lot&lt;/em&gt;
faster than calling &lt;tt&gt;mktime&lt;/tt&gt; etc."

&lt;p&gt; &lt;p&gt;Besides losing the libary-call overhead, there are other reasons
such a function could be made very fast.  Assuming a random
distribution of tiemstamps,

&lt;p&gt; &lt;ul&gt;

&lt;p&gt;  &lt;li&gt;Nine out of ten times this function would only be
incrementing one character.

&lt;p&gt;  &lt;li&gt;Fifty-nine times out of sixty this function would be incrementing
one or two characters.

&lt;p&gt;  &lt;li&gt;Since these times are GMT and we ignore leap seconds, only once
in 24 * 60 * 60 times do we care how many days are in any given month.

&lt;p&gt; &lt;/ul&gt;

&lt;p&gt; &lt;p&gt;Interestingly, &lt;em&gt;nobody&lt;/em&gt; seems interested in writing the
function this way.  It seems much more fun for people to focus on
conciseness rather than performance.

&lt;p&gt; &lt;p&gt;For what it's worth, I wrote a Scheme version that does not
allocate new objects, is tail recursive, uses functions that are
likely to be inlined, and does multiplication and modulo only with
constant powers of two, allowing compiler optimization into bitwise
operations.

&lt;p&gt; &lt;p&gt;It is longer than the other posted solutions, but all the way
through it focuses on finding the most common case, doing it, and
returning immediately.

&lt;p&gt; &lt;pre&gt;(define (timestamp-increment! timestamp)
  (timestamp-position-increment! timestamp 13))

&lt;p&gt; (define (timestamp-position-increment! timestamp pos)
  (let ((current-char (string-ref timestamp pos)))
    (case pos
      ((13 11 3 2 1 0) ; last digits of second, minute, all year digits
       (timestamp-position-increment-simple!
	timestamp pos current-char #\0 #\9))
      ((12 10) ; first digits of second, minute
       (timestamp-position-increment-simple!
	timestamp pos current-char #\0 #\5))
      ((9) ; last digit of hour
       (timestamp-position-increment-depending!
	timestamp pos current-char #\0 #\0 #\9 #\3 #\2))
      ((8) ; first digit of hour
       (timestamp-position-increment-simple!
	timestamp pos current-char #\0 #\2))
      ((7) ; last digit of day
       (timestamp-position-increment-day! timestamp pos current-char))
      ((6) ; first digit of day
       (timestamp-position-increment-simple!
	timestamp pos current-char #\0 (if (february? timestamp)
					   #\2
					   #\3)))
      ((5) ; last digit of month
       (timestamp-position-increment-depending!
	timestamp pos current-char #\0 #\1 #\9 #\2 #\1))
      ((4) ; first digit of month
       (timestamp-position-increment-simple!
	timestamp pos current-char #\0 #\1)))))

&lt;p&gt; (define (timestamp-position-increment-simple!
	 timestamp pos current-char ch0 ch9)
  (if (char=? current-char ch9)
      (begin
	(string-set! timestamp pos ch0)
	(timestamp-position-increment! timestamp (- pos 1)))
      (string-set! timestamp pos (next-digit current-char))))

&lt;p&gt; (define (next-digit ch)
  (integer-&amp;gt;char (+ 1 (char-&amp;gt;integer ch))))

&lt;p&gt; (define
  (timestamp-position-increment-depending!
   timestamp pos current-char ch0 ch0-special ch9 ch9-special chprev-special)
  (if (and (char=? current-char ch9-special)
	   (char=? (string-ref timestamp (- pos 1)) chprev-special))
      (begin
	(string-set! timestamp pos ch0-special)
	(timestamp-position-increment! timestamp (- pos 1)))
      (timestamp-position-increment-simple!
       timestamp pos current-char ch0 ch9)))

&lt;p&gt; (define
  (timestamp-position-increment-day! timestamp pos current-char)
  (let ((first-day-pos (string-ref timestamp (- pos 1))))
    (case first-day-pos
      ((#\0 #\1)
       (timestamp-position-increment-simple!
	timestamp pos current-char #\0 #\9))
      ((#\2)
       (if (char&amp;lt;? current-char #\8)
	   (string-set! timestamp pos (next-digit current-char))
	   (if (february? timestamp)
	       (timestamp-position-increment-simple!
		timestamp pos current-char #\1 (ly-day-char timestamp))
	       (timestamp-position-increment-simple!
		timestamp pos current-char #\0 #\9))))
      ((#\3)
       (timestamp-position-increment-simple!
	timestamp pos current-char #\1
	(case (string-ref timestamp (- pos 2))
	  ((#\2 #\3 #\5 #\7 #\8 #\0) #\1) ; 31 in December, March, etc.
	  ((#\1)
	   (if (char=? #\0 (string-ref timestamp (- pos 3)))
	       #\1 ; 31 days in January, 30 in November
	       #\0))
	  (else #\0)))))))

&lt;p&gt; (define (ly-day-char timestamp)
  (if (positive? (mod4 (string-ref timestamp 2)
		       (string-ref timestamp 3)))
      #\8 ; year not a multiple of 4
      (if (or (char&amp;lt;? #\0 (string-ref timestamp 2))
	      (char&amp;lt;? #\0 (string-ref timestamp 3)))
	  #\9 ; multiple of 4 but not on a century
	  (if (positive? (mod4 (string-ref timestamp 0)
			       (string-ref timestamp 1)))
	      #\8 ; multiple of 4 century
	      #\9)))) ; regular century

&lt;p&gt; (define (mod4 ch1 ch2)
  (modulo (+ (* 2 (modulo (char-&amp;gt;integer ch1) 2))
	     (modulo (char-&amp;gt;integer ch2) 4))
	  4))

&lt;p&gt; (define (february? timestamp)
  (and (char=? #\2 (string-ref timestamp 5))
       (char=? #\0 (string-ref timestamp 4))))&lt;/pre&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 18 Nov 2004 21:01:11 GMT</pubDate>
      <title>18 Nov 2004</title>
      <link>http://www.advogato.org/person/brlewis/diary.html?start=7</link>
      <guid>http://www.advogato.org/person/brlewis/diary.html?start=7</guid>
      <description>&lt;p&gt;I'm having fun with &lt;a href="http://www.advogato.org/article/804.html" &gt;ncm's programming challenge&lt;/a&gt;.  Here's a Scheme test harness for it, assuming you call the test function &lt;tt&gt;timestamp-increment!&lt;/tt&gt;

&lt;p&gt; &lt;pre&gt;(define test-values
  '(("19991231235959" . "20000101000000")
    ("20000228235959" . "20000229000000")
    ("20000229235959" . "20000301000000")
    ("20040228235959" . "20040229000000")
    ("21000228235959" . "21000301000000")
    ("19000228235959" . "19000301000000")
    ("16000228235959" . "16000229000000")))

&lt;p&gt; (define (test-answer q-a-pair)
  (let ((a (string-copy (car q-a-pair))))
    (timestamp-increment! a)
    (if (string=? a (cdr q-a-pair))
	'ok
	(cons a q-a-pair))))

&lt;p&gt; (define test-results
  (map test-answer test-values))
&lt;/pre&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 21 Feb 2002 16:17:09 GMT</pubDate>
      <title>21 Feb 2002</title>
      <link>http://www.advogato.org/person/brlewis/diary.html?start=6</link>
      <guid>http://www.advogato.org/person/brlewis/diary.html?start=6</guid>
      <description>&lt;a href="http://www.advogato.org/person/remle/" &gt;remle&lt;/a&gt;: Pretending you've received QUIT does
not imply you must pretend you've received CRLF.CRLF. </description>
    </item>
    <item>
      <pubDate>Wed, 31 Oct 2001 20:55:54 GMT</pubDate>
      <title>31 Oct 2001</title>
      <link>http://www.advogato.org/person/brlewis/diary.html?start=5</link>
      <guid>http://www.advogato.org/person/brlewis/diary.html?start=5</guid>
      <description>I've made a lot of progress on my &lt;a href="http://www.advogato.org/proj/BRL/" &gt;BRL&lt;/a&gt;
tutorial.  Now anybody with Tomcat or similar servlet engine
can unpack learnbrl.war and get right into it.   Instant
web/database app development!</description>
    </item>
    <item>
      <pubDate>Wed, 11 Apr 2001 20:53:21 GMT</pubDate>
      <title>11 Apr 2001</title>
      <link>http://www.advogato.org/person/brlewis/diary.html?start=4</link>
      <guid>http://www.advogato.org/person/brlewis/diary.html?start=4</guid>
      <description>It's great when management is supportive.  I got approval
for us to pay the author of Kawa Scheme for work that will
improve &lt;a href="http://www.advogato.org/proj/BRL/" &gt;BRL&lt;/a&gt; debugging.  Two coworkers got their
first &lt;a href="http://www.schemers.org/" &gt;Scheme&lt;/a&gt; lesson
yesterday.</description>
    </item>
    <item>
      <pubDate>Wed, 14 Feb 2001 17:10:06 GMT</pubDate>
      <title>14 Feb 2001</title>
      <link>http://www.advogato.org/person/brlewis/diary.html?start=3</link>
      <guid>http://www.advogato.org/person/brlewis/diary.html?start=3</guid>
      <description>Got my &lt;a
href="http://www.webappcabaret.com/brl/p/sweetie/index.brl"&gt;Ask
Your Sweetie&lt;/a&gt; app working.  It lets you make a page with
a yes/no question for someone to answer. They get back your
prepared response according to the answer.  You are e-mailed
their answer.</description>
    </item>
    <item>
      <pubDate>Tue, 13 Feb 2001 14:01:44 GMT</pubDate>
      <title>13 Feb 2001</title>
      <link>http://www.advogato.org/person/brlewis/diary.html?start=2</link>
      <guid>http://www.advogato.org/person/brlewis/diary.html?start=2</guid>
      <description>Self-correcting bug: My script for transfer of diary entry
from Palm would overwrite an old entry rather than create a
new one, so the entry in which I posted the code got
overwritten.  Hopefully nobody copied the old code before it
Darwinized itself.  I'll edit the old entry with corrected
code.

&lt;p&gt; My hosting provider is lame.  JServ has not been running for
some time.  They never got back to me on any bug reports.  I
would finally phone them days later to get the latest
promise.  Now they say they're moving to JRun.  We'll see. 
Meanwhile, the only place where I can demo &lt;a href="http://c2.com/cgi/wiki?BRL" &gt;BRL&lt;/a&gt;
is &lt;a href="http://www.webappcabaret.com/brl/" &gt;BRL
Cabaret&lt;/a&gt;.  This is a free service shared by thousands of
other apps, and the entire BRL environment gets unloaded
after a short period of inactivity.  This makes the first
page load exceptionally slow.  For now I'll wait and see how
things go with my regular provider.  If it doesn't improve
I'll have to consider paying more than $17.95/month for
servlet+db hosting.</description>
    </item>
    <item>
      <pubDate>Mon, 12 Feb 2001 20:01:56 GMT</pubDate>
      <title>12 Feb 2001</title>
      <link>http://www.advogato.org/person/brlewis/diary.html?start=1</link>
      <guid>http://www.advogato.org/person/brlewis/diary.html?start=1</guid>
      <description>&lt;pre&gt;
#!/bin/sh
# script to copy memo from Palm &amp;quot;advogato&amp;quot; category to diary
# Memo must be filed under &amp;quot;advogato&amp;quot; and have 1st line &amp;quot;diary.txt&amp;quot;
&amp;nbsp;
topdir=$HOME
tmphtml=$topdir/diary$$.html
&amp;nbsp;
memos -d $topdir
&amp;nbsp;
cat &amp;gt; $tmphtml &amp;lt;&amp;lt;EOF
&amp;lt;form method=&amp;quot;POST&amp;quot; action=&amp;quot;http://advogato.org/diary/post.html&amp;quot;&amp;gt;
&amp;lt;textarea name=&amp;quot;entry&amp;quot;
EOF
&amp;nbsp;
(echo ' cols=60 rows=16&amp;gt;' ; \
 tail +2 $topdir/[Aa]dvogato/diary.txt \
 | sed -e 's/&amp;amp;/\&amp;amp;amp;/g' -e 's/&amp;lt;/\&amp;amp;lt;/g' -e 's/&amp;gt;/\&amp;amp;gt;/g') &amp;gt;&amp;gt; $tmphtml
&amp;nbsp;
cat &amp;gt;&amp;gt; $tmphtml &amp;lt;&amp;lt;EOF
&amp;lt;/textarea&amp;gt;
 &amp;lt;p&amp;gt;
 &amp;lt;input type=&amp;quot;submit&amp;quot; name=preview value=&amp;quot;Preview&amp;quot;&amp;gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=key value=&amp;quot;-1&amp;quot;&amp;gt;
&amp;lt;/form&amp;gt;
EOF
&amp;nbsp;
netscape -remote &amp;quot;OpenFile($tmphtml)&amp;quot;
&lt;/pre&gt;
</description>
    </item>
    <item>
      <pubDate>Tue, 29 Aug 2000 15:56:24 GMT</pubDate>
      <title>29 Aug 2000</title>
      <link>http://www.advogato.org/person/brlewis/diary.html?start=0</link>
      <guid>http://www.advogato.org/person/brlewis/diary.html?start=0</guid>
      <description>Actively working on &lt;a
href="http://brl.sourceforge.net/"&gt;BRL&lt;/a&gt;.
</description>
    </item>
  </channel>
</rss>
