package jp.co.jid.exBasic;

public class MyMath {

	/**
	 * 加算を行うメソッド
	 * @param num1 被加算数
	 * @param num2 加算数
	 * @return num1 + num2 を返す
	 */
	public int calcPlus(int num1, int num2) {
		return num1 + num2;
	}

	/**
	 * 減算を行うメソッド
	 * @param num1 被減算数
	 * @param num2 減算数
	 * @return num1 - num2 を返す
	 */
	public int calcMinus(int num1, int num2) {
		return num1 - num2;
	}

	/**
	 * 乗算を行うメソッド
	 * @param num1 被乗数
	 * @param num2 乗数
	 * @return num1 * num2 を返す
	 */
	public int calcTime(int num1, int num2) {
		int result = 0;
		for (int i = 0; i < num2; i++) {
			result = calcPlus(result, num1);
		}
		return result;
	}

	/**
	 * 除算(商を求める)を行うメソッド
	 * @param num1 被除数
	 * @param num2 除数
	 * @return num1 / num2 の商を返す
	 */
	public int calcDiv(int num1, int num2) {
		return num1 / num2;
	}

	/**
	 * 除算(余を求める)を行うメソッド
	 * @param num1 被除数
	 * @param num2 除数
	 * @retur num1 / num2 の余を返す
	 */
	public int calcMod(int num1, int num2) {
		return calcMinus(num1, calcTime(calcDiv(num1, num2), num2));
	}

	/**
	 * 可変長変数の合計を求めるメソッド
	 * @param nums 可変長変数
	 * @return 合計
	 */
	public int calcSum(int... nums) {
		int sum = 0;
		for (int num : nums) {
			sum += num;
		}
		return sum;
	}

	/**
	 * 可変長変数の平均を求めるメソッド
	 * @param nums 可変長変数
	 * @return 平均
	 */
	public double calcAvg(int... nums) {
		return (double)calcSum(nums) / nums.length;
	}

	/**
	 * 第１引数から第２引数までカウントアップしながら、その時の値の和を返すメソッド
	 * @param fromNum カウントアップ開始の値
	 * @param toNum カウントアップ終了の値
	 * @return 合計
	 */
	public int countUpSum1(int fromNum, int toNum) {
		int sum = 0;
		for (int num = fromNum; num <= toNum; num++) {
			sum += num;
		}
		return sum;
	}

	/**
	 * 第１引数から第２引数までカウントアップしながら、その時の値の和を返すメソッド
	 * @param fromNum カウントアップ開始の値
	 * @param toNum カウントアップ終了の値
	 * @return 合計
	 */
	public int countUpSum2(int fromNum, int toNum) {
		int sum = 0;
		int num = fromNum;
		while (num <= toNum) {
			sum += num++;
		}
		return sum;
	}

	/**
	 * 第１引数から第２引数までカウントアップしながら、その時の値の和を返すメソッド
	 * @param fromNum カウントアップ開始の値
	 * @param toNum カウントアップ終了の値
	 * @return 合計
	 */
	public int countUpSum3(int fromNum, int toNum) {
		int sum = 0;
		int num = fromNum;
		do {
			sum += num++;
		} while (num <= toNum);
		return sum;
	}

	/**
	 * 第１引数によって以下のように返す値を変更するメソッド
	 *   １：第２引数と第３引数の和
	 *   ２：第２引数と第３引数の差
	 *   ３：第２引数と第３引数の積
	 *   ４：第２引数と第３引数の商
	 *   ５：第２引数と第３引数の余
	 * @param funcNum 度の処理を行うかの指定値
	 * @param num1
	 * @param num2
	 * @return 計算結果
	 */
	public int calc(int funcNum, int num1, int num2) {
		switch (funcNum) {
			case 1:
				return calcPlus(num1, num2);
			case 2:
				return calcMinus(num1, num2);
			case 3:
				return calcTime(num1, num2);
			case 4:
				return calcDiv(num1, num2);
			case 5:
				return calcMod(num1, num2);
			default:
				return 0;
		}
	}

	/**
	 * 最大値を求めるメソッド
	 * @param nums 検査対象の可変長変数
	 * @return 最大値
	 */
	public int max(int... nums) {
		int max = Integer.MIN_VALUE;
		for (int num : nums) {
			if (num > max) {
				max = num;
			}
		}
		return max;
	}

	/**
	 * 最小値を求めるメソッド
	 * @param nums 検査対象の可変長変数
	 * @return 最小値
	 */
	public int min(int... nums) {
		int min = Integer.MAX_VALUE;
		for (int num : nums) {
			if (num < min) {
				min = num;
			}
		}
		return min;
	}

	/**
	 * 第１引数によって以下のように返す値を変更するメソッド
	 *   １：第２引数以降の合計値
	 *   ２：第２引数以降の平均値（整数部のみ）
	 *   ３：第２引数以降の最大値
	 *   ４：第２引数以降の最小値
	 * ただし、引数が１つの場合は「０」を返す。
	 * @param nums 対象の可変長変数
	 * @return 処理結果
	 */
	public int calc2(int... nums) {
		if (nums.length == 1) {
			return 0;
		}
		switch (nums[0]) {
			case 1:
				int sum1 = 0;
				for (int i = 1; i < nums.length; i++) {
					sum1 += nums[i];
				}
				return sum1;
			case 2:
				int sum2 = 0;
				for (int i = 1; i < nums.length; i++) {
					sum2 += nums[i];
				}
				return sum2 / (nums.length - 1);
			case 3:
				int max = Integer.MIN_VALUE;
				for (int i = 1; i < nums.length; i++) {
					if (nums[i] > max) {
						max = nums[i];
					}
				}
				return max;
			case 4:
				int min = Integer.MAX_VALUE;
				for (int i = 1; i < nums.length; i++) {
					if (nums[i] < min) {
						min = nums[i];
					}
				}
				return min;
			default:
				return 0;
		}
	}
}
