
A Universe in One Line of Code with 10 PRINT - burningion
https://www.makeartwithpython.com/blog/10-print-in-python/
======
japhyr
This has me reflecting on how I learned to program, compared to how people
learn to program today.

I learned to program using BASIC when I was between 5 and 10 years old. My dad
was a software engineer at DEC, and he had a kit computer in our basement that
he let us play with once in a while. My first program was a number-guessing
game, and it went something like this:

    
    
        10  NUMBER = 23
        20  PRINT "I'm thinking of a number."
        30  INPUT "Make a guess: " $GUESS
        40  IF GUESS < NUMBER THEN
        50    PRINT "Too low!"
        60    GOTO 30
        70  ELSEIF GUESS > NUMBER THEN
        80    PRINT "Too high!"
        90    GOTO 30
        100 PRINT "You got it!"
    

That was pretty straightforward, because everything about it was linear except
for the GOTOs. You can think about each step with very little planning, and
when you need a break in program flow you can use a GOTO. It also means when
teaching, you can introduce each new concept as the need arises: store a
value, print a statement, prompt for input, check a condition, and go back to
a previous statement.

Let's see the same program in Python:

    
    
        number = 23
        print("I'm thinking of a number.")
    
        guess = 0
        while guess != number:
            guess = input("Make a guess: ")
            guess = int(guess)
            if guess < number:
                print("Too low!")
            elif guess > number:
                print("Too high!")
            else:
                print("You got it!")
    

The overall program logic isn't much different when you read the code. But to
write this code, you need to know a number of things in advance. You need to
know how you're going to approach the problem. You need to know what a loop
is, and specifically what a while loop is. Conceptually, especially for a
young person, a while loop is much more abstract than a GOTO statement.

I am happy that people get to learn a language like Python as their first
language today. They can do much more interesting things, in a shorter amount
of time, than they could in basic 40 years ago. But the very first programs
people write seem fundamentally different, and that's not a bad thing.

~~~
Jare
Hehe the guessing game was my fist too, way before I even had a computer.

I think what we have lost from the old 8-bit computers and their BASIC, was
the ability to instantly have something show on the screen, like the classic
Sinclair Spectrum spider web:

    
    
        10 FOR n=0 TO 31
        20 PLOT n*11,0
        30 DRAW -n*11, 175-n*8
        40 NEXT n
    

(or something like that) That stuff got me hooked.

~~~
Turing_Machine
You can get pretty close to that with JavaScript, especially with all the
CodePen-like sites out there -- but even without those, the JavaScript console
is pretty similar to the old BASIC prompt in terms of immediacy and ubiquity.

JavaScript also has this in common with BASIC: the language bigots hate it.
:-)

~~~
wruza
I like BASIC, C, D, Objective C, Perl, Lua, 8080 and x86 Assembly (no code for
around 15 years, but still) and probably few others catched my eye, like Io,
LISP, Haskell, but I had no time to master these, only done a bunch of
snippets discovering their power. But I hate js (and php) with all of my
soul’s strings, no matter how much time I spent learning or fixing it. How
about that single data point.

Otoh, I bet most js bigots only know one language very good, guess what it’s
name is.

