58
\$\begingroup\$

Inspired by this default for IO.

The Task

Write a program that, given an input integer x between 0 and 255, crashes with exit code x.

Restrictions

  • You may not call anything which is intended directly for exit code output (System.exit(x), returning from main, etc.). Instead, your program must cause an error or crash which will cause, with a probability of 1, the program to exit with the input integer.
    • In this case, the words "error" and "crash" means that the program caused some fatal unintended exception, wherein a method, operation or otherwise was used incorrectly that caused an irreversible failure.
    • You may not directly cause the error by throwing it directly. You must cause it by using a method, function, or otherwise whose purpose serves a different function (i.e. attempting to execute a file write to a read-only directory).
  • You must have at least two exit codes accounted for in your program.
  • Termination of the process with the use of signals is banned. (Reasoning may be found in this discussion)

Scoring

Your program's score is determined by the number of supported exit codes, where code concision is tiebreaker. The greatest number of supported exit codes wins!

\$\endgroup\$
13
  • \$\begingroup\$ Just to clarify, if I raise an error, that is illegal yes? \$\endgroup\$ Commented Jan 18, 2017 at 0:37
  • \$\begingroup\$ @AnthonyPham If you directly raise it (throw new Exception() style), that is illegal. If it is the byproduct of misuse of an existing function, then that's fine. \$\endgroup\$ Commented Jan 18, 2017 at 0:38
  • \$\begingroup\$ @VoteToClose I guess I wasn't clear enough. I agree with you, but was suggesting, say square, instead of factorial. But whatever, it doesn't really matter, was just a suggestion \$\endgroup\$
    – Maltysen
    Commented Jan 18, 2017 at 0:44
  • 8
    \$\begingroup\$ Is accepting input as spelt-out English digits (e.g. one zero zero for 100) acceptable? I have an idea for this challenge, but the language has some fairly unusual ideas about I/O, and this is the most natural input format. \$\endgroup\$
    – user62131
    Commented Jan 18, 2017 at 1:46
  • 5
    \$\begingroup\$ I would consider Exit Code Golfing a clickbait title, altho it is accurate. <(°_°<) \$\endgroup\$
    – Penguin9
    Commented Jan 18, 2017 at 23:34

22 Answers 22

49
\$\begingroup\$

Unix Shell (+ncurses +BSD utilities), 36, 26 bytes, 256 exit codes

Golfed

jot -bu0 $[252+$1]|tput -S

If the -S option is used, tput checks for errors from each line, and if any errors are found, will set the exit code to 4 plus the number of lines with errors. If no errors are found, the exit code is 0. No indication of which line failed can be given so exit code 1 will never appear. Exit codes 2, 3, and 4 retain their usual interpretation.

Once the tput exit code goes over 255, it just overflows, so 253 (errors on input) will result in the exit code of 1 e.t.c., thus yielding the desired exit status for the whole range of inputs.

Note: whether tput will fail on not, when setting/getting a particular capability, depends on the terminal type, I've used: xterm with 256 colors

jot is a BSD utility, which prints sequential or random data, and (AFAIK) is also available out of the box on OSX systems.

If your system does not have jot available, you can use a slightly longer (29 bytes) version:

yes u0|sed $[252+$1]q|tput -S

Try It Online ! (the 29 bytes version)

\$\endgroup\$
1
  • \$\begingroup\$ Wow, that's pretty good. +1 \$\endgroup\$ Commented Jan 18, 2017 at 12:14
47
\$\begingroup\$

Bash 4.2 + extras, 24 exit codes

grep \#$1$ $0|sed 's:#.*::;s:T:tcc -run -<<<main=:;s:C:curl -L x.org/! :'|sh;exit
man#1
C-#2
C/#3
sed#4
C-x/#5
C_#6
C0#7
man /#16
C-f#22
C-o/#23
C-L3#35
C--capath /#60
C--max-filesize 1#63
C--cacert /#77
timeout 1e-9 w#124
/#126
-#127
T6\;#132
T204\;#133
$[2**63%-1]#136
{0..1000000000}#137
T0\;#139
exit _#255

Thanks to @KenY-N for 3 exit codes. Thanks to @el.pescado for 1 exit code.

Verification

All tests have been performed on openSUSE 13.2.

$ for n in {0..255}; do bash exit.sh $n; (($? == $n)) && echo $n >&0; done &> /dev/null
0
1
2
3
4
6
7
16
22
23
35
60
63
77
124
126
127
132
133
136
137
139
255
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Exit code 5: http_proxy=fafa curl http://example.org \$\endgroup\$ Commented Jan 19, 2017 at 6:21
  • 1
    \$\begingroup\$ @el.pescado It took me over a year, but I finally implemented your suggestion. Thank you! \$\endgroup\$
    – Dennis
    Commented Jan 23, 2018 at 14:28
34
\$\begingroup\$

