Automate Saving the World

You are Desmond Hume. For the last 3 years, you and your partner, Kelvin, have been slave to a computer that requires a very specific sequence to be entered into it every 108 minutes to save the world.

4 8 15 16 23 42


Your partner died 40 days ago (due to an unfortunate accident involving Kelvin's head and a big rock), and you have no one to talk to. No one to enter the numbers for you. No one to break the monotony. At first it wasn't too bad, but you can't handle the silence anymore. And if you have to listen to "Make Your Own Kind Of Music" one more time, you're going to scream.

You decide that You need to get out. To escape. You decide that you will build a raft and sail off the island. But then you realize the bad news: you're stuck here. You need to keep saving the world.

But then you realize the good news: You are a programmer! You can automate saving the world! Excited, you run over to the computer, and, using your trusty python skills, you whip up a quick script to enter the numbers for you.

import time

while True:
print "4 8 15 16 23 42"
time.sleep(60 * 107)


Quick, simple, reliable, short, and easy. Everything that a good python script should be. But then, when you try to test it, you get an error.

Bad command or file name.


Huh, strange. Oh well, let's try c++.

#include <iostream>
#include <unistd.h>

int main()
{
while (true)
{
std::cout << "4 8 15 16 23 42" << std::endl;
sleep(60 * 107);
}
}


No! C++ isn't found either. You try every language you can think of. Javascript, Ruby, Perl, PHP, C#. Nothing. This computer was made before all of the popular languages of the day.

The Challenge

You must write a program that will:

1) Print exactly this: "4 8 15 16 23 42" (without quotes)

2) Wait some time between 104 and 108 minutes. (According to The Lost Wiki)

3) Repeat forever. (Or until you realize that this is all an elaborate scam, and that you're stuck in a weird limbo due to lazy writing, and asking questions that you don't have answers for. Thanks JJ Abrams!)

However there is a catch: You MUST use a language that the computer in the swan station would actually be capable of running. Assuming that

A) The computer was up to date at the time of construction,

B) There have been no updates to the computers software, and

C) There is no internet connection available (Meaning you can't download Golfscript...),

and making our best guess for the construction date of The Swan Station, (Again, The Lost Wiki.)

This means you have to use a language that was first released on or before Dec 31, 1977.

A few rule clarifications:

• Including libraries is OK, but the same rule applies (libraries must be pre-1977).

• You do not have to worry about OS compatibility.

• If you use system, or your languages equivalent, you must prove that any system commands you use would have been available before 1978. A wikipedia article is probably the best way to prove this.

• It doesn't matter when you start the program, just as long as it ends up in a pattern of alternating printing and sleeping. (print-sleep-print-sleep... and sleep-print-sleep-print... are both acceptable.)

This is Code-Golf, so shortest answer in bytes wins.

• Is a newline required at the end of each output? – Mego Jun 9 '16 at 9:28
• @Mego Yes, otherwise the numbers wouldn't actually get entered. – DJMcMayhem Jun 9 '16 at 13:43

APL, 282425 24 bytes

This worked in STSC's APL*PLUS and in IPSA's SharpAPL in 1977, and while modern APLs have a ton of new features, this happens to still work on all major APLs today:

+\4 4 7 1 7 19
→×⎕DL 6360


The first line prints the cumulative sum of the shown numbers, which are the required numbers. The second line delays 6360 seconds (106 minutes), then takes the signum of that (1, obviously), and goes to that line (i.e. the previous, number-printing one).

However, APL\360 (the APL for IBM System/360) from 1966 actually beats it by one byte (tested on the free IBM/370 emulator):

+\4 4 7 1 7 19
5⌶19E5
→1


The sleep I-beam ("IBM" – get it?) takes the wait-time in jiffies of 1300th of a second, so we wait 19×105 jiffies = 105 minutes and 3313 second.

• I'm giving all my time measurements in kilojiffies and megajiffies from now on. – Pavel Jul 20 '18 at 3:19
• +\⎕A⍳'EEHBHT' (if ⎕IO=0) – ngn Jul 20 '18 at 7:39
• @ngn APL*PLUS does not have ⎕A. – Adám Jul 20 '18 at 7:52
• @Adám +\4 4 7 1 7 19 then? – ngn Jul 20 '18 at 7:57
• @Adám ping ^­­­ – ngn Jul 22 '18 at 10:00

MUMPS - 30 characters, circa 1966 (ANSI standard first in 1977)

My first attempt at code golf, here we go!

f  w "4 8 15 16 23 42" h 6420


MUMPS is still a popular language for EHR software, created by Massachusetts General Hospital in Boston. Most known implementation is Epic Systems in Verona, WI.

• Great job! MUMPS is actually ideal for code golfing should you want to enter that particular circle of Hell... – Yimin Rong Jan 12 '15 at 15:37
• If the world were at stake I might put "U 0 " at the start... – psr Jan 12 '15 at 17:21
• @psr, what's more important: saving the world or code golfing?! – Andrew Robinson Jan 12 '15 at 17:59
• @psr Could you explain the joke to somebody who has never heard of MUMPS before? Not me, just uh-- hypothetically. In case somebody who hasn't heard of MUMPS stumbles upon this. ;) – DJMcMayhem Jan 13 '15 at 19:00
• @DJMcMayhem - The write statement (the "W") writes to the current output device (which device is current is held a global value whether you like that idea or not). The current device is probably going to be standard output. But U 0 would set it to standard output (er, usually, but going into that would no longer be funny to anyone). – psr Jan 13 '15 at 19:21

TECO, 53 bytes

TECO (Text [previously Tape] Editor and Corrector) is a text editor originating in 1962. It can also be used to run standalone programs. It's the state-of-the-art editor for PDPs, VAXen, etc.

According to the TECO manual, the ^H command gives the time of day. Make sure to check your operating system and power supply, as the unit of time may vary according to your machine:

OS/8:      ^H = 0
RT-11:     ^H = (seconds since midnight)/2
RSTS/E:    ^H = minutes until midnight
RSX-11:    ^H = (seconds since midnight)/2
VAX/VMS:   ^H = (seconds since midnight)/2
TOPS-10:   ^H = 60ths of a second since midnight
(or 50ths of a second where 50 Hz power is used)


The following program works on systems where time of day is measured in seconds/2:

I4 8 15 16 23 42
$<HT^HUA<^H-QAUDQD"L43200%D'QD-3180;>>  Note that ^H and $ should be entered by striking, respectively, CONTROL-H and ESCAPE.

The numbers in the program can be adjusted for the following machines:

   (number)        43200     3180
RSTS/E              1440      106
TOPS-10 60 Hz    5184000   381600
TOPS-10 50 Hz    4320000   318000
OS/8             goodbye, world...


Bourne shell, 47 45 bytes

while echo 4 8 15 16 23 42;do sleep 6420;done

• Beat me to it. I was trying to find proof that sleep was on fact available back then - did you find that? en.wikipedia.org/wiki/… – Digital Trauma Jan 8 '15 at 22:53
• You can use sleep as the while condition. Saves 2 bytes – ThinkChaos Jan 9 '15 at 10:11
• @plg That would sleep before outputting the number sequence, which doesn't appear to be allowed (it has to print the sequence immediately after running the program, then sleep). – Doorknob Jan 9 '15 at 12:43
• So you start the program immediately after the last time you manually input the numbers. ;) – Roger Jan 9 '15 at 14:30
• Unix version 6 did include the sleep command (see man.cat-v.org/unix-6th/1/sleep). – Matteo Italia Jan 11 '15 at 4:13

C, 54 52 bytes

main(){while(1)puts("4 8 15 16 23 42"),sleep(6360);}

• main(){for(;;sleep(6360))puts("4 8 15 16 23 42");} – Digital Trauma Jan 8 '15 at 22:55

FORTRAN 66 (108 98 Bytes)

      PROGRAM D
2     WRITE (*,*) '4 8 15 16 23 42'
CALL SLEEP(6420)
GOTO 2
END


It is certain that the computer in question had the FORTRAN compiler, as it dominated scientific and engineering fields in the era. I was born 18 years after the eponymous year, but during my math program in university we learned FORTRAN. One fun lecture we learned how to program on punching cards. It's not that easy to format it correctly here, there should be 6 blankspaces before each command and I could only find a reference to the Sleep-function for Fortran 77 but it should have existed already in Fortran IV and 66.

