using System;
using SpaceTime.Utilities;

namespace SpaceTime.Utilities
  {
    public class MathUtilities
      {
	public static void Main(string[] args)
	  {
	    System.Console.WriteLine(max(args));
	  }
	
	public static int max(params string[] args)
	  {
	    if (args.Length == 1)
	      {
		return Int32.Parse(args[0]);
	      }
	    
	    Boolean hasValue = false;
	    int rollingMax = Int32.MinValue;
	    int i = 0;
	    while ((i < args.Length) && (! hasValue))
	      {
		try
		  {
		    hasValue = true;
		    rollingMax = Int32.Parse(args[i]);
		  }
		catch (Exception)
		  {
		    // tolerate (and skip) non-integer values like "absent" or "N/A"
		  }
		i++;
	      }
	    
	    while (i < args.Length)
	      {
		try
		  {
		    rollingMax = System.Math.Max(Int32.Parse(args[i]), rollingMax);
		  }
		catch (Exception)
		  {
		    // tolerate (and skip) non-integer values like "absent" or "N/A"
		  }
		i++;
	      }
	    
	    return rollingMax;
	  }
	
	public static int sum(params string[] args)
	  {
	    int total = 0;
	    int i = 0;
	    while (i < args.Length)
	      {
		try
		  {
		    total += Int32.Parse(args[i]);		    
		  }
		catch (Exception)
		  {
		    // tolerate (and skip) non-integer values like "absent" or "N/A"
		  }
		i++;
	      }
	    
	    return total;
	  }
	
	public static int product(params string[] args)
	  {
	    int prod = 1;
	    int i = 0;
	    while (i < args.Length)
	      {
		try
		  {
		    prod *= Int32.Parse(args[i]);		    
		  }
		catch (Exception)
		  {
		    // tolerate (and skip) non-integer values like "absent" or "N/A"
		  }
		i++;
	      }
	    
	    return prod;
	  }
	
	public static int booleanIndicator(string arg)
	  {
	    if (arg.ToLower().Equals("yes"))
	      {
		return 1;
	      }
	    if (arg.ToLower().Equals("true"))
	      {
		return 1;
	      }
	    
	    try
	      {
		return Int32.Parse(arg);
	      }
	    catch (Exception)
	      {
		// tolerate (and skip) non-integer values
	      }
	    
	    return 0;
	  }  
      }

    public class ScoreUtilities
      {
	public static double iet2stm(double ietScore)
	  {
	    return -5 + (6.0 * ietScore);
	  }
      }
  }

namespace SpaceTimeMain
{
	public class RuleFunctions
	{
	  public static int capValThree(string a)
	    {
	      int attendance = Int32.Parse(a);
	      return (int)Math.Ceiling((double)attendance*1.1);
	    }
		public static int capValFour(string a)
		{
			int attendance = Int32.Parse(a);
			return (int)Math.Ceiling((double)attendance*1.1) - 1;
		}
		public static int capValFive(string a)
		{
			int attendance = Int32.Parse(a);
			return (int)Math.Ceiling((double)attendance*0.9091);
		}
		public static int capValSix(string a)
		{
			int attendance = Int32.Parse(a);
			return (int)Math.Ceiling((double)attendance*0.9091) - 1;
		}

		public static double capScoreFour(string a)
		{
			int attendance = Int32.Parse(a);
			return 6.0*Math.Min((double)capValFour(a)/(double)attendance-0.1, 1)-5.0;
		}
		public static double capScoreFive(string a)
		{
			int attendance = Int32.Parse(a);
			return 6.0*Math.Min((double)capValFive(a)/(double)attendance-0.1, 1)-5.0;
		}

	  public static int div11Minus1(string a)
	    {
	      return div11(a)-1;
	    }
	  public static int div11(string a)
	    {
	      int attendance = Int32.Parse(a);
	      return (int)Math.Ceiling((double)attendance/1.1);
	    }
	  public static double capScoreAtDiv11(string a)
	    {
	      double x = (double) div11(a);
	      double attendance = (double) Int32.Parse(a);
	      double ietScore = -0.1 + (x/attendance);
	      return ScoreUtilities.iet2stm(ietScore);
	    }
	  public static int div09(string a)
	    {
	      int attendance = Int32.Parse(a);
	      return (int)Math.Ceiling((double)attendance/0.9);
	    }
	  public static int prod2(string a)
	    {
	      int attendance = Int32.Parse(a);	   
	      return 2*attendance;
	    }
	  public static int prod2Plus1(string a)
	    {
	      return 1+prod2(a);
	    }

	  public static int leftmostDurPoint(string d)
	    {
	      return 60*(Math.Min(MathUtilities.sum(d)-45, 0));
	    }
	  public static int minus30Min(string d)
	    {
	      return 60*(MathUtilities.sum(d)-30);
	    }
	  public static double durScoreAtRMinus30(string r)
	    {
	      int req = MathUtilities.sum(r);
	      double ietScore = 0.0;
	      if (req != 30)
		{
		  ietScore = (0.4 / req) * (req - 30);
		}
	      return ScoreUtilities.iet2stm(ietScore);
	    }
	  public static int minus15Min(string d)
	    {
	      return 60*(MathUtilities.sum(d)-15);
	    }
	  public static int sum15Min(string d)
	    {
	      return 60*(MathUtilities.sum(d)+15);
	    }
	  public static int sum30Min(string d)
	    {
	      return 60*(MathUtilities.sum(d)+30);
	    }
	  public static int sum45Min(string d)
	    {
	      return 60*(MathUtilities.sum(d)+45);
	    }
	  public static double durScoreAtRPlus30(string r)
	    {
	      int req = MathUtilities.sum(r);
	      double ietScore =
		(0.4 * req) / (req + 30);
	      return ScoreUtilities.iet2stm(ietScore);
	    }

	  public static int max7(string s1,string s2,string s3,string s4,
				 string s5,string s6,string s7)
	    {
	      return MathUtilities.max(s1,s2,s3,s4,s5,s6,s7);
	    }

	  public static int sum2(string s1,string s2)
	    {
	      return MathUtilities.sum(s1,s2);
	    }

	  public static int sum3800000(string s1)
	    {
	      // rule syntax workaround
	      return MathUtilities.sum(s1,"3800000");
	    }
	
	  public static int regularMeals(string cateringRequested, string attendance,
					 string m1, string m2, string m3, string m4)
	    {
	      int indicator = MathUtilities.booleanIndicator(cateringRequested);
	      int irregularMeals = MathUtilities.sum(m1,m2,m3,m4);
	      return Math.Max(indicator*(Int32.Parse(attendance) - irregularMeals), 0);
	    }
	}
}
