Friday, October 25, 2024

Starting to Level Up Again

 Okay, we are making that climb up the mountain again.  Every few years, after falling behind on the latest advancements in all things Apple Developer, I make a concerted effort to fill in the gaps that have been created during that timeframe.  I am told the best way to hold myself accountable for sustained superior performance in this area is to find a "study" partner or to post about my journey on social media.  Given my partner has proven even less reliable than me, I am resorting to posting.  I will start here on Blogger, but may finally dust off my microblog account if it still exists or start posting to Mastodon (rather than just following).  I will definitely NOT be posting to X (nee twitter).  Wish me luck!

(LU1)

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.