19
\$\begingroup\$

Code Golf

Totally real backstory: I'm a contractor working on a website www.Sky.Net and one of our tasks it to create some self-aware program or something, I don't know I wasn't really listening to the boss. Anyways in an effort to make our code more self-aware we need IT to be able to know what code is on each line-number.


Challenge

Create a program or function that takes an input n and returns the code of said program or function on line n.


Rules

➊ Your program or function must be at least 4 lines long. Each line must be unique.

➋ You may assume the input will always be a positive integer greater than or equal to 1 and less than or equal to the number of lines in your program/function.

➌ The first line in your program/function is line 1, not line 0.

➍ You can not access the file that your program is on. (If someone has to ask "Isn't this technically breaking rule #4"; it probably is)

➎ Lines can-not be empty (this includes a space if spaces don't do anything in your language)

➏ Lines can-not be //comments (/* of any <!--style)


This is a -like challenge
This is , so the submission with the fewest bytes wins!

\$\endgroup\$
7
  • \$\begingroup\$ Let us continue this discussion in chat. \$\endgroup\$ Feb 27, 2017 at 0:17
  • 1
    \$\begingroup\$ I'd like to see this done in 99 :) \$\endgroup\$ Feb 27, 2017 at 1:14
  • 2
    \$\begingroup\$ @JonathanAllan You might run into the issue where not every line is unique \$\endgroup\$ Feb 27, 2017 at 1:15
  • \$\begingroup\$ "Lines cannot be comments, but I guess effective no-ops are OK" (but honestly, sometimes it's hard to say whether a line should count as a no-op or not; for example my Ruby answer has the last line be only a curly bracket to end the lambda) \$\endgroup\$
    – Value Ink
    Feb 27, 2017 at 1:26
  • \$\begingroup\$ The title might be better "Input number; Output line with that line number"? Or even "Output line by number". \$\endgroup\$ Feb 27, 2017 at 21:50

8 Answers 8

16
\$\begingroup\$

Vim, 7 bytes

1
2
3
4

Try it online!

As far as I can tell, this complies with all of the rules. In vim by default, the empty program prints out all of the input. Since

<N><CR>

Is a noop, nothing changes the input text, and since each input matches the desired output, this same approach works with any number of lines.

\$\endgroup\$
6
  • 2
    \$\begingroup\$ Will work in other languages - first addition: Pyth \$\endgroup\$ Feb 27, 2017 at 1:12
  • \$\begingroup\$ Wait, bytes? Vim is measured in keystrokes. \$\endgroup\$
    – Pavel
    Feb 27, 2017 at 4:57
  • \$\begingroup\$ @JonathanAllan It looks like Pyth is configured wrong on TIO. If you look at the debug output, you can see that the code that is actually being run is the thing in the argument field, not the thing in the code field. This is what actually running that code looks like. \$\endgroup\$
    – isaacg
    Feb 27, 2017 at 6:00
  • 1
    \$\begingroup\$ @Pavel only in editor golf challenges \$\endgroup\$ Feb 27, 2017 at 7:29
  • 2
    \$\begingroup\$ This also works in Brachylog \$\endgroup\$
    – Fatalize
    Feb 27, 2017 at 7:35
9
\$\begingroup\$

Ruby, 71 70 66 bytes

Try it online!

->n{
k=["}", "k[-n]%%k.inspect", "k=%s", "->n{"]
k[-n]%k.inspect
}

"Cheating" Mode: 7+1 = 8 bytes

Requires the -p flag for +1 byte. Literally a copy of the V answer. Prints the number that is inputted; the entire program is effectively just no-ops.

1
2
3
4
\$\endgroup\$
4
  • \$\begingroup\$ What does -p do? \$\endgroup\$
    – Pavel
    Feb 27, 2017 at 1:25
  • \$\begingroup\$ @Pavel It causes the program to read each line of STDIN into $_, runs the program contents, and then prints the contents of $_ to screen (repeating per line of STDIN). Since the program does nothing, it's practically just Unix cat, but that means that every input from 1-4 will output the contents of the line, because each line is literally its line number. \$\endgroup\$
    – Value Ink
    Feb 27, 2017 at 1:30
  • \$\begingroup\$ @Pavel for more information see robm.me.uk/ruby/2013/11/20/ruby-enp.html \$\endgroup\$
    – Value Ink
    Feb 27, 2017 at 1:31
  • \$\begingroup\$ I like your "cheating" answer. Perl also has -p, but 1\n2\n3\n4 is not a valid Perl program. \$\endgroup\$ Feb 27, 2017 at 18:54
7
\$\begingroup\$

Haskell, 69 59 bytes

(lines(s++show
 s)
 !!)
s="\n(lines(s++show\n s)\n !!)\ns="

Based on the standard Haskell quine. The first expression (spread over the first three lines) is an unnamed function that picks the nth line from the quinified string s (s++show s). +2 bytes for making indexing 1-based (imho an unnecessary rule).

For a Try it online! version I have to name the function which adds 4 bytes.

\$\endgroup\$
5
  • \$\begingroup\$ Does this break rule 6? :) \$\endgroup\$ Feb 27, 2017 at 1:11
  • \$\begingroup\$ Line indexing is not supposed to be 0-based, the rules explicitly require 1-indexing. \$\endgroup\$
    – Value Ink
    Feb 27, 2017 at 1:14
  • \$\begingroup\$ @AlbertRenshaw: fixed \$\endgroup\$
    – nimi
    Feb 27, 2017 at 1:24
  • \$\begingroup\$ @ValueInk: fixed \$\endgroup\$
    – nimi
    Feb 27, 2017 at 1:24
  • \$\begingroup\$ @nimi lol, "solutions" like this are why I was tempted to make this a popularity contest haha. Nevertheless, good work! \$\endgroup\$ Feb 27, 2017 at 1:28
5
\$\begingroup\$

PowerShell, 184 172 bytes

$v=0,
'$v=0,',
"'`$v=0',",(($q='"{0}`$v=0{0},",(($q={0}{1}{0})-f([char]39),$q)')-f([char]39),$q),
(($z='(($z={0}{1}{0})-f([char]39),$z;$v[$args]')-f([char]39),$z);$v[$args]

Try it online!

Explanation

Starts by creating an array $v on the first line. On that same line, the first (0th) element is set to 0, and a comma , continues its definition.

The next line sets the next element (1) of the array to a string representing the content of the first line of the script, so that $v[1] returns the first line.

The 3rd line first sets the 3rd element of the array (index 2) to a string representing the 2nd line of the script, then on the same line sets the 4th element (index 3) using a quine snippet that uses the format operator (-f) to replace certain instances of single quotes ([char]39) and the format template string, into itself, to reproduce the entirety of the 3rd line.

Line 4 basically does the same thing, but also ends the creation of the array and then indexes into it using the supplied argument.

\$\endgroup\$
4
\$\begingroup\$

Python 2, 104 73 67 bytes

Thanks to Jonathan Allan for saving 6 bytes!

s=\
['print s[input()]or s', 's=\\', 0, 'exec s[', '0]']
exec s[
0]

Edit: Same byte count, but I like this solution better

Try it online!

Python version of Value Ink's Ruby answer.

Older answer (67 bytes):

1
s=\
['print s[-input()]or s', 0, 's=\\', 1]
print s[-input()]or s
\$\endgroup\$
2
  • \$\begingroup\$ Save 6 by getting rid of n: TIO \$\endgroup\$ Feb 27, 2017 at 3:52
  • \$\begingroup\$ @ovs the challenge requirement requires 4 lines minimum of source code though :V \$\endgroup\$
    – Value Ink
    Feb 27, 2017 at 7:14
2
\$\begingroup\$

CJam, 19 18 17 bytes

1
{'_'~]ri(=}
_
~

Try it online!

Based on the standard CJam-quine. The {...}_~ runs the ... with the block itself on the stack (and in this case, also 1 below that). Then we do:

'_'~  e# Push the third and fourth line.
]     e# Wrap all four lines in a list.
ri    e# Read input and convert to integer.
(=    e# Use as index into the lines.
\$\endgroup\$
1
  • \$\begingroup\$ This is beautiful. Also like the logic's smiley face ending (= haha \$\endgroup\$ Feb 27, 2017 at 20:57
1
\$\begingroup\$

PHP, 261 bytes

<?php function f($l){
$a="aWYoJGw9PTEpJG09Ijw/cGhwIGZ1bmN0aW9uIGYoXCRsKXsiO2lmKCRsPT0yKSRtPSJcJGE9XCIkYVwiOyI7aWYoJGw9PTMpJG09IlwkYj1cIiR";
$b="iXCI7IjtpZigkbD09NCkkbT0iZXZhbChiYXNlNjRfZGVjb2RlKFwkYS5cJGIpKTt9Pz4iO2VjaG8gJG07";
eval(base64_decode($a.$b));}?>

Try it online !!

The encoded string is:

if($l==1)$m="<?php function f(\$l){";
if($l==2)$m="\$a=\"$a\";
if($l==3)$m="\$b=\"$b\";
if($l==4)$m="eval(base64_decode(\$a.\$b));}?>";
echo $m;
\$\endgroup\$
2
  • \$\begingroup\$ Interesting! What are the encoded strings? \$\endgroup\$ Feb 28, 2017 at 6:47
  • 1
    \$\begingroup\$ @Albert Renshaw I have edited it to add decoded version of the string. \$\endgroup\$
    – Divcy
    Feb 28, 2017 at 9:33
0
\$\begingroup\$

Perl, 52 bytes

$_=q{print+(split/
/,"\$_=q{$_};
eval")[<>-1]};
eval

This is a simple variation on the classic quine

$_=q{print"\$_=q{$_};eval"};eval

The "payload" is split on newlines and the correct line is selected by indexing into the resulting list.

Perl, 49 48 bytes (non-competing)

#!/usr/bin/perl -d:A
sub DB'DB{
print${"_<$0"}[<>]}
1

38 bytes for the code (excluding the shebang but including -d:A) plus 10 bytes for the filename, which must be Devel/A.pm. The Devel directory must be in @INC.

Technically, this violates Rule #4 because -d:A causes the file to be parsed twice, so it's a non-competing solution.

It uses a debugger hook to access the lines of the file, which perl stores in the @{"_<$filename"} array at compile time.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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