Quick Hacks 1

September 26, 2017 by Abhirath Mahipal


Here are a few ways of solving problems that deviate from the norm. They aren’t the best solutions nor do I recommend you to use these in production or critical systems. These may or may not be elegant or well expressed.

I think these are quite creative. I intend to document more of these as I find (and hopefully create in the future) them. I wager that they are a nice gentle examples of thinking outside the box. Also these are examples of how one tool can be used to solve a wide variety of problems.

1. Removing Duplicates and Sort

I don’t recall where I saw this (It was some Go repository). Now languages like Python, Haskell and JavaScript have inbuilt functions to remove duplicates from lists or arrays. Go does not.

You can quickly whip up an one liner in Python. Let’s see how this problem was solved in Go.

I feel this is a neat hack as you don’t have to implement a function to remove duplicates. The guy basically used the sort function and turned it to a tool to help him remove duplicates.

Problem:- It’s a slice (array, list whatever) of Strings. Go has a function to sort a slice of strings but no inbuilt function to remove duplicates.

import (
    "strings"
    "sort"
)

// a function which takes in a list of strings and returns a list of strings
func SortAndRemoveDuplicates(badList [] string) [] string {
    var lastIteration string

    // a variable to hold the return value
    var finalList []string = make([]string, 0)

    // badList is now sorted but still has duplicates
    sort.Strings(badList)

    // we iterate over the sorted list
    for _, individualString := range badList {

        // since it's sorted same strings appear together
        // if the last added string to the final list it is a duplicate
        // we only add it to the new list if the current string is not
        // identical to the previous string that was added

        if individualString != lastIteration {
            finalList = append(finalList, individualString)
            lastIteration = individualString
        }
    }


    return finalList
}

2. Accessing Elements in an Array

I saw this in a competitive programming repository.

Problem:- Access two consecutive elements in an array. If it’s the last element access the first element. First and second, second and third and so on until last and first. The length of the list is known in advance.

Note:- I think reduce (the functional programming pattern) is a good fit for an elegant solution to this problem. However I haven’t tried implementing it.

// normal straightforward way
var myList = [1, 2, 3, 4, 5, 6, 7, 8];
var indexOfLast = 8;
for (var i = 0; i < myList.Length; i++) {
  if (i == 8) {
    console.log(myList[i], myList[0]);
  } else {
    console.log(myList[i], myList[i + 1]);
  }
}

// hacky way
var myList = [1, 2, 3, 4, 5, 6, 7, 8];

// we just append the first element to the end
// myList is now [1,2,3,4,5,6,7,8,1]
myList = myList.concat(myList[0]);
var indexOfLast = 8;

for (var i = 0; i < 8; i++) {
  console.log(myList[i], myList[i + 1]);
}

It’s very similar to “Array Rotation” (Courtesy:- Henre Botha)

3. Bank Withdrawal Checking

I read this in the book The Go Programming Language by Alan Donovan and Brian Kernighan.

This is not a hack nor does it reduce work. I felt it gives a different approach to the problem. Many might disagree.

var balance int
func Deposit(amount int) {
    balance = balance + amount
}

// normally we check if balance is greater
// than the amount to be withdrawn
func Withdraw(amount int) bool {
    if balance >= amount {
        balance = balance - amount
        return true // withdrawal was a success
    }

    return false // failed
}

// A different way
func Withdraw(amount int) bool {
    Deposit(-amount) // we use deposit to make a negative deposit
    if balance < 0 {
        // if balance is less than 0, we add the original amount back
        Deposit(amount)
        return false
    }

    return true
}

4. Rounding to the Nearest Integer

I don’t recall the source.

**Problem:-**Rounding floats to their nearest complete values.
5.1 -> 5.0
5.7 -> 6.0

# Normal way
round(5.1, 0) # returns 5.0
round(5.7, 0) # returns 6.0

# A different way
import math

def my_round(float_please):
    # Please google math.ceil if you arent' aware of what it does
    # Just think about the different scenarios. I'm
    # pretty sure you won't need an explanation :)
    return math.ceil(float_please - 0.5)

my_round(5.1) # returns 5.0
my_round(5.7) # return 6.0

End

I’ll try my best to keep note of the link or repository that house such solutions from this point onwards. Also if you are aware of similar hacks or alternate ways of solving problems, please comment them below :)