regular expression to describe 16 degrees of wind direction 
Author Message
 regular expression to describe 16 degrees of wind direction

I am cross-posting this to a few newsgroups because it does not apply to any
group in particular, but I wanted to share it and perhaps get commets.

I'm attempting to write a regular expression that describes the 16 degrees
of wind direction without enumerating each.  I would like the regular
expression to be as elegant as possible.

The expression I have come up with is:
[NS]|((([NW]?N)|([SW]?S))?W)|((([NE]?N)|([SE]?S))?E)    (1)

which is one character longer than enumerating each:
N|S|E|W|NE|SE|NW|SW|NNE|ENE|SSE|ESE|NNW|WNW|SSW|WSW    (2)

I came up with (1) by grouping from right to left in the list below (since
the direction is modified by the prefix, and not vice-versa).
  N
  S
  E
 NE
NNE
ENE
 SE
SSE
ESE
  W
 NW
NNW
WNW
 SW
SSW
WSW

Can anyone conceive a more elegant RE that matches the 16 items and only the
16 items?  Does anyone see a reason why the one I have described (1) is not
correct?

Regards,
Jason



Sat, 06 Aug 2005 01:22:32 GMT  
 regular expression to describe 16 degrees of wind direction

Quote:
> I am cross-posting this to a few newsgroups because it does not apply to any
> group in particular, but I wanted to share it and perhaps get commets.

> I'm attempting to write a regular expression that describes the 16 degrees
> of wind direction without enumerating each.  I would like the regular
> expression to be as elegant as possible.

> The expression I have come up with is:
> [NS]|((([NW]?N)|([SW]?S))?W)|((([NE]?N)|([SE]?S))?E)    (1)

> which is one character longer than enumerating each:
> N|S|E|W|NE|SE|NW|SW|NNE|ENE|SSE|ESE|NNW|WNW|SSW|WSW    (2)

If you're really doing this as a puzzle, and more interested in fun,
go for it.  Puzzles are good.

But if you want to have readable, maintainable code, I suggest

%heading = {
      N =>   0        ,
    NNE =>   0 + 22.5 ,
     NE =>  45        ,
    ENE =>  45 + 22.5 ,
      E =>  90        ,
    ESE =>  90 + 22.5 ,
     SE => 135        ,
    SSE => 135 + 22.5 ,
      S => 180        ,
    SSW => 180 + 22.5 ,
     SW => 225        ,
    WSW => 225 + 22.5 ,
      W => 270        ,
    WNW => 270 + 22.5 ,
     NW => 315        ,
    NNW => 315 + 22.5 ,

Quote:
};

Then glom the keys together into a RE
    $heading_re = qr(sprintf "m/(?:%s)/", join("|", keys %heading));

This makes the lookup easy:

if ($new_compas_point =~ $heading_re) {
    $new_heading = $heading{$new_compas_point};

Quote:
} else {
    ....
}

