
   Introduction
 

  This time your task is to write a small number converter: from decimal no-
  tation to roman and back.  To make it  a bit more difficult and waste some
  more bytes, your entry has to handle some kinds of incorrect input.


   The task
 

   1. Roman notation

  Before we begin with the actual task,  here is a short description of what
  the roman notation is. Roman notation was used by the ancient Romans  (and
  this is not strange :)  and is sometimes  used nowadays,  for example,  on
  clock-faces or for numbering chapters in books. It is based on four digits
  for the first four powers of ten:  I=1, X=10, C=100, M=1000 and three more
  digits for their halves:  V=5, L=50 and D=500.  Only positive integers can
  be expressed in roman notation. All numbers are written with repetition of
  these seven digits.

  Now, your task  is to  convert  a stream of numbers from STDIN either from
  roman to decimal or  from decimal  to  roman. Your entry has to check each
  roman or decimal number  to be valid  and only output the conversion if it
  is valid. In our task we have chosen  the  following special  rules: (Some
  people think different about those, though if you do, express your opinion
  to the group at an early stage of the compo, and it will be seriously con-
  sidered.)

  I may only precede V or X
  X may only precede L or C
  C may only precede D or M

  and these combinations are invalid

  VIV ... should be written as IX
  LXL ... should be written as XC
  DCD ... should be written as CM

  The maximum number of repetitions of I,X,C or M are 3, so IIII is INVALID
  (even though the Romans who built my clock thought different about the 
  subject :-)

  These rules  ensure  that there is only  one roman representation  for any
  decimal number, and the other way round.

  For a more detailed description of roman numbers see detail.txt
    

   2. INPUT from STDin

  There are two types  of conversions, so there are  two corresponding STDin  
  input formats. In  both cases, the  only item in  the STDin  stream  is  a
  number in either of the two notations and  (guess what ;) your entry is to
  convert it into the other notation.  A valid number in decimal notation is
  a positive integer with a value between 1 and 4000. A roman number is con-
  sidered valid if it is  written in  uppercase and  follows rules explained 
  above.

  The input from STDIN may contain  any number of lines ending  with a CR,LF
  pair, each of which is no longer than 100 characters (102  with the CRLF).

  You may assume that DOS reflects  the full <cr><lf> pair at the end of each
  line in the input stream, i.e. the input IS redirected.  You may not assume
  on the other hand that the input is  NOT redirected, since  that's how  the
  test suite feeds the input to the entry.

  You may  assume that  the  last line in  the file  from  STDIN starts with 
  ^Z = EOF = 1ah and is followed by CRLF. You may also  assume that the input
  You  may also assume  that the EOF is the one and only char on its line
  followed by a CRLF pair.

  You can assume that each line contains either a decimal number a series of
  roman digits (i.e. the letters MDCLXVI only).  In the latter case, you may
  not assume that the roman number is a valid one: if the syntax is incorrect,
  don't print anything. For decimal numbers your entry has to check the value
  if the value is less than 1 or the value is greater than 3999 your entry
  must not print anything.

   3. Output

  Your program must output representations of all number in the STDin stream
  as specified above to STDout, allowing for redirection (again, this is ne-
  eded by the test suite).  Each number must be printed on the standard out-
  put with a trailing CRLF pair.  No space, no NUL,  no other character that
  doesn't belong to the representation.

  If a number  read from the STDin stream  is invalid,  your entry  must not
  output anything  and simply skip to the  next number until  a valid number
  is found or until EOF.  After EOF, your entry must quit to DOS immediately
  without crashing and without printing anything else.


   Other assumptions
 

  For all  other  assumptions that  can or  can't  be made, check general.txt
  which was taken from previous Hugi compos.


   Example algorithms
 

  A decimal number can be converted to its Roman equivalent using a two-
  step process. First replace each digit (n) in the decimal number with its
  Roman representation (r, s, and t) as shown here:

        n       Roman representation
        -       --------------------
        0        (nothing)
        1        r
        2        rr
        3        rrr
        4        rs
        5        s
        6        sr
        7        srr
        8        srrr
        9        rt

  Then replace the Roman representation with Roman numerals depending on
  the position (k) of the digit (n) in the decimal number.

        position        k       r s t
        --------        -       -----
        ones            0       I V X
        tens            1       X L C
        hundreds        2       C D M
        thousands       3       M - -

  For example, the number 1984 would be:

        1     9     8     4
        r     rt    srrr  rs
   k:   3     2     1     0
        M     CM    LXXX  IV

  Putting it together gives: MCMLXXXIV.


  A Roman number can be converted to decimal with this procedure:

    set Data[M] to 1000, Data[D] to 500, Data[C] to 100, etc.
    set Valsub[C] to "DM", Valsub[X] to "LC", Valsub[I] to "VX"
    set Valid to "MMMDCCCLXXXVIII"
    set Sum to 0

    for each character in the Roman number (in sequence, from left to right)
        read a character from the Roman number string and set Char to it
        set Next to the next character in the string

        check that Valid contains Char.  if absent, fail
        remove all the characters in Valid preceding the first instance of Char

        if Valsub[Char] contains Next
            set Sum to Sum - Data[Char]
            remove all occurrences of Char in Valid except the last one
            replace the first (remaining) character in Valid with Next
        else
            set Sum to Sum + Data[Char]
            remove the first (remaining) character in Valid


   Test suite
 

  The test suite does more than 400 tests for each of decimal->roman,
  roman->decimal and bad roman numerals.  Type TEST.BAT to run it and be
  patient...


   Submission
 

  For the first part of the compo, please send your submission to:
    fys@cybertrails.com
  and if you would place a subject line of
    [entry]
  it would help me out a lot, but it is not required :)

  For the second part of the compo, if Adok finishes his work before
  the schedule ends, please send your submission to:
    cdvolko@gmx.net   (will be corrected by Adok if he sees fit)


   Schedule
 

  May 22, 2002               Compo starts.
  Jul 31, 2002 11:59 pm MST  Deadline for entry submission.
  Aug 01, 2002               Entries and beta results will be released.
                             Start of Public Judgement.
  Aug 07, 2002 11:59 pm MST  End of Public Judgement.
  Aug 08, 2002               Final results will be released.


   Credits
 

  The task ................................................ Vinicius Fortuna
  The rules ............................... Boiled Brain, Bonz, Sniper, Ruud
  Example program ....................................... Bonz, Ruud, Boreal
  Test suite .............................. Ruud, Bonz, many Unix utilities!
  Compo hosting ............................................... Adok, Sniper

Adok/Hugi (hugi@netway.at) & co.

