Как написать код без оператора for и if - PullRequest
2 голосов
/ 02 мая 2020

Я пытаюсь переписать свой код без условного выражения и l oop. Мой код написан на основе подобной инструкции, но дополнительно без l oop и условного выражения

Программа, которая принимает входные данные в качестве начального месяца и дня до конца месяца и дня и

вычисления итоговая цена.

Предполагаемые входные данные всегда верны.

Диапазон ввода - один и тот же год с 1 января по De c 31

Январь 1/1 - понедельник.

День начала ввода всегда понедельник

Четный месяц состоит из 31 дня, Нечетный месяц состоит из 30 дней

Для цены Weekday -> $ 2

Сб -> $ 3

Вс -> 5 долларов

Если клиент заказывает более 50 дней, цена станет неизменной до 1


 public class test {
    int startMonth;
    int startDay;
    int endMonth;
    int endDay;
    int totalDate;

    public test (int startMonth, int startDay, int endMonth, int endDay) {
        this.endMonth = endMonth;
        this.endDay = endDay;
        this.startMonth = startMonth;
        this.startDay = startDay;
    }
    public int getPrice() {
        getTotalDate();
        int price = 0;
        int discount = totalDate > 50 ? totalDate - 50 : 0;
        System.out.println("discount " + discount);
        totalDate = totalDate > 50 ? 50 : totalDate % 50;
        System.out.println("totalData : " + totalDate);
        int sunDay = totalDate/7;
        int satDay = totalDate/7 + (totalDate%7)/6;
        int weekDay = totalDate - sunDay - satDay;
        price+= sunDay*5 + satDay*3 + weekDay*2;
        return price + discount;

    }
    public int getTotalDate() {
        int gapOfMonth = endMonth - startMonth;
        totalDate = gapOfMonth*30 + (gapOfMonth +1)/2 + (endDay - startDay);
        return totalDate;
    }

    public static void main (String[] args) {
        test t = new test(1,1,2,30);
        System.out.println("test");
        System.out.println(t.getPrice());
    }
}

Ответы [ 4 ]

2 голосов
/ 02 мая 2020

удалось завершить без троичного

public int getPrice(int totalDay) {
    int totalPrice = 0;
    int difference = totalDay-50;
    //from https://stackoverflow.com/a/2707438/529282
    int absDifference = difference*(1-2*((3*difference)/(3*difference+1)));

    //this essentially gives the minimum value between totalDay and 50
    int before50 = (totalDay+50-absDifference)/2;

    int after50 = totalDay-before50;

    totalPrice += after50;

    //the before 50 is where the complex calculation is needed
    int before50 = totalDay - after50;

    //first, the base price for weekday
    totalPrice += before50 * 2;

    //then we add the whole week difference (sat+sun price - weekday price)
    totalPrice += (before50 / 7) * 4;

    //the we add the stray saturday if any
    totalPrice += (before50 % 7) / 6;

    return totalPrice;
}

public int getTotalDate() {
    int totalDate = 0;
    //add month difference
    totalDate += 30 * (endMonth - startMonth);

    //add day difference
    totalDate += (endDay - startDay);

    //add the extra from having 31 days every two months
    totalDate += (endMonth - startMonth) / 2;

    //if the month start from even months and the end month is different, 
    //add another day since it ends with 31
    //the trick here, if startMonth == endMonth, startMonth/endMonth = 1,
    //so 1-1 is 0, nothing get added
    //while if startMonth<endMonth, startMonth/endMont = 0, so 1-0 is 1
    totalDate += ((startMonth + 1) % 2) * (1 - startMonth / endMonth);

    return totalDate;

}
1 голос
/ 02 мая 2020

Я придумал другое решение, используя несколько справочных таблиц:

public class PriceCalc {
    private static final int FULL_WEEK_PRICE = 18;
    private static final int REGULAR_DAYS = 50;

    private static final int[] PREV_DAYS = {
        0,  31,  61,  92, 122, 153, 183, 214, 244, 275, 305, 336
    };

    // remainders between start and end dates
    private static final int[][] RESTS = {
       // S   M   T   W   T   F   S 
        { 0,  5,  7,  9, 11, 13, 16},
        {13,  0,  2,  4,  6,  8, 10},
        {11, 16,  0,  2,  4,  6,  8},
        { 9, 14, 16,  0,  2,  4,  6},
        { 7, 12, 14, 16,  0,  2,  4},
        { 5, 10, 12, 14, 16,  0,  2},
        { 3,  8, 10, 12, 14, 16,  0}
    };  

