2
\$\begingroup\$

Introduction

This problem is a challenge that has to do with DOM manipulation at scale and overcoming some issues that may be inherent in dealing with the DOM.

  • This challenge is interesting because limitations push us to think through things differently and lean on the strengths of languages different than what we usually use.
  • I created this challenge myself based on a real world problem I ran into myself (details can be provided if needed). If this challenge has any relation to a differently know problem, those similarities are coincidental.

This challenge will be scored based on fastest execution.

Challenge

You must render one of the challenge levels in the Chrome web browser (84.0.4147.89 for standardization purposes) (submissions will need to be JavaScript functions for timing purposes):

Using JavaScript please complete the following:

  1. Get each table displayed and add a class table-n to each table where n is a zero based index of order of the table on the screen. If a table is nested within a table the parent would be N and the child would be N+1 with the next table being N+2.
  2. Get each row displayed in each table and add a class of table-n-row-r where r is a zero based index of rows in the table represented by table-n.
  3. Get each cell displayed in each table and add a class of table-n-row-r-cell-c where c is a zero based index of cells in a row represented by table-n-row-r.

At the end of the challenge the web page should still be able to be interacted through in the browser, and a call to document.getElementsByClassName('table-n-row-r-cell-c'); should return one and only one cell from the DOM.

Any method available to you as valid as long as:

  1. Access to one of the difficulty levels has been done through Chrome (84.0.4147.89)
  2. The URL of the browser and the page displayed doesn't change
  3. A call to document.getElementsByClassName('table-n-row-r-cell-c'); returns only one element

Output Examples

For this example we're using the easy level as input.

The abbreviated output in the DOM should be.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Code Golf Challenge</title>
</head>
<body>
    <table class="table-0">
        <thead>
            <tr class="table-0-row-0">
                <th class="table-0-row-0-cell-0">1</th>
                ...
            </tr>
        </thead>
        <tbody>
            <tr class="table-0-row-1">
                <td class="table-0-row-1-cell-0">11</td>
                <td class="table-0-row-1-cell-1">12</td>
                ...
            </tr>
            ...
    </table>
</body>
</html>

There are only <td> and <th> elements used as cell elements for the challenge.

As long as document.getElementsByClassName('table-n-row-r-cell-c'); returns an element with this class, we're good to go.

Qualifying Entries

All entries need to have an execution speed of under 40 seconds for at least one difficulty level to qualify.

Timing starts when your algorithm starts, but after the page has loaded completely as all elements must be available (the browser spinner has stopped spinning).

Calculate the runtime for your method by calling performance.now() before and and after your injection method, and subtracting the first from the second as in the example below.

let t0 = performance.now();
doSomething()   // <---- The function you're measuring time for 
let t1 = performance.now();
let totalTime = t1 - t0;

Winner

The entry that handles the highest difficulty within 40 seconds wins. Ties are broken by execution time at that difficulty.

\$\endgroup\$
11
  • 4
    \$\begingroup\$ It was. Then it was asked to be posted in the sandbox for review, I deleted it and posted it in the sandbox for review. It was reviewed by @Bubbler and FryAmTheEggman . Additions and edits were made according to their suggestions. Is there any reason that it doesn't meet standards now? \$\endgroup\$ Jul 20 '20 at 11:44
  • 2
    \$\begingroup\$ I totally forgot, welcome back to CG.SE! \$\endgroup\$
    – user92069
    Jul 20 '20 at 11:57
  • 9
    \$\begingroup\$ Ignoring the specifics of this question, it is generally recommended that you keep a submission in the Sandbox for around 3 days, just to make sure that plenty of people have the chance to read over it. Furthermore, it doesn't hurt to advertise in chat asking for feedback on Sandboxed proposals. For next time, I would definitely recommend sticking by the general recommendations (i.e. 3 days, or a score of +3) for how long you should leave a proposal in the Sandbox \$\endgroup\$ Jul 20 '20 at 12:22
  • 3
    \$\begingroup\$ And accounting for the specifics of this question, I'd suggest Sandboxing for much longer than the general guideline of 3 days. This is a fastest-code challenge, which tend to be harder to specify and balance than code golf; it has multiple difficulty levels; and, it deals with a specific language, which restricts who can give feedback on it. \$\endgroup\$
    – xnor
    Jul 21 '20 at 10:56
  • 3
    \$\begingroup\$ As someone who didn't know what a DOM is, I accept that I'm not the audience for this challenge. But, I'd prefer to realize that immediately on starting to read it. (And while I didn't downvote for this, others might have.) Note that because tags are displayed at the bottom of a question (which I wish SE would change), it's not immediately clear from the intro section that this is a language-specific question for Javascript, dealing with browsers and CSS. So I'd suggest putting a sentence about that at the very start, noting there that this challenge is about fastest execution. \$\endgroup\$
    – xnor
    Jul 21 '20 at 11:07
1
\$\begingroup\$

About 200 ms

function mark() {
  var t = 0, tp = '';
  var c = [], i = { r: 0, p: '', c: 0 };
  var elements = document.body.getElementsByTagName('*');
  var length = elements.length, index, v;
  for (index = 0; index < length; ++index) {
    v = elements[index];
    switch (v.tagName) {
      case 'TH':
      case 'TD':
        v.className = i.p + i.c++;
        if (i.c == 10 && i.r == 10) {
          i = c.pop();
        }
        continue;
      case 'TR':
        v.className = i.p = i.t + i.r++;
        i.c = 0;
        i.p += '-col-';
        continue;
      case 'TABLE':
        v.className = tp = 'table-' + t++;
        tp += '-row-';
        c.push(i);
        i = { t: tp, r: 0, p: '', c: 0 };
    }
  }
}

If your code runs more than 2s, you must do something wrong. I believe.

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