The NX source-length problem

18

1

On PPCG, we have had lots of challenges where the length of your output is dependent on the length of your source code. For the purposes of this challenge, we will call these Source-length problems. The two most well known examples of source-length problems are

More simply, the NX source length problem is the challenge of creating a program whose output is exactly N times (X) the length of the source code. There have even been some variants on this type of challenge, for example

These usually tend to be pretty interesting, although fairly simple to implement. However, we've never had a generalized source-length problem. Until today that is. Here is your challenge for today:

Given a positive integer N, output an answer to the NX source-length problem in the same language.

For example, let's say you wrote a submission in the language foo. If your program or function was given the input 3, you must output a new foo program or function s, that takes no input and whose output is exactly 3 times the length of s. Borrowing Martin's rules on the first challenge, here are some requirements for s:

  • Your code and your s may use any consistent encoding you like. However, s may only output bytes in the printable ASCII range (0x20 to 0x7E, inclusive), or newlines (0x0A or 0x0D).
  • s must not be a quine, so the code and the output must differ in at least one byte.
  • s must be at least one byte long.
  • If your output contains trailing newlines, those are part of the byte count.
  • The output doesn't always have to be the same, as long as you can show that every possible output satisfies the above requirements.
  • Usual quine rules don't apply. You may read the source code or its size, but I doubt this will be shorter than hardcoding it in most languages.

And adding a few rules of my own

  • Output from errors does not count towards output length.

  • If your solution fails for large N because of integer size restrictions, this is OK. Keep in mind, that this does not mean you can abuse native number types.

I highly recommend testing your code with inputs that are a different number of digits, since naive approaches that work for 1 digit Ns will fail for 2 digit Ns. Please also include an explanation of how you know your program is valid. Although this isn't mandatory, it is encouraged.

Since this task will be much easier in REPL languages, if you do answer in a REPL, please post your answer as

# Foo REPL, N bytes

so that it is distinguished from a regular answer in foo.

Of course, since this is a challenge, try to write the shortest possible answer in bytes as you can!

Leaderboard

Please format your answer like this so that it shows up in the leaderboard:

# <Language-name>, <n> bytes

    code
    code

/* Configuration */

var QUESTION_ID = 154961; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 31716; // This should be the user ID of the challenge author.

/* App */

var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;

function answersUrl(index) {
  return "https://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function commentUrl(index, answers) {
  return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}

function getAnswers() {
  jQuery.ajax({
    url: answersUrl(answer_page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      answers_hash = [];
      answer_ids = [];
      data.items.forEach(function(a) {
        a.comments = [];
        var id = +a.share_link.match(/\d+/);
        answer_ids.push(id);
        answers_hash[id] = a;
      });
      if (!data.has_more) more_answers = false;
      comment_page = 1;
      getComments();
    }
  });
}

function getComments() {
  jQuery.ajax({
    url: commentUrl(comment_page++, answer_ids),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      data.items.forEach(function(c) {
        if (c.owner.user_id === OVERRIDE_USER)
          answers_hash[c.post_id].comments.push(c);
      });
      if (data.has_more) getComments();
      else if (more_answers) getAnswers();
      else process();
    }
  });  
}

getAnswers();

var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

var OVERRIDE_REG = /^Override\s*header:\s*/i;

function getAuthorName(a) {
  return a.owner.display_name;
}

function process() {
  var valid = [];
  
  answers.forEach(function(a) {
    var body = a.body;
    a.comments.forEach(function(c) {
      if(OVERRIDE_REG.test(c.body))
        body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
    });
    
    var match = body.match(SCORE_REG);
    if (match)
      valid.push({
        user: getAuthorName(a),
        size: +match[2],
        language: match[1],
        link: a.share_link,
      });
    else console.log(body);
  });
  
  valid.sort(function (a, b) {
    var aB = a.size,
        bB = b.size;
    return aB - bB
  });

  var languages = {};
  var place = 1;
  var lastSize = null;
  var lastPlace = 1;
  valid.forEach(function (a) {
    if (a.size != lastSize)
      lastPlace = place;
    lastSize = a.size;
    ++place;
    
    var answer = jQuery("#answer-template").html();
    answer = answer.replace("{{PLACE}}", lastPlace + ".")
                   .replace("{{NAME}}", a.user)
                   .replace("{{LANGUAGE}}", a.language)
                   .replace("{{SIZE}}", a.size)
                   .replace("{{LINK}}", a.link);
    answer = jQuery(answer);
    jQuery("#answers").append(answer);

    var lang = a.language;
    lang = jQuery('<a>'+lang+'</a>').text();
    
    languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang, user: a.user, size: a.size, link: a.link};
  });

  var langs = [];
  for (var lang in languages)
    if (languages.hasOwnProperty(lang))
      langs.push(languages[lang]);

  langs.sort(function (a, b) {
    if (a.lang_raw.toLowerCase() > b.lang_raw.toLowerCase()) return 1;
    if (a.lang_raw.toLowerCase() < b.lang_raw.toLowerCase()) return -1;
    return 0;
  });

  for (var i = 0; i < langs.length; ++i)
  {
    var language = jQuery("#language-template").html();
    var lang = langs[i];
    language = language.replace("{{LANGUAGE}}", lang.lang)
                       .replace("{{NAME}}", lang.user)
                       .replace("{{SIZE}}", lang.size)
                       .replace("{{LINK}}", lang.link);
    language = jQuery(language);
    jQuery("#languages").append(language);
  }

}
body {
  text-align: left !important;
  display: block !important;
}

#answer-list {
  padding: 10px;
  width: 290px;
  float: left;
}

#language-list {
  padding: 10px;
  width: 290px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/all.css?v=ffb5d0584c5f">
<div id="language-list">
  <h2>Shortest Solution by Language</h2>
  <table class="language-list">
    <thead>
      <tr><td>Language</td><td>User</td><td>Score</td></tr>
    </thead>
    <tbody id="languages">

    </tbody>
  </table>
</div>
<div id="answer-list">
  <h2>Leaderboard</h2>
  <table class="answer-list">
    <thead>
      <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
    </thead>
    <tbody id="answers">

    </tbody>
  </table>
</div>
<table style="display: none">
  <tbody id="answer-template">
    <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>
<table style="display: none">
  <tbody id="language-template">
    <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>

James

Posted 2018-02-05T23:00:19.993

Reputation: 54 537

Question was closed 2018-02-06T08:50:48.603

Just a note that the 2X challenge was effectively an NX challenge in most languages, because of the bonus. But then it also had the weird requirement that N still needed to default to 2.

– Martin Ender – 2018-02-05T23:39:59.500

Sorry if this duplicated vote it uncalled for, but it seems they are the same to me. If anyone thinks differently, I'd like to know the differences. It is of course possible I misread either of the challenges. – Kevin Cruijssen – 2018-02-06T08:51:48.580

2@KevinCruijssen, if you think there might be a possibility you misread either of the challenges then be careful swinging that dupe hammer around. – Shaggy – 2018-02-06T09:10:23.083

4@Shaggy I'm fairly certain they are dupes of each other, but I will be completely honest: I recently got gold for code-golf which is why it got marked as duplicate right away, instead of being a 1/5 vote with a comment "Possible duplicate of".. Next time I'll post that comment manually. Although this challenge is much better specified, except for an example like the other had, they are identical: Create a program with input n that prints a program, which in turn prints anything with a string-length of n times the program length. – Kevin Cruijssen – 2018-02-06T09:25:34.563

The only difference is this one specifies positive N, while the other is non-negative and has slightly less restrictive output – Jo King – 2018-02-06T10:57:31.610

