# Programming challenge

Fri Sep 28 15:20:03 MDT 2007

```Thus said "Sasha Pachev" on Thu, 27 Sep 2007 15:44:45 MDT:

> Given a  string that  could contain  arithmetic expressions,  with the
> addition  that numeric  constants  could be  potentially expressed  as
> times, e.g  1:36 for  96 seconds,  or 2:10:08 for  2 hours  10 minutes
> and  8 seconds,  also  decimal fractions  after  seconds are  allowed,
> e.g  3:45.6 or  3:40:50.67, replace  all  the time  values with  their
> equivalent number of seconds.

Here's a Tcl implementation:

------------------------------------------------------------------------
#!/bin/sh
# \
exec tclsh "\$0" \${1+"\$@"}

while {[gets stdin line] >= 0} {
set j 0
while {[regexp -indices -start \$j {(?x) \d+:\d+(?::\d+)?(?:\.\d+)?} \$line matc
h]} {
foreach {i j} \$match {}
set s [split [string range \$line \$i \$j] :]
set y [llength \$s]
set z 0
for {set x 0} {\$x < \$y} {incr x} {
set z [expr \$z * 60 + [scan [lindex \$s \$x] "%d"]]
if {[regexp {(\.\d+)} [lindex \$s \$x] m]} {
set z [expr \$z + 60 * [scan \$m "%f"]]
}
}
set line [string replace \$line \$i \$j \$z]
incr j [expr [string length \$z] + \$i - \$j + 1]
}
puts stdout \$line
}
------------------------------------------------------------------------

Assumptions:

This is used as a traditional  Unix filter; the arithmetic expression is
provided  on  stdin, one  expression  per  line  (since we  are  talking
strings), and it writes the converted expression to stdout.

Andy
--
[-----------[system uptime]--------------------------------------------]
3:18pm  up  6:13,  1 user,  load average: 1.00, 1.00, 1.00

```