Charmve Coding | Codility - Counting Elevator Movements

Perface

Since last week, Apr 17. 2020, I had been starting to hold a Data Structs & Algorithms series training course. So I am going to make coding tests as a push study as much as possible, so that more excelent skills or methods can be relized and be meet your guys’ need.


Hereby, the following articles are all writen originally by myself, named Charmve Coding. This is a try for me to write contents completely in English, I hopefully wanna bring some special reading matters to you, my friends, to improve our English technolog reading ability.


To be honest, if those content appeals to you, a small click, themb-up, would make me happy. If you have any questions, feel free to reach out to me.

Good greeting to every Maiwei(邁微)members, I’m a FRIEND of yours, Charmve.

Today, we are going to explorle a few Codility test, which all have representativeness in Data Struct & Algorithms. At first, posting an interesting Codility test as usual, and then I will share different ways to solve this question. To be specific, it’s worth mentioning that a value-fulled summary will be shared to you.

Let’s begin! The test direction is followed.

1. Question

People are waiting for an elevator in a hotel. The elevator has limited capacity and you would like to analyse its movement.

The hotel has floors numbered from 0 (ground floor) to M. The elevator has a maximum capacity of X people and a weight limit of Y. There are N people gathered at the ground floor, standing in a queue for the elevator. You are given every person’s weight A[K] and target floor B[K]. (That is, A[0] and B[0] represent the first person in the queue.)


People continue to enter the elevator, in the order of their position in the queue (and push the buttons for their target floors), for as long as there is room for them. (The queue order cannot be changed even if there is room in the elevator for a particular person from the middle of the queue.) Then elevator goes up and stops at every selected floor, and finally returns to the ground floor. This process is repeated until there are no more people in the queue. The goal is to count the total number of times that the elevator stops.

For example, consider a hotel with floors numbered from 0 to M = 5, with an elevator with a maximum capacity of X = 2 people and a weight limit of Y = 200. The weights A and target floors B are:

A[0] = 60    B[0] = 2
A[1] = 80    B[1] = 3
A[2] = 40    B[2] = 5

The elevator will take the first two passengers together, stop at the 2nd and 3rd floors, then return to the ground floor. Then, it will take the last passenger, stop at the 5th floor and return to the ground floor. In total, the elevator will stop five times. Note that this number includes the last stop at the ground floor.

Write a function:


class Solution { public int solution(int[] A, int[] B, int M, int X, int Y); }


that, given zero-indexed arrays A and B consisting of N integers, and numbers X, Y and M as described above, returns the total number of times the elevator stops.

For example, given the above data, the function should return 5, as explained above.

For example, given M = 3, X = 5, Y = 200 and the following arrays:

A[0] =  40    B[0] = 3
A[1] =  40    B[1] = 3
A[2] = 100    B[2] = 2
A[3] =  80    B[3] = 2
A[4] =  20    B[4] = 3

the function should return 6, as the elevator will move in two stages: with the first three people and then with the two remaining people.

Assume that:

  • N, M and X are integers within the range [1…100,000];
  • Y is an integer within the range [1…1,000,000,000];
  • each element of array A is an integer within the range [1…Y];
  • each element of array B is an integer within the range [1…M].

Complexity:

  • expected worst-case time complexity is O(N*log(N)+M);
  • expected worst-case space complexity is O(N+M), beyond input storage (not counting the storage required for input arguments).

2. Process

  • Creating Waiting People Queue
  • Create elevator limit line conditions
  • Moving from Waiting People Queue to Elevator Queue
  • Return to the first floor when the elevator queue is empty and the elevator queue is empty.

3.Code (three versions)

JavaScript:

// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');

/** 
* Remove duplicate items from an array 
* @param {Array} arr 
* @returns {Array} 
*/ 
function uniq(arr) 
{ 
	return arr.reduce((prev, curr) => { 
		if (prev.indexOf(curr) === -1) 
		{ 
			prev = prev.concat(curr); 
		} 
		return prev; 
	}, []); } 
	
