Programming

The earliest memory I have of ‘programming’ is in the early/mid 90s when my father brought home a computer from work. We could play games on it … so of course I took the spreadsheet program he used (LOTUS 123, did I date myself with that?) and tried to modify it to print out a helpful message for him. It … halfway worked? At least I could undo it so he could get back to work…

After that, I picked up programming for real in QBASIC (I still have a few of those programs lying around), got my own (junky) Linux desktop from my cousin, tried to learn VBasic (without a Windows machine), and eventually made it to high school… In college, I studied computer science and mathematics, mostly programming in Java/.NET, although with a bit of everything in the mix. A few of my oldest programming posts on this blog are from that time.

After that, on to grad school! Originally, I was going to study computational linguistics, but that fell through. Then programming languages (the school’s specialty). And finally I ended up studying censorship and computer security… before taking a hard turn into the private sector to follow my PhD advisor.

Since then, I’ve worked in the computer security space at a couple of different companies. Some don’t exist any more, some you’ve probably heard of. I still program for fun too, and not just in security.

But really, I still have a habit of doing a little bit of everything. Whatever seems interesting at the time!


All posts

Recent posts

Phone Words--In English!

Okay, let’s take this one step further. Rather than generating just phone words, let’s actually generate phone words. Someone has provided a list of words in English as a package, so we’ll add a filter to add that to our comprehension:

from english_words import english_words_set

def letterCombinations(self, digits: str) -> List[str]:
    if not digits:
        return []

    letters = {
        '1': '',
        '2': 'abc',
        '3': 'def',
        '4': 'ghi',
        '5': 'jkl',
        '6': 'mno',
        '7': 'pqrs',
        '8': 'tuv',
        '9': 'wxyz',
        '0': ' ',
    }

    return [
        word
        for product in itertools.product(*[
            letters[digit] for digit in digits
        ])
        if ((word := ''.join(product)) in english_word_set)
    ]

I think I like the Walrus/assignment operator (:=), but it still is a bit bizarre at times. Basically, what it does is assign a call to a value (word = ''.join(product) in this case), but also returns it and can be used as an expression, which = cannot. So we can immediately check if it is in english_words. Since that’s a set, it should be pretty fast.

read more...


Phone Words

Working through a few problems on LeetCode. I haven’t quite decided what I think of the site, but it’s a fun way to play with simple algorithms. Figured I might as well write up any I find interesting.

First interesting problem:

Given a standard lettered keypad, generate all words from a given phone number.

read more...


A quick ruby DSL for creating L-Systems

L-Systems are pretty awesome. With only a bare few rules, you can turn something like this:

LSystem.new("Barnsley Fern") do
    start "+++X"

    rule "X", "F+[[X]-X]-F[-FX]+X" 
    rule "F", "FF"

    terminal "F" do forward end
    terminal "[" do push end
    terminal "]" do pop end
    terminal "-" do rotate -25 end
    terminal "+" do rotate +25 end
end

Into this:

read more...


A Tabbed View for Hugo

One thing I’ve been using for a lot of my recent posts (such as Backtracking Worms) is a tabbed view of code that can show arbitrarily tabs full of code or other content and render them wonderfully! For example, we can turn:

{{</*tabs*/>}}
    {{</*sourcetab ruby "examples/art-station.rune"*/>}}
    {{</*tab "art-station.svg"*/>}}
        {{</*include "output/art-station.svg"*/>}}
    {{</*/tab*/>}}

    {{</*sourcetab ruby "examples/astrology-and-moons.rune"*/>}}
    {{</*tab "astrology-and-moons.svg"*/>}}
        {{</*include "output/astrology-and-moons.svg"*/>}}
    {{</*/tab*/>}}

    {{</*sourcetab ruby "examples/text-circle.rune"*/>}}
    {{</*tab "text-circle.svg"*/>}}

        {{</*include "output/text-circle.svg"*/>}}
    {{</*/tab*/>}}
{{</*/tabs*/>}}

Into the tabbed example view at the end of yesterday’s post!

read more...


A DSL for rendering magic circles and runes

Let’s make magic circles/runes!

Turn this:

rune do
    scale 0.9 do 
        circle
        polygon 7
        star 14, 3
        star 7, 2
        children 7, scale: 1/8r, offset: 1 do |i|
            circle
            invert do
                text (0x2641 + i).chr Encoding::UTF_8
            end
        end
    end
    scale 0.15 do
        translate x: -2 do circle; moon 0.45 end
        circle
        translate x: 2 do circle; moon 0.55 end
    end
end

Into this:

read more...


GMail Oldest First

