Some codes are sourced from Loony Corn’s Udemy Course (https://www.udemy.com/user/janani-ravi-2/). This post is for personal notes where I summarize the original contents to grasp the key concepts
General Programming Problems
Often coding interviews involve problems which do not have complicated algorithms or data structures – These are straight programming problems
They test your ability to work through details and get the edge cases right
The bad thing about them is that they involve lots of cases which you need to work through – They tend to be frustrating
The great thing about them is that if you are organised and systematic in your thought process it is reasonably straightforward to get them right
These are problems you should nail. All they need is practice
None of them require any detailed knowledge of standard algorithms
We’ll solve 8 general programming problems here – They all use arrays or simple data structures which you create
Example 1. Check whether a given string is a palindrome
Palindromes are strings which read the same when read forwards or backwards
You can reverse all the letters in a palindrome and get the original string
Examples of palindromes are
MADAM, REFER, LONELY TYLENOL
Note
the string can have spaces, ignore spaces in the palindrome check, the spaces can all be collapsed
The check is Case-Insenstive
publicfuncisPalindrome(_input: String) -> Bool {
var firstIndex = 0
var lastIndex = input.count - 1
let lowerCasedInput = Array(input.lowercased())
print(lowerCasedInput)
while firstIndex < lastIndex {
var first: Character? = lowerCasedInput[firstIndex]
var last: Character? = lowerCasedInput[lastIndex]
while lowerCasedInput[firstIndex] == " " {
firstIndex += 1
first = lowerCasedInput[firstIndex]
}
while lowerCasedInput[lastIndex] == " " {
lastIndex -= 1
last = lowerCasedInput[lastIndex]
}
print("First char: \(first) Last char: \(last)")
if first != last {
returnfalse
}
firstIndex += 1
lastIndex -= 1
print("First index: \(firstIndex)")
print("Last index: \(lastIndex)")
}
returntrue
}
isPalindrome("MaIay a Ia m") //True
isPalindrome("MADAM") //True
isPalindrome("REFER") //True
isPalindrome("LONELY TYLENOL") //True
isPalindrome("LONELY TYLENOLF") //False
Example 2. Find all points within a certain distance of another point
Find points (Given X, Y coordinates) which are within a certain distance of another point. The distance and the central point is specified as an argument to the function which computes the points in range
Example. All points within a distance 10 of (0,0) will include the point at (3, 4) but not include the point at (12, 13)
Hint: If you are using an OO Programming language set up an entity which represents a point and contains methods within it to find the distance from another point.
return sqrt(pow(otherPoint.x - x, 2) + pow(otherPoint.y - y, 2))
}
publicfuncisWithinDistance(_otherPoint: Point, distance: Double) -> Bool {
let distanceX = abs(x - otherPoint.x)
let distanceY = abs(y - otherPoint.y)
if distanceX > distance || distanceY > distance {
returnfalse
}
return getDistance(otherPoint) <= distance
}
}
publicfuncgetPointsWithinDistance(points: [Point], center: Point, distance: Double) -> [Point] {
var withinPoints = [Point]()
for point in points {
if point.isWithinDistance(center, distance: distance) {
withinPoints.append(point)
}
}
print("Points within \(distance) of point x: \(center.x) y: \(center.y)")
for p in withinPoints {
print("Point: x: \(p.x) y: \(p.y)")
}
return withinPoints
}
Example 3. Game of Life: Get the next generation of cell states
A cell is a block in a matrix surrounded by neighbours. A cell can be in two states, alive or dead. A cell can change its state from one generation to another under certain circumstances
Rule
A live cell with fewer than 2 live neighbours dies of loneliness
A dead cell with exactly 2 live neighbours comes alive
A live cell with greater than 2 live neighbours dies due to overcrowding
Given a current generation of cells in a matrix, what does the next generation look like? Which cells are alive and which are dead? Write code to get the next generation of cells given the current generation
Hint
Represent each generation as rows and columns in a 2D matrix. Live and Dead states can be represented by integers or boolean states
iflet value = states[currentGeneration[row][col - 1]]{
states[currentGeneration[row][col - 1]] = value + 1
}
else {
states[currentGeneration[row][col - 1]] = 1
}
}
if col - 1 >= 0, row - 1 >= 0 {
iflet value = states[currentGeneration[row - 1][col - 1]]{
states[currentGeneration[row - 1][col - 1]] = value + 1
}
else {
states[currentGeneration[row - 1][col - 1]] = 1
}
}
if col - 1 >= 0, row + 1 < rowCount {
iflet value = states[currentGeneration[row + 1][col - 1]]{
states[currentGeneration[row + 1][col - 1]] = value + 1
}
else {
states[currentGeneration[row + 1][col - 1]] = 1
}
}
if col + 1 < colCount {
iflet value = states[currentGeneration[row][col + 1]]{
states[currentGeneration[row][col + 1]] = value + 1
}
else {
states[currentGeneration[row][col + 1]] = 1
}
}
if col + 1 < colCount, row - 1 >= 0 {
iflet value = states[currentGeneration[row - 1][col + 1]]{
states[currentGeneration[row - 1][col + 1]] = value + 1
}
else {
states[currentGeneration[row - 1][col + 1]] = 1
}
}
if col + 1 < colCount, row + 1 < rowCount {
iflet value = states[currentGeneration[row + 1][col + 1]]{
states[currentGeneration[row + 1][col + 1]] = value + 1
}
else {
states[currentGeneration[row + 1][col + 1]] = 1
}
}
if row + 1 < rowCount {
iflet value = states[currentGeneration[row + 1][col]]{
states[currentGeneration[row + 1][col]] = value + 1
}
else {
states[currentGeneration[row + 1][col]] = 1
}
}
if row - 1 >= 0 {
iflet value = states[currentGeneration[row - 1][col]]{
states[currentGeneration[row - 1][col]] = value + 1
}
else {
states[currentGeneration[row - 1][col]] = 1
}
}
if currentState == 0 {
//A dead cell with exactly 2 live neighbours comes alive
let livedCount = states[1] ?? 0
return livedCount == 2 ? 1 : 0
}
else {
let livedCount = states[1] ?? 0
//A live cell with fewer than 2 live neighbours dies of loneliness
//A live cell with greater than 2 live neighbours dies due to overcrowding
if livedCount < 2 || livedCount >= 2 {
return0
}
return currentState
}
}
Example 4. Break A document into chunks
A document is stored in the cloud and you need to send the text of the document to the client which renders it on the screen (Think Google docs)
You do not want to send the entire document to the client at one go, you want to send it chunk by chunk. A chunk can be created subject to certain constraints
Rule
A chunk can be 5000 or fewer characters in length (This rule is relaxed only under one condition see below)
A chunk should contain only complete paragraphs – This is a hard and fast rule
A paragraph is represented by the ‘:’ Character in the document
List of chunks should be in the order in which they appear in the document (Do not set them up out of order)
If you encounter a paragraph > 5000 characters that should be in a separate chunk by itself
Get all chunks as close to 5000 characters as possible, subject to the constraints above
Given a string document return a list of chunks which some other system can use to send to the client
Hint: public func chunkify(doc: String) -> [String]
while next < arrayInput.count, Int(String(arrayInput[next])) != nil {
numberStr += String(arrayInput[next])
print(numberStr)
next += 1
}
let repeatedCount = Int(numberStr) ?? 1
//Step 2. Generate repeated characters
result += String(repeating: arrayInput[next], count: repeatedCount)
//Step 3. Important! Pointing to next number
start = next + 1
}
return result
}
Example 6. Add two numbers represented by their digits
Given two numbers where the individual digits in the numbers are in an array or a list add them to get the final result in the same list or array form
Example using Arrays: [1, 2] represents the number 12. Note that the most significant digit in the 0th index of the array, with the least significant digit at the last position
Adding [1, 2] and [2, 3] should give the result [3, 5]
Requirements
Don’t convert the number format to a real number to add them. Add them digit by digit
Remember to consider the carry over per digit if there is one!
var sum = a[currentIndexA] + b[currentIndexB] + carry
if sum > 9 {
carry = sum / 10
sum = sum % 10
}
else {
carry = 0
}
result.insert(sum, at: 0)
currentIndexA -= 1
currentIndexB -= 1
}
if currentIndexA >= 0 {
while currentIndexA >= 0 {
var sum = a[currentIndexA] + carry
if sum > 9 {
carry = sum / 10
sum = sum % 10
}
else {
carry = 0
}
result.insert(sum, at: 0)
currentIndexA -= 1
}
}
if currentIndexB >= 0 {
while currentIndexB >= 0 {
var sum = a[currentIndexB] + carry
if sum > 9 {
carry = sum / 10
sum = sum % 10
}
else {
carry = 0
}
result.insert(sum, at: 0)
currentIndexB -= 1
}
}
if carry != 0 {
result.insert(carry, at: 0)
}
return result
}
Example 7. Increment number by 1
Suppose that you invent your own numeral system (which is neither decimal, binary nor any of the common ones). You specify the digits and the order of the digits in that numeral system.
Given the digits and the order of digits used in that system and a number, write a function to increment that number by 1 and return the result
Leave a Reply