(this is a resend of a message that got caught in the moderation queue) I have a friend who occasionally runs programming competitions for kids, and when he's putting together exercises he sometimes runs them by us just to see what we'll come up with. The other day he posted a description of a simple task and I thought I'd have a go. I got it working in Python very neatly, but then I decided I'd see if I could figure out how to do the same in Factor.
Here's the problem description: Code Golf Challenge #1 ====================== Write something that will: * Encode stdin into chunks like so: 01 1 octet SOH xxxx 2 octets chunk number (monotonically increasing) xx 1 octet chunk length ... <256 octets up to 255 bytes of data xx 1 octet checksum (8-bit sum of all data bytes) with an "end of transmission" marker of: 04 1 octet EOT xxxx 2 octets chunk number 00 1 octet length 0 * optionally shuffle chunks * base64-encode output Your entry should be *readable*. Use any standard libraries you want. Par 78 SLOC (ANSI C). It relies on standard Unix tools and pipes. For what it's worth, I'm told this algorithm is very similar to the ancient XMODEM file-transfer protocol. Yes, 'readable' conflicts with 'code golf'; at least for the Factor version I'm trying to prefer readability over brevity. Also, comparing my implementation to the sample ANSI C implementation, it turns out there are extra rules: - chunk length is actually capped at 128 bytes - the uint16 chunk length should be stored in big-endian order Here's my Factor implementation. It works (that is, it produces identical output to the reference implementation), but it's not very pretty (note that I've ignored the 'shuffle' feature, and base64 encoding is done with an external tool, same as the reference implementation): USING: arrays io io.encodings io.encodings.binary kernel locals make math pack sequences syntax ; IN: bmodem CONSTANT: WINDOW 128 ! Splits stdin into an array of WINDOW-sized byte-arrays. : read-chunks ( -- seq ) [ [ WINDOW read dup f = [ ] [ , t ] if ] loop ] { } make ; ! Takes a sequence of payload byte-arrays and frames each one ! with a packet-header and check-sum. ! Also adds the trailer ("EOT") packet. : format-packets ( seq -- seq' ) [ [ [| payload index | 1 index payload length 3array "CSC" pack-be % payload % payload sum 256 mod , ] B{ } make ] map-index ] [ length 4 swap 0 3array "CSC" pack-be ] bi suffix ; ! Slurp bytes from stdin, spit packets to stdout. : main ( -- ) binary decode-input read-chunks binary encode-output format-packets [ write ] each ; MAIN: main In particular, the way read-chunks breaks out of the loop when it's hit EOF strikes me as ugly, what with the if word's quotations having different stack signatures. Also, there's still a few stack-shuffling words lurking about in there. I'm not sure if that's within standard tolerances, or if I'm doing something wrong. Any hints or suggestions? ------------------------------------------------------------------------------ Try before you buy = See our experts in action! The most comprehensive online learning library for Microsoft developers is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3, Metro Style Apps, more. Free future releases when you subscribe now! http://p.sf.net/sfu/learndevnow-dev2 _______________________________________________ Factor-talk mailing list Factor-talk@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/factor-talk