PS: We could scrap off one Byte by using label 1 instead of label 42.

PPS: If the computer in question uses punching-cards for program input you're all out of luck and the bytes don't matter anymore :D .

• @proudhaskeller No, the left 7 columns are reserved so you only save the one byte at the end of line 4. – frodoskywalker Jan 9 '15 at 20:46
• Exactly, I'd only safe one byte thats why I didn't change it ;) – Bersaelor Jan 10 '15 at 14:59
• Ah, the mandatory whitespace puts a nostalgic tear in my eye :D – Yves Klett Jan 11 '15 at 18:11
• You could shave off a byte by replacing 60*107 with 80**2, too. – Mark Jan 16 '15 at 1:13
• Ok, but then one can also just use 6420. – Bersaelor Jan 16 '15 at 15:46

MacLisp, 47 46 bytes

(do()(())(print"4 8 15 16 23 42")(sleep 6360))


All constructions taken from 1974 reference manual (PDF). Not tested though as I don't have a MacLisp interpreter.

• save one byte, nil can be written () – coredump Jan 18 '16 at 22:09

Altair Basic

For sure, Desmond and Kelvin would have had an Altair 8800 (or an emulator) just for fun. Altair Basic (from some guy named Bill Gates, of some little two-man start-up called Micro-Soft) squeaks in with a 1975 release.

Desmond would need to fine tune a bit to ensure the inner FOR loop lasts one minute. Back then, everybody knew busy loops were wrong, but everybody used them!

1 REM ADJUST "D" AS REQUIRED
2 LET D = 1000
3 PRINT "4 8 15 16 23 42"
4 FOR A = 0 TO 105 * 60
5 REM THIS LOOP SHOULD LAST ONE MINUTE +/- 0.05 SECONDS
6 FOR B = 0 TO D
7 LET C = ATN(0.25)
8 NEXT
9 NEXT
10 GOTO 3


