POSIX sed, 245 ============== POSIX sed, no extensions or extended regexps. Input is limited to the maximum hold space size of sed - POSIX mandates at least 8192; GNU manages more. This version assumes that there will be no blank lines before or after the shape; an extra 10 bytes of code, indicated in the expansion, can accommodate that if it's a requirement (original question doesn't specify). H /^\([L\\]_*\/\|V\| \)*$/!d x s/[_ ]/ /g s/^/!/ s/$/!/ :g s/\([^V]\)V/V\1/ tg y/V/ / s/L/! /g s,[/\\], ! ,g s/![^!]*!//g :d / /{ s/ /v/g s/vv/x/g /[ v]/!s/\b/0/2 s/ /b/g s/bb/4/g s/b /3/ s/v /6/ s/vb/7/ s/v3/8/ s/v4/9/ y/ bvx/125 / td } Expanded and annotated ---------------------- #!/bin/sed -f # If leading blank lines may exist, then delete them (and add 8 bytes) #/^ *$/d # Collect input into hold space until we reach the end of the figure H /^\([L\\]_*\/\|V\| \)*$/!d x # Space and underscore each count as two units s/[_ ]/ /g # Add an edge at the beginning and end, so we can delete matching pairs s/^/!/ s/$/!/ # Move all the V's to the beginning and convert to a single unit of area :gather s/\([^V]\)V/V\1/ tgather y/V/ / # L is a boundary to left of cell; / and \ in middle s/L/! /g s,[/\\], ! ,g # Strip out all the bits of outer region s/![^!]*!//g # Now, we have a space for each unit of area, and no other characters # remaining (spaces are convenient because we will use \b to match # where they end). To count the spaces, we use roman numerals v and x # to match five and ten, respectively. We also match two (and call # that 'b'). At the end of the loop, tens are turned back into spaces # again. :digit / /{ s/ /v/g s/vv/x/g /[ v]/!s/\b/0/2 s/ /b/g s/bb/4/g s/b /3/ s/v /6/ s/vb/7/ s/v3/8/ s/v4/9/ y/ bvx/125 / tdigit } # If trailing blank lines may exist, then stop now (and add 2 bytes) #q