It’s been rather a while since I last worked on a userscript, but there’s been a problem I’ve been trying to solve for some time.

I want to have my GMail in order from oldest to newest. While you can do this for all messages, you can’t do it within a single page.

read more...


Genuary: Triple Nested Loops

The fine people of /r/generative / Genuary2021 have a series of challenges for generative works for the month of January. I don’t think I’m going to do all of them, but pick and choose. For example, the very first prompt is:

// TRIPLE NESTED LOOP

My goal was to draw a grid of circles across the X/Y the image and nest them for the third dimension. To make it a little more interesting, I added a few different color modes. seededRandom is my personal favorite, that was interesting to get working.

read more...


yt-cast: Generating podcasts from YouTube URLs

Today’s goal: Turn a collection of YouTube links into a podcast.

Start with a config.json like this:

{
  "brandon-sanderson": [
    "https://www.youtube.com/watch?v=H4lWbkERlxo&list=PLSH_xM-KC3ZuOZayK68JAAjj5W9ShnFVC",
    "https://www.youtube.com/watch?v=YyaC7NmPsc0&list=PLSH_xM-KC3ZtjKTR2z8rPWxv1pP6bOVzZ",
    "https://www.youtube.com/watch?v=o3V0Zok_kT0&list=PLSH_xM-KC3ZuteHw3G1ZrCDWQrAVgO0ER"
  ]
}

And it will automatically download all referenced YouTube videos, convert them to MP3 (both using youtube-dl), and serve an RSS feed that’s compatible with most podcast programs.

Tested URLs include:

  • Playlist URLs (like the above)
  • Single video URLs
  • Channel URLs

Most youtube URLs should work though.

read more...


Pictogenesis: Stack Transpiling

Much like transpiling register machines, now we have a chance to transpile stack machines. Unfortunately, it doesn’t actually speed up the code nearly so much (the stack is just not as effective of a memory structure in this case), but it’s still an interesting bit of code.

In this case, we turn something like this:

invsub
polT
writeG
id
neg
zero?
sin
invsub
ZERO
inv

Into this:

function(X, Y) {
  this.x = X;
  this.y = Y;

  this.stack = [];
  this.r = undefined;
  this.g = undefined;
  this.b = undefined;

  this.stack.push(X);
  this.stack.push(Y);

  var arg0 = 0;
  var arg1 = 0;
  var arg2 = 0;
  var result = 0;

  // invsub
  arg0 = this.stack.pop() || 0;
  result = 1 - arg0;
  result = result % 1.0;
  this.stack.push(result);

  // polT
  arg0 = this.stack.pop() || 0;
  arg1 = this.stack.pop() || 0;
  result = Math.atan2(arg0, arg1);
  result = result % 1.0;
  this.stack.push(result);

  // writeG
  arg0 = this.stack.pop() || 0;
  this.g = arg0;

  // id
  arg0 = this.stack.pop() || 0;
  result = arg0;
  result = result % 1.0;
  this.stack.push(result);

  // neg
  arg0 = this.stack.pop() || 0;
  result = -arg0;
  result = result % 1.0;
  this.stack.push(result);

  // zero?
  arg0 = this.stack.pop() || 0;
  arg1 = this.stack.pop() || 0;
  arg2 = this.stack.pop() || 0;
  result = arg0 === 0 ? arg1 : arg2;
  result = result % 1.0;
  this.stack.push(result);

  // sin
  arg0 = this.stack.pop() || 0;
  result = Math.sin(arg0);
  result = result % 1.0;
  this.stack.push(result);

  // invsub
  arg0 = this.stack.pop() || 0;
  result = 1 - arg0;
  result = result % 1.0;
  this.stack.push(result);

  // ZERO
  result = 0;
  result = result % 1.0;
  this.stack.push(result);

  // inv
  arg0 = this.stack.pop() || 0;
  result = 1 / arg0;
  result = result % 1.0;
  this.stack.push(result);


  return [
    this.r === undefined ? this.stack.pop() || 0 : this.r,
    this.g === undefined ? this.stack.pop() || 0 : this.g,
    this.b === undefined ? this.stack.pop() || 0 : this.b,
  ];
}

read more...


Pictogenesis: Stack Machine

Okay, enough with register machines. Let’s make something new. This time, a stack based machine!

Rather than keeping it’s memory in a series of memory cells, there will be a single stack of values. All functions can pop values from the top of the stack or push them back on. I will add the ability to read the X/Y value and directly write R/G/B, but you can’t write to the former or read from the latter, so you can’t use them as registers. Let’s see what that looks like!

read more...