But then again, why have a hash to create a RE?  Just use exists...

    if (exists $heading{$new_compas_point}) {
    ...

--
Michael R. Wolf
    All mammals learn by playing!



Sat, 06 Aug 2005 02:26:22 GMT  
 regular expression to describe 16 degrees of wind direction
Quote:
"Jason R. Coombs" wrote...

..
Quote:
>I'm attempting to write a regular expression that describes the 16 degrees
>of wind direction without enumerating each.  I would like the regular
>expression to be as elegant as possible.

>The expression I have come up with is:
>[NS]|((([NW]?N)|([SW]?S))?W)|((([NE]?N)|([SE]?S))?E)    (1)

>which is one character longer than enumerating each:
>N|S|E|W|NE|SE|NW|SW|NNE|ENE|SSE|ESE|NNW|WNW|SSW|WSW    (2)

..

First off you need to have some sort of delimiter, or you'll very likely get
false matches. So something like

/^[ENSW]?([NS][EW])?$/

which recognizes the fact that N(orth) and S(outh) only appear as the last char
for due North and due South. I don't think you can name that tune in fewer
chars.

--
Public Service Announcement
Don't attach files to postings in nonbinary newsgroups like this one.



Sat, 06 Aug 2005 03:08:43 GMT  
 regular expression to describe 16 degrees of wind direction
Quote:
"Harlan Grove" wrote...

..
Quote:
>/^[ENSW]?([NS][EW])?$/

..

And as for converting bearings to degrees and degrees to closest bearing
(rounding counterclockwise), in awk use a mechanism like

BEGIN {
split("E,ENE,NE,NNE,N,NNW,NW,WNW,W,WSW,SW,SSW,S,SSE,SE,ESE", _bd_, ",")

for (i = 1; i <= 16; ++i) {
_bd_[x = (i - 1) * 22.5] = _bd_[i]
_bd_[_bd_[i]] = x
delete _bd_[i]

Quote:
}
}

function b2d(b) { return (b in _bd_) ? _bd_[b] : "" }

function d2b(d) {
return (d "" == "0" || -d < 0) ? _bd_[22.5 * int((d + 11.25) / 22.5)] : ""

Quote:
}

--
Public Service Announcement
Don't attach files to postings in nonbinary newsgroups like this one.


Sat, 06 Aug 2005 04:14:50 GMT  
 regular expression to describe 16 degrees of wind direction
Bug fix!

function d2b(d) {
return (d "" == "0" || -d < 0) ? \
_bd_[(22.5 * int((d + 11.25) / 22.5)) % 360] : ""

Quote:
}



Sat, 06 Aug 2005 04:17:56 GMT  
 regular expression to describe 16 degrees of wind direction

Quote:
> I am cross-posting this to a few newsgroups because it does not apply to any
> group in particular, but I wanted to share it and perhaps get commets.

> I'm attempting to write a regular expression that describes the 16 degrees
> of wind direction without enumerating each.  I would like the regular
> expression to be as elegant as possible.

> The expression I have come up with is:
> [NS]|((([NW]?N)|([SW]?S))?W)|((([NE]?N)|([SE]?S))?E)    (1)

> which is one character longer than enumerating each:
> N|S|E|W|NE|SE|NW|SW|NNE|ENE|SSE|ESE|NNW|WNW|SSW|WSW    (2)
> N
> S
> E
> W
> NE
> NW
> SE
> SW
> NNE
> NNW
> SSE
> SSW
> ENE
> ESE
> WNW
> WSW

- 1/2 letters: [NS]?[EW]?
- 3 letters: (NN|SS)[EW] E[NS]E W[NS]W

--

Linux solution for data management and processing.



Sat, 06 Aug 2005 07:25:42 GMT  
 regular expression to describe 16 degrees of wind direction
Quote:
"William Park" wrote...

..

Quote:
>- 1/2 letters: [NS]?[EW]?
>- 3 letters: (NN|SS)[EW] E[NS]E W[NS]W

You did a better job than me, but the 1/2 letters regex would match zero-length
strings. The 1 letter case must be separate - [ENSW]. So it looks like the whole
thing must be /^([ENSW]|E?[NS]E|W?[NS]W|(NN|SS)[EW])$/ .


Sat, 06 Aug 2005 08:23:57 GMT  
 regular expression to describe 16 degrees of wind direction

Quote:
> "William Park" wrote...
> ..
>>- 1/2 letters: [NS]?[EW]?
>>- 3 letters: (NN|SS)[EW] E[NS]E W[NS]W

> You did a better job than me, but the 1/2 letters regex would match zero-length
> strings. The 1 letter case must be separate - [ENSW]. So it looks like the whole
> thing must be /^([ENSW]|E?[NS]E|W?[NS]W|(NN|SS)[EW])$/ .

I don't know why OP wants a shorter one.  Maybe for homework.  But,
listing them all explicitly is not that bad.

--

Linux solution for data management and processing.



Sat, 06 Aug 2005 09:41:16 GMT  
 regular expression to describe 16 degrees of wind direction

Quote:
> The expression I have come up with is:
> [NS]|((([NW]?N)|([SW]?S))?W)|((([NE]?N)|([SE]?S))?E)    (1)
> which is one character longer than enumerating each:
> N|S|E|W|NE|SE|NW|SW|NNE|ENE|SSE|ESE|NNW|WNW|SSW|WSW    (2)

/^(((N|S)?(E|W)(N|S)?))$|^(((E|W)?(N|S)(E|W)?))$|^((SS|NN)(W|E))$/

I have put it under some abuse, ie SS, NN, SNE, but i havent test it
carefully. There is a swedish saying about this: "genv?gar ?r ofta senv?gar".
Meaning shortcuts are longer :)

Next step would be to extend it to 4 character codes, ie ENNE. Anyone? :)
//Mats

--
My code (if any) in this message are Copyright (C) 2003 Mats Blomstrand
and licensed under GNU GPL, http://www.gnu.org/licenses/gpl.html



Sat, 06 Aug 2005 18:46:53 GMT  
 regular expression to describe 16 degrees of wind direction
..
Quote:
>/^(((N|S)?(E|W)(N|S)?))$|^(((E|W)?(N|S)(E|W)?))$|^((SS|NN)(W|E))$/

..

(N|S)?(E|W)(N|S)? would match, e.g., EN, which is not a bearing. Due North and
due South are the only bearings that that have N or S as the rightmost char. For
that matter, a|b is never preferable to [ab].

Quote:
>Next step would be to extend it to 4 character codes, ie ENNE. Anyone? :)

..

/^([ENSW]|[EN]{0,2}NE|[NW]{0,2}NW|[SW]{0,2}SW|[ES]{0,2}SE)$/