3@KevinCruijssen Eh, I think the other one allows for different languages for your solution and the output programs, although I won't hammer this open yet. – Erik the Outgolfer – 2018-02-06T13:01:58.597

Answers

9

M, 4 bytes

;“ x

For input n, this prints the program n x.

Try it online!

The program n x sets its argument and return value to n, then executes the x atom to repeat n n times, resulting in an array of n n's.

Try it online!

Proof of validity

Let d be the number of digits of n, so the program n x is d+2 bytes long.

Python 3 (and, therefore, M) prints an array of n n's like [n, ..., n].

Since all n copies of n are d bytes long, the first n-1 copies of n are followed by , (2 bytes), and [] surrounds the array (2 bytes), the output is nd + 2(n-1) + 2 = nd + 2n = n(d+2) bytes long.

Dennis

Posted 2018-02-05T23:00:19.993

Reputation: 196 637

4

Operation Flashpoint scripting language, 68 bytes

f={format["g={i=0;s={};while{i<%1}do{i=i+1;s=s+{    }+g};s}",_this]}

A function that takes a number n as input and outputs a function g that produces output with n times the length of its own source code.

Example:

3 call f

outputs

g={i=0;s={};while{i<3}do{i=i+1;s=s+{    }+g};s}

which outputs

    i=0;s={};while{i<3}do{i=i+1;s=s+{    }+g};s    i=0;s={};while{i<3}do{i=i+1;s=s+{    }+g};s    i=0;s={};while{i<3}do{i=i+1;s=s+{    }+g};s

Alternative version ( 75  71 bytes):

f={format[{g={i=0;s={};while{i<%1}do{i=i+1;s=s+"g={"+g+"}"};s}},_this]}

Outputs a function g which outputs its own source code n times.

Example:

3 call f

outputs

g={i=0;s={};while{i<3}do{i=i+1;s=s+"g={"+g+"}"};s}

which outputs (when called with hint call g)

Steadybox

Posted 2018-02-05T23:00:19.993

Reputation: 15 798

How do you choose where to take your screenshots? Do you do a screenshot in a different place each time? – cole – 2018-02-06T01:41:19.147

1

@cole I just take them where I happen to feel like taking them. Usually it's a different place each time. I used to take them always in the same place before Magic Octopus Urn suggested taking them in other places as well.

– Steadybox – 2018-02-06T01:52:06.007

4

MATL, 20 19 18 bytes

`@G*qVn4+@-}3M'Z"'h

This ouputs a program of the form

abc
Z"

followed by a newline, where abc represents a positive integer. The function Z" gives a string of that many spaces, which is implicitly printed with a trailing newline.

Try it online!

Examples:

  • Input 142 produces the program

    993
    Z"
    

    (plus newline). Try it online with footer code that changes space to ! for visibility.

    The program length is 7 (including the newline), and its output has 994 characters (993 spaces and 1 newline), which equals 142*7.

  • Input 143 produces the program

    1143
    Z"
    

    with a trailing newline. Try it online with the same modification.

    The program length is 8 (including the trailing newline), and its output has 1144 characters (1143 spaces and 1 newline), which equals 143*8.

Explanation

The most difficult part is, given input N, computing the number abc. Let f denote the function "number of digits of". The code finds the first positive integer K that satisfies

f(K*N-1)+4 = K

The 1 above accounts for the trailing newline which is output by the produced program after the string of spaces, and the 4 accounts for the length of the Z" statement and the two newlines in the produced program. The number abc to be included in the output program is then K*N-1.

In the examples above:

  • For N=142 the obtained K is 7, which gives K*N-1 = 993.
  • For N=143 the obtained K is 8, which gives K*N-1 = 1143.

Commented code

`         % Do...while
  @       %   Push iteration index. This is a potential K
  G       %   Push input, N
  *       %   Multiply
  q       %   Subtract 1
  V       %   Convert to string (*)
  n       %   Number of characters
  4       %   Push 4
  +       %   Add
  @       %   Push K
  -       %   Subtract. This is the loop condition. If 0 (meaning the
          %   condition f(K*N-1)+3 = K is fulfilled) the loop is exited
}         % Finally (execute on loop exit)
  3M      %   Push string (*) from automatic clipboard
  'Z"'    %   Push string 'Z"'
  h       %   Concatenate horizontally
          % End (implicit). Display with trailing newline (implicit)