As an alternative, Desmond could install the 88-RTC board (assembled from components!: http://www.classiccmp.org/altair32/pdf/88-virtc.pdf) and get access through interrupts to a real time clock running off the power line or internal crystal.

He would need to write an interrupt routine to handle the clock input, which in turn could update a port, say every 59 seconds bring to ground for a second, then raise high.

Altair Basic had a WAIT function, so the code would be simplified to something like the following (I couldn't find a port listing, so I just chose 125 in the hopes it would be unused.):

1 PRINT "4 8 15 16 23 42"
2 FOR A = 0 TO 105 * 60
3 WAIT 125,0
4 WAIT 125,255
5 NEXT
6 GOTO 1


This was actually a fun little question, going back into some really rudimentary computers. The patience those old-timers (including me) must have had!

• Ah, busy loops... +1 – Geobits Jan 9 '15 at 19:14
• Hmm, Desmond, Altair... Is there a language called "Ezio" by any chance? – Kroltan Jan 11 '15 at 2:15

PDP-11 assembler for Unix System 6 - 7368 74 characters

Talking about the 70s, it's mandatory to honor Unix and the hardware where it all started!

s:mov $1,r0 sys write;m;18 mov$6240.,r0
sys 43
br s
m:<4 8 15 16 23 42;>


You can easily run it here (but first you have to rediscover the joys of using ed to insert the text - in my specific case, I even had to discover how to actually edit text in it :)).

Assembled it becomes 108 bytes.

# cat mini.as
s:mov $1,r0 sys write;m;18 mov$6240.,r0
sys 43
br s
m:<4 8 15 16 23 42;>
# as mini.as
# ls -l a.out mini.as
-rwxrwxrwx  1 root      108 Oct 10 12:36 a.out
-rw-rw-rw-  1 root       74 Oct 10 12:36 mini.as
# od -h a.out
0000000 0107 0022 0000 0000 0018 0000 0000 0000
0000020 15c0 0001 8904 0012 0010 15c0 0004 8923
0000040 01f7 2034 2038 3531 3120 2036 3332 3420
0000060 3b32 0000 0000 0000 0002 0000 0000 0000
0000100 0000
0000120 0000 0000 0073 0000 0000 0000 0002 0000
0000140 006d 0000 0000 0000 0002 0012
0000154
# ./a.out
4 8 15 16 23 42;

• Remove \n for 2 less characters, he didn't say it had to be in separate lines. :) – Andrew Robinson Jan 11 '15 at 1:18
• @AndrewRobinson: it seems a bit unfair, all the output that follows will have the 4 bashed together with 42... I could instead change the \n (two characters) with a semicolon. Also, msg is wasteful, I can go with m (shaving other 4 bytes). – Matteo Italia Jan 12 '15 at 1:16
• You'd save a letter and an instruction word by using br instead of jmp, wouldn't you? Also, write requires the file descriptor in r0 - you apparently happen to have 1 (or 2) in it for your first loop, but you're smashing it with your sleep time. – Random832 Jan 12 '15 at 14:59
• @Random832: wops, it probably worked when I tested it because I used 1 or 2 as sleep time to quickly try if it worked. Correct about the br, thanks to that one and to some other tricks (mainly cutting on whitespace and using octal whenever possible) we got to 74 characters even adding the first mov. – Matteo Italia Jan 12 '15 at 21:35

LOGO, 61 bytes (possibly) or 48 bytes (probably not)

Unfortunately, I haven't managed to find an online copy of The LOGO System: Preliminary Manual (1967) by BBN, or any references by the MIT Logo Group (1960s+). Apple Logo by LCSI is a bit too recent (~1980). However, based on online books, some variation of the following probably worked at the time. Note that WAIT 60 waits for 1 second, not 60.

TO a
LABEL "l
PRINT [4 8 15 16 23 42]
WAIT 381600
GO "l
END
a


We can do a bit better with tail call optimization, though this was probably not available at the time.

TO a
PRINT [4 8 15 16 23 42]
WAIT 381600
a
END
a

• TCO absolutely was available at the time. (Yes, I know from experience.) TCO was the norm for Lisp (and then Scheme); it is only recently that it has come to be seen as exotic. – rici Jan 10 '15 at 0:42

CBM BASIC 1.0, 52 38 characters, tokenized to 45 31 bytes

1?"4 8 15 16 23 42":fOa=1to185^3:nE:rU


CBM BASIC 1.0 was introduced with the Commodore PET in October 1977. Commands would normally be shown in uppercase and CBM graphics characters, but I've listed them here in lowercase + uppercase for the sake of ease (both mine and yours! :-)). Note also that the ^ would actually be displayed as ↑. Detokenized, after listing this with LIST this would result in:

1 PRINT "4 8 15 16 23 42":FOR A=1 TO 185^3:NEXT:RUN


The PET's 6502 ran at 1MHz, so this should take around 105 minutes or so to complete.

Edit: Realized that nested loops weren't really necessary and I'd miscomputed my tokens. Still not enough to win (and too late, to boot), but at least it's better.

Pascal - 107 95 bytes

PROGRAM S;USES CRT;BEGIN WHILE TRUE DO BEGIN WRITELN('4 8 15 16 23 42');DELAY(6300000);END;END.


Ungolfed version:

PROGRAM S;
USES CRT;
BEGIN
WHILE TRUE DO
BEGIN
WRITELN('4 8 15 16 23 42');
DELAY(6300000); { 105 minutes * 60 seconds * 1000 milisseconds }
END;
END.


Forth, 50 bytes

Though FORTH-79 is the earliest standardized version, the language was in development starting in 1968, and was usable on the IBM 1130. It was used on other systems as well before 1977 came around. I may do a bit more research to ensure these words were all available, but I'm fairly certain this is basic enough to have existed by then. These were all available by FORTH-79, for sure.

Loops forever, waiting 6420000 milliseconds between string printing. No newline is printed.

: F 0 1 DO 6420000 MS ." 4 8 15 16 23 42" LOOP ; F


Smalltalk, 95 (or 68 if loophole is allowed)

Been around since 1972

|i|[i:=0.[i<5] whileTrue: [(Delay forSeconds: 6480) wait.Transcript show: '4 8 15 16 23 42'.]]fork


No experience with this one, saw it on wikipedia :P
Looked it up online how to loop and delay, syntax should be correct but couldn't find a way to run it.

Possible loophole

It should print the sequence every 108 minutes, but it doesn't state that it has to be 108 minutes.
This could make the code shorter

|i|[i:=0.[i<5] whileTrue: [Transcript show: '4 8 15 16 23 42'.]]fork


Code will print the sequence with no interval, so its guaranteed that it will print after 108 mins too.

• But the problem does say Wait some time between 104 and 108 minutes, so I don't think the loophole is possible. – matsjoyce Jan 9 '15 at 8:47
• @matsjoyce Which is why I posted one with a timer and one without :) – Teun Pronk Jan 9 '15 at 8:58
• While your loophole doesn't work for the challenge, I wonder if Desmond would be able to get away with it. I'm pretty sure the computer does nothing unless it's in-between the 104-108 minute window, so it would just ignore the extra "4 8 15 16 23 42" that are being entered. However, I'm sure that Walt would be very confused by all the numbers someone is sending him. =D – DJMcMayhem Jan 9 '15 at 17:23

