/* Import the Java I/O package */ import java.io.*; import AppletConsoleApp; /** * Solution to the 1998 British Informatics Olympiad exam * question 1: Roman numerals * * This application that can be run either from the console * as a stand-alone application or from an in-applet * console created with the AppletConsole applet. * * Solution copyright (c) 1998 The British Informatics Olympiad (BIO). * * This program may be freely copied by persons or organisations * involved in the British Informatics Olympiad or the International * Olympiad in Informatics, on condition that no changes are made and * this notice is not altered. Distribution for profit is forbidden * unless permission is first obtained in writing from the BIO. * * This program is for educational purposes only and comes with no * warranty, implied or otherwise, as to its fitness for any purpose. * * Author: Antony Rix * Internet: http://www.christs.cam.ac.uk/bio/ * E-mail: a.rix@lineone.net * S-mail: The British Informatics Olympiad * Christ's College * Cambridge CB2 3BU * United Kingdom * * @author Antony Rix * @version 0.1 * @see AppletConsoleApp * @see AppletConsole */ class BIO98R1Q1App extends AppletConsoleApp { /** * Start the application from the command line. */ public static void main(String[] args) { BIO98R1Q1App thisApp = new BIO98R1Q1App(); thisApp.redirectStreams(System.in, System.out); thisApp.run(); } /** * The implementation of this application. * For 1(a), run() gets a number; if it is between 1 and * 3999 it translates it using toRoman(), and prints it. * If the number is less than 1, it solves part 1(c) by * exhaustive search. * * The answer to 1(b) is mccxlix + dcxv = mdccclxiv * (1249 + 615 = 1864). */ public void run() { int n, i, lgth, countLess, countMore; out.println( "Enter a number from 1 to 3999:" ); out.print( ">" ); try { /* Create a StreamTokenizer to allow us to read in the two numbers */ StreamTokenizer sin = new StreamTokenizer( in ); sin.nextToken(); n = (int)sin.nval; if( n <= 0 ) { countLess = 0; countMore = 0; for( i = 1; i < 10; i++ ) { lgth = toRoman( i ).length(); if( lgth > 1 ) countMore++; } for( i = 10; i < 100; i++ ) { lgth = toRoman( i ).length(); if( lgth < 2 ) countLess++; if( lgth > 2 ) countMore++; } for( i = 100; i < 1000; i++ ) { lgth = toRoman( i ).length(); if( lgth < 3 ) countLess++; if( lgth > 3 ) countMore++; } for( i = 1000; i < 4000; i++ ) { lgth = toRoman( i ).length(); if( lgth < 4 ) countLess++; if( lgth > 4 ) countMore++; } out.println( countLess + " Roman numerals from 1 to 3999 have fewer" ); out.println( "characters than digits and " + countMore + " have more." ); } else { if( n < 4000 ) out.println( n + " -> " + toRoman( n ) + "." ); else out.println( "Invalid number!" ); } } catch (IOException e) { out.println("I/O failure"); }; out.println( "Program finished." ); } static String[] units = // Units 0 to 9 { "", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix" }; static String[] tens = // Tens 0 to 90 { "", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc" }; static String[] hundreds = // Hundreds 0 to 900 { "", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm" }; static String[] thousands = // Thousands 0 to 3000 { "", "m", "mm", "mmm" }; public static String toRoman( int n ) { return thousands[ (n / 1000) ] + hundreds[ (n / 100) % 10 ] + tens[ (n / 10) % 10 ] + units[ (n) % 10 ]; } }