program DigitalRivers;
{
Solution to the 1999 British Informatics Olympiad exam
question 1: Digital Rivers

Solution copyright (c) 1999 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
}

{ Start value }
var
    n: integer;

function next_river( n: integer ): integer;
var
    s: integer;
begin
    s := n;
    while s > 0 do begin
        n := n + (s mod 10);
        s := s div 10;
    end;
    next_river := n;
end;

procedure part1a;
var
    river1, river3, river9: integer;
begin
    { We will use these variables to follow the routes of rivers 1, 3 and 9 }
    river1 := 1; river3 := 3; river9 := 9;

    { If we have not found a match, move along each river until we meet or
      pass n.  If we still haven't met n, move one step along river n. }
    while (n <> river1) and (n <> river3) and (n <> river9) do begin
        while river1 < n do river1 := next_river( river1 );
        while river3 < n do river3 := next_river( river3 );
        while river9 < n do river9 := next_river( river9 );
        if (n <> river1) and (n <> river3) and (n <> river9) then
            n := next_river( n );
    end;

    { Show the solution }
    if river1 = n then writeln( 'First meets river 1 at ', n );
    if river3 = n then writeln( 'First meets river 3 at ', n );
    if river9 = n then writeln( 'First meets river 9 at ', n );
end;

procedure part1b;
var
    start: integer;
    current: integer;
    hits: array[1..500] of integer;
begin
    { hits will store the number of times we have reached each river. }
    for current := 1 to 500 do hits[current] := 0;

    { Follow rivers 1 to 500 and note each time a value is 'hit' }
    for start := 1 to 500 do begin
        current := start;
        while current < 500 do begin
            inc(hits[current]);
            current := next_river( current );
        end;
    end;

    { Find the first time we meet a value 100 times }
    for current := 1 to 500 do if hits[current] = 100 then begin
            writeln( 'First number in 100 rivers is ', current );
            break;
        end;
end;

begin
    writeln( 'Enter a number from 1 to 16384 for part (a), or 0 for part (b)' );
    readln( n );
    if (n > 0) and (n <= 16384) then
        part1a
    else
        part1b;
    writeln( 'Program finished.' );
end.