which scales nicely to 5 char bearings as

/^([ENSW]|[EN]{0,3}NE|[NW]{0,3}NW|[SW]{0,3}SW|[ES]{0,3}SE)$/

etc.

--
Public Service Announcement
Don't attach files to postings in nonbinary newsgroups like this one.



Sun, 07 Aug 2005 04:42:33 GMT  
 regular expression to describe 16 degrees of wind direction

Yes, my expression is not good enough. But im afraid your suggestions
isnt either :(

Quote:
> /^([ENSW]|[EN]{0,2}NE|[NW]{0,2}NW|[SW]{0,2}SW|[ES]{0,2}SE)$/
> /^([ENSW]|[EN]{0,3}NE|[NW]{0,3}NW|[SW]{0,3}SW|[ES]{0,3}SE)$/

bash$ awk ' .. line 1 above ..' data
N
S
W
E

Same for for line 2.  This is the input file.

bash$ cat data
N
NW
NE
NNW
NNE
S
SW
SE
SSW
SSE
W
WNW
WSW
E
ENE
ESE

NN
SS
EE
WW
SSS
SNE

The shortest regex is the strings themselves, i believe.
A good example of when regex's doesnt cut it.
//Mats

--
My code (if any) in this message are Copyright (C) 2003 Mats Blomstrand
and licensed under GNU GPL, http://www.gnu.org/licenses/gpl.html



Sun, 07 Aug 2005 16:50:28 GMT  
 regular expression to describe 16 degrees of wind direction
Quote:


>Yes, my expression is not good enough. But im afraid your suggestions
>isnt either :(

>> /^([ENSW]|[EN]{0,2}NE|[NW]{0,2}NW|[SW]{0,2}SW|[ES]{0,2}SE)$/
>> /^([ENSW]|[EN]{0,3}NE|[NW]{0,3}NW|[SW]{0,3}SW|[ES]{0,3}SE)$/

>bash$ awk ' .. line 1 above ..' data
>N
>S
>W
>E

>Same for for line 2.  This is the input file.

>bash$ cat data
>N
>NW
>NE
>NNW
>NNE
>S
>SW
>SE
>SSW
>SSE
>W
>WNW
>WSW
>E
>ENE
>ESE

>NN
>SS
>EE
>WW
>SSS
>SNE

..

Looks like (1) you're using Linux, (2) are unaware that 'awk' under bash under
Linux is usually an alias or symlink to gawk, and (3) that you must use either
the --posix or --re-interval command line switch with gawk to use interval
qualifiers like {0,3}.

With your data, running GnuWin32 gawk 3.1.0 under a Win32 zsh port,

$cat a
/^([ENSW]|[EN]{0,2}NE|[NW]{0,2}NW|[SW]{0,2}SW|[ES]{0,2}SE)$/
$gawk --re-interval -f a data
N
NW
NE
NNW
NNE
S
SW
SE
SSW
SSE
W
WNW
WSW
E
ENE
ESE
$

Looks like my regex is adequate for anyone who knows the peculiarities of
his/her awk implementation, and if that awk implementation supports interval
qualifiers.

--
Public Service Announcement
Don't attach files to postings in nonbinary newsgroups like this one.



Mon, 08 Aug 2005 01:40:59 GMT  
 regular expression to describe 16 degrees of wind direction

Quote:
> Looks like (1) you're using Linux, (2) are unaware that 'awk' under bash under
> Linux is usually an alias or symlink to gawk, and (3) that you must use either
> the --posix or --re-interval command line switch with gawk to use interval
> qualifiers like {0,3}.

1: Yes.
2: No.

3: That i didnt know! I have been struggling with them and not getting them
   to work. Thanks!

//Mats

--
My code (if any) in this message are Copyright (C) 2003 Mats Blomstrand
and licensed under GNU GPL, http://www.gnu.org/licenses/gpl.html



Mon, 08 Aug 2005 15:48:25 GMT  
 
 [ 13 post ] 

 Relevant Pages 

1. wind direction in a string

2. Help need with regular expressions and try to find the expression .t

3. YAPC::Canada - May 15 and 16, 2003, Ottawa, Canada

4. Converting UTF-16 string from big-endian to little-endian

5. Perl on DOS (16 bit version that is)?

6. Error in LWP [Bad arg length for Socket::unpack_sockaddr_in, length is 0, should be 16]

7. rand producing numbers 2^16 too small

8. Need 16 to 8 bit hint...

9. 16-bit perl programs?

10. UTF - SEEK_SET workaround for BOM encoding(utf-16/32) layer Bug

11. 16 bit application

12. YAPC::Canada - May 15 and 16, 2003 in Ottawa - http://www.yapc.ca/

 

 
Powered by phpBB® Forum Software