Monday, October 31, 2016

задачка о тортике, Си и Хаскель

ВиниПух и Пятачок сьели торт за t секунд. если бы ели тот же торт два Винни–Пуха, то у них торт был бы съеден на 1 минуту раньше, а если бы тот же самый торт ели два Пятачка, то они на 4 минуты больше бы времени затратили. так за сколько же времени съели торт друзья?

сначала Винни сжирает по-быстрому свою половину, а потом еще 1 минуту они хомячат вместе то, что Пятачок в одиночку ел бы дополнительные 5 мин - т.е. _вдвоем_ Винни и Пятачок едят как _пять_ Пятачков, т.е. Винни один ест за четверых Пятачков


-- import Debug.Trace
import Control.Monad
-- import System.IO
import System.Environment

pudding :: Double -> Double -> Double
pudding t1 t2 = 
  head $ [1..] >>= \t -> -- traceShow t $ 
    let p = (recip t) / 5 
        b = p * 4 
        f = \t0 v1 v2 -> guard $ 1e-8 >= (abs $ t0 * (v1 + v2) - 1) 
    in (f t b p) >> (f (t + t1) b b) >> (f (t + t2) p p) >> return t

main :: IO () 
main = 
  getEnv "vin" >>= \x -> getEnv "pig" >>= \y -> 
  return (pudding (read x) (read y)) >>= print
{-
  (pudding <$ putStr "медведи  : " <* hFlush stdout <*> readLn 
           <* putStr "поросята : " <* hFlush stdout <*> readLn) >>= print 

  getArgs >>= \args -> 
  if (length args == 2)  
  then return (pudding (read $ head args) (read $ head $ tail args)) >>= print 
  else putStrLn "usage: a.out  two_winnies_delta two_piggies_delta"
-}

и на сях:


#include <stdlib.h>
#include <stdio.h>

int comp (float, float, float) ;

int main (int argc, char** argv, char** envp)
{
  float t0 , t1 , t2 , p , b ; t0 = 60.0 ; 

  /* if (argc != 3) 
       { printf ("usage: two_winnies_delta two_piggies_delta\n") ; return 1 ; }
   t0 = 0.0 ; t1 = atof (argv[1]) ; t2 = atof (argv[2]) ;  */

  printf ("winnies : ") ; scanf ("%f", &t1) ;
  printf ("piggies : ") ; scanf ("%f", &t2) ;

  while (1) 
  {
    t0 = t0 + 1 ; p = 1 / (5 * t0) ; b = 4 * p ;   
    // printf ("%5.2f\n", t0) ;
    if ((comp (t0, p, b) == 1) & 
        (comp (t0 + t1, b, b) == 1) & 
        (comp (t0 + t2, p, p) == 1)) break ;
   }

  printf ("%5.2f\n", t0) ;
  return 0 ;
}

int comp (float t0, float t1, float t2)
{
  if ((t0 * (t1 + t2) - 1.0) < 0.00000001) return 1 ; else return 0 ;
}

No comments: