16
\$\begingroup\$

In this challenge you'll be building a program that grows as it traverses through the ages… Until it's 2017.

Challenge

Whenever this challenge description says “program”, you can also read “function”.

Your submission, when executed, will output a program that is THE LENGTH OF YOUR SUBMISSION + 1 bytes long.

When that program is executed, it will output a program that is THE LENGTH OF YOUR SUBMISSION + 2 bytes long… and so on.

However, when your program has reached a length of 2017 bytes, it must instead output 2017 and exit.

Rules

  • The output of the final program has to be 2017 and only 2017. It can be a string or an integer, but it must read 2017 and not 2017.0 or 0x7E1 or other such nonsense.
  • No standard loopholes.
  • Only your initial program is allowed to require input, which will be added to your bytecount.
    So if your initial program is 324 characters long and takes an input of 13 bytes, your total score will be 324 + 13 = 337 and the program outputted by it must be 338 bytes long.
    • Using command line flags (e.g. perl -X) is fine, however – as long as your initial program as well as all generated programs use the same flags. Also, they too count towards the total bytecount. Dashes, slashes etc. in front of a command line flag don't count towards the total, so e.g. perl -X counts as one additional byte.
  • If you return a function, it should be an actual function and not a string that, when evaluated, produces a function.
  • Improper quines (if your program is a quine) are disallowed.

Example

Pseudocode, 99 bytes

IF (PROGRAM LENGTH == 2017)
  PRINT 2017
ELSE
  PRINT (THE SOURCE OF THIS PROGRAM + 1 BYTE PADDING)

Your submission may work differently, as long as it complies with the rules above.

\$\endgroup\$
  • \$\begingroup\$ Is just appending NOPs such as ;;; allowed? \$\endgroup\$ – FlipTack Jan 1 '17 at 9:49
  • \$\begingroup\$ @FlipTack Yes.· \$\endgroup\$ – user2428118 Jan 1 '17 at 10:05
  • \$\begingroup\$ "Dashes, slashes etc. in front of a command line flag don't count towards the total, so e.g. perl -X counts as one additional byte." -- Is this intentionally contrary to the norm here as described on Meta? Normally, dashes, slashes, etc. should sometimes be counted, depending on what the invocation without that option looks like: meta.codegolf.stackexchange.com/questions/273/… \$\endgroup\$ – hvd Jan 1 '17 at 13:34
  • \$\begingroup\$ @hvd Don't think I read that one, so no, it's not intentional. That said, I don't think there is much harm in ignoring them so I won't change it for this challenge. \$\endgroup\$ – user2428118 Jan 1 '17 at 13:50
6
\$\begingroup\$

*><>, 29 28 30 bytes

" r::2+l'-':*7-(?ul1-n;Ol?!;ou

Try it here! (*try with 2017 bytes)
*set delay to 0ms or you might have to wait a long time

This adds an additional each subsquent run. If it has 2017 bytes and is run, it will output 2017 and stop execution with no other output.

Update: Saved 1 byte by checking if the length is less than 2017 instead of equal

Update 2: Fixed output for +2 bytes

Explanation

" r: 2+                         build quine
    :                           copy extra " "
       l                        push length to stack
        '-':*7-                 push "2018" to stack
               (?u     O        if not length < 2018:
                  l1-n;           output length-1 and exit
                       Ol?!;ou  output entire stack and exit
\$\endgroup\$
  • \$\begingroup\$ yeah, not quite right when your program has reached a length of 2017 bytes, not 2016 \$\endgroup\$ – Destructible Lemon Jan 1 '17 at 0:34
  • \$\begingroup\$ @DestructibleWatermelon fixed \$\endgroup\$ – redstarcoder Jan 1 '17 at 0:56
4
\$\begingroup\$

Python 2.7, 90 bytes

Here's a relatively simple one:

p='q';s=r"p+='q';print('p=\''+p+'\';s=r\"'+s+'\";exec s')if len(p)<1929 else'2017'";exec s

Try the first iteration here! Try the penultimate iteration here! Try the final iteration here!

Ungolfed:

p='q'      # The length of string p is the number of iterations so far.

s=r"p+='q';print('p=\''+p+'\';s=r\"'+s+'\";exec s')if len(p)<1928 else'2017'"

exec s     # s contains the source code, but also contains a line saying "p += 'q'",
           # which makes the byte count longer. When the length of p is 1928 (i.e. when the
           # entire program is 2017 bytes long), 2017 is printed instead.
\$\endgroup\$
  • \$\begingroup\$ @redstarcoder The final iteration has exactly 2017 characters. You can see the byte count in the upper right corner I think.... \$\endgroup\$ – Calconym Jan 2 '17 at 1:26
  • \$\begingroup\$ Ah my mistake, not sure how that happened, sorry! \$\endgroup\$ – redstarcoder Jan 3 '17 at 18:19
  • \$\begingroup\$ You can use p='';... and 1929else, but note that the printing also prints a newline at the end, so you should add a trailing newline to your program, else it grows two bytes after the first run. \$\endgroup\$ – mbomb007 Feb 17 '17 at 22:53
2
\$\begingroup\$

Microscript II, 38 bytes

{v{h}sl+s""+vK#s2017=(2017ph)lp"~"ph}~
\$\endgroup\$
1
\$\begingroup\$

><>, 34 bytes

":l' '95**)b*f3++0.1-}'#'r>o<:ln;#

Try it online! Note that, in order to test this for smaller values, your value (minus 1) must be able to be generated in 7 bytes.

Explanation

":l' '95**)b*f3++0.1-}'#'r>o<:ln;#
".................................   push this string
 :                                   duplicate
  l                                  push length of stack
   ' '95**                           push 2016
          )                          1, if length > 2016, 0 otherwise
           b*                        multiply by 11
             f3++                    add 18
                 0.                  jump to that character on this line
                                     if the length is sufficiently long, this skips the
                                     next 10 characters, to the 11th (`b` from earlier):
                             :ln;    (if length is > 2016)
                             :         duplicate
                              l        push length
                               n       output as number
                                ;      terminate
                   1-}'#'r>o<        (if length <= 2016)
                   1-                  subtract 1 from the last char, `#`, to get `"`,
                     }                 which is then moved to the bottom
                      '#'              pushes `#` (will be appended)
                         r             reverses the stack
                          >o<          output stack, until error (accepted by default)
                                 #   This is never reached, but is used to generate `"`
