program pokeris;
  { 140 u‘davinys }
  const MAX_K = 5;  { duot— kort— skai‡ius }
        MAX_P = 8;  { ižložian‡i— pad‚‡i— skai‡ius }
        MAX_R = 6;  { kort— rang— skai‡ius }
  type  korta = record
                  ran: longint; { kortos rangas }
                  sp : char     { kortos r–žis }
                end;
        kortos = array [1..MAX_K] of korta;
        islosimas = array [1..MAX_P] of longint; { ižložiamos sumos }
        log_mas = array [1..MAX_K] of boolean;
                  { paliekama korta ar kei‡iama }
        rangai = array [1..MAX_R] of longint;

  {--------------------------------------------------------}
  procedure skaityk (var k: kortos; var isl: islosimas);
  { perskaito pradinius duomenis }
    var f: text;
        i: longint;
  begin
    assign (f, 'POKERIS.DAT');
    reset (f);
    for i := 1 to MAX_K do
       readln (f, k[i].sp, k[i].ran);
    for i := 1 to MAX_P do
       readln (f, isl[i]);
    close (f);
  end;  { skaityk }

  {--------------------------------------------------------}
  procedure rezultatai (opt: log_mas);
    var f: text;
        i: longint;
  begin
     assign (f, 'POKERIS.REZ');
     rewrite (f);
     for i := 1 to MAX_K do
        if opt[i] then writeln (f, 'TAIP')
                  else writeln (f, 'NE');
     close (f)
  end; { rezultatai }

  {--------------------------------------------------------}
  procedure spresk (k: kortos;      { duotosios kortos }
                    isl: islosimas;  { kiekvienos ižložian‡ios pad‚ties }
                                   { ižložimo sumos }
                    var opt: log_mas { u‘davinio rezultatas - paliekam— }
                                   { ir kei‡iam— kort— s…ražas });

    var pal: log_mas;
        max_nauda: real; { maksimalus ižložimo vidurkis }

    {*********************************************** }
    function kokia_nauda (k: kortos; isl: islosimas;
                          pal: log_mas): real;
                          { kiek atitinkamo rango kortu yra palikta }
    { skai‡iuoja, koks ižlosimo vidurkis pakeitus nurodytas kortas }
      var vien: array [1..4] of longint; { vien[i] > 0, jei yra i }
                                         { vienod— kort— }
          rng: rangai; { kiek tarp palikt— kort— yra žio rango kort— }
          kiek: islosimas; { kelias kombinacijas galima sudaryti, kad
                           { gautume i-t…j… ižložian‡i…j… pad‚t }
          isviso, { galim— skirting— kombinacij— skai‡ius, kei‡iant }
                  { nurodytas kortas }
          liko,  { kiek kort— reikia parinkti }
          vid, i: longint;
          skirt: boolean;
      {++++++++++++++++++++++++++++++++++++++++++++++++ }
      function cNpok (n, k: longint): longint;
      { randa derini— be pasikartojim— skai‡i— c iž n po k }
        var sk: longint;
            i: longint;
      begin
         sk := 1;
         for i := n downto n-k+1 do sk := sk*i;
         for i := 2 to k do sk := sk div i;
         cNpok := sk
      end; { cNpok }
      {++++++++++++++++++++++++++++++++++++++++++++++++ }
       function min (a, b: longint): longint;
       begin
         if a < b then min := a
                  else min := b
       end; { min }
      {++++++++++++++++++++++++++++++++++++++++++++++++ }
       procedure perrinkti (ran, liko: longint; komb: longint);
       { randa por—, trejet—, ketvert— kombinacij— skai‡i—, rekursijos }
       { gyl nurodo rangas ran, einama pad‚tis gali susidaryti komb b–dais }
       { taip pat randa vis— manom— kombinacij— skai‡i— }
       { proced–ra naudoja globalius kintamuosius: vien, ižviso, kiek }
       { proced–ros rezultatai - ižviso ir kiek reikžm‚s }
         var i: longint;
       begin
          if ran > MAX_R { perb‚gti visi rangai }
          then if liko = 0 { visos 5 kortos parinktos }
               then begin
                     if vien[4] > 0 then kiek[7] := kiek[7] + komb
                     else if vien[3] > 0
                        then if vien[2] > 0
                             then kiek[6] := kiek[6]+komb
                             else kiek[3] := kiek[3]+komb
                        else if vien[2] > 0
                             then kiek[vien[2]] := kiek[vien[2]]+komb;
                     isviso := isviso + komb
                    end
               else
          else for i := 0 to min (liko, 4-rng[ran]) do
              { imamas visoks imanomas skai‡ius ran rango kort— }
                begin
                  if i + rng[ran] > 0
                     then vien[i + rng[ran]] := vien[i + rng[ran]] + 1;
                  perrinkti (ran+1, liko-i, komb * cNpok (4-rng[ran], i));
                  if i + rng[ran] > 0
                     then vien[i + rng[ran]] := vien[i + rng[ran]] - 1;
                end;
       end; { perrinkti }
      {++++++++++++++++++++++++++++++++++++++++++++++++ }
      function kelk (a, n : longint) : longint;
      { a kelia n-tuoju laipsniu }
        var i : longint;
            sk : longint;
      begin
         sk := 1;
         for i := 1 to n do
            sk := sk * a;
         kelk := sk
      end; { kelk }
      {++++++++++++++++++++++++++++++++++++++++++++++++ }
      function vienodos_spalvos (k: kortos; pal: log_mas): boolean;
      { patikrina, ar paliktos kortos yra vienodos spalvos }
        var sp: char;
            i: longint;
      begin
         vienodos_spalvos := true;
         sp := ' ';        { ne‘inome pirmosios paliktos kortos spalvos }
         for i := 1 to 5 do        { patikrinama ar paliktos kortos yra }
            if pal[i] then         {      vienodos spalvos              }
               if sp = ' '  { jei tai pirma palikta korta }
                  then sp := k[i].sp
                  else if k[i].sp <> sp { yra nevienodos spalvos kortu }
                          then vienodos_spalvos := false
      end; { vienodos_spalvos }
      {++++++++++++++++++++++++++++++++++++++++++++++++ }
      procedure vien_spalvos_komb (liko: longint; var kiek: islosimas);
      { randa kiek yra vienodos spalvos kombinacij— }
      begin
         kiek[5] := cNpok (MAX_R-(5-liko), liko);
         if liko = 5 then kiek[5] := kiek[5]*4; { tinka bet kuri spalva }
         { atimamos Pokerio kombinacijos }
         kiek[5] :=  kiek[5] - kiek[8]
      end; { vien_spalvos_komb }
      {++++++++++++++++++++++++++++++++++++++++++++++++ }
      procedure is_eiles_komb (liko: longint; pal: log_mas; k: kortos;
                                var kiek: islosimas);
      { suskai‡iuoja kiek yra galim— kombinacij—, kuriose kortos yra }
      { ižd‚liotos iž eiles; t. y. skai‡iuoja keliais variantais sudaroma }
      { ketvirta ir ažtunta ižložianti kombinacija }
        var komb, min, max, i, kr, kair, des: longint;
      begin
         { prad‘ioje skai‡iuosime kombinacijas, tarsi tur‚tume tik }
         { vienos r–žies kortas }
         if liko = MAX_K then komb := MAX_R - MAX_K + 1
         else begin
               max := 1; min := MAX_R;  { randamos ma‘iausio ir did‘iausio }
               for i := 1 to MAX_K do  {    rango paliktos kortos         }
                  if pal[i]
                     then begin
                        if k[i].ran > max then max := k[i].ran;
                        if k[i].ran < min then min := k[i].ran
                     end;
                if max - min >= MAX_K { jei atstumas tarp rang— per didelis }
                   then komb := 0
                   else begin
                          { tiek kort— reikia prid‚ti iž gal— }
                          kr := MAX_K - (max - min + 1);
                          komb := 0;
                          for kair := 0 to kr do
                            begin
                              { tiek kort— prid‚sime iž dežinio galo }
                              des := kr - kair;
                              if (min - kair >= 1) and (max + des <= MAX_R)
                                 then komb := komb + 1;
                             end;
                        end;
              end;
         { rasime kombinacij— skai‡i—, kai kortos yra keturi— r–ži— }
         kiek[4] := komb * kelk (4, liko); { kiekviena iž parenkam— kort— }
                                     { gali b–ti vienos iž keturi— spalv— }
         if vienodos_spalvos (k, pal) { Pokeris }
            then begin
               if liko = 5 then kiek[8] := komb*4 { tinka bet kuri spalva }
                  else kiek[8] := komb;  { tinka tik palikt— kort— spalva }
               { žios kombinacijos jau buvo priskai‡iuotos prie ketvirtos }
               { ižložiamosios pad‚ties }
               kiek[4] := kiek[4] - kiek[8]
            end
      end; { iž_eil‚s_komb }
      {++++++++++++++++++++++++++++++++++++++++++++++++ }
      procedure analizuok_paliktas (k: kortos;   { duotosios kortos }
                                    pal: log_mas; { paliktos kortos }
                                    var rng: rangai;
                                    var liko: longint);
      { suskai‡iuoja kiek iž kort— reikia parinkti }
      { ir kiek kiekvieno rango kort— palikta }
        var i: longint;
      begin
        for i := 1 to  MAX_R do
          rng[i] := 0;
        liko := MAX_K;
        for i := 1 to MAX_K do
          if pal[i] then begin
                            liko := liko - 1;
                            rng[k[i].ran] := rng[k[i].ran] + 1
                          end;
      end; { analizuok_paliktas }
      {++++++++++++++++++++++++++++++++++++++++++++++++ }
    begin
      { suskai‡iuojama kiek kort— reikia parinkti }
      { ir kiek kokio rango kort— liko }
      analizuok_paliktas (k, pal, rng, liko);
      { kol kas nesudar‚me nei vienos ižložiamos pad‚ties }
      for i := 1 to MAX_P do
        kiek[i] := 0;
      for i := 1 to 4 do
        vien[i] := 0;
      isviso := 0; { nesudar‚me nei vienos kombinacijos }
      { rasime vis— galim— kombinacij— skai‡i— bei kombinacij— skai‡i—, kai }
      { susidaro ižložian‡ios pad‚tys: Pora, Dvi poros, Trejetas, Ketvertas }
      {  likusias kombinacijas nekreipiama d‚mesio; proced–ros rezultatas - }
      { masyvas kiek }
      perrinkti (1, liko, 1);
      { bandysime sudaryti likusias kombinacijas }
      { patikrinsime, ar paliktos kortos yra skirtingo rango }
      skirt := true;
      for i := 1 to MAX_R do
        skirt := skirt and (rng[i] <= 1);
      if skirt { visos kortos skirtingos }
         then begin { iežkosime 4-tos, 5-tos ir 8-tos ižložian‡i— }
                is_eiles_komb (liko, pal, k, kiek);     { pad‚‡i— }
                if vienodos_spalvos (k, pal)
                   then vien_spalvos_komb (liko, kiek)
              end;
      { apskai‡iuojamas ižložimo vidurkis }
      vid := 0;
      for i := 1 to MAX_P do
         vid := vid + kiek[i] * isl[i];
      kokia_nauda := vid/isviso;
    end; { kokia_nauda }
    { *********************************************** }
    procedure palikti_keisti (n: longint; pal: log_mas);
    { perrenkami visi manomi paliekam— ir kei‡iam— kort— deriniai }
    { naudojami global–s kintamieji k, isl, max_nauda ir opt }
    { kintam—j— k ir isl reikžm‚s nekei‡iamos }
    { proced–ros rezultatas - kintamojo opt reikžm‚ }
      var nauda: real;
    begin
      if n = 6 { visos kortos arba paliktos arba nurodytos keisti }
         then begin
                nauda := kokia_nauda (k, isl, pal);
                if nauda > max_nauda
                then begin { rastas naudingesnis kort— pasilikimo variantas }
                       max_nauda := nauda;
                       opt := pal;
                     end
              end
         else begin
                pal[n] := false;
                palikti_keisti (n + 1, pal);
                pal[n] := true;
                palikti_keisti (n + 1, pal);
             end
    end; { palikti_keisti }
    {*********************************************** }
  begin { sprŠsk }
    max_nauda := -1;
    palikti_keisti (1, pal);
  end; { sprŠsk }
  {--------------------------------------------------------}
  var k: kortos;
      isl: islosimas;
      opt: log_mas;
begin
  skaityk (k, isl);
  spresk (k, isl, opt);
  rezultatai (opt)
end.




