Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Write a function that contains five lines.

If you run the function as-is, it should return 0.

If you remove any one of the five lines and run the function, it should tell you which of the lines has been removed (e.g., if you remove the final line it should return 5).

Brevity, novelty, and elegance all deserve consideration. Highest upvoted solution (after a reasonable amount of time) wins.

share|improve this question
4  
Can the function take a parameter? –  Jeremy Dec 28 '13 at 4:54
6  
Does the function declaration count as one of the lines if we want to use that sort of language, or is only the body counted? –  meiamsome Dec 28 '13 at 4:58
1  
Also, do our lines need to be numbered 1, 2, 3, 4, 5 or is any numbering scheme allowed? –  meiamsome Dec 28 '13 at 5:11
    
@Jeremy, yes, that's fine. –  jawns317 Dec 28 '13 at 12:20
    
@meiamsome, only the body counts, and the lines should be numbered 1, 2, 3, 4, 5 for the purpose of return values. –  jawns317 Dec 28 '13 at 12:22

12 Answers 12

up vote 17 down vote accepted

Ruby

Eschewing magic numbers since it's not code golf.

def f
  r=2^3^4^5
  defined?(r) ? r^=2 : r=1^3^4^5
  r^=3
  r^=4
  r^=5
end

Each line strips its own number out of 1^2^3^4^5. It's Ruby, so the last line defines the return value.

share|improve this answer

JavaScript ( 134   77   69   65   60 chars)

→ live demo ←

function(n){
a=n-=1
n-=2
+3
+4;if(this.a)return 5
return n;var a
}

call this function with n = 10.

  • If no line is missing, line 5 returns n == 0.
  • If line 1 is missing, line 5 returns n == 1.
  • If line 2 is missing, line 5 returns n == 2.
  • If line 3 is missing, line 5 returns n == 3.
  • If line 4 is missing, line 5 returns n == 4.
  • If line 5 is missing, the var "a" becomes global and line 4 detects that to return "5".
  • If line 5 is present, the JS engine performs "variable hoisting", "a" becomes a local var, and line 4 doesn't return "5".



Previous versions:

65 chars

function(n){
a=n-=1
n-=2
+3
+4;if(this.a)return 5
n-=5;return n;var a
}

(must be called with n = 15)

69 chars

function(n){
n-=1
n-=2
n-=3
a=n-=4;if(this.a)return 5
n-=5;return n;var a
}

(must be called with n = 15)

77 chars

function(){
a=
b=
c=
d=1;if(this.a)return 5
1;var a,b,c,d;return d?c?b?a?0:1:2:3:4
}

134 chars

function w(){
a=1;e=1;if(this.e)return 5
b=1;if(!a)return 1
c=1;if(!b)return 2
d=1;if(!c)return 3
var a,b,c,d,e;return d?0:4
}

non-golfed

  function whichlineisremoved(){
    /* 1 */ var a = 1; e = 1; if(window.e) return 5;
    /* 2 */ var b = 1, a; if(!a) return 1;
    /* 3 */ var c = 1, b; if(!b) return 2;
    /* 4 */ var d = 1, c; if(!c) return 3;
    /* 5 */ var e = 1, d; if(!d) return 4; return 0;
  }
share|improve this answer
    
What exactly does the var a after the return do? In theory, it shouldn't be reached. –  B1KMusic Feb 13 at 3:24
    
@B1KMusic, in fact it is "reached" due to something called JavaScript variable hoisting. When JS is "compiled", all the "var" declarations are virtually placed at the beginning of the functions in which they are. –  xem Feb 13 at 8:19
    
Hmm, that's odd. Is there a practical use for this in the language, or is this purely a golf/exploit? I don't recall reading anything about variable hoisting in Mozilla's documentation. –  B1KMusic Feb 13 at 21:32
    
it's a JS feature. Described here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… –  xem Feb 14 at 3:19
    
Ah, so it's more of an exploit for golfing. –  B1KMusic Feb 14 at 3:29

Python

If parameters are allowed, then this will work:

def f(n=10):
    n -= 1
    n -= 2
    n -= 3
    if n == 4: return 0 if f(7) else 5
    return n - 4 or 4
share|improve this answer

R

f <- function() {
  T <- FALSE
  F <- TRUE
  month.abb <- TRUE
  (pi <- 5)
  T + (!F) * 2 + (!isTRUE(month.abb)) * 3 + (pi != 5) * 4
}

