Friday, October 29, 2021

Solving Coding Interview Problems

One of the reasons I got into programming was that I loved solving problems. Brain teasers, crosswords, Encyclopedia Brown mysteries, sudoku, those weird word problems with all those statements where you have to figure out who lives in the blue house - bring them on!  Programming gave me that same rush as when I solved one of those puzzles. However, one thing I hear continuously from my peers is that they hate coding interviews.  This is surprising as I find them comparable to solving a puzzle.

I get that coding interviews are artificial, that they bear little resemblance to real programming, and that they can be stress inducing especially when they prevent you from coding in the IDE of your choice (forcing you to code on a whiteboard or in CodePad).  But they can also be fun (in a non-masochistic way).

First, make your peace that you are going to be happy regardless of the result of the interview.  Second, treat the coding problems presented like the puzzles and exercises you do for fun.  If you can remove the stresses and instead have fun, you are far more likely not to suffer brain-freeze and to be more successful.

Let's take a simple common coding problem.  How do you check if two strings are anagrams of each other?  Anagrams have all the same letters, just in a different order.  That reminds me, make sure you understand the problem before you start trying to solve it.  As far as I know, no interviewer subtracts points from you for asking for clarification.

So let's give this one a whirl, solving it using Swift:

extension String {

    func isAnagram(str: String) -> Bool {

        var str = str

        for char in self {

            let index = str.firstIndex(of: char)

            guard index != nil else { return false }

            str.remove(at: index!)

        }

        return str.isEmpty

    }

}

Nicely done. You even made it an extension of String and followed the naming convention for functions returning Bool. This is a straightforward implementation that solves the problem in a clear, understandable way. We have a copy of the comparison string and we just keep removing letters that we have in the source string.  If we wind up with an empty string, we matched each letter of the source string, regardless of the order.  However, this solution has a computational complexity of O(2N-squared) where N is the number of characters in the string.  Can we do better?  

Is there a way we could organize each string such that they could be compared directly?  Since the two strings may be anagrams, they would have the same number of occurrences of each letter, that sounds like a counted set.  A counted set, is a set of unique items (in this case letters) and the number of times they occur.  We can implement it with a Dictionary.  

func isAnagram(str: String) -> Bool {

        var dictSelf = [Character : Int]()

        var dictStr = [Character : Int]()

        for char in self {

            let sum = dictSelf[char, default: 0]

            dictSelf[char] = sum + 1

        }

        for char in str {

            let sum = dictStr[char, default: 0]

            dictStr[char] = sum + 1

        }

        return dictSelf == dictStr

    }

We just created a dictionary with the letter as the key and the number of occurrences as the value.  The computational complexity of this solution is O(3N).  Creating each dictionary is O(N) as is the comparison.

Swift doesn't't directly implement CountedSet in its standard library, but Objective-C/Foundation does.  Using NSCountedSet, the above solution becomes a single line:

func isAnagram(str: String) -> Bool {

        return NSCountedSet(array: Array(self)) == NSCountedSet(array: Array(str))

    }

One other common solution to this problem which is not quite as efficient ( O(N㏒(N)) ) as the above but uses the same reasoning of arranging the strings in such a way that they can be compared directly is:

func isAnagram(str: String) -> Bool {

        return self.sorted() == str.sorted()

    }

This solution has the tentative advantage that it is directly supported in Swift and will be more easily understood by Swift developers.

There are usually many right answers to any programming problem or interview question.  Look for a way to represent the data in a way that helps you more easily solve the problem.  Remember to relax, have fun, and you will do your best.  Thank you to Kevin Tarr for suggesting this problem.  You can find videos by Kevin here on a variety of programming problems.

Thursday, July 23, 2015

Swift Fun Facts

Fact 1: Assigning a variable to itself is a compiler error.  I believe this is legal in Swift, but the LLVM compiler (Xcode 6 and 7) doesn't allow it.
var i = 0
i = i     <--- compiler gives error: "Assigning variable to itself"