INTERCAL (C-INTERCAL), 15 codes, 313 + 2 = 315 bytes

        PLEASE WRITE IN .1
(8)     PLEASE CREATE .1 A
        PLEASE A
        PLEASE COME FROM #2$!1/#1'

        DO X
(123)   DO (123) NEXT
        DO COME FROM (222)
(222)   DO STASH .2
(240)   DO ,1 <- #0
(241)   DO ,1 SUB #0 <- #1
(19)    DO .2 <- #256 $ #0
(21)    DO .1 <- #2
(148)   DO GO BACK
(180)   DO RETRIEVE .2
        DO COME FROM (50)
(50)    DO WRITE IN .2
(109)   DO RESUME #0
(120)   DO RESUME #9
        MAYBE COME FROM (223)
(223)   DO COME FROM (223)
(121)   PLEASE NOT X

Try it online!

All whitespace here is irrelevant. (The original program contained tabs, but I converted them to spaces so that it'd line up correctly on SE; it's conventional to use a tab width of 8 for INTERCAL. I've tested a version of the program with all tabs, spaces, and newlines deleted, though, and it works fine.)

Compile with -abm (2 byte penalty, because -b is required for the compiler to be deterministic).

As usual for INTERCAL, this takes numeric input in the format, e.g., ONE TWO THREE for 123.

Explanation

When a C-INTERCAL program errors out, the exit status is the error code modulo 256. As a result, we can aim to write a program that's capable of producing as many runtime errors as possible. This program only omits two runtime errors that don't indicate internal compiler issues: ICL200I, because reproducing it requires the use of external libraries that are only compatible with a single-threaded program (and multithreaded programs have more errors available); and ICL533I, because 533 has the same value modulo 256 as 277 does, and the program's capable of producing ICL277I.

The program always starts the same way. First, we input (WRITE IN) a value for the variable .1. Then, we use a computed CREATE statement to create new syntax (here, A); but because it's computed, the definition of the syntax varies based on the value of .1. Finally, in most cases we run our new A statement, which has been defined to produce an error; the table of possible definitions we have contains a definition for each possible runtime error (other than the exceptions listed above).

First, there are two exceptions to this general scheme. (0) is not a valid line number, so if the user inputs ZERO, we jump from the second line (numbered (8)) to the fourth line by means of a computed COME FROM statement. This then falls through into a syntax error DO X, which produces error ICL000I. (In INTERCAL, syntax errors happen at runtime, due to the tendency of commands to be disabled, syntax to be redefined under you, etc.). The COME FROM statement also has a side effect, even if no actual COME FROM happens, creating an operand overload from .1 to #1 whenever a line with a line number is executed; this is used later on when producing output 21. (Random global side effects are fairly idiomatic in INTERCAL.)

The other exception is with input ONE TWO NINE. There's no line number (129) in the program, so we get an error for a missing line number, which is ICL129I. So I didn't have to write any code to cover that case at all.

Here are the other errors, and what causes them:

  • 123 is a NEXT stack overflow (DO (123) NEXT). The NEXT statement needs other modifiers (FORGET or RESUME) in order to retroactively determine what sort of control statement it was. Not having those causes error ICL123I once there are 80 unresolved `NEXT statements.
  • 222 is a stash overflow (DO STASH .2 in a COME FROM loop). The stashes are limited only by available memory, but that will run out eventually, causing error ICL222I.
  • 240 is dimensions an array to size zero. That's exactly what DO ,1 <- #0 means, and it causes error ICL240I.
  • 241 is caused by assigning outside the bounds of an array. In this case, ,1 hasn't been allocated (, is used for array-type variables in INTERCAL), so indexing it causes error ICL241I.
  • 19 assigns 65536 (#256 $ #0) to a 16-bit variable .2. It doesn't fit, causing error ICL275I.
  • 21 assigns #2 to .1. That might look like a simple enough assignment, but we overloaded .1 to mean #1 earlier, and attempting to change the value of 1 with no -v option on the command line causes error ICL277I.
  • 148 attempts to return to the top entry of the choicepoint stack (GO BACK), which doesn't exist at this point in the program (we haven't run any commands to manipulate the choicepoint stack, so it's still empty). That causes error ICL404I.
  • 180 attempts to RETRIEVE .2 from a nonexistent stash (because we didn't stash anything there in this branch of the program), causing error ICL436I.
  • 50 requests input (WRITE IN) forever in a COME FROM loop. Eventually we'll end up reading past EOF, causing error ICL562I.
  • 109 runs the statement DO RESUME #0, which is meaningless and specifically documented as causing an error (ICL621I).
  • 120 runs the statement DO RESUME #9. We haven't run that many NEXT statements yet, and thus we get error ICL120I. (Intriguingly, this particular error is defined in the INTERCAL documentation as exiting the program normally and then causing the error, rather than exiting the program with an error. I don't believe these two cases are observably different, though.)
  • 223 is basically a complex tangle of multithreading primitives that all point back to line 223, causing an infinite loop that blows up memory. Eventually, there's memory exhaustion in the multithreading subsystem, leading to error ICL991I.
  • 121 is actually a valid statement (it's a comment), but it appears at the end of the program. As such, execution falls off the end of the program immediately after it executes, causing error ICL633I.

Verification

Some of the errors involve intentionally running the program out of memory, so I suggest setting fairly small memory limits. Here's the shell command I used to test the program (with newlines added for readability; delete them if you run it yourself):

for x in "ZERO" "ONE NINE" "TWO ONE" "FIVE ZERO" "ONE ZERO NINE"
         "ONE TWO ZERO" "ONE TWO ONE" "ONE TWO THREE" "ONE TWO NINE"
         "ONE FOUR EIGHT" "ONE EIGHT ZERO" "TWO TWO TWO"
         "TWO TWO THREE" "TWO FOUR ZERO" "TWO FOUR ONE";
do  echo;
    echo $x;
    echo $x | (ulimit -Sd 40000; ulimit -Sv 40000; ulimit -Ss 40000;
               ./errors; echo $?);
done

And here's the output (with the line numbers and "PLEASE CORRECT SOURCE" messages deleted to save space), which I added partly to demonstrate the program working but mostly to show off INTERCAL's silly error messages:

ZERO
ICL000I PLEASEWRITEIN.1(8)PLEASECREATE.1APLEASEAPLEASECOMEFROM#2$!1/#1'DOX(123)DO(123)NEXTDOCOMEFROM(222)(222)DOSTASH.2(240)DO,1<-#0(241)DO,1SUB#0<-#1(19)DO.2<-#256$#0(21)DO.1<-#2(148)DOGOBACK(180)DORETRIEVE.2DOCOMEFROM(50)(50)DOWRITEIN.2(109)DORESUME#0(120)DORESUME#9MAYBECOMEFROM(223)(223)DOCOMEFROM(223)(121)PLEASENOTX
0

ONE NINE
ICL275I DON'T BYTE OFF MORE THAN YOU CAN CHEW
19

TWO ONE
ICL277I YOU CAN ONLY DISTORT THE LAWS OF MATHEMATICS SO FAR
21

FIVE ZERO
ICL562I I DO NOT COMPUTE
50

ONE ZERO NINE
ICL621I ERROR TYPE 621 ENCOUNTERED
109

ONE TWO ZERO
ICL632I THE NEXT STACK RUPTURES.  ALL DIE.  OH, THE EMBARRASSMENT!
120

ONE TWO ONE
ICL633I PROGRAM FELL OFF THE EDGE
121

ONE TWO THREE
ICL123I PROGRAM HAS DISAPPEARED INTO THE BLACK LAGOON
123

ONE TWO NINE
ICL129I PROGRAM HAS GOTTEN LOST
129

ONE FOUR EIGHT
ICL404I I'M ALL OUT OF CHOICES!
148

ONE EIGHT ZERO
ICL436I THROW STICK BEFORE RETRIEVING!
180

TWO TWO TWO
ICL222I BUMMER, DUDE!
222

TWO TWO THREE
ICL991I YOU HAVE TOO MUCH ROPE TO HANG YOURSELF
223

TWO FOUR ZERO
ICL240I ERROR HANDLER PRINTED SNIDE REMARK
240

TWO FOUR ONE
ICL241I VARIABLES MAY NOT BE STORED IN WEST HYPERSPACE
241
\$\endgroup\$
1
  • 6
    \$\begingroup\$ This is possibly the greatest INTERCAL program I have ever seen. \$\endgroup\$
    – Skyler
    Commented Jan 18, 2017 at 19:02
29
\$\begingroup\$

C90 (gcc), 256 exit codes, 28 27 18 bytes

main(){getchar();}

I'm not sure if this is clever or cheaty, but I don't think it violates the rules as written: it technically doesn't use exit, return, or any error throwing mechanism, but simply relies on undefined behavior and the fact that gcc does something rather convenient as far as this challenge goes.

Try it online!

How it works

This simply uses getchar to read one byte from STDIN. By itself, this does nothing.

However, a compliant C90 program must end with a return statement or something equivalent; everything else is undefined behavior. gcc ends the generated assembly with a ret anyway, so whatever value was casually in the register EAX will get returned by the program. Luckily, glibc's getchar stores the byte it reads from STDIN in EAX, so the value of that byte is the exit code of our program.

\$\endgroup\$
5
  • \$\begingroup\$ It would be interesting to see if this can be modified to break through the 8 bit barrier, using the shell like jsh, which supports set -o fullexitcode. \$\endgroup\$
    – zeppelin
    Commented Jan 19, 2017 at 15:10
  • 1
    \$\begingroup\$ That's clever. But the program doesn't actually crash, then. It returns normally, whether the spec is to "cause a fatal exception/irreversible failure/crash" \$\endgroup\$
    – dim
    Commented Jan 19, 2017 at 20:02
  • \$\begingroup\$ Either way, this is awesome. \$\endgroup\$
    – Quentin
    Commented Jan 19, 2017 at 20:43
  • 4
    \$\begingroup\$ @dim I guess that depends on your definition of crash. Not ending main with return or exit is an error as far as the C90 standard goes, and it results in an exit code that indicates failure. That's all a crash does at heart. \$\endgroup\$
    – Dennis
    Commented Jan 19, 2017 at 21:17
  • \$\begingroup\$ A crash is a program stopping to function properly. Your program does all that you told it to do properly, it reads one character from the input and then stops. So even though the exit code indicates an error it didn't crash. \$\endgroup\$
    – findusl
    Commented Mar 23, 2017 at 14:18
26
\$\begingroup\$

Perl, 108 bytes, 256 exit codes

This program (ab)uses Test::More module. It tries to open file named "" n times where n is given as command line argument. It fails every time, and each invocation is treated as a test. Test::More return number of failed tests as exit code. plan tests => $ARGV[0]%255 is needed to get exit code 255.

#!/usr/bin/perl
use Test::More;
plan tests => $ARGV[0]%255 if($ARGV[0]>0);
ok(open(F,"")) for (1..$ARGV[0])
\$\endgroup\$
1
  • \$\begingroup\$ Golfed: perl -MTest::More -e'plan tests,$%%255if$%=<>;ok 0for 1..$%', 51 bytes (38 bytes + 13 bytes for -MTest::More<space>). Takes input on stdin. \$\endgroup\$ Commented Jan 19, 2017 at 20:27
19
\$\begingroup\$

C (gcc) under bash shell on x86, 230 bytes, 8 exit codes

Newlines added to aid readability. Comments ignored in score.

main(int c, char **v){
int p[2];
switch(atoi(v[1])-128){
case 2:__asm("UD2");        /* SIGILL: x86 undefined instruction */
case 5:__asm("int $3");     /* SIGTRAP: x86 breakpoint instruction */
case 6:abort();             /* SIGABRT: raise() is called under the covers */
case 8:c/=c-2;              /* SIGFPE: divide by 0 (c-2) */
case 11:c=*(int *)c;        /* SIGSEGV: dereference of invalid pointer */
                            /* SIGPIPE: write() to a pipe closed at the other end */
case 13:socketpair(1,1,0,p);close(p[1]);write(p[0],v,1);
case 14:alarm(1);sleep(2);  /* SIGALRM: kernel will send alarm signal after 1 sec */
}
}

A feature of the bash shell:

When a command terminates on a fatal signal N, bash uses the value of 128+N as the exit status.

So all we need to do is trigger various signals from within a c program. At this point, I assume simply doing kill(n-128); is banned. So instead we execute code that triggers various signals, which causes the corresponding error codes to be made available at the calling shell.

The exit codes are 0, 130, 133, 134, 136, 139, 141, 142.

Try it online. Expand the "Debug" section to see the return code.

This can certainly be golfed deeper. But I'd be more interested in adding more signals.

\$\endgroup\$
8
  • \$\begingroup\$ Would I be correct to assume that the signals are caused outside your code by pre-existing functions or operations? \$\endgroup\$ Commented Jan 18, 2017 at 19:02
  • 1
    \$\begingroup\$ @VoteToClose yes, that's right. For example, __asm("UD2") runs the x86 "undefined instruction" which will cause a CPU exception which will be relayed by the kernel to the program in the form of a SIGILL signal. For the socketpair example, SIGPIPE will be sent by the kernel or glibc as we are trying to write() to a pipe that was close()d at the other end. \$\endgroup\$ Commented Jan 18, 2017 at 19:11
  • 1
    \$\begingroup\$ Then I have no issue with it. :P \$\endgroup\$ Commented Jan 18, 2017 at 19:11
  • 1
    \$\begingroup\$ You can golf out 1) two characters if you use int3 and not int $3 and 2) one character if you declare v as int**, given that you do not fundamentally rely on the char-ness of the datatype in your pointer arithmetic, plus 3) two characters if you use *p instead of p[0], or 4) six characters, if you're willing rely on the predictable fd numbers returned by all syscalls that create them, and replace p[0] and p[1] by their near-certain values. Lastly, pipe(fd) is much shorter than socketpair(...) and generates the same error when closing fd[0] and writing to.fd[1]. \$\endgroup\$ Commented Jan 20, 2017 at 5:34
  • 2
    \$\begingroup\$ A few additional golfing suggestions: 1) Use &63 instead of -128. 2) Replace sleep(2) with for(;;). 3) Replace c=*(int*)c with atoi(0). 4) Replace c/=c-2 with c/=0. \$\endgroup\$
    – nwellnhof
    Commented Jan 21, 2017 at 15:59
10
\$\begingroup\$

Python 2, 13 Bytes, 2 exit codes

1/(input()-1)

If you enter 0, it tries to print 1/-1 which is -1 which is perfectly fine thus exit code 0. If you enter 1, you get 1/0 which raises a ZeroDivisionError in which there is an exit code of 1. With my IDE, there is only 0 and 1 for the exit codes...

Outputs:


enter image description here


enter image description here

\$\endgroup\$
0
10
\$\begingroup\$

PHP, 15 bytes, 2 exit codes

Without die/exit, PHP cannot return anything but 0 or 255 (afaik; probably ~1), so ...

!$argv[1]?:p();

If command line argument is falsy, it evaluates to 1 and exits with 0. If not, it tries to call a function and exits with <b>Fatal error</b>: Uncaught Error: Call to undefined function p().

Run with -r.

\$\endgroup\$
2
  • 5
    \$\begingroup\$ That's not true. exit() sets an exit status... which you can't use for this challenge, granted. But your code is also invalid. It sets the exit status to 255 \$\endgroup\$
    – aross
    Commented Jan 18, 2017 at 13:13
  • \$\begingroup\$ @aross: Hmm I always assumed error would exit with 1. I searched for a list of exit codes, but couldn´t find one. \$\endgroup\$
    – Titus
    Commented Jan 18, 2017 at 17:43
10
\$\begingroup\$

Excel VBA, 414 514 533 + 3 Bytes, 14 exit codes

Takes input as a Conditional Compilation Argument, n=[input value] and produces that number's associated error code.

Sub e()
Dim a As Application, b As Byte, s As String, v(), x
Set a=Application
#If n=3 Then
Return
#ElseIf n=5 Then
b=a.CommandBars("")
#ElseIf n=6 Then
b=2^8
#ElseIf n=7 Then
ReDim v(9^9)
#ElseIf n=9 Then
v=Sheets("")
#ElseIf n=10 Then
v=Array(1)
For Each x In v
ReDim v(9)
Next
#ElseIf n=11 Then
b=1/0
#ElseIf n=13 Then
Debug.?Int("X")
#ElseIf n=14 Then
Debug.?String(9E8,1)
#ElseIf n=20 Then
Resume
#ElseIf n=28 Then
f 256
#ElseIf n=35 Then
Call c
#ElseIf n=92 Then
For Each x In v
ReDim v(9)
Next
#ElseIf n=94 Then
b=Null
#End If
End Sub

Sub f(n):DoEvents:f n-1:End Sub

+3 for n=[Value] conditional compilation call

Handles Inputs where n=

3
5
6
7
9
10
11
13
14
20
28
35
92
94    

Note: VBA does not have exit codes 0 or 1. I have included the solutions for 3 and 5, which are the two lowest numbered exit codes available to VBA in their place

\$\endgroup\$
5
  • 1
    \$\begingroup\$ I won't disallow this answer, because it's synonymous for me disallowing due to language capability for output types. \$\endgroup\$ Commented Jan 18, 2017 at 7:13
  • 1
    \$\begingroup\$ What does the # do here? \$\endgroup\$
    – BruceWayne
    Commented Jan 19, 2017 at 3:47
  • \$\begingroup\$ The #if and #ElseIf are conditional compilation statements meaning that the statements that follow it are only compiled if the condition is true \$\endgroup\$ Commented Jan 22, 2017 at 0:13
  • 1
    \$\begingroup\$ So, if they're not true, the statements aren't compiled...that's different than not using #, where they'd be compiled whether or not the statements are true? I know how If statements work, but I'm new to getting down to what actually compiles, so sorry for such a simple question. \$\endgroup\$
    – BruceWayne
    Commented Jan 22, 2017 at 0:59
  • 1
    \$\begingroup\$ @BruceWayne, yes, that is exactly the case. Because these lines are designed to throw specific errors, it is necessary to have only the lines that produce the desired error code be compiled at a give time. To do this #if is used in place of If or Select Case as only truthy conditional statements are actually compiled. In this case specifically, this keeps the program from exiting with error code 3, Return without GoSub on every execution, but rather only exiting with this code when n=3 \$\endgroup\$ Commented Jan 22, 2017 at 17:44
7
\$\begingroup\$

Turtlèd, 4 bytes, 2 exit codes

I don't know if there are any ways to get more exit codes... are there even any more ways in the interpreter language

I found a few four length answers

' ?;

Try it online!

!.(0

Try it online!

?;(*

Try it online!

How these work:

' ?;

in my interpreter, there is a bug feature that causes errors when the grid in memory has more than one line, and has no non-space characters on it. this program erases the * on the origin cell '[space], takes non-negative integer input ? (0 or 1 really), and moves down that many ;, if it is zero, the grid will only have one line and not error, otherwise it will move down and the error will occur

!.(0

parentheses and stuff don't get parsed, they just get executed at run time to mean: "skip to the matching paren, if the cell symbol isn't right". in this program, inputting (!) one causes the program to write it to the cell (.), execute the paren, which checks if the cell symbol is 0, try to skip to the matching paren, but instead throw an error as there is none. if it is zero, it writes it down, checks the parentheses, finds itself on a 0, and then ignores it, and the program finishes

?;(*

has elements of the previous answer, and the first. it takes non-negative integer input, moves down that many, and checks whether the cell is '*', searching for a non existing extra paren if it is not. if the input is 1, it will move off the starting space, and find the cell is a space, and error, if it is zero, it will stay on the start space and ignore the paren.

\$\endgroup\$
7
\$\begingroup\$

Javascript (node), 19 bytes, 2 exit codes

Full program:

+process.argv[2]&&a

Function:

f=i=>i&&f(i)

process.argv is an array that contains the path to the node executable, the path to the javascript file executed and the command line arguments. In this case, this will be either "1" or "0". The string is converted to a number with the unary + operator. If the number is zero the lazy && operator won't evaluate the right hand side, if the number is truthy (not zero), the right hand side of && is evaluated and an error is thrown because it's referencing an undefined variable, and the program exists with exit code 1.

The function expects the input as a number. If the input is truthy, the function calls itself, and crashes the node runtime with a stack overflow. If the input is 0, the lazy && operator returns 0 without evaluating the right hand side.

\$\endgroup\$
5
  • \$\begingroup\$ @VoteToClose Changed it to an undefined variable \$\endgroup\$
    – corvus_192
    Commented Jan 18, 2017 at 11:16
  • \$\begingroup\$ That works. :P‮ \$\endgroup\$ Commented Jan 18, 2017 at 11:16
  • \$\begingroup\$ The full program can be shortened to +process.argv[2]&&a. \$\endgroup\$ Commented Jan 18, 2017 at 11:45
  • \$\begingroup\$ @user2428118 You're right \$\endgroup\$
    – corvus_192
    Commented Jan 18, 2017 at 11:46
  • \$\begingroup\$ Just out of curiosity, would ReferenceError.prototype.name=process.argv[2]?a:0 be valid? \$\endgroup\$ Commented Jan 22, 2017 at 6:12
6
\$\begingroup\$

Perl 6, 57 bytes, 256 exit codes

use Test;plan $_=@*ARGS[0];ok try {open ""} for ^($_%255)

Try it
This is a translation of the Perl 5 example.

Expanded

use Test;  # bring in 「plan」 and 「ok」

plan $_ = @*ARGS[0]; # plan on having the input number of tests
                     # only actually needed for the 255 case
                     # if the plan is greater than the number of tests
                     # it fails with exitcode 255


  ok                 # increment the failure counter if the following is False
    try {            # don't let this kill the whole program
      open ""        # fails to open a file
    }

for                  # repeatedly do that

  ^(                 # upto Range
    $_ % 255         # either the input number of times, or 0 times for 255
  )
\$\endgroup\$
5
\$\begingroup\$

Scala, 19 bytes, 2 exit codes

if(args(0)=="1")1/0

1/(args(0).toInt-1)

The JVM supports only 1 and 0 as exit codes if you don't call System.exit.

The first program tries to calculate 1/0 if the first argument is 1, which will crash the JVM with an exit code of 1. If the argument is 0, it wil exit succesfully.

The second program to converts the argument to integer, subtracts one and tries to divide 1 by that number. If the argument if 1, it calculates 1/0, so the JVM will crash; if the argument is 0, it calculates 1/-1 and exits.

\$\endgroup\$
5
\$\begingroup\$

Python 3, 15 bytes, 2 exit codes

Obviously, this is longer than the Python 2 solution, because in Python 3 we can't take a literal input without calling eval. However, we can use string comparison techniques interestingly...

1/(input()<'1')

Input will be either the string 0 or 1 - if it's 1, the condition evaluates to 0 (false), resulting in an attempt to compute 1 / 0 which obviously crashes (exit code 1). Otherwise, nothing happens, and Python exits with the regular exit code 0.

As far as I'm aware, Python is incapable of crashing with other exit codes.

\$\endgroup\$
0
5
\$\begingroup\$

Java, 71 66 bytes, 2 exit codes

4 bytes saved thanks to Holger

Full program:

interface I{static void main(String[]a){a[a[0].charAt(0)-48]="";}}

Function taking an int as an argument:

i->1/(i-1)

The program takes the first char of the first argumant (either '0' or '1' and subtracts 48 (ascii value of '0') to get an integer (0 or 1). It then tries to set the argument at the position of that integer to the empty string. If the input is 1, the program crashes with an ArrayIndexOutOfBoundsException, beacuse the argument array only has one element at position 0 (zero-indexed).

\$\endgroup\$
1
  • \$\begingroup\$ You can assign the value or use it in any other way, e.g. as array index a[a[0].equals("1")?1/0:1]="";, which is on par with int x=a[0].equals("1")?1/0:1;. But changing the program further to provoke an ArrayIndexOutOfBoundsException instead of ArithmeticException saves a few bytes: interface I{static void main(String[]a){a[a[0].charAt(0)-'0']="";}} \$\endgroup\$
    – Holger
    Commented Jan 19, 2017 at 9:39
4
\$\begingroup\$

Python 2, 11 bytes, 2 exit codes

1>>-input()
1/~-input()
0<input()<x

Three different 11-byte solutions for three different errors! (Just for fun, this doesn't give points.) By default, Python only has exit codes 0 for successful exit and 1 for error. The successful runs don't output anything.

 1>>-input()

On input 1, gives "ValueError: negative shift count". On input 0, a zero shift count succeeds and gives 1.

1/~-input()

On input 1, gives "ZeroDivisionError: integer division or modulo by zero" due to ~-input(), aka input()-1 being 0. In input 1, 1/-1 gives -1. 0**-input() would also work.

0<input()<x

On input 1, gives "NameError: name 'x' is not defined". On input 0, these first inequality 0<0 is evaluated to False, so the rest is not evaluated and the result is just False.

\$\endgroup\$
3
\$\begingroup\$

SmileBASIC, 640 bytes, 39 exit codes (out of 52)

SPSET.,0INPUT C$GOTO"@"+C$@0
STOP@3
A
@4
CLS.@5@A
GOSUB@A@7?1/A@8
X$=3@9
A%=POW(2,31)@10
BEEP-1@11
DIM B[#ZL*#R]@13
READ A
@15
V"OPTION STRICT?X
@16
CALL@D@17
V@A*2
@18
V"VAR A,A
@19
V"DEF A:END:DEF A
@20
V"FOR I=0TO
@21
V"NEXT
@22
V"REPEAT
@23
V"UNTIL
@24
V"WHILE.
@25
V"WEND
@26
V"IF.THEN
@27
V"IF.THEN"+CHR$(10)+"ELSE
@28
V"ENDIF
@29
V"DEF X
@30
RETURN@31
DIM E[-1]@32
V"DEF A:DEF
@34
GOTO"|
@36
XOFF MIC
MICSTOP
@37
XOFF MOTION
GYROSYNC
@38
PRGDEL
@39
DIM F[66]SPANIM.,1,F
@40
DIM G[2]SPANIM.,1,G
@42
MPSTART 2,@A@L
MPSEND"A"GOTO@L@44
PROJECT
@46
USE"PRG1:A
@47
BGMPLAY"`
@48
X=
@51
DLCOPEN"
DEF V C
PRGEDIT 1PRGDEL-1PRGSET C
EXEC 1
END

This could definitely be made shorter. SB only has error codes from 0 to 51, and some are impossible to trigger.

\$\endgroup\$
2
\$\begingroup\$

Node.js (ES6), 77 bytes, 2 exit codes

require('readline').createInterface({input:process.stdin}).prompt("",i=>i&&x)
\$\endgroup\$
2
\$\begingroup\$

Jelly, 4 exit codes, 18 bytes

߀
2*
Ṁ¹Ŀ
RÇĿỌḊ?R

Supports exit codes 0, 1, 137 (killed), and 139 (segmentation fault).

Try it online!

How it works

RÇĿỌḊ?R  Main link. Argument: n (integer)

R        Range; yield [1, ..., n] if n > 1 or [] if n = 0.
    Ḋ?   If the dequeued range, i.e., [2, ..., n] is non-empty:
 Ç         Call the third helper link.
  Ŀ        Execute the k-th helper link, where k is the the integer returned by Ç.
         Else, i.e., if n is 0 or 1:
   Ọ       Unordinal; yield [] for n = 0 and "\x01" for n = 1.
      R  Range. This maps [] to [] and causes and error (exit code 1) for "\x01".


Ṁ¹Ŀ      Third helper link. Argument: r (range)

Ṁ        Maximum; retrieve n from r = [1, ..., n].
 ¹Ŀ      Call the n-th helper link (modular).
         When n = 139, since 139 % 3 = 1, this calls the first helper link.
         When n = 137, since 137 % 3 = 2, this calls the second helper link.


2*       Second helper link. Argument: k

2*       Return 2**k.
         Since 2**137 % 3 = 174224571863520493293247799005065324265472 % 3 = 2,
         ÇĿ in the main link will once again call the second helper link.
         Trying to compute 2**2**137, a 174224571863520493293247799005065324265472-
         bit number, will get the program killed for excessive memory usage.


߀       First helper link. Argument: k

߀       Recursively map the first helper link over [1, ..., k].
         This creates infinite recursion. Due to Jelly's high recursion limit,
         a segmentation fault will be triggered.
\$\endgroup\$
1
\$\begingroup\$

Python 3, 64 52 bytes, 3 exit codes (0, 1, 139)

-12 from emanresu A
from ctypes import*
1//~-int(input())or string_at(0)

Try it out here! (The TIO version uses a semicolon instead of newline, but it functions the same)

This works similarly to this Python 2 answer, but a few things are added:

  • We first import everything from ctypes, since we need string_at later.
  • Since we are in Python 3, we need to cast the input to an int.
  • Then we decrement it, using ~- which negates it then bitwise NOTs the value.
  • Then, we do floor division on it with 1:
    • If it is 0, 1//-1 will resolve to -1, so we exit successfully, since -1 is truthy
    • If it is 1, we error out trying to do floor division with 1.
    • If it is 3 or higher, 1//-x will return 0, which is falsy, therefore we run the string_at function from ctypes. Targeted at an address of 0, this causes it to segfault.
      • Since we segfault, this means that for an input of 139, we return the correct exit code.
\$\endgroup\$
5
  • \$\begingroup\$ Welcome to Code Golf, and nice first answer! There are quite a few ways you can shorten this: Since you only need to support exit codes 0, 1 and 139, you can just check that V is at least 2, and you can do this concisely with 1//(V:=int(input())-1)or string_at(0). If given 0, V will be -1, 1//V will be -1, so string_at won't be evaluated; if given 1, V=0 and 1//0 crashes; if given 139 1//139 is 0 so the string_at gets evaluated with a segfault. Putting this together gives 52 bytes from ctypes import*;1//~-int(input())or string_at(0). \$\endgroup\$
    – emanresu A
    Commented Dec 6 at 23:33
  • \$\begingroup\$ also (ran into comment char limit) here's a TIO link with a bash script testing all three cases, so other people can test this. \$\endgroup\$
    – emanresu A
    Commented Dec 6 at 23:36
  • \$\begingroup\$ I was under the assumption that all non-implemented codes had to return 0, but that wasn't actually stated, so I changed it to your version. (Also added the TIO link) \$\endgroup\$ Commented Dec 7 at 0:03
  • \$\begingroup\$ (side note: ~-x is a fairly common golfing idiom for x-1 with higher precedence, so you can use e.g. 2/~-x instead of 2/(x-1)) \$\endgroup\$
    – emanresu A
    Commented Dec 7 at 0:12
  • \$\begingroup\$ See, in theory I should know these things because I've lurked here for a while, but in practice I just forget that that works \$\endgroup\$ Commented Dec 7 at 0:15
0
\$\begingroup\$

ZX81 BASIC >255 exit codes - 52 bytes (listing)

1 INPUT N
2 GOTO 1+(2*(N>0 AND N <=255))
3 PRINT "EXIT CODE ";N
4 RAND USR N

Technically, N could be any 24 bit floating point number within the range, but we'll assume integers here. Line 2 is equivalent to IF N>0 AND N <=255 THEN GOTO 3: ELSE GOTO 1 if ZX81 BASIC had IF/ELSE in its symbolic instructions.

\$\endgroup\$
6
  • 3
    \$\begingroup\$ How does this satisfy the program caused some fatal unintended exception? This just prints out some text and finishes execution. \$\endgroup\$ Commented Mar 21, 2017 at 14:42
  • \$\begingroup\$ You are right - I need to be more awake in the mornings. \$\endgroup\$ Commented Mar 21, 2017 at 15:01
  • \$\begingroup\$ RAND USR N will cause unintended effects as calling part of the ROM from an unexpected place is not a good idea, therefore RAND USR 0 has been excluded as that is too graceful. \$\endgroup\$ Commented Mar 21, 2017 at 15:12
  • \$\begingroup\$ Can you elaborate a bit more on how that actually causes the program to crash? I'm not intimately familiar with ZX81 BASIC. \$\endgroup\$ Commented Mar 21, 2017 at 15:19
  • \$\begingroup\$ The ROM resides from 0x0000 - 0x1fff; calling ROM routines will work if you start at the right place. Starting one or more bytes into any machine code routine in Z80 will cause unexpected effects. If you have a simple LD BC, 0000 RST 10 RET at 0x1000 but called RAND USR 4097 then you'll miss out the LD operand and the machine code will therefore be skewed. I don't remember all ROM calls but I'll work out all legal/graceful ends and exclude them later. \$\endgroup\$ Commented Mar 21, 2017 at 15:25
0
\$\begingroup\$

Uiua, 2 exit codes, 5 bytes

⍥∘⋕&sc

⋕&sc reads an integer from STDIN. ⍥∘ applies the identity function repeatedly N times. If N is zero, nothing happens. If N is one, it attempts to apply identity to a value which doesn't exist, erroring.

Most cases which would result in behavior like this are disallowed by Uiua's stack signature checking, but here, the signature is known--1 input to 1 output--except in the case where the repetition count is zero, in which case nothing happens.

There has been discussion in the past of changing this behavior to do an N-wise identity, which means apply identity to N values, where N is the number of inputs and outputs handled by the repeated function. This idea has not been widely backed at this time, however, and this works correctly at least as of Uiua 0.14.0-dev.6.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.