DEV Community

Challenge: Write your worst program

Florian Rohrer on October 30, 2017

Hi everyone, As you may know, there is no way in JavaScript to determine whether or not a number is a multiple of another number, so I wrote this f...
Collapse
 
isaacdlyman profile image
Isaac Lyman • Edited

Can I suggest an improvement to your program? It turns out that there is an operator for doing exactly that in JavaScript.

function isMultiple(big, small) {
  return big % small === 0;
}

The modulo operator retrieves the remainder of division, which is always 0 for whole multiples.

Collapse
 
r0f1 profile image
Florian Rohrer

Hi, thank you for your response. Of course, I know about the modulo operator. This challenge was supposed to be about your worst programs. And as an example I posted this function that divides two numbers, casts the result to a string, searches the whole string for a comma and returns whether a comma was found or not instead of just using %. This is pretty bad in my view. I thought you (the community) might have some other terrible examples like this.

Collapse
 
isaacdlyman profile image
Isaac Lyman

Ohhhhh. I definitely missed that nuance in your original question. My mistake.

Collapse
 
tbodt profile image
tbodt

This is not the worst program I've ever written, but it's pretty bad.

I recently participated in the ICPC (International Collegiate Programming Contest) at my school. To get everyone used to the judging system and the idea of a programming contest, it starts with a 45 minute long practice contest with one problem, which is "input a number and output the sum of the numbers from 1 to that number."

Of course, I could have written a program to do that in 5 minutes. But a guy on the team that eventually got first place said, "Theodore, I expect you to do this in the most insane and inefficient way possible." So I wrote this (as best as I can remember):

#include <stdio.h>
#define s(n) (((n) * ((n) + 1)) / 2)
#define s1(n) s(n),s(n+1)
#define s2(n) s(n),s(n+2)
#define s3(n) s(n),s(n+4)
#define s4(n) s(n),s(n+8)
#define s5(n) s(n),s(n+16)
#define s6(n) s(n),s(n+32)
#define s7(n) s(n),s(n+64)
#define s8(n) s(n),s(n+128)
#define s9(n) s(n),s(n+256)
#define s10(n) s(n),s(n+512)
#define s11(n) s(n),s(n+1024)
#define s12(n) s(n),s(n+2048)
#define s13(n) s(n),s(n+4096)
#define s14(n) s(n),s(n+16384)
#define s15(n) s(n),s(n+32768)
#define s16(n) s(n),s(n+65536)
#define s17(n) s(n),s(n+131072)
#define s18(n) s(n),s(n+262144)
#define s19(n) s(n),s(n+524288)
long lookup[] = {s19(0L)};

int main() {
    char buf[10];
    fgets(buf, sizeof(buf), stdin);
    int n = atoi(buf);
    int result = (n * (n + 1)) / 2;
    if (n < sizeof(lookup)/sizeof(lookup[0]))
        result = lookup[n];
    printf("%d\n", lookup);
}

When you compile this, the C compiler will, after about 30 seconds, generate a lookup table with the answer for any input value up to 1,048,575. This isn't the absolute maximum number you could input though, so as a failsafe, it first calculates the answer at runtime, and then checks if the input is in the lookup table. If it is, then it uses the value from the lookup table instead.

When I came back from the practice contest, I told the other team about what I'd done, and they said "whoa that's the perfect way to do it." They'd written a Python program to generate a C program with the lookup table. They also showed me a screenshot from a judge's machine saying:

Compiling...
00:00:13
Collapse
 
r0f1 profile image
Florian Rohrer

haha nice!

Collapse
 
foresthoffman profile image
Forest Hoffman

I don't have any terrible program ideas at this moment, but here's an equally terrifying scenario for anyone who uses Git.

# Friday, 9:00 PM
$ git reset --hard HEAD~2 && git push origin master -f
Collapse
 
arcticshadow profile image
Cole Diffin

I Javascript snippet I wrote recently - I really couldn't be bother properly implementing the consumer (of this func) to be async - so I made the async func sync.

    let done = false
    let result = undefined;

    this.isAuthenticationValid().then((theResult) => {
      done = true;
      result = theResult;
    })

    const asyncChecker = () => {
      setTimeout(() => {
        if(done === true){ // i.e. promise has resolved
          if(result === false){ // i.e. not authenticated
            this.getStrategy().authenticate();
          }
        } else { // promise not yet resolved.
          asyncChecker();
        }
      }, 1000);
    }
    asyncChecker();

N.B. this was in no way production code.

Collapse
 
hrmny profile image
Leah

This is still async

Collapse
 
arcticshadow profile image
Cole Diffin

