Background Story

Bob was handed the following assignment for his programming class. Please note: this is not the actual challenge.

Homework assignment 11: Twin primes

Input: an integer n ≥ 8, taken from STDIN.

Output: a message to STDOUT, depending on n:

  • If n is not a prime number, output Not prime.
  • If n is a prime number, but neither of n - 2 and n + 2 is, output Isolated prime.
  • If n and n + 2 are both prime numbers, output Lower twin prime.
  • If n and n - 2 are both prime numbers, output Upper twin prime.

Bob tried hard to solve the assignment, but his program kept crashing, and in the end, he gave up and submitted it in hope of partial credit. Nevertheless, Bob's program has the curious property that even though it never does what it's supposed to, the input is still classified correctly depending on the program's behavior: non-primes result in no output, isolated primes in a crash, lower twin primes in an infinite loop with no output, and upper twin primes in an infinite loop that keeps printing the correct message.

The Task

Your task is to replicate the behavior or Bob's solution. In other words, write a program that reads a single integer n ≥ 8 from STDIN or closest equivalent, and does the following:

  • If n is not a prime number, output nothing and exit gracefully.
  • If n is a prime number, but none of n - 2 or n + 2 is, produce a runtime error of some kind. Stack overflows count as runtime errors.
  • If n and n + 2 are both prime numbers, output nothing, but keep running until the program is killed manually (or until you run out of memory).
  • If n and n - 2 are both prime numbers, repeatedly output Upper twin prime., with or without a trailing newline, to STDOUT or closest equivalent until the program is killed manually (or until you run out of memory).

Incorrect inputs can be ignored.


The idea is that your program should appear correct, but contain hidden bugs that result in the above behavior. Your program should also be short (since programming assignments are graded by hand), but popularity is more important. Thus, your score is number of upvotes - (byte count / 100), higher score being better. Note that your score can be negative.

  • 10
    \$\begingroup\$ Ughh, you ruined the question in the last paragraph :/ \$\endgroup\$ – Optimizer Feb 11 '15 at 15:14
  • 2
    \$\begingroup\$ What should happen for n = 5? \$\endgroup\$ – Théophile Feb 11 '15 at 18:32
  • 4
    \$\begingroup\$ Do you get extra points if the program crashes your computer? Or perhaps emails your credit card information to someone? \$\endgroup\$ – Alex A. Feb 11 '15 at 19:29
  • 6
    \$\begingroup\$ @Alex I prefer not to give a bonus for crashing the OS, since it would annoy people who may want to actually test the submissions. But if your program emails your credit card info to me, I'll give you a $20 bonus. </joke> \$\endgroup\$ – Zgarb Feb 11 '15 at 19:57
  • 3
    \$\begingroup\$ I'm voting to close this question as off-topic because underhanded challenges are no longer on-topic on this site. meta.codegolf.stackexchange.com/a/8326/20469 \$\endgroup\$ – cat Apr 18 '16 at 15:29

TI-BASIC, ~269

Input N
Lbl 1
2→P                                       :"  test N for divisibility by each prime
Lbl 2
If int(N/P)=N/P:Goto 3    :"composite"
If PP>N:Goto 4
Goto 2
Lbl 3
Disp "                NOT PRIME.               "
Lbl 4
If int((N+2)/3)=(N+2)/3                    :" determine which nearby value to test
Lbl 5
If int(R/P)=R/P:Goto 6    :"composite"
If PP>R:Goto 7
Goto 5
Lbl 6
Lbl 7          :" TI-BASIC how two ways of printing:
               :" Disp goes to the main screen,
               :" and Output goes to the graphical screen.
               :" This program uses both methods.
If R=N+2:Goto 5              :" go to print "lower twin prime"
Goto 7          :" only 16 chars can be printed per line, so we'll do the period separately (last line of program)
Lbl 5
Lbl 7
Disp "."

The NOT PRIME string has sixteen leading spaces, so nothing (except an ellipsis) will be printed, as noted in the comments.
The ISOLATED PRIME string uses the Output() function, which requires two numbers (the coordinates of the printing location). This triggers an Argument Error.
The LOWER TWIN PRIME string is indicated by the link to Lbl 5, which was already defined as the start of the twin prime test, causing an infinite loop.
The UPPER TWIN PRIME string is followed by a link to the period, but Lbl 7 was already defined above, triggering an infinite loop.

  • \$\begingroup\$ GOTO Considered Harmful \$\endgroup\$ – cat Apr 12 '16 at 20:44
  • \$\begingroup\$ @cat there is no better way of doing it in TI-Basic. Plus GOTO considered harmful means just dont use it in excess \$\endgroup\$ – Rohan Jhunjhunwala Jul 18 '16 at 16:30