    private int startDate;
    private int startMonth;

    private int endDate;
    private int endMonth;

    public PriceCalc(int startDate, int startMonth, int endDate, int endMonth) {
        super();
        this.startDate = startDate;
        this.startMonth = startMonth;
        this.endDate = endDate;
        this.endMonth = endMonth;
    }

    private static int dayOfYear(int day, int month) {
        return day + PREV_DAYS[(month - 1) % 12];
    }

    private static int dayOfWeek(int day, int month) {
        return dayOfYear(day, month) % 7;
    }

    private static int isFlat(int duration) {
        int flat = duration / REGULAR_DAYS;
        try {
            flat /= flat;
            return flat;
        }
        catch(ArithmeticException e) {
            return 0;
        }
    }

    private int durationDays() {
        int startDOY = dayOfYear(startDate, startMonth);
        int endDOY = dayOfYear(endDate, endMonth);

        return endDOY - startDOY;
    }

    public int calcPrice() {
        int startDOW = dayOfWeek(startDate, startMonth);

        int duration = durationDays();
        int flat = isFlat(duration);

        int regularDuration = duration * (1 - flat) + REGULAR_DAYS * flat;
        int discount = flat * (duration - REGULAR_DAYS);

        int fullWeeks = regularDuration / 7;
        int rem = regularDuration % 7;
        int endDOW = (dayOfYear(startDate, startMonth) + regularDuration) % 7;
        int remainder = RESTS[startDOW][endDOW];

        int price = fullWeeks * FULL_WEEK_PRICE + remainder + discount;

        System.out.printf("Price for %3d days = %2d full weeks + %d days + %3d flat-rate days is: $%3d + $%2d + $%3d = $%3d%n",
            duration, fullWeeks, rem, discount, 
            fullWeeks * FULL_WEEK_PRICE, remainder, discount, price
        );
        return price;
    }

    public static void main(String[] args) {
        new PriceCalc(1,  1,  4, 1).calcPrice(); // $  0 + $ 6 + $  0 = $  6
        new PriceCalc(6,  1, 11, 1).calcPrice(); // $  0 + $14 + $  0 = $ 14
        new PriceCalc(1,  1,  9, 1).calcPrice(); // $ 18 + $ 2 + $  0 = $ 20
        new PriceCalc(3,  1, 17, 1).calcPrice(); // $ 36 + $ 0 + $  0 = $ 36
        new PriceCalc(4,  1, 23, 1).calcPrice(); // $ 36 + $14 + $  0 = $ 50
        new PriceCalc(27, 1,  5, 3).calcPrice(); // $ 90 + $12 + $  0 = $102
        new PriceCalc(28, 2,  1, 6).calcPrice(); // $126 + $ 2 + $ 45 = $173
    }
}
1 голос
/ 02 мая 2020

Если вы не против Java позаботиться о цикле, вы можете использовать LocalDate и ChronoUnit.

    Long totalPrice;

    // I gave this date for example . You can convert your input to a LocalDate format
    LocalDate startDate = LocalDate.now();
    LocalDate endDate = LocalDate.now().plusDays(15);

     //+1 or +2 or 0 based on your requirement
    Long duration = DAYS.between(startDate,endDate )+1;
    if(duration>50)
        return 50;

    long saturdays = WEEKS.between(startDate.with(DayOfWeek.SATURDAY), endDate.with(DayOfWeek.SATURDAY));
    long sundays = WEEKS.between(startDate.with(DayOfWeek.SUNDAY), endDate.with(DayOfWeek.SUNDAY));

    long weekDays = duration - (saturdays+sundays);

    totalPrice = weekDays + (saturdays*3 +sundays*5);

    return totalPrice;
0 голосов
/ 02 мая 2020

Возможно, создатель хочет, чтобы вы нашли формулу. У меня есть и ваш код:

public int getPrice() {
    getTotalDate();
    int comboDate;
    int normalDate;
    if (totalDate > 50){
        comboDate = totalDate - 50;
        normalDate = 50;
    } else {
        comboDate = 0;
        normalDate = totalDate;
    }
    int sunDay = normalDate/7;
    int satDay = normalDate/7 + (normalDate%6)/6;
    int weekDay = normalDate - satDay - sunDay;
    return comboDate*1 + sunDay*5 + satDay*3 + weekDay*2;
}
public int getTotalDate() {
    int start = startMonth*30 + (startMonth-1)/2 + startDay;
    int end = endMonth*30 + (endMonth-1)/2 + endDay;
    totalDate = end - start + 1;
    return totalDate;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...