------
herodotus
In the distant past, when I was an undergraduate at Wits University in
Johannesburg (around 1970), someone discovered APL and they posted a 1-line
APL program that printed the multiplication matrix for all numbers from 1 to
10. This lead to a flurry of postings on the (real!) bulletin board, but the
show-stopper was a very short program written in IBM Assembler language, using
macros. The code was written by a brilliant physicist named Colin Marquard who
also single-handedly re-wrote (in assembler!) the so-called time-sharing
system that we used for our courses. (IBM selectric typewriters connected by a
proprietary network to the 360). Colin later had to flee South Africa (see,
for example, [https://goo.gl/Hw3WWb](https://goo.gl/Hw3WWb)) because of his
anti-apartheid activities.

~~~
herodotus
I also found this: [http://www.catb.org/jargon/html/O/one-liner-
wars.html](http://www.catb.org/jargon/html/O/one-liner-wars.html) about APL
one-liners

------
red_hare
For the python example, instead of using "\" and "/", you could just use the
PETSCII characters that the original 10 PRINT as they were ported to unicode.

This is my version

    
    
      python3 -c "while 1: print(chr(int(9585.5 + __import__('random').random())), end='')"

~~~
Cthulhu_
I tried a JS version, but first I locked my browser window (lol, while
(true)), then used console.log which in a browser will always do a newline and
deduplicate double logs, then used a string concatenation and the result just
isn't as interesting, nor the code as sexy. Note also that ascii codes are
different, so no magic with floats and such.

    
    
        var str = ''
        for (var i = 0; i < 1000; i++) {
          Math.random() > 0.5 ? str += '/' : str += '\\'
        }
        console.log(str)

------
JeanMarcS
Geez I feel old when I read a post where the OP feels the need to explain how
BASIC works !

It's kind for those who weren't there at the time (and is a logical thing to
do)

Where are those 30 years gone :) ?

~~~
ttoinou
Understood it because it looked like the code for my childhood calc (TI 83 :p)

~~~
free_everybody
I had no concept of computer programming growing up. It was playing around
with my TI-84 around junior year of high school that exposed me to it. I saw
the PROGRAM button so I looked in the calculator manual and started writing
TI-BASIC. I told my precalc teacher about it and she looked at me funny. She
had no idea you could write programs on graphing calculators. I will always
appreciate my TI-84.

~~~
jcalabro
Exactly the same story here. I really enjoyed my time tinkering with the
TI-84.

~~~
ttoinou
Yeah ! School was so boring, programming calc is what got me into computer
science. I'll never forget all my programs for IFS fractals, Syracuse suite
visualization, Tic Tac Toe, Minesweeper...

------
tmountain
This reminds me of another great article.

[http://www.learningclojure.com/2010/09/graphics-like-
its-197...](http://www.learningclojure.com/2010/09/graphics-like-its-1979-how-
to-get.html)

The author talks about how its harder to get graphics on the screen without
installing prerequisite software than it used to be, and goes on to sing the
praises of the ZX Spectrum and its concise and well written manual. He
finishes the article with some fun coding experiments writing Clojure code in
the spirit of the ZX.

~~~
forinti
If you are not too picky, there's always JavaScript and Canvas.

~~~
Piskvorrr
That's "without prerequisites" nowadays? Interesting. In my world, this
requires installing one of the most complex pieces of software in existence (a
web browser, plus its dependencies), on top of a graphical OS (also a highly
complex network of interdependencies).

~~~
Turing_Machine
> In my world, this requires installing one of the most complex pieces of
> software in existence (a web browser, plus its dependencies), on top of a
> graphical OS (also a highly complex network of interdependencies).

In most people's world (where "most" is probably > 95%), their computer comes
with those things already installed.

~~~
Piskvorrr
Complex architectural stacks have costs beyond install in most people's world:
how many layers of indirection between &lt;canvas&gt; and actually drawing on
the screen? That's a lot of cycles spent doing busywork.

------
nyankosensei
There's an interesting book that uses that C64 one liner to "understand the
cultural context of computing" and it's an open access book:
[https://mitpress.mit.edu/books/10-print-
chr2055rnd1-goto-10](https://mitpress.mit.edu/books/10-print-
chr2055rnd1-goto-10)

~~~
jccc
The opening line of the article is:

"10 PRINT[1] is a new book which explores the magical power of a single line
of code."

[1] [https://www.amazon.com/10-PRINT-CHR-205-5-RND-
ebook/dp/B00C9...](https://www.amazon.com/10-PRINT-CHR-205-5-RND-
ebook/dp/B00C9K9OE2/ref=as_li_ss_tl?ie=UTF8&qid=1510162754&sr=8-1&keywords=10+print&linkCode=ll1&tag=travelingfore-20&linkId=2962f94a2dbc433edeb005c125fb6e7e)

~~~
dsnuh
I got a hardcover of this book when I bought a used C64 off eBay. I was hoping
to see it mentioned!

------
fareesh
I dunno what the need for using pygame was if the goal was to replicate this
you could just use print in the REPL with a loop or recursion

~~~
khedoros1
The Commodore 64 version has square characters that are close to being aligned
with each other. You can get the same characters output in a few lines of
Python, but you can't replicate the look unless you make a careful choice of
font to render it in. The output from the REPL with my normal terminal font
looks like a bunch of characters more than it does a randomly-generated maze.
The visual connection just isn't there.

~~~
KwanEsq
One can also do better with the right choice of characters: ╲ ╱

    
    
      from random import choice; print(''.join(choice(('╲', '╱')) for i in range(10000)))

------
tyingq
You can match the spirit of it pretty closely with Perl.

perl -C -e '$|++;X:print chr(9585.5+rand());goto X'

~~~
laurent123456
Why "9585.5", is that a particular unicode character? That only displays
squares on my terminal. I've tried to replace this with 205.5 like in the
example but that would only display Î or Í.

~~~
tyingq
9585 is ╱ 9586 is ╲ (both mentioned elsewhere in the thread by their hex
equivalents 2571 and 2572)

Try a different terminal maybe? Works in xterm, xfce, etc, for me. Also, I
have LANG set to en_US.UTF-8

The ".5" is because Perl's chr() will convert it to an int by chopping off the
decimal portion. rand() returns a floating point number between 0 and 1.
That's very similar to what the BASIC program is doing.

------
bonzini
It would actually be doable in 2-3 lines using Unicode characters 2571 and
2572 (both hex), respectively "╱" and "╲".

~~~
lima

      import sys, random
    
      while True:
          sys.stdout.write(random.choice([u'\u2571', u'\u2572']))
          sys.stdout.flush()
    

They're called box drawing characters, it's how ncurses applications draw
their GUI.

[https://en.wikipedia.org/wiki/Box-
drawing_character](https://en.wikipedia.org/wiki/Box-drawing_character)

~~~
zaf
# Without unicode or pygame (using Python3)

    
    
      import sys, random
      while True :
        print( random.choice( [ chr( 92 ) , chr( 47 ) ] ) , end = "" )
        sys.stdout.flush( )

~~~
icc97
This one doesn't look correct in the terminal though as the characters don't
join up

(parent):

    
    
      ╱╱╱╲╲╲╲╲╲╱╲╲╲╱╱╱╲╱╱╱╲╲╲
      ╱╱╲╲╲╲╲╲╲╲╱╱╲╲╲╱╲╲╱╱╲╲╲
    

vs (yours)

    
    
      \\\/\\\//\//\\///\\\\////\
      /\////\\\//\\\/\/\/\\\\/
    

Also in the terminal there isn't the space between the lines for the parent
either (that's just HN formatting), but there is a space when using \ or /

~~~
rubenbe
The C64 font is (almost?) square, this also contributes to the nice effect.

~~~
rothron
It's square as it's 8x8 pixels, but the pixels themselves are not. There's a
difference in aspect ratio between PAL and NTSC variants, and because the C64
was usually connected to a CRT, pretty much all bets are off.

------
dEnigma
They definitely didn't succeed in reviving the magic of that one-liner. I
could see myself explaining the BASIC code to my little brother, but when it
comes to the new version I don't think I would succeed.

------
lottin
Speaking of one-liners, this one is pretty cool:
[https://twitter.com/isislovecruft/status/447568252223647744](https://twitter.com/isislovecruft/status/447568252223647744)

------
diydsp
Hi! One of the authors of 10 PRINT here.

You might enjoy this browser-based graphical variation. Many people also made
Processing-based variations, too:

[http://diydsp.com/fun/10print/10_print_param.html](http://diydsp.com/fun/10print/10_print_param.html)

~~~
makapuf
Hi diydsp ! Do you still do low-level microcontrollers audio hacking ? kudos
for that clever art generation !

~~~
diydsp
Hey makapuf! Good to see you here!!! I'm mostly using a color these days and
spending time on the rest of the instrument! See
[http://dsp.guitars](http://dsp.guitars) for example!

~~~
makapuf
Very Interesting !

------
dugmartin
I too cut my programming teeth in BASIC, first on my brother's Challenger 1P
and then on my very own CoCo I. While it was fun being closer to the metal I'd
much rather of had the 16GB laptop connected to the 43" monitor that I have
now at 46 when I was 8.

btw, you can get pretty close to the spirit of the code with just a few more
lines of Javascript:

    
    
        var col = 0;
        setInterval(() => {
          document.body.innerHTML += String.fromCharCode(47+(Math.round(Math.random())*45)) + (++col % 80 ? "" : "<br/>")
        }, 10);
    

or if you want to code golf you can get it into 1 line:

    
    
        var col = 0, fn = setInterval(() => {document.body.innerHTML += String.fromCharCode(47+(Math.round(Math.random())*45)) + (++col % 80 ? "" : "<br/>")}, 10);
    

You can see it in action here:

[https://jsfiddle.net/x5mz341z/](https://jsfiddle.net/x5mz341z/)

(edited to point to new jsfiddle with css body rules)

~~~
dragonsky67
doesn't really work with a proportional font.

~~~
dugmartin
Agreed - I created a new jsfiddle with a couple of body style rules and
updated the link.

~~~
keithnz
created a new fiddle taking various suggestions through the post...

[https://jsfiddle.net/tj1zwqat/](https://jsfiddle.net/tj1zwqat/)

interesting that it renders perfect ( for me ) in chrome, and a bit of an
offset in firefox

js

setInterval(() => {document.body.innerHTML += (Math.random() > 0.5 ?
"╲":"╱")}, 1)

css

body { line-height:1em; max-width: 500px; word-wrap:break-word;}

------
wruza
For those interesting what “; :” is, “;” is print’s command syntax for not
putting a newline, and “:” is a command separator. Old basics were lexically
rich, e.g. box drawing looked like:

    
    
      LINE (x1, y1) - (x2, y2), 2, BF
    

[B]ox, [F]ill

~~~
int_19h
Newer BASICs were, too. In fact, the statement you wrote above was still valid
in Visual Basic 6.0, provided that it was inside a method in a form (window) -
in which case it drew the line on that window. If you wanted to draw it on
another one, then you had to use the dot-syntax, but the rest of it would be
the same, e.g.:

    
    
       otherForm.LINE (x1, y1) - (x2, y2), 2, BF
    

Curiously, LINE was an actual method, with regular parameters; it's just that
it had this irregular syntax when calling it. VB had a bunch of special-cased
rules for some identifiers like that, for back-compat reasons. Pretty much
anything you could do in QB, you could do in VB - CIRCLE, PSET etc.

[https://msdn.microsoft.com/en-
us/library/aa230480(v=vs.60).a...](https://msdn.microsoft.com/en-
us/library/aa230480\(v=vs.60\).aspx)

This all got ditched in VB.NET in favor of a regular syntax.

But my favorite part in old BASICs was that the function MID$() - which in
other languages is usually known as "substring" or "substr" \- was special-
cased so that it could be used as target of assignment. So:

    
    
       s$ = "foobar"
       PRINT MID$(s$, 2, 3)   ' oba
       MID$(s$, 1, 2) = "uu"
       PRINT s$               ' fuubar
    

And yes, VB has this, too. In fact, even VB.NET does (although it did away
with $).

------
partingshots
When BASIC needs to be explained. Is it everyone else, or am I just getting
old? :’(

------
quickthrower2
I remember a one-liner in BBC basic that gave you the snake game.

I wish I could see that again. Not sure if it was in one of the old acorn
electron mags.

It seemed like magic, did some pretty low level stuff.

------
nurettin
I'm one of the lucky people who got to type that line into the C64 basic
console as a kid back in the 80's. Then I played the Great Giana Sisters.

------
martyalain
This single line code

    
    
        {def U1 {lambda {:n} {if {< :n 0} then else {if {< {floor {* {random} 2}} 1} then ╲ else ╱} {U1 {- :n 1}}}}} {U1 1000} 
    

draws the labyrinthic universe in any web browser. See
[http://lambdaway.free.fr/workshop/?view=U1](http://lambdaway.free.fr/workshop/?view=U1)

~~~
martyalain
This is a smaller one:

    
    
       {map {lambda {_} {if {< {floor {* {random} 2}} 1} then ╲ else ╱}} {serie 1 2000}}

------
redasadki
[https://10print.org](https://10print.org)

------
spektom
Two favorite programs of my childhood:

    
    
      10 REM drawing a galaxy
      20 FOR r=1 to 50
      30 CIRCLE 150, 100, r
      40 NEXT r
      50 ...
    
    
      10 REM playing a song
      20 BEEP 1,0: BEEP 1,2: BEEP .5,3: BEEP.5,2: BEEP 1,0
      30 ...

------
qualitytime
One line Tetris in Acorn BBC Basic:

[https://survex.com/~olly/rheolism/dsm_rheolism/](https://survex.com/~olly/rheolism/dsm_rheolism/)

------
th0ma5
Nice to get a shout out with the GIF credit from my YouTube video. After I saw
Casey Reas speak at Eyeo about the 10 PRINT book, I recorded that with Vice.
While the other authors made a version, Slate for some reason used my version,
and it was my 15 minutes I guess, heh. It is a great book, and I still flip
through it now and again. This is a great post, and I have a lot of fondness
for the C64 from when I was a kid.

------
Jupe
I still remember my very first program. It was similar to the maze, but
"animated":

10 PRINT " __ __ __ __ __" ;

20 PRINT " ";

30 GOTO 10

If you choose the right # of *'s and ' 's you get a series of diagonals moving
across the screen (since the semicolons prevented the carriage return). For
me, the impression of travelling along a bridge was completely captivating,
and I was hooked on programming ever since.

------
daemonk
Cool. Looking at this closer, I realized this doesn't create a maze with
multiple branching paths. It creates just linear paths.

------
Aardappel
Same program in Lobster (a Python-alike statically typed language with built-
in graphics):
[https://github.com/aardappel/lobster/blob/master/lobster/sam...](https://github.com/aardappel/lobster/blob/master/lobster/samples/mazepattern.lobster)

------
dnel
I have a strange feeling of synchronicity, I saw this code for the first time
only this morning on the 8bit guy's YT channel, looks like this page just pre-
dates that video though.
[https://youtu.be/KAivGLHJzJM?t=18m54s](https://youtu.be/KAivGLHJzJM?t=18m54s)

------
madengr
Does the random number generator in C64 basic start with the same seed? I know
the QBasic rand function was horrid.

~~~
kowdermeister
Yes, I remember when they demonstrated this to us in elementary school with
C16-s. It's clock based IIRC :)

~~~
eggy
I remember doing it on my Vic-20, and I had done ASCII graphics on my
Commodore PET in 1978! I had a thermal printer for my Vic-20 the width of
receipt paper. I wrote a program from an astronomy calculation book to show
where the 4 major moons of Jupiter were on an almost line due to their orbital
planes being parallel to our line of sight here on Earth. So much easier to
just get going with stuff then from bootup. It's why I like the interpreter
that comes with J (jsoftware.com). Rosetta almost-one-liner for the Sierpinski
triangle in J:

    
    
      load 'viewmat'
      'rgb'viewmat--. |. (~:_1&|.)^:(<@#) (2^8){.1

------
bencollier49
This reads like a parody of Pygame. Why write something in a single line of
Commodore Basic when you can do it in 50 lines of Python?

~~~
sp332
This is "a hello world for pygame", not "PRINT 10 for python".

------
mjcohen
I did exactly that in about 1978 on the Commodore PET and showed it at a
meeting.

------
emersonrsantos
Title should be 'A Universe in One Line of Code with PRINT' because 10 is just
the line number.

Line numbers are used in console BASIC to reference and edit a line, it
normally doesn't have a screen editor.

------
pqh
Neither a game nor a single line (using semicolons is disingenuous)

~~~
mjn
This might vary by language, but in the ones I'm familiar with, the culture of
"one-liners" has always permitted multiple statements on the line with
statement separators. E.g. the awk one-liners:
[http://www.pement.org/awk/awk1line.txt](http://www.pement.org/awk/awk1line.txt)
(similar for Perl and shell).

~~~
pqh
Okay, fair enough. I'll grant you this.

But this certainly doesn't fit in one line by my standard. It linebreaks in my
standard tiling setup. `from random import choice;
print(''.join(choice(('\\\', '/')) for i in range 10000)))`

------
mickotron
Or Powershell:

    
    
      While ($True) { Write-Host (Get-Random '\','/') -NoNewLine }

------
cdsousa
In Julia:

    
    
        while true; print(rand(Bool) ? '╲' : '╱'); end

------
pmarreck
elixir one-liner:

    
    
        for _ <- 1..1000, do: IO.write Enum.random(["\u2571","\u2572"]); IO.write "\n"

------
Ysx
I'm impressed C64 Basic had floating point!

------
cian_maguire
Interesting, thanks for sharing this.

