Search Amazon.com:
Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us $3,400 per month for bandwidth bills alone, and since we don't believe in shoving popup ads to our registered users, we try to make the money back through forum registrations.
  • Post
  • Reply
Admiral Snackbar
Mar 13, 2006


I just picked up an Arduino to tinker with and, being fairly new to C/C++, I'd like to learn to be as efficient with my coding as possible. I put together a Morse Code Generator that seems to work pretty well, but I'd like to get some feedback on it if anyone's interested. I can PM the code to you - it's 274 lines (compiles to 3,622 bytes), so I don't want to bloat this post with it. About two thirds of that length is devoted to assigning dots and dashes to letters, and this is something I'm a little concerned about - should I be able to do that job in less space?

Adbot
ADBOT LOVES YOU

Sinestro
Oct 31, 2010

Too hot for this airflow.


I'll help, but I don't have PMs. Just put it up as a gist. Edit: http://gist.github.com

Sinestro fucked around with this message at Mar 2, 2013 around 07:05

ShoulderDaemon
Oct 9, 2003


There are all kinds of stupid tricks you can do with compressing Morse code encoders and decoders.

For example, here's a fun way to store an encoder table:

C++ code:
#include <stdio.h>

#define LETTER(x) (letters[x-'A'])

#define DASH(x) (x & 0x80)
#define NEXT(x) (x & 0x7f)

static const char letters[] =
  { 'T'        // a . -
  , 'S' | 0x80 // b - ...
  , 'R' | 0x80 // c - .-.
  , 'I' | 0x80 // d - ..
  , 0          // e .
  , 'R'        // f . .-.
  , 'N' | 0x80 // g - -.
  , 'S'        // h . ...
  , 'E'        // i . .
  , 'O'        // j . ---
  , 'A' | 0x80 // k - .-
  , 'D'        // l . -..
  , 'T' | 0x80 // m - -
  , 'E' | 0x80 // n - .
  , 'M' | 0x80 // o - --
  , 'G'        // p . --.
  , 'K' | 0x80 // q - -.-
  , 'N'        // r . -.
  , 'I'        // s . ..
  , 0x80       // t -
  , 'A'        // u . .-
  , 'U'        // v . ..-
  , 'M'        // w . --
  , 'U' | 0x80 // x - ..-
  , 'W' | 0x80 // y - .--
  , 'D' | 0x80 // z - -..
  };

int main( int argc, char *argv[] ) {

  for ( char c = 'A'; c <= 'Z'; ++c ) {

    fprintf( stdout, "%c = ", c );

    char n = c;

    do {
      char l = LETTER(n);
      fprintf( stdout, "%c", DASH(l) ? '-' : '.' );
      n = NEXT(l);
    } while ( n );

    fprintf( stdout, "\n" );

  };

}
Here, I've abused the fact that all letters in Morse code are encoded as either a single dot or dash, or as a dot or dash followed by the legal encoding for some other letter. I store the encodings as an array of characters, where the lower 7 bits of the character are the character that encodes the tail, and the upper bit is set iff the first symbol for this character is a dash.

The only reason I use the big array notation and the eighth bit is for clarity when reading the code, of course. I could equivalently have written:

C++ code:
#define DASH(x) (x & 0x20)
#define NEXT(x) (x & 0xdf)

static const char *letters = "Tsri\0RnSEOaDtemGkNI AUMuwd";
by abusing the sixth bit instead of the eighth, which happens to be set in all lowercase ASCII letters and clear in all uppercase ASCII letters. Helpfully, the special cases of 0x00 and 0x20 (for E and T, respectively) have easy representations in ASCII as well.

Edit: It's somewhat interesting to note, or at least I am tired enough that it is interesting to me, that if you are encoding Morse-like encodings in this manner, the letters string should never have a character repeat.

More specifically, it should be some permutation of the string "\0 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", with the '\0' and ' ' characters always appearing in the first 26 characters (well, at least one, but it's dumb to not have both), and with no cycles under the NEXT operator (which of course only matters for the first 26 characters, as none of the remaining characters are reachable by the NEXT operator).

You can generate such strings programatically without too much trouble, so if you ever for some reason need to build a Morse-like encoding on the fly that isn't the real Morse code, building one of these strings is a reasonably cheap means of doing so. Presumably if you are ever going to write an old-school adventure game and require the player to do amateur cryptography to decode an in-game message this may be useful information.

ShoulderDaemon fucked around with this message at Mar 2, 2013 around 07:26

Admiral Snackbar
Mar 13, 2006


Sinestro posted:

I'll help, but I don't have PMs. Just put it up as a gist. Edit: http://gist.github.com

Thanks - here's the gist.

ANIME AKBAR
Jan 25, 2007

afu~

There is an Arduino thread in DIY.

Actually, Arduino language isn't really based on C/C++. It's based on the Processing language, which is actually based on Java.

ANIME AKBAR fucked around with this message at Mar 3, 2013 around 02:32

ShoulderDaemon
Oct 9, 2003


ANIME AKBAR posted:

Actually, Arduino language isn't really based on C/C++. It's based on the Processing language, which is actually based on Java.

The Arduino language actually is C++. It's not a different language, it's straight-up C++. It has a bunch of macros defined, and a special-purpose standard library, but the language itself is unchanged. The only gotcha is that there isn't an easily-available libstdc++ for the platform, so features which require runtime support like exceptions may not function.

Adbot
ADBOT LOVES YOU

Admiral Snackbar
Mar 13, 2006


ANIME AKBAR posted:

There is an Arduino thread in DIY.

Thanks for the heads up!

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply