wiki:codekata1

Version 1 (modified by lifeng, 13 years ago) (diff)

--

2013-05-10 && 2013-05-17 活动

为了减少对工作的影响,每周活动安排在周五下午,每次活动时间控制为2小时。 题目由参与同事各自出一个,之后汇总由大家以无记名投票的方式选举出一个。本次丁健勇贡献的题目贴近生活,有趣味,难度适中。最后以较高票数中标。题目如下:

 
公司饭堂排队吃饭,有11元,13元,15元3个窗口。
 
固定有500人就餐,其中280人第一选择是11元窗口,150人第一选择是13元窗口,70人第一选择是15元窗口。
 
每分钟11元窗口可打饭3人,13元窗口可打饭2人,15元窗口可打饭1人,每分钟有10名员工依次进场。
 
由于人的排队耐心有限,所以假如11元窗口的队伍人数大于50人时,员工会选择13元窗口,当13元窗口的队伍人数大于30人时,员工会选择15元窗口,
当15元窗口人数大于15人时,员工则不会再等待,直接出外就餐。
 
求出饭堂一天的营业额。

依靠小组成员的集体智慧与优秀的团队合作精神,经过2周的时间,成功地完成了这一题目。


测试代码如下:

package lunch;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author pc
 */
public class LunchTest {

    private Lunch lunch = null;
    private LinkedList<String> list;

    public LunchTest() {
    }

    @BeforeClass
    public static void setUpClass() {
    }

    @AfterClass
    public static void tearDownClass() {
    }

    @Before
    public void setUp() {
        lunch = new Lunch();
        list = lunch.getPeople();
        list.offer("11");
        list.offer("13");
        list.offer("11");
        list.offer("11");
        list.offer("15");
        list.offer("15");
        list.offer("11");
        list.offer("13");
        list.offer("13");
        list.offer("13");

        list.offer("13");
        list.offer("13");
        list.offer("13");
        list.offer("13");
        list.offer("15");
        list.offer("15");
        list.offer("11");
        list.offer("13");
        list.offer("13");
        list.offer("13");
    }

    @After
    public void tearDown() {
    }


    @Test
    public void testInit() {
        lunch = new Lunch();
        lunch.init();
        List<String> people = lunch.getPeople();
        Assert.assertEquals(Lunch.TOTAL_PEOPLE, lunch.getPeople().size());
        int count11 = 0;
        int count13 = 0;
        int count15 = 0;
        for (String s : people) {
            if ("11".equals(s)) {
                count11++;
            }
            if ("13".equals(s)) {
                count13++;
            }
            if ("15".equals(s)) {
                count15++;
            }
        }
        //TODO 验证首选11元的人数
        Assert.assertEquals(Lunch.TOTAL_PEOPLE_11, count11);

        //TODO 验证首选13元的人数
        Assert.assertEquals(Lunch.TOTAL_PEOPLE_13, count13);

        //TODO 验证首选15元的人数
        Assert.assertEquals(Lunch.TOTAL_PEOPLE_15, count15);

        //TODO 验证随机

    }

    @Test
    public void testCheckpoint() {
        //lunch.init();

        Map<String, Integer> queue = lunch.getQueue();
        queue.put("11", 0);
        queue.put("13", 0);
        queue.put("15", 0);
        lunch.setQueue(queue);
        
        lunch.checkpoint();
        Assert.assertEquals(10, list.size());
        Assert.assertEquals(1, (int) queue.get("11"));
        Assert.assertEquals(2, (int) queue.get("13"));
        Assert.assertEquals(1, (int) queue.get("15"));
        Assert.assertEquals(4, lunch.getPersonCount11());
        Assert.assertEquals(4, lunch.getPersonCount13());
        Assert.assertEquals(2, lunch.getPersonCount15());
        
        lunch.checkpoint();
        Assert.assertEquals(0, list.size());
        Assert.assertEquals(0, (int) queue.get("11"));
        Assert.assertEquals(7, (int) queue.get("13"));
        Assert.assertEquals(2, (int) queue.get("15"));
        Assert.assertEquals(5, lunch.getPersonCount11());
        Assert.assertEquals(11, lunch.getPersonCount13());
        Assert.assertEquals(4, lunch.getPersonCount15());
    }
    
    @Test
    public void testCheckPointHavePeople() {
        Map<String, Integer> queue = lunch.getQueue();
        queue.put("11", 50);
        queue.put("13", 30);
        queue.put("15", 10);
        lunch.setQueue(queue);        
        
        lunch.checkpoint();
        Assert.assertEquals(10, list.size());
        Assert.assertEquals(47, (int) queue.get("11"));
        Assert.assertEquals(28, (int) queue.get("13"));
        Assert.assertEquals(14, (int) queue.get("15"));
        Assert.assertEquals(0, lunch.getPersonCount11());
        Assert.assertEquals(0, lunch.getPersonCount13());
        Assert.assertEquals(5, lunch.getPersonCount15());
    }

    @Test
    public void testGetBalance() {
        int balance = lunch.getPersonCount11() * Lunch.COST_ELEVEN
                + lunch.getPersonCount13() * Lunch.COST_THIRTEEN
                + lunch.getPersonCount15() * Lunch.COST_FIFTEEN;
        Assert.assertEquals(balance, lunch.getBalance());
    }

    @Test
    public void testChoose() {

        Map<String, Integer> queue = new HashMap<String, Integer>();
        queue.put("11", 33);
        queue.put("13", 0);
        queue.put("15", 0);


        String people = "11";
        lunch.setQueue(queue);

        Assert.assertTrue(lunch.choose11(people));

        queue = new HashMap<String, Integer>();
        queue.put("11", 49);
        queue.put("13", 0);
        queue.put("15", 0);
        lunch.setQueue(queue);
        Assert.assertTrue(lunch.choose11(people));

        queue = new HashMap<String, Integer>();
        queue.put("11", 50);
        queue.put("13", 0);
        queue.put("15", 0);
        lunch.setQueue(queue);
        Assert.assertFalse(lunch.choose11(people));

        people = "13";
        Assert.assertFalse(lunch.choose11(people));
    }

    @Test
    public void testChoose13() {
        Map<String, Integer> queue = new HashMap<String, Integer>();

        String people = "13";
        queue = new HashMap<String, Integer>();
        queue.put("11", 0);
        queue.put("13", 30);
        queue.put("15", 0);
        lunch.setQueue(queue);
        Assert.assertFalse(lunch.choose13(people));

        queue = new HashMap<String, Integer>();
        queue.put("11", 0);
        queue.put("13", 29);
        queue.put("15", 0);
        lunch.setQueue(queue);
        Assert.assertTrue(lunch.choose13(people));

        people = "15";
        Assert.assertFalse(lunch.choose13(people));

    }

    @Test
    public void testChoose15() {

        Map<String, Integer> queue = new HashMap<String, Integer>();

        String people = "15";
        queue = new HashMap<String, Integer>();
        queue.put("11", 0);
        queue.put("13", 0);
        queue.put("15", 15);
        lunch.setQueue(queue);
        Assert.assertFalse(lunch.choose15(people));

        queue = new HashMap<String, Integer>();
        queue.put("11", 0);
        queue.put("13", 0);
        queue.put("15", 14);
        lunch.setQueue(queue);
        Assert.assertTrue(lunch.choose15(people));
    }
    
    @Test
    public void testHandlePieceOfLunch(){
        Map<String, Integer> queue = lunch.getQueue();
        queue.put("11", 30);
        queue.put("13", 20);
        queue.put("15", 10);
        lunch.setQueue(queue);
        
        lunch.handlePieceOfLunch();
        Assert.assertEquals(27, (int) queue.get("11"));
        Assert.assertEquals(18, (int) queue.get("13"));
        Assert.assertEquals(9, (int) queue.get("15"));
        
        queue = lunch.getQueue();
        queue.put("11", 0);
        queue.put("13", 0);
        queue.put("15", 0);
        lunch.setQueue(queue);
        lunch.handlePieceOfLunch();
        Assert.assertEquals(0, (int) queue.get("11"));
        Assert.assertEquals(0, (int) queue.get("13"));
        Assert.assertEquals(0, (int) queue.get("15"));
        
        queue = lunch.getQueue();
        queue.put("11", 3);
        queue.put("13", 2);
        queue.put("15", 1);
        lunch.setQueue(queue);
        lunch.handlePieceOfLunch();
        Assert.assertEquals(0, (int) queue.get("11"));
        Assert.assertEquals(0, (int) queue.get("13"));
        Assert.assertEquals(0, (int) queue.get("15"));
        
    }
}

源代码如下:

package lunch;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

/**
 *
 * @author pc
 */
public class Lunch {

    public static final int WAIT_NUM_OF_11 = 50;
    public static final int WAIT_NUM_OF_13 = 30;
    public static final int WAIT_NUM_OF_15 = 15;
    
    public static final int TOTAL_PEOPLE = 500;
    public static final int TOTAL_PEOPLE_11 = 280;
    public static final int TOTAL_PEOPLE_13 = 150;
    public static final int TOTAL_PEOPLE_15 = 70;
    public static final int COST_ELEVEN = 11;
    public static final int COST_THIRTEEN = 13;
    public static final int COST_FIFTEEN = 15;

    public static final int NUM_OF_HANDLE_11 = 3;
    public static final int NUM_OF_HANDLE_13 = 2;
    public static final int NUM_OF_HANDLE_15 = 1;
    
    
    private Map<String, Integer> queue = new HashMap<String, Integer>();
    private LinkedList<String> people = new LinkedList<String>();
    
    private int personCount11 = 0;
    private int personCount13 = 0;
    private int personCount15 = 0;

    public Map<String, Integer> getQueue() {
        return queue;
    }

    public void setQueue(Map<String, Integer> queue) {
        this.queue = queue;
    }

    public LinkedList<String> getPeople() {
        return people;
    }

    public int getPersonCount11() {
        return personCount11;
    }

    public int getPersonCount13() {
        return personCount13;
    }

    public int getPersonCount15() {
        return personCount15;
    }

    /**
     * 初始化进场顺序
     */
    public void init() {
        for (int i = 0; i < TOTAL_PEOPLE_11; i++) {
            people.add("11");
        }
        for (int i = 0; i < TOTAL_PEOPLE_13; i++) {
            people.add("13");
        }
        for (int i = 0; i < TOTAL_PEOPLE_15; i++) {
            people.add("15");
        }

        queue.put("11", 0);
        queue.put("13", 0);
        queue.put("15", 0);

        Collections.shuffle(people);
    }

    public int getBalance() {
        return COST_ELEVEN * personCount11 + COST_THIRTEEN * personCount13
                + COST_FIFTEEN * personCount15;
    }

    /**
     * 每分钟时的处理方法
     */
    public void checkpoint() {
        for (int i = 0; i < 10; i++) {
            String p = people.poll();

            // 判断队列人数
            boolean result = choose11(p);
            if (result) {
                queue.put("11", queue.get("11") + 1);
                personCount11++;
            } else {
                result = choose13(p);
                if (result) {
                    queue.put("13", queue.get("13") + 1);
                    personCount13++;
                } else {
                    if (choose15(p)) {
                        queue.put("15", queue.get("15") + 1);
                        personCount15++;
                    }
                }
            }
        }

        handlePieceOfLunch();
    }

    public void handlePieceOfLunch() {
        queue.put("11", queue.get("11") - 3 < 0 ? 0 : queue.get("11") - 3);
        queue.put("13", queue.get("13") - 2 < 0 ? 0 : queue.get("13") - 2);
        queue.put("15", queue.get("15") - 1 < 0 ? 0 : queue.get("15") - 1);
    }

    public boolean choose11(String p) {
        return queue.get("11") < WAIT_NUM_OF_11 && "11".equals(p);
    }

    public boolean choose13(String p) {
        return queue.get("13") < WAIT_NUM_OF_13 && ("11".equals(p) || "13".equals(p));
    }

    public boolean choose15(String p) {
        return queue.get("15") < WAIT_NUM_OF_15;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        int times = TOTAL_PEOPLE % 10 == 0 ? TOTAL_PEOPLE / 10 : TOTAL_PEOPLE / 10 + 1;
        Lunch lunch = new Lunch();
        lunch.init();
        for (int i = 0; i < times; i++) {
            lunch.checkpoint();
        }
        int total = lunch.getBalance();
        System.out.println("total:" + total);
        System.out.println("getPersonCount11:" + lunch.getPersonCount11());
        System.out.println("getPersonCount13:" + lunch.getPersonCount13());
        System.out.println("getPersonCount15:" + lunch.getPersonCount15());
    }
}

这次Code Kata活动,总体来说,还是比较顺利,中途也出现了一些,代码设计上的分歧意见,和代码设计中发现的问题,但小组成员都虚心倾听别人意见,认真思考 最后讨论统一编程思路,大家都受益良多。

比如说,开始活动之前,王安宁就发现题目本身存在一些设计不合理的地方,后来经过讨论修改,敲订题目。

秦鸿源在大家在陷入过度设计陷井的时候,站出来,提出分解问题,各个击破的方案,让大家思路更清晰,更有条理。

陈阳提出使用队列比使用数组更适合解决打饭排队问题,丁健勇与邝巨桓,在小组成编码过程中给过很多非常不错的经验与建议。

新入职的黄志强和李炳岳,也作为顾问全程参与了活动,虽然没有直接参与编码,但也从中学习到了不少知识。

活动之中还有很多精彩的细节...

欢迎其他组有兴趣的同事加入:)

Attachments