import java.util.Scanner;
class Date {
//data members
private int year;
private int month;
private int day;
public static int[] days_leap={31,29,31,30,31,30,31,31,30,31,30,31};
public static int[] days_nonleap={31,28,31,30,31,30,31,31,30,31,30,31};
//default constructor
Date(){}
//constructor with parameter
Date(int ds){
day=ds0;
month=((ds-day)000)/100;
year=(ds-month*100-day)/10000;
}
//static member function for determine leap year or not
public static boolean IsLeap(int d){
boolean result=false;
if(d%4==0 && d0!=0 || d@0==0)
result=true;
else
result=false;
return result;
}
//day counting function
public static int day_counter(Date d1,Date d2){
int period=0;
//if d1 is later than d2,reverse it
if((d1.year10000+d1.month100+d1.day)>(d2.year10000+d2.month100+d2.day))
{
return day_counter(d2,d1);
}
else{
//not same year
if(d1.year!=d2.year){
//first: days between intermediate years
for(int i=d1.year+1;i<=(d2.year-1);i++){
if(IsLeap(i)==false)
period+=365;
else
period+=366;
}
//second: days in first year
if(IsLeap(d1.year)==false){
for(int j=d1.month+1;j<=12;j++){
period+=days_nonleap[j-1];
}
period=period+days_nonleap[d1.month-1]-d1.day;
}
else{
for(int j=d1.month+1;j<=12;j++){
period+=days_leap[j-1];
}
period=period+days_leap[d1.month-1]-d1.day;
}
//third: days in last year
if(IsLeap(d2.year)==false){
for(int j=1;j<=d2.month-1;j++){
period+=days_nonleap[j-1];
}
period=period+d2.day;
}
else{
for(int j=1;j<=d2.month-1;j++){
period+=days_leap[j-1];
}
period=period+d2.day;
}
return period;
}
//on the same year
else{
if(IsLeap(d1.year)==false){
for(int i=d1.month+1;i<=d2.month-1;i++){
period=period+days_nonleap[i-1];
}
period=period+d2.day+days_nonleap[d1.month-1]-d1.day;
}
else{
for(int i=d1.month+1;i<=d2.month-1;i++){
period=period+days_leap[i-1];
}
period=period+d2.day+days_leap[d1.month-1]-d1.day;
}
return period;
}
}
}
//change the data of a member
public void setDate(int y,int m,int d){
this.year=y;
this.month=m;
this.day=d;
}
//function for determine future date
public static Date Future_date(Date d,int m){
Date result=new Date(19900101);
//checking if this original date is month end or not
boolean end=true;
if(IsLeap(d.year)==true){
if(d.day==days_leap[d.month-1]){
end=true;
}
else{
end=false;
}
}
else{
if(d.day==days_nonleap[d.month-1]){
end=true;
}
else{
end=false;
}
}
//do not cross year
if(d.month+m<=12){
if(IsLeap(d.year)==true){
if(end=true){
result.setDate(d.year, d.month+m, days_leap[d.month+m-1]);
return result;
}
else{
int tempday=0;
tempday=d.day>days_leap[d.month+m-1]?days_leap[d.month+m-1]:d.day;
result.setDate(d.year,d.month+1,tempday);
return result;
}
}
else{
if(end==true){
result.setDate(d.year, d.month+1, days_nonleap[d.month+m-1]);
return result;
}
else{
int tempday=0;
tempday=d.day>days_nonleap[d.month+m-1]?days_nonleap[d.month+m-1]:d.day;
result.setDate(d.year,d.month+1,tempday);
return result;
}
}
}
//cross years
else{
int tempyear=0;
int tempmonth=0;
int tempday=0;
if((d.month+m)==0){
tempmonth=12;
tempyear=d.year-1+(d.month+m)/12;
}
else{
tempyear=d.year+((d.month+m)-(d.month+m))/12;
tempmonth=(d.month+m);
}
if(IsLeap(tempyear)==true){
if(end==true){
tempday=days_leap[tempmonth-1];
result.setDate(tempyear,tempmonth,tempday);
//result.testsay();
return result;
}
else{
tempday=d.day>days_leap[tempmonth-1]?days_leap[tempmonth-1]:d.day;
result.setDate(tempyear,tempmonth,tempday);
//result.testsay();
return result;
}
}
else{
if(end==true){
tempday=days_nonleap[tempmonth-1];
result.setDate(tempyear,tempmonth,tempday);
//result.testsay();
return result;
}
else{
tempday=d.day>days_nonleap[tempmonth-1]?days_nonleap[tempmonth-1]:d.day;
result.setDate(tempyear,tempmonth,tempday);
//result.testsay();
return result;
}
}
}
}
//test function to see if i got things right
void testsay(){
System.out.print(this.year+" “);
System.out.print(this.month+" “);
System.out.print(this.day+" “);
}
}
public class loanAmortization {
private double loanAmt;
public double interestRate;
public int terms;
public Date startday;
//constructor
loanAmortization(double l,double i,int t,Date d){
this.loanAmt=l;
this.interestRate=i;
this.terms=t;
this.startday=d;//remains to be seen if i need shallow or deep
}
//function to determine remaining debt
public static double debt(double pmt,loanAmortization loan){
double remaining=loan.loanAmt;
int length=loan.terms*12;
Date startday=loan.startday;
Date head=startday;
double interest=0;
double principal=0;
for(int i=1;i<=length;i++){
Date next=Date.Future_date(startday,i);
//next.testsay();
int numday=Date.day_counter(head,next);
interest=remainingloan.interestRatenumday/365;
principal=pmt-interest;
remaining=remaining-principal;
head=next;
}
return remaining;
}
//function of bisect search
public static double bi_search(loanAmortization loan){
double result=0;
double head=loan.loanAmt/(loan.terms*12);//average payment, the debt would be left positive
double tail=loan.loanAmt;//pay all the amount each time, the debt would be left negative
if(debt(tail,loan)*debt(head,loan)<0)//if solution exists
{
double error=debt(head,loan)-debt(tail,loan);//difference of two points’s output
double mid=(head+tail)/2;
do{
if(debt(mid,loan)*debt(tail,loan)<0){
head=mid;
mid=(head+tail)/2;
error=debt(head,loan)-debt(mid,loan);
//result=mid;
result=(mid+head)/2;
}
else{
tail=mid;
mid=(head+tail)/2;
error=debt(mid,loan)-debt(tail,loan);
//result=mid;
result=(mid+tail)/2;
}
}while((tail-head>0.1)||error>0.1);// error
}
else{
System.out.println(“wrong starting bi-search parameter,check again”);
}
//System.out.println(tail-head);
System.out.println(result);
return result;
}
public static void main(String[] args) {
System.out.println(“Enter the loan amount:”);
System.out.println(“Enter the annual interest rate:”);
System.out.println(“Enter the terms in a year:”);
System.out.println(“Enter start date:”);
Scanner s1=new Scanner(System.in);
Scanner s2=new Scanner(System.in);
Scanner s3=new Scanner(System.in);
Scanner s4=new Scanner(System.in);
double loan=s1.nextDouble();
double interest=s2.nextDouble();
int term=s3.nextInt();
int d=s4.nextInt();
Date d1=new Date(d);
loanAmortization myloan=new loanAmortization(loan,interest,term,d1);
loanAmortization.bi_search(myloan);
}
}