The function uses built-in "constants" and assigns another value to each of them. If all of these variables are equal to the new value, the function returns 0. Logical values are transformed to numeric ones because of the mathematical operators. The parentheses around the 4th line allow visibly returning its result (if it's the last command).

share|improve this answer

Lua 5.2+

55 chars in the function body excluding newlines. I couldn't come up with anything better but this:

function f()
return 7--[[
return 1--[=[]]-2
--[[
-2--[=[]]
-5--]=]--]]-1
end

Hoping to get extra points for comments abuse :P

The reason it does not work in 5.1 is that nested [[]] were removed, and in 5.1 it gives a compilation error instead of ignoring it like 5.2 does.

  • If none of the lines are removed, the function body is eqivalent to return 7-2-5
  • If the first line is removed, return 1
  • If the second, return 7-5
  • If the third, return 7-2-2
  • If the fourth, return 7-2-1
  • If the fifth, return 7-2
share|improve this answer

Ruby

I tried doing it with bitwise operations and then I realized there is a much simpler solution using lists! This challenge is best served by a programming language that automatically returns the last value it sees, such as Ruby.

def tellMe(x=[1,2,3,4,5])
    x.delete(1)
    x.delete(2)
    x.delete(3)
    x.delete(4);x[0]
    x.delete(5);x==[]?0:x[0]
end
share|improve this answer

Befunge doesn't have explicit functions, but here is what I'd call a function in Befunge:

v^    <
>v
1>v
 2>v
##3>5v
$0v4 >
>>>>>>^

The first and last lines are function start and function end. It does the closest thing to "return", that is, it pushes the correct value onto the stack.

share|improve this answer

MuPAD, 57 chars

subs(()->
-d(1)
-d(2)
-d(3)
-d(4)
-d(5)
,d=Dom::IntegerMod(15))
share|improve this answer

Common LISP:

(defun which-line-is-removed (&aux (x 30)) 
  (decf x 2)
  (decf x 4)
  (decf x 8)
  (decf x 16) 5
  (if (zerop x) 0 (log x 2))
)

NB: Having ending parenthesis on it's own line is considered bad style, but since other languages has end and } I assume it is allowed.

share|improve this answer

C#

byte self_aware(byte do_not_use = 0)
{
    do_not_use += do_not_use == 0 ? 1 : do_not_use < 10 ? 10 : 0; // 1
    do_not_use += do_not_use == 1 ? 1 : do_not_use < 10 ? 10 : 0; // 2
    do_not_use += do_not_use == 2 ? 1 : do_not_use < 10 ? 10 : 0; // 3
    do_not_use += do_not_use == 3 ? 11 : do_not_use < 10 ? 10 : 0; // 4
    return do_not_use - 9; // 5
}

Nearly works.

share|improve this answer

New Answer

I found another solution. That's so bad, I liked the math one so much. This solution uses recursion and global variables (yuck!) to tell if every line has been run or not. I wanted to do something different from the other solutions, so this isn't much elegant, but it works properly :)

PHP

function LOL($a) {
    if (!$a) { LOL(true); if (!$GLOBALS['b']) return 2; if (!$GLOBALS['c']) return 3; if (!$GLOBALS['d']) return 4; if (!$GLOBALS['e']) return 5; return 0; } 
    if ($a) $GLOBALS['b'] = true; else return 1;
    $GLOBALS['c'] = true;
    $GLOBALS['d'] = true;
    $GLOBALS['e'] = true;
}

I really enjoyed this challenge, thank you! :)


Old Answer

I solved it using maths. If each variable is seen as an unknown, and we do one declaration per line, there are five unknowns and five lines of code: this leads us to the following 5x5 system:

b+c+d+e = 1;
a+c+d+e = 2;
a+b+d+e = 3;
a+b+c+e = 4;
a+b+c+d = 5;
//Solutions are displayed in the code below.

Once I found the values, I hardcoded them and added some basic stuff.

PHP

function LOL(){
    $a = 2.75;
    $b = 1.75;
    $c = 0.75;
    $d = -0.25; if ($a+$b+$c+$d == 5) return $a+$b+$c+$d;
    $e = -1.25; return $a+$b+$c+$d+$e;
}

Note: The Old Answer won't work if left as-is.

share|improve this answer

Bash, 131 chars

#!/bin/bash

# the function:
function f(){
  a=1;
  b=2;
  c=3;
  d=4;[ ! $1 ]&&f 1&&return 5||true
  [ $1 ]&&return 6;e=5;s=$((a+b+c+d+e));return $((15-$s))
}

# call it:
f
# report the result:
echo Removed line $?

It's all straightforward up to line 5. Then it needs to detect if the final line is gone. This takes advantage of permitted function parameters by calling itself recursively, once, to test its own success value when it's being told to fail on line 5, and if line 5 is removed, line 4 returns 5 instead.

(Note: it's down to a minimum of 131 characters if stripping out everything but the function, ditching whitespace, and changing /bin/bash to /bin/sh)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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