\$\endgroup\$
1
\$\begingroup\$

Java, 251 Bytes (Eclipse IDE)

import java.io.*;class G{public static void main(String[]args) throws Exception{File x=new File("./src/G.java");if(x.length()==2017){System.out.print("2017");}else{PrintWriter y=new PrintWriter(new FileOutputStream(x,1>0));y.print("A");y.close();}}}//

This is assuming the project was made in Eclipse, using the convention of .java files in the SRC of the working dir. There are other ways to detect where the source is, but I don't think this is against the rules either.

Basically opens the .java source-code, and appends As until 2017 (after a comment). When the file-size of the source reaches a total of 2017 bytes, it will instead print 2017.

\$\endgroup\$
1
\$\begingroup\$

C, 197 Bytes

#define A ""
char*s="#define A %c %s%c%cchar*s=%c%s%c;%cmain(){printf(sizeof A==1820?%c2017%c:s,34,A,34,10,34,s,34,10,34,34);}";
main(){printf(sizeof A==1820?"2017":s,34,A,34,10,34,s,34,10,34,34);}
\$\endgroup\$
1
\$\begingroup\$

Python 2, 217 167 78 bytes

Note that there should be a trailing newline. I used similar concepts to what Calconym used, so thanks for the inspiration!

p='q';s='p+=p[0];print"p=%r;s=%r;exec s"%(p,s)if len(p)<1941else 2017';exec s

Try it online

Try at 2016; Try at 2017


Previous Version:

This program uses the inspect module to get the current line number. Then, it prints itself but with an extra line after the import, which changes the line number for the next program. There should also be a trailing newline here.

from inspect import*
n=stack()[0][2];s='from inspect import*%sn=stack()[0][2];s=%r;print(s%%(chr(10)*n,s))if n<1852else 2017';print(s%(chr(10)*n,s))if n<1852else 2017

Try it online

\$\endgroup\$
1
\$\begingroup\$

CJam, 39 33 30 bytes

33q:X~

with the input

2017:N=N{33')X+`":X~"+}?

Try it online!

This is functionally equivalent to my previous version, except that it avoids the need to write and escape the quotes. The previous version:

33"2017:N=N{33')X+`\":X~\"+}?":X~

Which outputs

33")2017:N=N{33')X+`\":X~\"+}?":X~

which outputs

33"))2017:N=N{33')X+`\":X~\"+}?":X~

and so on. Finally, the program

33"))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))2017:N=N{33')X+`\":X~\"+}?":X~

Outputs 2017.

How it works

33      Push 33
  q     Read the input: 2017:N=N{33')X+`":X~"+}?
   :X   Store it in variable X
     ~  Eval it

But what does the code in the input actually do?

 2017:N                      Push 2017 and store it in N
       =                     Check if the other number (33 on first run) equals 2017
        N                     If it does, push 2017
         {                    Else, execute this block:
          33                   Push 33
            ')                 Push the ) character
              X                Push X
               +               Concatenate with ')
                `              String representation (wraps it in quotes, escapes quotes inside)
                 ":X~"       Push the string ":X~"
                      +      Concatenate
                       }?    (end of block)

If the first number of the program isn't equal to 2017, then it will output a program in which that number is incremented one more time than it was this time. If it does equal 2017 (i.e. it's been incremented 1984 times), then simply push 2017 and terminate. The first number starts out as 33 (the length of the code); every increment increases the code length by 1 AND that number by 1, so when 33 has been incremented enough to become 2017, the code will also be 2017 bytes long.

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

JavaScript, 98 83 bytes

That was quite a challenge… Guess that's what I get for requiring actual functions to be returned and not just the function's source.

Original function

function x(){return "3".length>1933?2017:Function(`return ${x}`.replace(/3/,33))()}

I'm using function instead of => here because the latter doesn't support named functions, just assigning anonymous functions to a variable.

First iteration

Running the above in your browser console returns a function that, when cast to a string, looks like:

function x(){return "33".length>1933?2017:Function(`return ${x}`.replace(/3/,33))()}

Getting to 2017

Since every function returns a new function, you can call the original function / its result 1934 times to get 2017.

console.log((
function x(){return "3".length>1933?2017:Function(`return ${x}`.replace(/3/,33))()}
)()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
)

Tested with Firefox.

\$\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.