Now why you would want to do this is another question entirely.

Fact 2: Trying to use Swift's print() statement inside an extension or subclass of an NSView brings up the print panel.  Despite having different argument lists, Xcode and the LLVM compiler would only recognize the NSView method print.  Swift's print was totally masked.  To access Swift's print function, preface it with:
Swift.print()

Fact 3: In strongly typed situations, Swift allows you to use just the enum member name without having to also use the enum type name.  For example:
enum CompassPoint {
    case North, South, East, West
}
var pointing: CompassPoint
pointing = .East  

I didn't have to use "CompassPoint.East".  This is great for readability and for saving time.  Now if Xcode's autocomplete would just get with the program in these strongly typed situations, I wouldn't have to type the enum name just to get it to list the members.  Feel free to duplicate this Apple Bug Reporter radar (rdar://21976034)

Opinion 1
Favorite Swift 2 feature: Protocol extensions and constraints
Welcome to the age of Protocol Oriented Programming

Friday, October 17, 2014

First Impressions of OS X Yosemite

First Impressions of Yosemite

So I stayed up late last night to install Yosemite on both my computers.  First Yosemite impressions are of translucence EVERYWHERE and of supersaturated colors.  The colors pop even to the point of distraction because so many other aspects of the user interface have been de-emphasized. Buttons and other controls have been simplified and flattened.  Chrome/window dressing has been almost eliminated so that your content is front and center.
I guess the reasons for these changes are to emphasize content, maximize use of space, and reduce distractions.  However I am not sure the goal has been realized.  The colors on the dock are so bright they overcome most of the benefit of reducing districts elsewhere.  I guess I will have to change the setting on my dock to be out of sight.  It never bothered me before but now it does.
Other highlights for me:

  • Mail seems to be working again.  Hallelujah!  I have struggled the last few years using Mail under Mountain Lion and Mavericks.  My gmail account would constantly stall and hang.  I would have to quit and restart mail multiple times a day to get it working again.  I kept the activity window always in view.  I would find mail on my phone that never showed up in my inbox on my Mac (I could find in my gmail archive folder).  After 24-hours all seems well.  
  • Phone calls on my Mac.  This is proving a little touchy.  I tried to place a phone call on my Mac - and it kept reporting that my Mac and iPhone had to be on the same local network.  After disconnecting and re-connecting my Mac and iPhone from my wi-fi network, it worked.  Receiving a call while using my Mac comes through FaceTime.  Fortunately, video is turned off by default unless specifically turned on.  Watch out for mis-clicks.  Also, when I got notified of an incoming call while using my Mac, I wanted to answer the call on my phone.  I closed my MacBook to answer the call on my iPhone and by doing so, I disconnected the call.  These are early days and I’m sure rough edges like these will show up and be addressed in updates.
  • iCloud Drive.  This can be a little anxious to set up initially, but worked perfectly.  The warning that your iCloud data will be inaccessible once you upgrade unless your other devices are upgraded to iOS 8 or Yosemite is scary but it lists your all devices and I knew what to expect.  The iCloud Drive was a little slow to access the first time - Finder just kept showing me a blank window or the files from the last selected folder when I tried to access iCloud Drive initially.  Things finally synced up and all was well.  Some indications of syncing would be helpful.  Comparisons to Dropbox® will be plentiful and this is at least one place where Dropbox does a better job.  iCloud Drive is a change of direction for Apple.  Initially, Apple seemed intent on doing away with the file system for cloud based files and mobile applications.  They have either retreated from this far-sighted strategy or have admitted defeat.  Being Apple, means never having to explain.

Every new OS X, John Siracusa does a detailed and magnificent review for Ars Technica.  The one for Yosemite can be found at: http://arstechnica.com/apple/2014/10/os-x-10-10/

