Hello World but it Gets Increasingly Disturbing
What Is Hello World Even For?
Hello World is usually the first program written by the budding programmer.
Millions of people have no doubt written their very own Hello, World! program as their first step in their computer programming journey.
Hello World in C is structured as follows:
// Hello, World! in C
#include <stdio.h>
int main() {
printf('Hello, World!');
return 0;
}
There's a fair bit going on here. It shows how to import libraries and how to write functions.
This is in stark contrast to Python, where you will meet the ultimate form of Hello World:
# Hello, World! in Python
print("Hello, World!")
This is hardly even a program, it's simply one single global function call.
Revisiting Hello World
It’s safe to say that most of us leave our Hello World days behind us soon after beginning programming.
However, whilst working on some Codewars problems, I came across Function 1 - hello world.
Make a simple function called
greet
that returns the most-famous "hello world!".
Well, anybody on Codewars is likely beyond that. But what results is people taking the opportunity to write the function in fun, terrible and inefficient ways.
Some of my favourites are:
Hello World but the code spells “Hello World” in ASCII art
A function that carefully picks random number seeds in order to ‘randomly’ generate “Hello World” one character at a time
Hello World, but in obfuscated Javascript rendering it completely undecipherable
Hello World but it’s written in Brainfuck and interpreted through a Javascript interpreter
Hello World but an ASCII art drawing of Wallace and Gromit stare at you
One of my implementations iterates over each letter of “Hello World” and appends it to a string. A random number of times. If it fails to generate the full “Hello World” as required, it loops.
Codewars has infinite loop prevention which means programs will time out after 12 seconds.
I managed to get this program to pass, with a probability of 1 in 48,828,125. And yes, it took a good bit of time.
// hello world! in Javascript but it's dreadfully inefficient
const greet = function() {
let greeting = "";
while (greeting != "hello world!") {
greeting = "h".repeat(Math.ceil(Math.random() * 5));
greeting += "e".repeat(Math.ceil(Math.random() * 5));
greeting += "l".repeat(Math.ceil(Math.random() * 5));
greeting += "o".repeat(Math.ceil(Math.random() * 5));
greeting += " ".repeat(Math.ceil(Math.random() * 5));
greeting += "w".repeat(Math.ceil(Math.random() * 5));
greeting += "o".repeat(Math.ceil(Math.random() * 5));
greeting += "r".repeat(Math.ceil(Math.random() * 5));
greeting += "l".repeat(Math.ceil(Math.random() * 5));
greeting += "d".repeat(Math.ceil(Math.random() * 5));
greeting += "!".repeat(Math.ceil(Math.random() * 5));
}
return greeting;
}
Exploring Other Programming Languages
If I'm looking to pick up something new, I tend to try out the Hello, World! program to get a feel for things.
COBOL is best known for being incredibly verbose, with absurd restrictions which don't even make sense in the modern day, such as a character limit per line to allow programs to be written to punch cards. People are always making jokes about COBOL and how all the COBOL programmers are dying out, leaving legacy mainframes with nobody able to maintain them.
Maybe I can fill the niche. How hard can it be?
identification division.
program-id. greet.
data division.
linkage section.
01 result pic a(12).
procedure division using result.
* hello world!
end program greet.
That’s the starter code. Oh...oh no. Let’s not learn COBOL.
On the other hand, I quite enjoy working with Brainfuck, so here's my Brainfuck Hello World:
Hello, World! in Brainfuck
++++>+++++++[<++++>-]++>+++++>+++++[<++++++>-]<[<++>-]+++++>++++>+++[<+++++>-]<[<+++++>-]
<<.>+.+++++++..+++.<<.>+++++++++++++++.>.+++.------.--------.<<+.
I won’t go through it since it’s pretty self explanatory.
Of course, we can make it better. Here's the code golfed version of Brainfuck's Hello World, courtesy of Code Golf Stack Exchange (because of course that’s a thing).
Code Golfed Hello, World! in Brainfuck
+[-->-[>>+>-----<<]<--<---]>-.>>>+.>>..+++[.>]<<<<.+++.------.<<-.>>>>+.
It’s particularly satisfying watching it run through a visualiser.
Hello World Using Machine Learning
The Brainfuck code for Hello World got me thinking, what is the string 'Hello World' if not just a sequence of ASCII character codes?
What if we took those character codes, made them into data points, and tried to fit a polynomial equation to them to get a generalised Hello World function?
Well I did just that. Or at least I tried. It seems our best result is to fit polynomial features of degree 13, resulting in a linear regresssion model predicting “Gelln World”.
# Python script to find a polynomial equation which will map to the ASCII codes for "Hello, World!"
# Plots the results of each polynomial degree
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
def get_hello_world_str(y_pred):
return "".join([chr(int(y)) for y in y_pred])
# Define the data
X = list(range(12))
y = ['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!']
# Transform to ASCII codes
y = [ord(c) for c in y]
# Maximum degree of the polynomial
degrees = 20
# Define plot area
fig, axs = plt.subplots(degrees // 4, 4, figsize=(20, 20))
axs = axs.flatten()
# Loop over the degrees
for i in range(degrees):
# Transform the data to a polynomial of degree i
poly = PolynomialFeatures(degree=i)
X_poly = poly.fit_transform(np.array(X).reshape(-1, 1))
# Fit a linear regression model to the data
linear_regressor = LinearRegression()
# Fit the model and make predictions
linear_regressor.fit(X_poly, y)
y_pred = linear_regressor.predict(X_poly)
# Get the resulting string
hello_world_str = get_hello_world_str(y_pred)
# Plot the results as a smooth curve with title hello_world_str
axs[i].plot(X, y_pred, label=hello_world_str)
axs[i].set_title(f"Degree {i}, {hello_world_str}")
We can go totally overkill and train a neural network to try and do this for us. Which I did. This gave me a respectible “Hello Wqond!”.
So you may ask, what comes after "Hello World!"?
Using the neural network to predict for values between -100 to 100 gives us:
ɾɸɲɭɧɡɛɖɐɊɄȿȹȳȭȨȢȜȖȑȋȅǿǺǴǮǨǣǝǗǑnjdžǀƺƵƯƩƣƞƘƒƌƇƁŻŵŰŪŤŞřœōŇłļĶİīĥğęĔĎĈĂý÷ñëæàÚÔÏÉý¸²¬¦¡~xsmga\VPJHello Wqond!
That is, the characters that were not invalid.
# A simple neural network to try generate "Hello, World!"
from tensorflow.keras import Sequential, layers
from tensorflow.keras.callbacks import EarlyStopping
es = EarlyStopping(monitor='loss', patience=100)
# Sample data
letters = ['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!']
X = list(range(len(letters)))
y = [ord(letter) for letter in letters]
# Define the neural network architecture
model = Sequential([
layers.Dense(64, activation='relu', input_shape=(1,)),
layers.Dense(64, activation='relu'),
layers.Dense(1)
])
# Compile the model
model.compile(optimizer='adam', loss='mean_squared_error')
# Train the model
# Yes it does need that many epochs
model.fit(X, y, epochs=15000, verbose=1, callbacks=[es])
# Test the model
y_pred = model.predict(X)
y_pred = y_pred.flatten().tolist()
letters = [chr(int(round(x))) if x > 0 else ' ' for x in y_pred]
hello_world = ''.join(letters)
print(hello_world)
The Hello World Formula
My friend David of David Social used the perhaps not-so-overengineered numpy polyfit to construct a “Hello, World!” formula, which once again show that I have a terrible habit of overcomplicating things.
The following will perfectly reconstruct “Hello, World!” using a polynomial equation (it cheats a bit using rounding, but close enough).
# Use numpy to fit a polynomial to a set of data points
import numpy as np
# Generate some data points
input_str = "Hello, World!"
y = np.array([ord(c) for c in input_str])
for i in range(20):
poly = np.polyfit(np.arange(len(y)), y, i)
X = np.linspace(0, len(y) - 1, len(y))
# Now try reconstructing the data using the polynomial
y_pred = np.polyval(poly, X)
if np.allclose(y, y_pred):
print("Found polynomial of degree %d" % i)
break
# Go through y-pred and round to nearest integer
input_str_reconstructed = ''.join([chr(int(round(c))) for c in y_pred])
print(input_str_reconstructed)
This, on the downside, leaves us little scope to extend the Hello World formula since the numbers generated outside the bounds [0, 12] quickly descend into numbers so large that Python throws an overflow error, by which point we are already well beyond the range of ASCII character codes.
End
So there we have it, a small blog about Hello World, its uses, and how we can have fun with it.
It seemed like a relevant way to start this blog off.
Goodbye, World!