Skip to content
This repository was archived by the owner on Dec 12, 2023. It is now read-only.

Commit 5087234

Browse files
committed
Merge pull request #152 from cjjavellana/master
Skiing in Singapore
2 parents f792d94 + 988466e commit 5087234

File tree

2 files changed

+297
-0
lines changed

2 files changed

+297
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Skiing in Singapore
2+
I came across this programming excercise from redmart that caught my interest. At the same time im in the midst of the harvard's cs50 course which i took through edx as a refresher. So I thought of taking up the programming excercise challenge and try to implement it using c. So without further ado, the challenge description goes like this:
3+
4+
====================
5+
6+
Sometimes it's nice to take a break and code up a solution to a small, fun problem. Here is one some of our engineers enjoyed recently called Skiing In Singapore.
7+
8+
Well you can’t really ski in Singapore. But let’s say you hopped on a flight to the Niseko ski resort in Japan. Being a software engineer you can’t help but value efficiency, so naturally you want to ski as long as possible and as fast as possible without having to ride back up on the ski lift. So you take a look at the map of the mountain and try to find the longest ski run down.
9+
10+
In digital form the map looks like the number grid below.
11+
12+
4 4
13+
4 8 7 3
14+
2 5 9 3
15+
6 3 2 5
16+
4 4 1 6
17+
18+
The first line (4 4) indicates that this is a 4x4 map. Each number represents the elevation of that area of the mountain. From each area (i.e. box) in the grid you can go north, south, east, west - but only if the elevation of the area you are going into is less than the one you are in. I.e. you can only ski downhill. You can start anywhere on the map and you are looking for a starting point with the longest possible path down as measured by the number of boxes you visit. And if there
19+
are several paths down of the same length, you want to take the one with the steepest vertical drop, i.e. the largest difference between your starting elevation and your ending elevation.
20+
21+
On this particular map the longest path down is of length=5 and it’s highlighted in bold below: 9-5-3-2-1.
22+
23+
4 4
24+
4 8 7 3
25+
2 5 9 3
26+
6 3 2 5
27+
4 4 1 6
28+
29+
There is another path that is also length five: 8-5-3-2-1. However the tie is broken by the first path being steeper, dropping from 9 to 1, a drop of 8, rather than just 8 to 1, a drop of 7.
30+
31+
Your challenge is to write a program in your favorite programming language to find the longest (and then steepest) path on this map specified in the format above. It’s 1000x1000 in size, and all the numbers on it are between 0 and 1500.
32+
33+
Send your code or a github link (and a resume if you like) to [?????? at redmart dot com], replacing “??????” with the concatenation of the length of the longest path with the largest drop, and the size of the drop. So in the simple example above length=5, drop=8, so the email address would be [58 at redmart dot com]. If your e-mail gets through - you got the right answer.
34+
35+
Good luck and have fun!

