program Tehtava12456(input, output);

{myös viimeisen kohdan operaatiot on ohjelmoitu}

type string  = ^merkki;
     merkki  = record
                  cha: char;
                  nex: string
               end;

var a, b, p, q: string;
    i: integer;

function length(s: string):integer;
  var kpl: integer;
begin
  kpl := 0;
  while s <> nil do
    begin
      kpl := kpl + 1;
      s := s^.nex;
    end;
  length := kpl;
end;

procedure empty(var s: string); {s := ''}
begin       {käytetään vain uuden merkkijonon alustamiseen!}
  s:= nil;
end;

procedure writestring(s: string);  
begin
  while s <> nil do
    begin
      write(s^.cha);
      s := s^.nex;
    end;
end; 

{---------readstring-----------------------------}
procedure readstring(var s: string);
  {Ohittaa välilyönnit ja rivinvaihdot ja sitten
   lukee välilyöntiin tai rivinvaihtoon asti.
   Käytetään input-tiedoston puskurimuuttujaa.}
var c: char;
    viim, uusi: string;
    alkublankoja: boolean;
begin
  s := nil; {oikeastaan s:n osoitt. lista pitäisi vapauttaa}
  if not eof then
    begin
      alkublankoja := (input^ = ' ');
      while alkublankoja do
        begin
          read(c); {luetaan välilyönti}
          if eof then
            alkublankoja := false
          else if (input^ <> ' ') then
            alkublankoja := false
        end;
      if not eof then
        while (input^ <> ' ') do {ei voi tulla eof,}
          begin                  {koska sitä ennen}
            read(c);             {input^ = ' '!!}
            new(uusi);
            uusi^.cha := c;
            uusi^.nex := nil;
            if s = nil then 
              begin {eka}
                s := uusi;
                viim := s;
              end
           else  {perään}
             begin
               viim^.nex := uusi;
               viim := uusi;
             end;
          end;
    end;
end;

{---------catenate------------------------------}
procedure catenate(var a: string; b: string);
 { a := a + b }
  var anloppu, kopiob, uusi, viim: string;
begin
  {tehdään ensin kopio b:stä}
  kopiob := nil;
  while b <> nil do
    begin
      new(uusi);
      uusi^.cha := b^.cha;
      uusi^.nex := nil;
      if kopiob = nil then {eka}
        begin 
          kopiob := uusi;
          viim := uusi;
        end
      else  {perään}
        begin
          viim^.nex := uusi;
          viim := uusi
        end;
      b := b^.nex;
    end;
  if a = nil then 
    a := kopiob
  else 
    {etsitään a:n loppu ja liitetetään sinne kopio}
    begin
      anloppu := a;
      while anloppu^.nex <> nil do 
        anloppu := anloppu^.nex;
      anloppu^.nex := kopiob;
    end;
end;

{---------trim----------------------------------}
procedure trim(var s: string);
  var p, q, lopunalku: string;
begin
  if length(s) > 1 then
    begin
      lopunalku := nil;
      p := s;
      while p^.nex <> nil do
        begin
          if (lopunalku = nil) and (p^.nex^.cha = ' ') then
            lopunalku := p
          else if p^.nex^.cha <> ' ' then
            lopunalku := nil;
          p := p^.nex;
        end;
      if lopunalku <> nil then
        begin
          p:= lopunalku^.nex;
          lopunalku^.nex := nil;
          while p <> nil do
            begin
              q := p;
              p := p^.nex;
              dispose(q);
            end;
        end;
    end;
end;

{---------pos-----------------------------------}
function pos(e, s: string): integer;
  var loytyi: boolean;
      sveralku, sver, ever: string; {'ver' = 'vertailtava'}
      paikka, enpit, i: integer;
begin
  pos := 0;  {pessimistisiä ennakko-odotuksia}
  loytyi := false;
  sveralku := s;
  enpit := length(e);
  paikka := 0;
  while (enpit <= length(sveralku)) and not loytyi do
    begin
       loytyi := true;
       ever := e;
       sver := sveralku;
       for i := 1 to enpit do
         begin
           if ever^.cha <> sver^.cha then
             loytyi := false;
           ever := ever^.nex;
           sver := sver^.nex;
         end;
       paikka := paikka + 1;
       sveralku := sveralku^.nex;     
    end;
  if loytyi then
    pos := paikka
end;

{--------------------------------------------------------}
begin            {TESTIPÄÄOHJELMA}
  writeln('>>>anna merkkijono');
  readstring(a);
  writeln('se oli:');
  writestring(a);
  writeln;
  writeln('>>>sen pituus on ',length(a):1);

  
  if not eof then begin
    writeln('>>>anna toinen merkkijono');
    readstring(b);
    writeln('se oli:');
    writestring(b); 
    writeln;
    writeln('>>>sen pituus on ',length(b):1);


    catenate(a, b);
    writeln('>>>eka + toka on:');
    writestring(a);
    writeln;
    writeln('>>>sen pituus on ', length(a):1);
    writeln('>>>toka on nyt:  ');
    writestring(b);
    writeln;   
  end;

  if not eof then begin
    writeln('>>>anna trimmattava merkkijono');
    readstring(a);
    writeln('>>>lisään sen loppuun blankoja, pari tähteä ja loppuun 7 blankoa');
    p := a;
    for i := 1 to length(a)-1 do
      p := p^.nex;
    for i := 1 to 3 do 
      begin
        new(q);
        q^.cha := ' ';
        q^.nex := nil;
        p^.nex := q;
        p := q;
      end;
    for i := 1 to 2 do 
      begin
        new(q);
        q^.cha := '*';
        q^.nex := nil;
        p^.nex := q;
        p := q;
      end;
    for i := 1 to 7 do 
      begin
        new(q);
        q^.cha := ' ';
        q^.nex := nil;
        p^.nex := q;
        p := q;
      end;
  

    write('>>>');
    writestring(a);
    writeln('<<<');
    writeln('>>>sen pituus on ',length(a):1);
    trim(a);
    write('>>>');
    writestring(a);
    writeln('<<<');
    writeln('>>>trimmattuna sen pituus on ',length(a):1);

    empty(a);
    trim(a);
    writeln('>>>trimmatun tyhjän merkkijonon pituus on ', length(a):1);

    new(a);
    a^.cha := ' ';
    a^.nex := nil;
    trim(a);
    writeln('>>>trimmatun '' ''- merkkijonon pituus on ', length(a):1);

    writeln('>>>posin testaus merkki ''*'' lopettaa');
    repeat
      writeln('anna se josta haetaan');
      readstring(a);
      writeln('anna se jota haetaan');
      readstring(b);
      writeln('posin arvo on ',pos(b, a):1); 
    until (a^.cha = '*') or (b^.cha = '*')
  end;

end.