The new site Six Colors features the writing of columnist Jason Snell.  I cannot recommend it strongly enough.  His review can be found at: http://sixcolors.com/post/2014/10/os-x-yosemite-review/

Thursday, October 16, 2014

New iPads

The new iPads look awesome.  I have been nursing an original iPad which has become less and less useful as iOS has advanced and the apps I use drop support for older models.  Looking at the comparisons that Phil Schiller showed of up to 12X greater CPU performance and 180X greater GPU performance, I got the feeling that it was time for a new iPad. I have squeezed all the value I could from my original purchase.  I am feeling very good about ordering my new iPad later today.  Now I just have to decide on a color: Silver, Gold, or Space Gray.

Sunday, September 14, 2014

A Fascinating Feature of Swift

I was just re-reading the swift book, The Swift Programming Language, and came across a feature that I overlooked the first time.

You can define a collection whose type is a protocol type.  This collection can include a bunch of objects of different types that all conform to a single protocol.  

Why is this useful?  When working with values whose type is a protocol type, methods and properties outside the protocol definition are not available.  This allows you to have a collection of different objects, but narrowly define the set of operations on that collection through the protocol type of the collection.  What a great way to create a particular perspective on a collection of different objects.

I can use the protocol to encapsulate the reasons I brought these different objects together, preventing unintended access to methods and properties outside the scope of why I brought these objects together.  This has great security benefits.  While we usually think of protocols as a way to extend objects, we can also use protocols to define a subset of existing capabilities of a set of objects.

Swift is a huge language and it continues to grow.  But even with the current features, there are further depths to explore.

Wednesday, September 3, 2014

Apple to Introduce Updated Hardware and New Product Categories on 9.9.14

At the moment, Xcode 6 Beta 7 has just been released.  We are less than a week from Apple's announcement of new hardware this Fall (Apple teaser: "Wish we could say more").  iOS 8 has been stuck at Beta 5 for a month.  My guess is that Apple may be ahead of the game on iOS 8 and are holding off releasing another beta because of support for unannounced hardware and features in the latest builds they don't wish to become public until the announcement on 9.9.14.

People are always trying to find hidden meanings from the teasers on the announcement invites.  I warrant this one is just a tongue-in-cheek reference to all the times Tim Cook avoided the "what's coming next" question.  Apple will be saying plenty come 9.9.14.

Thursday, August 21, 2014

Vulnerability


I am a bit of an Amanda Palmer fan.  She is a singer/songwriter who really puts herself out there.  She has the ability to make me laugh or cry, not every time, but with enough regularity that she must be tapping into something very raw and human. So, I pay some attention when she produces something.  I am on her mailing list and I get a notice from her (she writes infrequently) that she has a new book coming out.  Now I know this because I have read what she and others have written about how she twisted her life around in order to be able to write it.  So I get this notice which basically just tells me it how to get my hands on hew new book.  Now, honestly, I am not that interested in her book.  I saw her TED talk on the topic and I was wholly satisfied by that.  I am not interested in more details or the broader ramifications or how I too can put this into practice in my own life.  I got what I think I needed to know from her TED talk.  So I am looking at the cover to her book which is so Amanda Palmer (painted writing on naked skin - human parchment), and I notice the forward is written by Brene Brown.  Now, Amanda's husband is Neil Gaiman, a pretty famous writer, but she's got some other person doing the forward which makes me curious so I google her, as one does when you have no idea who a person is but maybe should. Up pops Brene Brown's TED talk.  So I am feeling a little guilty about my intention not to buy Amanda's book after she worked so hard on it and e-mailed me and all, so I decide I'll look at Brene's TED talk on vulnerability -  not my usual fair.  So, I watch the TED talk, find some non-obvious truths there to which I happen to ascribe and decide to share it with you.  You may already know all these truths but sometimes its nice to get a little affirmation about why we keep putting ourselves out there and getting our hearts roughed up a little.