Write a function that tells you which of its lines has been removed

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.

• Can the function take a parameter? – jeremy Dec 28 '13 at 4:54
• 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
• 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

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.

→ 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".

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;
}

• What exactly does the var a after the return do? In theory, it shouldn't be reached. – Braden Best Feb 13 '14 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 '14 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. – Braden Best Feb 13 '14 at 21:32
• it's a JS feature. Described here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… – xem Feb 14 '14 at 3:19
• Ah, so it's more of an exploit for golfing. – Braden Best Feb 14 '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


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).

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

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


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. 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! :)

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.

• I like the system of linear equations idea. – M L Dec 28 '15 at 19:41

beeswax, 86 bytes

Trying out my first invented esolang. After initial confusion I found that the solution is so simple.

_1 p
_^v>~2+p
>   >~3+p
>   >~4+X@7~8+~@$^^{; > >~5+@7~8+~@${;


Explanation:

beeswax programs work on a 2D hexagonal grid. Programs are stored in a rectangular format.

    a — b — c — d
/ \ / \ / \ /
e — f — g — h
/ \ / \ / \ /
i — j — k — l


is stored as

abcd
efgh
ijkl


The instructions for moving in certain directions are:

    b — d
/ \ / \                                  bd
< —IP — >    or in compact form (β=IP):   <β>
\ / \ /                                   pq
p — q


Short explanation

_1 p Create an IP, add 1, then redirect IP to line 2

_^v>~2+p Create another IP, just in case line 1 is missing, slow down IP to make sure IP from line one is ahead, then add 2, then redirect to line 3

> >~3+p Add 3, then redirect to line 4

> >~4+X@7~8+~@$^^{; Add 4, then set 2nd lstack value to 15, then XOR lstack top and 2nd values, slow down IP (to make sure IP in line 5 is ahead, if line 5 exists) and output the result, then terminate the program. > >~5+@7~8+~@${; Add 5, then do the same as in line 4, except the slow down.

Basically the program just calculates a sum xor 15

• Program intact: (1+2+3+4+5) xor 15 = 0
• Line 1 missing: (2+3+4+5) xor 15 = 1
• Line 2 missing: (1+3+4+5) xor 15 = 2
• Line 3 missing: (1+2+4+5) xor 15 = 3
• Line 4 missing: (1+2+3+5) xor 15 = 4
• Line 5 missing: (1+2+3+4) xor 15 = 5

The additional > in lines 3 to 5 just guarantee that if one of lines 2 to 4 are missing, the IP still gets redirected properly and doesn’t leave the program.

You can clone my beeswax interpreter, written in Julia, from my GitHub repository

The readme on GitHub is more up to date and better structured than the esolangs page.

subs(()->
-d(1)
-d(2)
-d(3)
-d(4)
-d(5)
,d=Dom::IntegerMod(15))


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.

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)

Javascript

function(){
/*aa*/if(arguments.callee.toString().indexOf("*"+"a".repeat(6)+"*")==-1)return 5;
/*aaa*/if(arguments.callee.toString().indexOf("*"+"a".repeat(5)+"*")==-1)return 4;
/*aaaa*/if(arguments.callee.toString().indexOf("*"+"a".repeat(3)+"*")==-1)return 2;
/*aaaaa*/if(arguments.callee.toString().indexOf("*"+"a".repeat(4)+"*")==-1)return 3;
/*aaaaaa*/return +!~arguments.callee.toString().indexOf("*"+"a".repeat(2)+"*");
};