NYCJUG/2011-02-08/VeederCounter

From J Wiki
Jump to navigation Jump to search

Veeder Counter

from		Skip Cave <skip@caveconsulting.com>
to		Programming forum <programming@jsoftware.com>
date		Mon, Jan 31, 2011 at 4:17 PM
subject	[Jprogramming] Text Manipulation Question

if I generate a series of random numbers 0-999 in the array "a":

   a = 200 ? 1000
   4 {. a
590 730 584 189

And an array of text strings in the array "b":

   $ b
200
   3 {. b
+-----+-----+-----+
|C1001|E3014|V2233|
+-----+-----+-----+

how can I add some more non-varying characters, and build those random numbers and text strings into a third array of text strings, called array c?:

   c
abc _590 = C1001.txt
abc _730 = E3014.txt
abc _584 = V2233.txt
...
Skip Cave

---

from	Henry Rich <HenryHRich@nc.rr.com>
date	Mon, Jan 31, 2011 at 4:29 PM


	
require 'printf'

    > 'abc _%d = %s.txt' vbsprintf (3{.a) ;"0 (3{. b)
abc _734 = a.txt
abc _480 = b.txt
abc _671 = c.txt

   > 'abc _%5.5d = %s.txt' vbsprintf (3{.a) ;"0 (3{. b)
abc _00734 = a.txt
abc _00480 = b.txt
abc _00671 = c.txt

Henry Rich ---

from	Ian Clark <earthspotty@gmail.com>
date	Mon, Jan 31, 2011 at 8:03 PM

Smart stuff.

I make heavy use of my own routines to do this sort of stuff and I see I needn't have bothered. It's not my inability to cobble up what's needed, as it's needed (a mundane skill for someone who hates looking up documentation), but the time entailed in testing out homespun routines (voluntary or enforced). Freedom from gotchas is more vital to me than naked machine efficiency, so it's good to use something venerable like printf.

Henry's solution will suit a requirement I often encounter: handling ids of the form: abc00123, ie treating those trailing digits as a sort of Veeder counter. But let me just ask this, as a rider to Skip's request:

What's people's fave way to generate the next (or previous) id in a series, eg 'abc00100' from the string 'abc00099'?

Much software bilks the user, stepping say from: "image9.tiff" to: "image10.tiff". This is unhelpful when sorting generated filenames in a Fileman or Finder window

Ignore the obvious problem with: abc99999 --depend on having enough 0s in there. Don't demand a parameter like 3 or 'abc' to isolate the suffix. Oh, and don't assume the prefix is digit-free. There can be 1 to 8 digits in the suffix, so you can employ 100000000+y and drop the '1'. Restrict to +integer suffixes (stepping back abc00000 should wraparound to abc99999) but beware the prefix might actually end with '-' or '_', viz: abc_002. ---

from	[[User:Raul Miller|Raul Miller]] <rauldmiller@gmail.com>
date	Mon, Jan 31, 2011 at 10:31 PM

On Mon, Jan 31, 2011 at 8:03 PM, Ian Clark <earthspotty@gmail.com> wrote:

> What's people's fave way to generate the next (or previous) id in a
> series, eg 'abc00100' from the string 'abc00099'?

I never use this but if I did, I probably would use:

incsfx=: (,  >:&.".&.(,~&'1')@,&'x')&>/@(</.~  <./\.@e.&'0123456789')

Note, however, that I did not limit the suffix length to 8 digits, instead I wrap when however many digits were in use becomes inadequate.

Note also that this requires that a non-numeric prefix be present. If that were a problem you could use incsfx&.(,~&' ')

-- Raul

---

from	Devon McCormick <devonmcc@gmail.com>
date	Mon, Jan 31, 2011 at 10:33 PM

I usually rely on knowledge of the prefix - like using 3&}. - but a more general solution might use something like this (in J7):

   *./\&.|.'a2b33c00100' e. Num_j_
0 0 0 0 0 0 1 1 1 1 1

to generate the boolean selector for the number portion. This assumes that the prefix has a non-numeric ending to separate it from the number part. ---

from	Ian Clark <earthspotty@gmail.com>
date	Wed, Feb 2, 2011 at 10:45 AM
}}}	

Thanks Raul and Devon.

You echo my own line of thinking. So I felt reassured I wasn't missing a trick.

Then, mulling over your answers, I thought: "it's a Veeder counter! Why not use the Veeder algorithm?" To the younger generation: a Veeder counter is a non-electronic click-around cycle meter.

Here's the algorithm in explicit form:

bump=: 3 : 0
   try.
       (}:y), '0123456789' {~ >: ". {:y      NB. inc last digit only
   catch.
       '0',~ bump }:y                        NB. inc (}:y) and append '0'
   end.
)

Note the use of: '0123456789' {~ -in place of: ": to force an error at nnnn9. (...Shame there isn't a noun: (n.) -: '0123456789' analogous to (a.).)

And here's my first proper go at a complex tacit verb (with heavy use of (13 :) and (f.) I must confess ;)

bump=: (}: , '0123456789' {~ [: >: [: ". {:) ::('0' ,~ [: $: }:)

   bump y=: 'abc00098'
abc00099
   bump y9=: 'abc00099'
abc00100
   bump yz=: 'abc09999'
abc10000

Is there any advantage over Raul's incsfx I wondered? Mine looks shorter, but surely such a cloddish recursion is going to be inefficient? So I did some timings:

     timer 'incsfx y'
5.00488e_5
     timer 'incsfx y9'
5.41687e_5
     timer 'incsfx yz'
5.38635e_5

     timer 'bump y'
1.38855e_5
     timer 'bump y9'
2.59399e_5
     timer 'bump yz'
3.09753e_5

...Made my day!

Thanks, guys, for helping turn the hay in my mind.

I'm really sold on ($:) and (::) now... though the latter does seem like cheating.