HackerRank Gridland Metro Problem Solution
In this post, we will solve HackerRank Gridland Metro Problem Solution.
The city of Gridland is represented as an n x m matrix where the rows are numbered from 1 ton and the columns are numbered from 1 to m.
Gridland has a network of train tracks that always run in straight horizontal lines along a row. In other words, the start and end points of a train track are (r, c1) and (r, c2), where r represents the row number, c1 represents the starting column, and c2 represents the ending column of the train track.
The mayor of Gridland is surveying the city to determine the number of locations where lampposts can be placed. A lamppost can be placed in any cell that is not occupied by a train track.
Given a map of Gridland and its k train tracks, find and print the number of cells where the mayor can place lampposts.
Note: A train track may overlap other train tracks within the same row.
Example
If Gridland’s data is the following (1-based indexing):
k = 3 r c1 c2 1 1 4 2 2 4 3 1 2 4 2 3
Function Description
Complete the gridlandMetro function in the editor below.
gridlandMetro has the following parameter(s):
- int n:: the number of rows in Gridland
- int m:: the number of columns in Gridland
- int k:: the number of tracks
- track[k][3]: each element contains 3 integers that represent row, column start. column end, all 1-indexed
Returns
- int: the number of cells where lampposts can be installed
Input Format
The first line contains three space-separated integers n, m and k, the number of rows,
columns and tracks to be mapped.
Each of the next lines contains three space-separated integers, r, c1 and c2, the row
number and the track column start and end.
Sample Input
STDIN Function ----- -------- 4 4 3 n = 4, m = 4, k = 3 2 2 3 track = [[2, 2, 3], [3, 1, 4], [4, 4, 4]] 3 1 4 4 4 4
Sample Output
9
Explanation
the yellow cells denote the first train track, green denotes the second, and blue denotes the third. Lampposts can be placed in any of the nine red cells.
Gridland Metro C Solution
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int compare(const void *a, const void *b);
int main()
{
int n = 0, m = 0, k = 0, i = 0;
uint64_t s = 0;
scanf("%d %d %d", &n, &m, &k);
int *a = (int *)malloc(3 * k * sizeof(int));
for (i = 0; i < k; i++) {
scanf("%d %d %d", a + 3 * i, a + 3 * i + 1, a + 3 * i + 2);
}
qsort(a, k, 3 * sizeof(int), compare);
s = (uint64_t )n * (uint64_t )m;
i = 0;
while (i < 3 * k) {
int r = a[i];
int c = a[i + 1];
int d = a[i + 2];
i += 3;
while (i < 3 * k && a[i] == r) {
if (a[i + 1] <= d && a[i + 2] > d) {
d = a[i + 2];
} else if (a[i + 1] > d) {
s -= (uint64_t )(d + 1 - c);
c = a[i + 1];
d = a[i + 2];
}
i += 3;
}
s -= (uint64_t )(d + 1 - c);
}
printf("%ld\n", s);
return 0;
}
int compare(const void *a, const void *b)
{
int *x = (int *)a;
int *y = (int *)b;
if (*x > *y) {
return 1;
} else if (*x < *y) {
return -1;
} else {
if (*(x + 1) > *(y + 1)) {
return 1;
} else if (*(x + 1) < *(y + 1)) {
return -1;
} else {
return 0;
}
}
}
Gridland Metro C++ Solution
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
struct gg{
int c,l,r;
};
bool cmp(gg a, gg b){
return (a.c<b.c || ( (a.c==b.c) && ( (a.l<b.l) || ( (a.l==b.l) && (a.r,b.r) ) ) ) );
}
long long gt,n,m;
int k,l,r;
gg a[1001];
int main() {
cin>>n>>m>>k;
for (int i=1;i<=k;i++)
cin>>a[i].c>>a[i].l>>a[i].r;
sort(a+1,a+1+k,cmp);
gt=n*m;
l=a[1].l;
r=a[1].r;
k++;
a[k].c=n+1;
for (int i=2;i<=k;i++)
if (a[i].c==a[i-1].c){
if (a[i].l>r){
gt=gt-(r-l+1);
l=a[i].l;
}
r=max(r,a[i].r);
}else{
gt=gt-(r-l+1);
l=a[i].l;
r=a[i].r;
}
cout<<gt;
return 0;
}
Gridland Metro C Sharp Solution
// https://www.hackerrank.com/challenges/gridland-metro
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution
{
private class Track
{
internal long R, C1, C2;
internal Track Copy()
{
return new Track { R = this.R, C1 = this.C1, C2 = this.C2 };
}
}
private class TrackComparer : IComparer<Track>
{
public int Compare(Track t1, Track t2)
{
int rDiff = t1.R.CompareTo(t2.R);
if (rDiff != 0)
{
return rDiff;
}
return t1.C1.CompareTo(t2.C1);
}
}
public static void Main(String[] args)
{
long[] input = Console.ReadLine().Split(' ').Select(s => Convert.ToInt64(s)).ToArray();
long n = input[0];
long m = input[1];
long k = input[2];
long total = n * m;
if (k == 0)
{
Console.WriteLine(total);
return;
}
Track[] tracks = new Track[k];
for (int i = 0; i < k; i++)
{
long[] trackInput = Console.ReadLine().Split(' ').Select(s => Convert.ToInt64(s)).ToArray();
tracks[i] = new Track { R = trackInput[0], C1 = trackInput[1], C2 = trackInput[2] };
}
Array.Sort(tracks, new TrackComparer());
List<Track> curRowTracks = new List<Track>() { tracks[0] };
for (int i = 1; i < tracks.Length; i++)
{
if (curRowTracks[curRowTracks.Count - 1].R != tracks[i].R)
{
total -= CalculateTrackLength(curRowTracks);
curRowTracks.Clear();
}
curRowTracks.Add(tracks[i]);
}
total -= CalculateTrackLength(curRowTracks);
Console.WriteLine(total);
}
private static long CalculateTrackLength(IList<Track> curRowTracks)
{
Track range = curRowTracks[0].Copy();
long total = 0;
for (int i = 1; i < curRowTracks.Count; i++)
{
if (curRowTracks[i].C1 > range.C2)
{
total += range.C2 - range.C1 + 1;
range = curRowTracks[i].Copy();
continue;
}
range.C2 = Math.Max(range.C2, curRowTracks[i].C2);
}
total += range.C2 - range.C1 + 1;
return total;
}
}
Gridland Metro Java Solution
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
class Result {
/*
* Complete the 'gridlandMetro' function below.
*
* The function is expected to return an INTEGER.
* The function accepts following parameters:
* 1. INTEGER n
* 2. INTEGER m
* 3. INTEGER k
* 4. 2D_INTEGER_ARRAY track
*/
public static long gridlandMetro(int n, int m, int k, List<List<Integer>> track) {
Map<Integer,List<List<Integer>>> rowMap = new HashMap<>();
for(List<Integer> t : track){
int r= t.get(0);
int ll = t.get(1);
int rr = t.get(2);
if(rr < ll){
int tt = ll;
ll= rr;
rr =tt;
}
if(!rowMap.containsKey(r)){
rowMap.put(r,new ArrayList<>());
}
List<List<Integer>> row = rowMap.get(r);
List<List<Integer>> newRow = new ArrayList<>(row.size());
for(int i = 0;i<row.size();i++){
List<Integer> cur = row.get(i);
if(ll <= cur.get(1) && cur.get(0)<=ll ||cur.get(0) <= rr && rr <= cur.get(1) || cur.get(0) <= ll && rr <= cur.get(1)){
//System.out.println("merge: " + ll + " " + rr + " " + cur.get(0) + " "+ cur.get(1));
ll = Math.min(ll,cur.get(0));
rr = Math.max(rr,cur.get(1));
continue;
}
else{
newRow.add(cur);
}
}
newRow.add(Arrays.asList(ll,rr));
rowMap.put(r,newRow);
}
long ret = ((long)n)*((long)m);
for(List<List<Integer>> rows : rowMap.values()){
for(List<Integer> en : rows){
ret -= en.get(1) -en.get(0) + 1;
//System.out.println("b " + en.get(0) + " " + en.get(1));
}
}
return ret;
}
}
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
String[] firstMultipleInput = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
int n = Integer.parseInt(firstMultipleInput[0]);
int m = Integer.parseInt(firstMultipleInput[1]);
int k = Integer.parseInt(firstMultipleInput[2]);
List<List<Integer>> track = new ArrayList<>();
IntStream.range(0, k).forEach(i -> {
try {
track.add(
Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
.map(Integer::parseInt)
.collect(toList())
);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
});
long result = Result.gridlandMetro(n, m, k, track);
bufferedWriter.write(String.valueOf(result));
bufferedWriter.newLine();
bufferedReader.close();
bufferedWriter.close();
}
}
Gridland Metro JavaScript Solution
'use strict';
var BigNumber = require('bignumber.js');
const fs = require('fs');
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let inputString = '';
let currentLine = 0;
process.stdin.on('data', inputStdin => {
inputString += inputStdin;
});
process.stdin.on('end', _ => {
inputString = inputString.replace(/\s*$/, '')
.split('\n')
.map(str => str.replace(/\s*$/, ''));
main();
});
function readLine() {
return inputString[currentLine++];
}
function resolve(aoa, prev) {
if (aoa.length == 0) return 0;
let arrn = [];
//console.log("PR:", prev, aoa);
aoa.sort((a, b) => a[0] - b[0]);
arrn.push(aoa[0]);
for (let ind = 1; ind < aoa.length; ind++) {
let last = arrn[arrn.length - 1],
curr = aoa[ind];
if (curr[0] <= last[1]) {
last[1] = Math.max(curr[1], last[1]);
} else arrn.push(aoa[ind]);
}
const ret = arrn.reduce((acc, elem) => acc + elem[1] - elem[0] + 1, 0);
// console.log("RET:", BigInt(ret), arrn);
return new BigNumber(ret);
}
// Complete the gridlandMetro function below.
function gridlandMetro(n, m, k, track) {
let sum = BigNumber(m).multipliedBy(n);
track.sort((a, b) => a[0] - b[0]);
let prev = -1;
let accArr = [];
for (let i = 0; i < k; i++) {
if (track[i][0] !== prev) {
sum = sum.minus(resolve(accArr, prev));
prev = track[i][0];
accArr = [];
}
accArr.push([track[i][1], track[i][2]]);
}
sum = sum.minus(resolve(accArr, prev));
return String(sum);
}
function main() {
const ws = fs.createWriteStream(process.env.OUTPUT_PATH);
const nmk = readLine().split(' ');
const n = parseInt(nmk[0], 10);
const m = parseInt(nmk[1], 10);
const k = parseInt(nmk[2], 10);
let track = Array(k);
for (let i = 0; i < k; i++) {
track[i] = readLine().split(' ').map(trackTemp => parseInt(trackTemp, 10)-1);
}
let result = gridlandMetro(n, m, k, track);
ws.write(result + "\n");
ws.end();
}
Gridland Metro Python Solution
n, m, k = (int(x) for x in input().split())
def intersect(ab, xy):
if ab[0] <= xy[0] and ab[1] >= xy[0]:
return True
if ab[0] <= xy[1] and ab[1] >= xy[1]:
return True
return False
def superinterval(ab, xy):
return (min(ab[0], xy[0]), max(ab[1], xy[1]))
tracks = dict()
for i in range(k):
r, c1, c2 = (int(x) for x in input().split())
t = (c1, c2)
deletion = []
if r not in tracks:
tracks[r] = [t]
continue
for i, interval in enumerate(tracks[r]):
if intersect(interval, t):
t = superinterval(interval, t)
deletion.append(i)
for i in reversed(deletion):
del tracks[r][i]
tracks[r].append(t)
covered = 0
for row in tracks:
for track in tracks[row]:
covered += (track[1] - track[0] + 1)
#print(tracks)
print(n*m - covered)