/** 
* Solution to our problem 
* 
* @param {Array.<Number>} A Array of passengers weights 
* @param {Array.<Number>} B Array of passenger destination floors 
* @param {Number} M Number of floors in the building 
* @param {Number} X Elevator max passenger capacity 
* @param {Number} Y Elevator max weight capacity 
* @returns {Number} Number of total stops 
*/ 

function solution(A, B, M, X, Y) 
{ 
	let trip = 0, 
	tripWeight = 0, 
	rounds = []; 
	
	for (let i = 0, len = A.length; i < len; i += 1) 
	{ 
		// If there's an unclosed trip, let’s see if we can get more people in 
		if (typeof rounds[trip] !== 'undefined') 
		{ 
			// Check if we have filled the capacity for the current trip, 
			// if so, then close the existing trip and create a new one 
			if (rounds[trip].length === X || tripWeight + A[i] > Y) { 
				// Increase trip count 
				trip++; 
				// Reset current weight 
				tripWeight = 0; 
			} 
		} 
		
		// Create an empty array for the current trip 
		rounds[trip] = rounds[trip] || []; 
		// Push passengers destination to current trip 
		rounds[trip].push(B[i]); 
		// Increase current load 
		tripWeight += A[i]; 
	} 

	// Remove duplicate floors from each trip, since 
	// the elevator will make 1 stop for pessengers that
	// go to the same floor. Then add 1 (return to ground floor) 
	rounds = rounds.map(round => uniq(round).length + 1); 
	
	// To get number of total stops, we sum up 
	// destination count in each trip. 
	return rounds.reduce((prev, curr) => prev + curr, 0); 
}

C++:

// you can use includes, for example:
#include <algorithm>
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;

// you can write to stdout for debugging purposes, e.g.
// cout << "this is a debug message" << endl;

class Solution
{
	/// <summary>
	/// Return total stops used
	/// </summary>
	/// <param name="A">weight of people</param>
	/// <param name="B">floors they need to get down</param>
	/// <param name="M">total floors in the building</param>
	/// <param name="X">Max people to carry at a time</param>
	/// <param name="Y">max weight to carry at a time</param>
	/// <returns></returns>
public:
	int solution(std::vector<int> &A, std::vector<int> &B, int M, int X, int Y)
	{
		// initialize variables
		int totalStops = 0;
		long long totalWeightPerRound = 0;
		int maxPersonsCount = 0;
		std::vector<int> lstFloors;
		int currPerson = 0;
		bool startLift = false;
		while (currPerson < A.size())
		{
			//Should current person be considered?
			if ((totalWeightPerRound + A[currPerson]) <= Y && (maxPersonsCount + 1) <= X)
			{
				totalWeightPerRound += A[currPerson];
				maxPersonsCount++;
				lstFloors.push_back(B[currPerson]);
				//If curr person is last person then start the lift
				if (currPerson == A.size() - 1)
				{
					startLift = true;
				}

				currPerson++;
			}
			else
			{
				startLift = true;
			}

			if (startLift)
			{
				totalStops += lstFloors.Distinct()->Count() + 1;
				//reset variable
				lstFloors.clear();
				maxPersonsCount = 0;
				totalWeightPerRound = 0;
				startLift = false;
			}
		}

		return totalStops;
	}
};
 

int main(void)
{
	int A[] = {0,2,4,7,5,3,6,1};
	//0,1,3,3,3,5,7,11
	int len = sizeof(A)/sizeof(A[0]);
	
	cout<<solution(A,len)<<endl;
}

Java:

import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

public class TestMain {
    public static void main(String args[]) {
        TestMain t = new TestMain();
        int[] A = {60, 80, 40};
        int[] B = {2, 3, 5};
        int M = 5;
        int X = 2;
        int Y = 200;
        System.out.println(t.solution(A, B, M, X, Y));
    }

