# A pulsating puzzle – with answer

#1

About this time of year I usually try to present one or more problems on the uLisp Forum, to provide a challenge during the festive season. This year the problem is to write the shortest uLisp program that pulsates the built-in LED smoothly on and off.

### Introduction

The classic “Hello World” program in the Arduino ecosystem is Blink: a four-line C program that blinks the LED provided on most Arduino boards. If Blink doesn’t run on your board it’s probably dead (or it’s one of the few boards without an LED).

The Lisp equivalent of the Arduno blink is as follows:

``````(defun blink ()
(pinmode :led-builtin t)
(loop
(digitalwrite :led-builtin t)
(delay 1000)
(digitalwrite :led-builtin nil)
(delay 1000)))
``````

A slightly more interesting variant of blink is possible if the built-in LED is connected to an output that supports analogue output, using PWM. It’s then possible to pulse the LED smoothly on and off. Here’s a typical program:

``````(defun pulse ()
(loop
(dotimes (x 256) (analogwrite :led-builtin (- 255 x)) (delay 8))
(dotimes (x 256) (analogwrite :led-builtin x) (delay 8))))
``````

This pulse program outputs a triangular waveform to the LED, repeatedly decreasing the value on the PWM output from 255 to 0, and then increasing it back up again from 0 to 255:

This will work on the following uLisp platforms that support PWM output to the built-in LED:

### The puzzle

The above pulse program takes 47 uLisp objects, which you can measure by looking at the space remaining, shown before the ‘>’ prompt, before and after defining the function, and taking the difference.

The problem is to create the smallest possible pulse program with the same behaviour. If you’re getting it below 40 uLisp objects you’re doing well! I’ll give my best answer at the beginning of the New Year.

### Previous puzzles

If you missed my previous Lisp puzzles here are links to them:

A small collection of uLisp challenges – with answers

Another collection of uLisp puzzles – with answers

2nd January 2024: I’ve changed the size of the original pulse program to 47 objects, not 50 as originally stated, to correspond to the correct value for 32-bit platforms.

#2

In the original post I gave the problem of creating a smaller version of the following pulse program, that pulsates the built-in LED on and off smoothly, using analogwrite. Its size is 47 Lisp objects, which you can measure by looking at the space remaining, shown before the ‘>’ prompt, before and after defining the function, and taking the difference:

``````; 47 Lisp objects
(defun pulse ()
(loop
(dotimes (x 256) (analogwrite :led-builtin (- 255 x)) (delay 8))
(dotimes (x 256) (analogwrite :led-builtin x) (delay 8))))
``````

The sizes here are for a 32-bit platform, and they will all be slightly higher on a 16-bit platform.

We can save one Lisp object by making pulse call itself recursively, taking advantage of the uLisp Tail Call Optimisation that makes this equivalent to a loop:

``````; 46 Lisp objects
(defun pulse ()
(dotimes (x 256) (analogwrite :led-builtin (- 255 x)) (delay 8))
(dotimes (x 256) (analogwrite :led-builtin x) (delay 8))
(pulse))
``````

We can save a further three Lisp objects with the following version in which x goes in a sawtooth waveform from from 0 to 510; this is converted into the triangle wave by the expression `(abs (- x 255))`:

``````; 43 Lisp objects
(defun pulse (&optional (x 0))
(analogwrite :led-builtin (abs (- x 255)))
(delay 8)
(pulse (mod (incf x) 511)))
``````

The major breakthrough comes from rewriting the function using space-time programming, as follows:

``````; 34 Lisp objects
(defun pulse ()
(analogwrite :led-builtin (abs (- (mod (truncate (millis) 8) 511) 255)))
(pulse))
``````

Here we repeatedly call pulse, with the argument to analogwrite calculated as a function of the current time, millis, designed to give the correct triangular waveform. This gets the size down to just 34 Lisp objects, which I think is probably the best that can be done.