CS admissions, Fall 2022

tl/dr advice to kids and parents aiming for admission to a good undergraduate CS program in 2022-2023:

  • Research what your target schools are looking for.
  • Calculate the cost/benefit ratio.
  • Have a back-up plan.

Having just helped my three kids get into undergraduate CS programs at, respectively a top-10, a top-25, and a top-35 school, I want to share my family’s experience.

More …

A Solver for Hitman Go Levels

I wrote a solver for Hitman Go levels. You can use it to:

  • Solve existing levels.
  • Design and test your own levels.
  • Study graph search algorithms like A-Star.

The code is available in four related projects:

Screenshot of Spy Puzzle App

In this screenshot of a simple test level, the “Agent” needs to pick up a red key to open the red door, followed by the blue key to open the blue door. The solver has correctly solved the moves required to solve the level as “east, east, south”.

More …

Calming Ripples App

Calming Ripples is a SwiftUI app that lets you draw animated ripples.

Available for iOS, iPadOS and macOS.

Study the source code to learn these techniques:

  • Handle multi-finger touch events.
  • Draw complex 2D designs using the SwiftUI Canvas view.
  • Animate using the SwiftUI TimelineView view.
  • Use the onChanged() view method to create a dynamically changing animation.

You could use the techniques in this project to create a 2D game.

Screenshot of Calming Ripples App

More …

Tailscale and Tablo

My son’s away at college, without a TV. He wanted to watch the Superbowl. We realized that one way to do that would be for him to access our family’s Tablo DVR remotely. Tablo supports remote access, but there’s a catch: The client software has to be set up while the Tablo device and the client machine are on the same local network.

But my son was 1400 miles away.

This seemed like a good opportunity to experiment with a Tailscale private network. And therein lies a tale.

More …

Animating along a SwiftUI Path

We can use trigonometry and finite differences to animate rigid objects along a SwiftUI path.

The SwiftUI Path class is missing several useful methods for evaluating properties of a path:

  • finding the position (as a CGPoint) of a given fractional position of the path.
  • finding the heading (as an angle) of a given fractional position of the path.
  • finding the total length of the path, measured in points.

Happily, we can write these methods based on the existing trimmedPath method.

With the aid of these methods it’s possible to create animations that move rigid bodies along arbitrary paths.

More …

The Zen of Advent of Code

For the past three years I’ve been participating in the Advent of Code programming puzzle contest. It’s a free contest that has run every December since 2015. It’s appropriate for people who can write programs at the undergraduate college student level. (Which means that many high school students can do it.)

The way the contest works is that, starting at midnight East Coast time on the morning of December 1st, a puzzle is announced every day from December 1st to December 25th.

The puzzles are designed to be solved by an ordinary developer within a few hours. The focus tends to be on figuring out a good algorithm, and the problems are usually solvable using under a hundred lines of code in standard Python.

More …

Why Apple is Unlikely to Create a Game Console

Apple’s new M1 Max SOC has good graphics performance. Some people are speculating that this would enable Apple to create a competitive video game console. I think that’s unlikely.

The bull case for Apple making a video game console is:

  • Apple has designed a series of excellent SOCs to serve their existing product lines.
  • The recent Macbook Pro M1 Max SOC has performance that is comparable to AMD/NVIDIA laptop gaming SOCs, but at lower power consumption.
  • Apple could use the M1 Max SOC to create a video game console with similar performance to existing video game consoles, but with much lower power requirements.
  • This would enable Apple to compete in the console video game market.

The bear case is:

  • Apple doesn’t care about the console video game market. It’s small and not growing.
  • Video game console customers don’t value the benefits that Apple’s M1 Max SOC would bring to video games.

In this blog post I explain why the video game console market is shaped the way it is.

More …

A Smooth AsyncImage Replacement

iOS 15.0 introduced an AsyncImage SwiftUI view to enable asynchronously loading URL-based images. AsyncImage works well for many scenarios, but has several limitations:

  1. AsyncImage doesn’t provide a mechanism for “inflating” an image before drawing it. This means that large images can take a long time to render the first time that they are drawn. This can cause “hitches” or “jank” when scrolling.

  2. AsyncImage doesn’t provide a mechanism for pre-scaling large UIImages down to screen size. This can cause slow rendering and excessive memory use when displaying large images.

Here’s a replacement view, SmoothAsyncImage, that fixes these two problems.

More …

Swift 5.5 Concurrency


Concurrency features are now available in Swift 5.5, released as part of Apple Xcode 13 beta 1. Let’s update our Web Scraping code to use the Swift 5.5 concurrency APIs.

More …

Web Scraping Using Structured Concurrency


In this tutorial we’ll modify our toy web scraper to use the newly proposed Swift async/await and Structured Concurrency APIs.

func scrapeHouseplants(url: URL) async throws -> HouseplantCategoryDictionary {
  return try reduceHouseplantInfos(
    infos: await scrapeListOfHouseplants(url: url, html: fetch(url: url))
      .asyncMap { ticket in
        (ticket.key, try scrapeHouseplantInfo(url: ticket.url,
                                              html:await fetch(url: ticket.url)))
More …