    // 모든 사람의 체중 = A [K]
    // 대상 층 = B [K]
    // 존재하는 층수 = M
    // 엘리베이터의 최대 수용 인원 : X명
    // 무게 제한 : Y
    // (즉, A [0]과 B [0]은 대기열에있는 첫 번째 사람을 나타냅니다.)
    public int solution(int[] A, int[] B, int M, int X, int Y) {
        Queue<People> waitingQueue = new LinkedList<>();
        for (int i = 0; i < A.length; i++) {
            waitingQueue.offer(new People(A[i], B[i]));
        }
        return getInElv(waitingQueue, X, Y, 0);
    }

    private int getInElv(Queue<People> queue, int X, int Y, int count) {
        int xSum = 0;
        int ySum = 0;
        int floor = 1;

        while (!queue.isEmpty()) {
            Queue<People> elevatorQueue = new LinkedList<>();
            // 엘레베이터 용량 확인
            People waitPeople = queue.poll();
            elevatorQueue.add(waitPeople);
            if (xSum + 1 <= X || ySum + waitPeople.getWeight() <= Y) {
                xSum += 1;
                ySum += waitPeople.getWeight();
            }

            while (!elevatorQueue.isEmpty()) {
                People p = elevatorQueue.poll();
                if (floor != p.getGoal()) {
                    floor = p.getGoal();
                    count++;
                }
            }
            // 1층으로 돌아가기
            if (elevatorQueue.isEmpty()) {
                count++;
                return getInElv(queue, X, Y, count);
            }
        }
        return count;
    }

    public class People {
        private int weight;
        private int goal;

        public People(int weight, int goal) {
            this.weight = weight;
            this.goal = goal;
        }

        public int getWeight() {
            return weight;
        }

        public int getGoal() {
            return goal;
        }

        @Override
        public String toString() {
            return "People{" +
                    "weight=" + weight +
                    ", goal=" + goal +
                    '}';
        }
    }
}

4. Outro

4개의 문제가 넉넉한 시간이었음에도 불구하고 풀지를 못했네요. 알고리즘 공부를 계속해서 해야겠습니다. ㅠㅠ

사진관련 데이터를 컨버팅 하는 2번 문제는 개인적으로 보관하고 있지만, Sort 부분이 더 설명이 필요할 것으로 보여집니다. 문제가 깔끔해 보이지 않았다고 개인적으로 말씀드리고 싶네요. 나중에 더 봐서 해결이 가능하면 올려보도록 하겠습니다. 그리고, String으로 나열된 데이터를 바꾸는 것이 참 번거로워서 이 부분을 좀 더 연습해야 될 것 같습니다.

이번 과정은 Queue를 통해 생산자와 소비자 패턴을 쓰듯이 풀어보았습니다. 나중에 더 개선해보겠습니다.

Original comment comes from Hi-Cord.

Tanslate to English:

Although the four problems were generous, I couldn’t solve them. I should continue studying the algorithm. ㅠㅠ

The second issue of converting photo-related data is kept personally, but the Sort section seems to need more explanation. I want to tell you personally that the problem didn’t look neat. I will try to see more later if I can solve it. And, it is very cumbersome to change the data listed as a String, so I think I should practice this part a little more.

This course was solved as if writing producer and consumer patterns through Queue. We will improve it later.

THANKS for your attention!

Worthly Recommended:
[1] Charmve Coding | the smallest positive integer that does not occur in Array A

[2] 數據結構與算法 | 你知道快速排序,那你知道它的衍生應用嗎?Partition函數

[3] 數據結構與算法 | 二分查找:劍指offer53 在排序數組中查找數字

[4] 數據結構與算法 | 數據結構中到底有多少種“樹”?一文告訴你


Follow my WeChat Office Account 邁微電子研發社,to get more exciting content. First published in the personal public account.
在這裏插入圖片描述

△Scan the QC to follow MaiweiE-com

Knowledge Planet (in Charge):The community aims to share the autumn / spring preparation strategies (including brush questions), face-to-face and internal referral opportunities, learning routes, knowledge question banks, etc.

在這裏插入圖片描述

△Scan the QC to entry the community of MaiweiE-com

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章