{---------------------------------------------------------------------
 - Subiect:
   Bunica mea are un ceas cu cuc care canta la ore fixe (de numarul de 
   ori egal cu ora) si la "si jumatate" (o singura data). 
   Pe ceasul bunicii orele sunt numerotate de la 1 la 12. 
   Eu am plecat de acasa exact dupa ce cucul a cantat de ora fixa si 
   am lipsit cel putin o ora. 
   Dupa ce m-am intors, cucul a cantat de "si jumatate" si bunica 
   suparata mi-a spus "De cand ai plecat, cucul a canat de k ori!"
 
 - Cerinta:
   Fiindca nu inteleg de ce bunica mea e asa de suparata, scrieti un 
   program care sa determine numarul minim de ore ce am lipsit de acasa!
   
 - Intrare:
   Numarul k se citeste de la tastatura.
 
 - Iesire:
   Numarul natural L care reprezinta numarul minim de ore cat am lipsit
   de acasa si ora P a plecarii de acasa se afiseaza la ecran.
   
 - Restrictii:
   0 < k < 1 000 000 000 
 ---------------------------------------------------------------------}
 
 
Program Cucul ;
uses crt ;

const max_cuc = 1000000000 ;

var   P, L, k: longint ; 
      k_calc, L_min, P_: longint ;

function Sn(m, n: integer): longint ;
{ Suma numerelor: m + (m+1) + ... + (n-1) + n }
begin
  { s := 0 ; for i := m to n do s := s + i ; }
  Sn := (n-m+1) * (n+m) div 2 ;
end ;

function Cucu_12: word ; { De cate ori canta cucul in 12 ore }
begin
 { Canta la fiecare ora P de P ori si la si jumate o data }
 Cucu_12 := Sn(1, 12) + 12 ;
end ;

function k_(P, L: Word): longint ; { k este functie de P si L }
{ De cate ori canta cucul daca eu am plecat la ora P }
{ si am venit peste L ore? }
var rez: longint ;
begin
   rez := Cucu_12 * (L div 12) ; { De cate ori a cantat cucul in primele 12 * x ore }
   L := L mod 12 ;               { L - 12 * x ore (ceea ce a mai ramas) }
   while L > 0 do begin
     dec(L) ;              { A mai trecut o ora }
     P := P mod 12 + 1 ;   { if P = 12 then P := 0 ; inc(P) ; }
     inc(rez, 1 + P) ;     { Cucul a cantat la jumate o data, si la fix de P ori }
   end ;
   k_ := rez ;
end ;

BEGIN
clrscr ;
   { Voi utiliza metoda Backtracking }
   WriteLn('Daca lipseam 12 ore, cucu canta de ', Cucu_12, ' ori!'#10) ;
   Write('De cate ori a cantat cucul?  ') ;  ReadLn(k) ;
   P_ := 0 ;
   
   { Daca cucul a cantat mai mult de Cucu_12 * x ori, atunci eu am lipsit mai mult de 12 * x ori }
   L_min := 12 * (k div Cucu_12) ;
   if L_min = 0 then L_min := 1; { Am lipsit cel putin o ora. }

   { Oare la ce ora am iesit din casa? }
   for P := 1 to 12 do begin { Pe ceasul bunicii orele sunt numerotate de la 1 la 12 }
     L := L_min ;
     repeat
        k_calc := k_(P, L) ;      { Presupun ca am iesit la ora P si am lipsit L ore... }
        if k_calc = k then        { Oare am ghicit ? }
        if  L <= L_min then begin 
           L_min := L ;
           P_    := P ;
           Break ;  { L nu va fi mai mic in acest repeat }
        end ;
        inc(L) ;
     until not( (0 < k_calc)and(k_calc < max_cuc)and(k_calc <= k) ) ;
   end ;

if P_ <> 0 then WriteLn('Am iesit din casa la ora ', P_:2, ' si am lipsit ', L_min:2, ' ore.') 
           else WriteLn('Nu am iesit din casa...');

readkey ;
END.