SAS, 8275 69

data;
file stdout;
a:;
put "4 8 15 16 23 42";
a=sleep(6300,1);
goto a;
run;


Not a typical golfing language, but I think it qualifies for this challenge, assuming that file stdout was valid in 1977-era SAS.

Improvements:

• data _null_; --> data; saves 7 characters (and now produces an empty dataset as well as printing to stdout).
• Replaced do-while loop with goto - saves 6 characters

Thompson shell, 1971 (1973 for sleep command)

43 bytes

: x
echo 4 8 15 16 23 42
sleep 6480
goto x


Since the Bourne shell, though it existed in 1977, wasn't in a released version of Unix until v7 in 1979. The original Unix shell didn't have any fancy loop control commands. (If you wanted to end a loop, you could use the if command to skip the goto.)

• Would it have had exec $0 for a small saving over goto? – Neil Jan 15 '16 at 11:59 C, 50 bytes Shorter than the other C solution, and thus not a duplicate. I actually wrote this before I noticed Digital Trauma's (nearly) identical comment on the other C solution. main(){for(;;sleep(6240))puts("4 8 15 16 23 42");}  • I'd argue that this is a trivial modification/improvement on the other solution, and thus is a dupe. Whether or not you saw the comment before writing this is irrelevant. – Mego Oct 27 '16 at 8:49 COBOL, 240 bytes Yes, the leading whitespace is significant. Compile and run like cobc -x save.cob; ./save. (The -x option produces an executable as opposed to a shared lib and thus I don't think it needs to be counted.)  IDENTIFICATION DIVISION. PROGRAM-ID.S. PROCEDURE DIVISION. PERFORM UNTIL 1<>1 DISPLAY"4 8 15 16 23 42" CALL"C$SLEEP"USING BY CONTENT 6402
END-PERFORM.
GOBACK.


If we want to be boring, we can add the --free compilation option for free-format code, then 158 + 6 = 164 bytes but this would be unlikely to work back in '77.

IDENTIFICATION DIVISION.
PROGRAM-ID.S.
PROCEDURE DIVISION.
PERFORM UNTIL 1<>1
DISPLAY"4 8 15 16 23 42"
CALL"C\$SLEEP"USING BY CONTENT 6402
END-PERFORM.
GOBACK.


ALGOL 60 / 68 / W, 7447 50 bytes

Run this full program with a68g save.a68, using algol68g.

ALGOL doesn't have a builtin way to sleep but we can run essentially /bin/sleep:

DO print("4 8 15 16 23 42");system("sleep 6380")OD


ALGOL doesn't have a sleep builtin, so we can abuse ping which is surely on a Unix of the time (idea from here) for 74 69 bytes.
DO print("4 8 15 16 23 42");system("ping 1.0 -c1 -w6240>/dev/null")OD

• @DrGreenEggsandIronMan Where is the line for where system is okay and not okay? You're fine with system("ping ...") but the challenge says I can't use system from C for e.g bash commands. ALGOL is doing the printing, but I don't have another way than ping(8) or sleep(1) to sleep. – cat Jul 8 '16 at 0:55
• Well, when I wrote the challenge, I googled and saw that bash came out in 89, so I thought "Using bash is cheating!". I suppose the bigger issue is whether or not system("sleep") would work on an OS from that time. I'll edit the post. – DJMcMayhem Jul 8 '16 at 1:06