Luis Mendo

Posted 2018-02-05T23:00:19.993

Reputation: 87 464

3

Befunge-98, 22 21 14 bytes

Edit: Didn't see that the output has to be printable ASCII only. Funnily enough, this saved a byte.

Edit: I was being stupid. What do you do if you to do something X times, N times? You do it X times N, times, duh.

Edit: Just realised this won't work with 10 or 13, because they print newlines, so I changed to the alternate version:

"&3*1-''5k,@.k

which can't print newlines.

Try it online! Try it N = 1, 2, 3 and 100

The NX program is in the form:

'N k.@

Where N is the char code of the inputted number. Prints N*3*("0 ")

Old version:

"&''fk,@.k7p01-1_@#!:

Try it online! Try N = 1, 2, and 3

Jo King

Posted 2018-02-05T23:00:19.993

Reputation: 38 234

2

Haskell, 55 bytes

f n="'a'<$[1.."++show(n*(10+length(show$n*10+10)))++"]"

Try it online!

totallyhuman

Posted 2018-02-05T23:00:19.993

Reputation: 15 378

1

Zsh, 28 22 bytes

repeat $1 echo rev \$0

For input n, this prints n copies of rev $0 and a linefeed.

Try it online!

The generated programs print n reversed copies of themselves.

Try it online!

Dennis

Posted 2018-02-05T23:00:19.993

Reputation: 196 637

Any reason why you chose rev over cat, apart from giggles? – tomsmeding – 2018-02-06T09:12:28.930

The rules state that the code and the output must differ in at least one byte. cat would violate this rule when n = 1. – Dennis – 2018-02-06T13:24:43.240

1

JavaScript (ES6), 51 bytes

n=>`_=>("${n}"[r="repeat"](2)+" "[r](41))[r](${n})`

Outputs (e.g.) _=>("42"[r="repeat"](2)+" "[r](38))[r](42) which has length 42 and whose output has length 1764.

Neil

Posted 2018-02-05T23:00:19.993

Reputation: 95 035

1

Python 2, 56 bytes

f=lambda n:"print`f`*"+`n*n`+','+'#'*(33*n-9-len(`n*n`))

Creates a string of the form

print`f`*<number>################...#####

where the number is n^2 and there are enough #s to make the string 33n characters long. Depending on the way your OS stores memory addresses, the 33 might need to change.

There's also that annoying +',' in the middle so that it conforms to the newline requirement; if anyone can figure out how to shorten that it would be much appreciated.

There's a less iffy version with 58 bytes in the following form:

f=lambda n:"print`id`*"+`n*n`+','+'#'*(22*n-10-len(`n*n`))

which functions identically and more reliably, but at the cost of using "id" instead of "f" as the function and having to subtract 10 instead of 9, using an extra character.

An explanation of this technique is given here.

Carl Schildkraut

Posted 2018-02-05T23:00:19.993

Reputation: 403

0

Clean, 117 bytes

import StdEnv
$l n="import StdEnv\nf={#'0'\\\\_<-[1.."+++fromInt n+++"],_<-[0.."+++fromInt l+++"]}"

\n= $(size($99n))n

Try it online!

An anonymous function taking Int and giving the source for a function returning a string of the requisite length, having the signature f :: String. While this is technically reliant on the native integer type having less than 256 bits, I don't believe that this qualifies as abuse thereof.

Οurous

Posted 2018-02-05T23:00:19.993

Reputation: 7 916