【CodeWars】Human readable duration format

15 篇文章 0 订阅

1.题意

题目链接:https://www.codewars.com/kata/52742f58faf5485cae000b9a

Your task in order to complete this Kata is to write a function which formats a duration, given as a number of seconds, in a human-friendly way.

The function must accept a non-negative integer. If it is zero, it just returns "now". Otherwise, the duration is expressed as a combination of years, days, hours, minutes and seconds.

It is much easier to understand with an example:

TimeFormatter.formatDuration(62)   //returns "1 minute and 2 seconds"
TimeFormatter.formatDuration(3662) //returns "1 hour, 1 minute and 2 seconds"
For the purpose of this Kata, a year is 365 days and a day is 24 hours.

Note that spaces are important.

Detailed rules
The resulting expression is made of components like 4 seconds, 1 year, etc. In general, a positive integer and one of the valid units of time, separated by a space. The unit of time is used in plural if the integer is greater than 1.

The components are separated by a comma and a space (", "). Except the last component, which is separated by " and ", just like it would be written in English.

A more significant units of time will occur before than a least significant one. Therefore, 1 second and 1 year is not correct, but 1 year and 1 second is.

Different components have different unit of times. So there is not repeated units like in 5 seconds and 1 second.

A component will not appear at all if its value happens to be zero. Hence, 1 minute and 0 seconds is not valid, but it should be just 1 minute.

A unit of time must be used "as much as possible". It means that the function should not return 61 seconds, but 1 minute and 1 second instead. Formally, the duration specified by of a component must not be greater than any valid more significant unit of time.

题目意思很简单,就是给定一个秒数seconds,计算这个seconds的year、day、hour、minute、second,以"1year, 2 days, 1 hour, 1 minute and 2 seconds"这样形式的字符串返回,其中数值为0 的部分不显示,最后一个数值用"and"拼接,如果这个0秒则返回"now"

2.代码

一开始想的是算出这些值,然后用if else来进行判断拼接字符串,后来发现需要嵌套的if else太多了,就改为使用一个队列,计算过程中把这些数值对应的字符串按year、day、hour、minute、second的顺序加入到队列中,全部计算完成之后一个一个出队拼接到最终需要返回的字符串中,通过队列的大小来判断当前使用逗号拼接还是用"and"拼接

import java.util.LinkedList;
import java.util.Queue;

public class TimeFormatter {  
    public static String formatDuration(int seconds) {
        // your code goes here
        if (seconds == 0) return "now";

        int oneMinute = 60;
        int oneHour = 60 * oneMinute;
        int oneDay = 24 * oneHour;
        int oneYear = 365 * oneDay;

		// 注意这里不要用PriorityQueue,因为它是会自动给你排序的,用LinkedList,它也是一个队列
        Queue<String> queue = new LinkedList<>();

        String result = "";
        int year = seconds / oneYear;
        if (year == 1) queue.add(year + " year"); else if (year > 1) queue.add(year + " years");
        seconds = seconds - year * oneYear;

        int day =  seconds / oneDay;
        if (day == 1) queue.add(day + " day"); else if (day > 1) queue.add(day + " days");
        seconds = seconds - day * oneDay;

        int hour = seconds / oneHour;
        if (hour == 1) queue.add(hour + " hour"); else if (hour > 1) queue.add(hour + " hours");
        seconds = seconds - hour * oneHour;

        int minute = seconds / oneMinute;
        if (minute == 1) queue.add(minute + " minute"); else if (minute > 1) queue.add(minute + " minutes");
        seconds = seconds - minute * oneMinute;

        if (seconds == 1) queue.add(seconds + " second"); else if (seconds > 1) queue.add(seconds + " seconds");

        StringBuilder stringBuilder = new StringBuilder();

        while (!queue.isEmpty()){
            String tmp = queue.poll();
            stringBuilder.append(tmp);
            if (queue.size() > 1){
                stringBuilder.append(", ");
            }else if (queue.size() == 1){
                stringBuilder.append(" and ");
            }
        }

        return stringBuilder.toString();
    }
}

测试用例

import org.junit.Test;
import static org.junit.Assert.*;

public class TimeFormatterTest {
    @Test
    public void testFormatDurationExamples() {
        // Example Test Cases
        assertEquals("1 second", TimeFormatter.formatDuration(1));
        assertEquals("1 minute and 2 seconds", TimeFormatter.formatDuration(62));
        assertEquals("2 minutes", TimeFormatter.formatDuration(120));
        assertEquals("1 hour", TimeFormatter.formatDuration(3600));
        assertEquals("1 hour, 1 minute and 2 seconds", TimeFormatter.formatDuration(3662));
        assertEquals("1 hour and 1 second", TimeFormatter.formatDuration(3601));
    }
}

另外,有人给出了一种很简洁的Python写法,使用了if else表达式,具体可以参考https://segmentfault.com/a/1190000006704096

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WGeeker

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值