Appearances can be deceiving. On a technicality yes it's still async. However, from a callers perspective, it operates synchronously. The debate on if this is synchronous or non-synchronous was not the point of me posting this code. If you need a reminder, see the OP title.

Thread Thread
 
hrmny profile image
Leah

For the caller the function returns on the setTimeout call

Collapse
 
prodigalknight profile image
RevanProdigalKnight • Edited

Once, about a year ago (maybe less), I was writing a GreaseMonkey/TamperMonkey script to replace all occurrences of a given string in a web page, and I was treating the list of as-of-yet unscanned nodes as a queue. This was before I learned that Array.prototype.shift is about as ineffecient as you can get for getting elements out of a large array in JS. Suffice to say I learned the hard way just how bad it gets

const
  nodes = [document.body],
  res = [];

let
  scanned = 0,
  n;

while (n = nodes.shift()) {
  scanned++;
  if (!n.scanned) {
    if (n.nodeType === Node.TEXT_NODE && !/^s*$/.test(n.nodeValue)) {
      n.scanned = true;
      const repl = replacers.filter(r => r.willRun(n.data));
      if (repl.length) {
        res.push({ node: n, replacers: repl });
      }
    } else if (
      n.hasChildNodes() &&
      ignoreTags.indexOf(n.tagName.toLowerCase()) === -1 &&
      ignoreClasses.every(c => !n.classList.contains(c))
    ) {
      nodes.push(...n.childNodes);
    }
  }
}

With the amount of work that things like replacers.filter(...) were doing, even after offloading the actual replacing work until after the loop, scanning the page kangax.github.io/compat-table/es6 (which at the time had roughly 194,000 nodes on it [and has only grown since then]) took anywhere between 60 and 90 seconds on page load.

After switching from a queue-based array to a stack-based array (by replacing nodes.shift() with nodes.pop(), the same page took about 4 seconds to scan.

I actually had an even worse-designed algorithm before this where I attempted to use nothing but Array.prototype methods and ended up iterating the result arrays multiple times, so the function to scan the page had something like a O(15n) runtime complexity. It was a very readable algorithm, though.

Collapse
 
jorinvo profile image
jorin

One thing that comes to my mind is this factorial implementation using only lambda calculus. In JavaScript. I took the idea from this talk and implemented it in JS.

// Y Combinator
// makes the recursion
(function (improver) {
  return (function (gen) { return gen(gen) })(
    function (gen) {
      return improver(function (v) {
        return gen(gen)(v)
      })
    }
  )
})(
// this part is the condition for the factorial
function (partial) {
  return function (n) {
    return n === 0 ? 1 : n * partial(n - 1)
  }
}
// pass any number here to get its factorial
)(5)
Collapse
 
zalithka profile image
Andre Greeff

Had a good chuckle reading through the comments. Although, perhaps you should have posted this as a "share the worst single function snippet you have of a working program", now I imagine those comments would be quite something.. Lol.

Collapse
 
r0f1 profile image
Florian Rohrer

Haha yeah agreed, that is a more accurate description of what I want :D

Collapse
 
ben profile image
Ben Halpern

"Write your worst program"? Not sure I follow exactly what you're looking for.

Collapse
 
r0f1 profile image
Florian Rohrer

Ok, I've updated the description to better reflect what I mean!

Collapse
 
helpermethod profile image
Oliver Weiler • Edited

Multiplication should be hard

EDIT Improved version

fun multiply(a: Int, b: Int): Int {
    tailrec fun multiplyRec(a: Int, b: Int, acc: Int = 0): Int =
        when (b) {
            0 -> acc
            else -> multiplyRec(a, b - 1, acc + a)
        }

    return multiplyRec(a, b)
}
Collapse
 
yakovmeister profile image
the furious dev • Edited
class isBoolean {
   constructor(value) {
       this.value = value
   }

   assert() {
     if(typeof value === "string") {
       this.value = false
     } else if (typeof value === "undefined") {
       this.value = false
     } else if (typeof value === "object") {
       this.value = false
     } else if (typeof value === "number") {
       this.value = false
     } else if (typeof value === "symbol") {
       this.value = false
     } else if (typeof value === "function") {
       this.value = false
     } else {
       if(this.value === true || this.value === false) {
          this.value = true
       } else {
          this.value = false
       }
     }

     return this.value
   }
}

module.exports = isBoolean
Collapse
 
rigidnetwork profile image
Rigid Network • Edited

while(true);

Collapse
 
gruhn profile image
Niklas Gruhn

I bet you'll like this

alf.nu/ReturnTrue

It's a set of super weird JavaScript code golf challenges. Cringe guaranteed for the shortest solutions. I love it!