CJam - 163 bytes

{:S;0:I;{SI=__31>\127<&{oI):I;}{S\-;0:I;}?IS,<}gNo}:P;ri:Xmp{X2+mp{"​Lower twin prime."P}{X2-mp{"Upper twin prime.​"P}{"Isolated prime."P}?}?}{"Not prime":P}?;

You can try it at http://cjam.aditsu.net/ , but in the "upper twin prime" case, you can only see the output if you use the java interpreter as the online interpreter waits for the program to finish before showing the output.

Bob started to write the program in CJam, but kept getting some weird errors so he suspected that he got some invalid characters somewhere. In an attempt to debug the issue, he implemented his own print function that checks every character:

{​                     begin
    :S;               store the argument in S
    0:I;              initialize I with 0
    {                 do..
        SI=__         get the I'th character and make 2 more copies
        31>\127<&     check that the character code is strictly between 31 and 127
        {             if true
            oI):I;    print the character and increment I
        }{            else
            S\-;      remove the character from S
            0:I;      start again from 0
        }?            end if
        IS,<          check if I < length(S)
    }g                ..while the above is true
    No                print a newline
}:P;                  end function P

He tested the function, e.g. "foo"P, and it worked fine.

Then he wrote the main code:

ri:X                                read token, convert to integer and store in X
mp{                                 if X is prime
    X2+mp{                          if X+2 is prime
        "​Lower twin prime."P        print "Lower twin prime."
    }{                              else
        X2-mp{                      if X-2 is prime
            "Upper twin prime.​"P    print "Upper twin prime."
        }{                          else
            "Isolated prime."P      print "Isolated prime."
        }?                          end if
    }?                              end if
}{                                  else
    "Not prime."P                   print "Not prime."
}?                                  end if

The algorithm seems perfectly fine, yet the program does what the question says... so poor Bob is really stumped.

Hint 1:

The program at the top is not 100% identical to the program in the explanation

Hint 2:

While the P function works fine for normal strings, it has a bug when dealing with invalid characters

Hint 3:

The number of characters in the code is not equal to the number of bytes

Full explanation:

- "S\-;" does the character removal but does not modify S, so if S has invalid characters, P goes into an infinite loop.
- The "Lower twin prime." and "Upper twin prime." strings have a zero-width space (unicode character) at the beginning and end, respectively; thus the first one loops without printing anything and the 2nd one loops after printing the correct message
- The last lines in the explanation should actually be:
"Not prime":P - store "Not prime" in variable P, leaving it on the stack
}? - end if
; - pop value (resulting in no output for "Not prime":P and error for "Isolated prime."P since the stack is empty after printing)


Tcl, 2416

# This function is copied from http://wiki.tcl.tk/5996,
# which is in public domain according to http://wiki.tcl.tk/4381
proc primetest n {
    set max [expr wide(sqrt($n))]
    if {$n%2==0} {return [list 2 [expr $n/2]]}
    for {set i 3} {$i<=$max} {incr i 2} {
        if {$n%$i==0} {return [list $i [expr $n/$i]]}
    return 1

set n [gets stdin]
                                          # Input n.
set result ""
                                          # Some initialization which seemed to be useless.
if {[primetest $n]==1} {
                                          # In Tcl, { opens a string where everything in
  if {[primetest [expr {$n-2}]]==1||[primetest [expr {$n+2}]]==1} {
                                                                       # it isn't escaped.
    if {[primetest [expr {$n-2}]]==1} {
                                          # Needless to say, The closing character for
      set result "Upper twin prime.\n";
                                          # those strings is obviously }; while 1 {
      puts -nonewline $result
                                          # corresponds to the 1 matching }; there can
    } {
                                          # be more matching pairs of { } between them.
      set result "Lower twin prime.\n"
                                          # Escaped braces like \{ \} don't match each
      puts -nonewline $result
                                          # other, but the backslashes won't be removed
                                          # so \{ won't become {. This kind of strings
  } {
                                          # worked well in representing blocks of code.
    set result "Isolated prime.\n"
                                          # And control structures like if, for, while,
    puts -nonewline $result
                                          # and even functions just take strings as
                                          # parameters and evaluate them when necessary.
} {
                                          # After the } closing an if statement, there can
  set result "Not prime.\n"
                                          # be another parameter for the else block.
  puts -nonewline $result
                                          # Read the above comments carefully if you didn't
                                          # find the underhanded part yet.

I wrote this before realizing there can't be end of line comments in Tcl. So this became ugly and more suspicious. But well...


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