solutions/c/sgski.c

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
// required; otherwise clang will complain that getline has not been declared
2+
#define _XOPEN_SOURCE 700
3+
#include <stdio.h>
4+
#include <ctype.h>
5+
#include <string.h>
6+
#include <stdlib.h>
7+
8+
typedef struct {
9+
int **matrix;
10+
int rowCount;
11+
int colCount;
12+
} matrix;
13+
14+
typedef struct {
15+
char* solution;
16+
int distance;
17+
int drop;
18+
} solution;
19+
20+
typedef struct {
21+
int row;
22+
int col;
23+
} cellIndex;
24+
25+
// input file reading routines
26+
void readfile(matrix *m, FILE* fp);
27+
void initMatrix(matrix *m, char* line);
28+
void readline(matrix *m, char* line, int rowIndex);
29+
30+
// solution finder
31+
void findSkiPath(matrix *m, solution *sol);
32+
void checkAdjacentCells(const char* path, matrix *m, cellIndex index, solution *sol, int currentValue);
33+
void evaluateSolution(solution *sol, const char* path);
34+
35+
// miscellaneous routines
36+
void showContents(matrix *m);
37+
38+
int main(int argc, char* argv[]) {
39+
40+
if(argc != 2) {
41+
printf("usage: sgski <input file>\n");
42+
exit(1);
43+
}
44+
45+
char* filename = argv[1];
46+
FILE *ifp = fopen(filename, "r");
47+
if (ifp == NULL) {
48+
printf("Unable to open input file %s\n", filename);
49+
exit(EXIT_FAILURE);
50+
}
51+
52+
// initialize the solution structure
53+
solution *sol = malloc(sizeof(solution));
54+
sol->solution = malloc(sizeof(char) * 100);
55+
sol->distance = 0;
56+
sol->drop = 0;
57+
58+
matrix *m = malloc(sizeof(matrix));
59+
60+
// read the input file into the matrix
61+
readfile(m, ifp);
62+
63+
// close file after reading
64+
fclose(ifp);
65+
66+
findSkiPath(m, sol);
67+
68+
printf("Ski Path: %s; Distance: %d; Drop: %d\n", sol->solution, sol->distance, sol->drop);
69+
70+
// release resources
71+
free(sol);
72+
free(m);
73+
74+
return 0;
75+
}
76+
77+
void findSkiPath(matrix *m, solution *sol) {
78+
for (int i = 0; i < m->rowCount; i++) {
79+
for (int j = 0; j < m->colCount; j++) {
80+
int value = m->matrix[i][j];
81+
char* path = malloc(sizeof(char) * 6);
82+
sprintf(path, "%d ", value);
83+
84+
cellIndex index;
85+
86+
// check east
87+
index.row = i;
88+
index.col = j + 1;
89+
checkAdjacentCells(path, m, index, sol, value);
90+
91+
// check west
92+
index.row = i;
93+
index.col = j - 1;
94+
checkAdjacentCells(path, m, index, sol, value);
95+
96+
// check north
97+
index.row = i - 1;
98+
index.col = j;
99+
checkAdjacentCells(path, m, index, sol, value);
100+
101+
// check south
102+
index.row = i + 1;
103+
index.col = j;
104+
checkAdjacentCells(path, m, index, sol, value);
105+
}
106+
}
107+
}
108+
109+
void checkAdjacentCells(const char* path, matrix *m, cellIndex index, solution *sol, int currentValue) {
110+
111+
// The base case - If we go beyond the limits of the matrix
112+
if(index.row < 0 || index.row > (m->rowCount - 1)
113+
|| index.col < 0 || index.col > (m->colCount - 1)) {
114+
evaluateSolution(sol, path);
115+
return;
116+
}
117+
118+
// check if the next cell has a lower value than the current cell
119+
int val = m->matrix[index.row][index.col];
120+
if(val < currentValue) {
121+
char* newPath = malloc(sizeof(char) * (strlen(path) + 4 + 1 + 1)); // the 4-digit value + space + \0
122+
strcpy(newPath, path);
123+
124+
char *ch = malloc(sizeof(char) * (5 + 1)); // support upto 4-digit value and \0 (string terminator)
125+
if(ch == NULL) {
126+
printf("Unable to allocate memory\n");
127+
exit(EXIT_FAILURE);
128+
}
129+
sprintf(ch, "%d ", val);
130+
strcat(newPath, ch);
131+
free(ch);
132+
133+
int r = index.row, c = index.col;
134+
135+
// check east
136+
index.row = r;
137+
index.col = c + 1;
138+
checkAdjacentCells((const char*) newPath, m, index, sol, val);
139+
140+
// check west
141+
index.row = r;
142+
index.col = c - 1;
143+
checkAdjacentCells((const char*) newPath, m, index, sol, val);
144+
145+
// check north
146+
index.row = r - 1;
147+
index.col = c;
148+
checkAdjacentCells((const char*) newPath, m, index, sol, val);
149+
150+
// check south
151+
index.row = r + 1;
152+
index.col = c;
153+
checkAdjacentCells((const char*) newPath, m, index, sol, val);
154+
155+
free(newPath);
156+
}
157+
158+
// all ajacent cells have bigger value then the current cell
159+
evaluateSolution(sol, path);
160+
return;
161+
}
162+
163+
/**
164+
* Checks if the longest path with the steepest drop has been found.
165+
*/
166+
void evaluateSolution(solution *sol, const char* path) {
167+
// split the string by the space delimiter
168+
int distance = 1;
169+
char *dropTemp[2];
170+
dropTemp[0] = strtok(strdup(path), " ");
171+
char* end = dropTemp[1] = strdup(dropTemp[0]);
172+
173+
while ((end = strtok(NULL, " ")) != NULL) {
174+
dropTemp[1] = end;
175+
distance++;
176+
}
177+
178+
if(distance < sol->distance) {
179+
return;
180+
}
181+
182+
int drop = atoi(dropTemp[0]) - atoi(dropTemp[1]);
183+
if(distance > sol->distance || drop > sol->drop) {
184+
strcpy(sol->solution, path);
185+
sol->distance = distance;
186+
sol->drop = drop;
187+
}
188+
}
189+
190+
void readfile(matrix *m, FILE* fp) {
191+
int rowIndex = 0;
192+
size_t len = 0;
193+
size_t read = -1;
194+
char *line;
195+
196+
while ((read = getline(&line, &len, fp) != -1)) {
197+
if (rowIndex == 0) {
198+
// the first row of the input file
199+
// contains the size of the matrix.
200+
initMatrix(m, line);
201+
} else {
202+
readline(m, line, rowIndex);
203+
}
204+
205+
rowIndex++;
206+
}
207+
}
208+
209+
/**
210+
* Reads the size of the matrix from the first line of the input file and
211+
* sets the row and column counts into the parameters rowCount and colCount
212+
* attributes of matrix m.
213+
*
214+
* This function is to be called on the first line of the input file.
215+
*/
216+
void initMatrix(matrix *m, char* line) {
217+
218+
// reads the row count - the first value on the line string
219+
char *ch = strtok(line, " ");
220+
m->rowCount = atoi(ch);
221+
222+
// reads the column count - the second value on the line string
223+
ch = strtok(NULL, " ");
224+
m->colCount = atoi(ch);
225+
226+
// initialize a two-dimentional array of size rowCount * columnCount
227+
int** matrix = (int **) malloc(sizeof(int *) * m->rowCount);
228+
for(int i = 0; i < m->rowCount; i++) {
229+
matrix[i] = (int *) malloc(sizeof(int) * m->colCount);
230+
}
231+
232+
m->matrix = matrix;
233+
}
234+
235+
void readline(matrix *m, char* line, int rowIndex) {
236+
int colIndex = 0;
237+
char *ch = strtok(line, " ");
238+
239+
while(ch != NULL) {
240+
int val = atoi(ch);
241+
if(val > 9999) {
242+
printf("Invalid input file. Cannot have value greater than 9999\n");
243+
exit(EXIT_FAILURE);
244+
}
245+
246+
m->matrix[rowIndex - 1][colIndex] = atoi(ch);
247+
ch = strtok(NULL, " ");
248+
colIndex++;
249+
}
250+
}
251+
252+
/**
253+
* Prints the contents of the matrix into the console
254+
*/
255+
void showContents(matrix *m) {
256+
for(int i = 0; i < m->rowCount; i++) {
257+
for (int j = 0; j < m->colCount; j++) {
258+
printf("%d ", m->matrix[i][j]);
259+
}
260+
printf("\n");
261+
}
262+
}

0 commit comments

Comments
 (0)