A JS1K Byte-Saver Quiz!

Here’s a little javascript quiz to help you limber up for JS1K. Each problem is solvable with one statement. Answer with the shortest possible solution.

This is not about writing the most readable or production-ready code. Its a fun test of versatility and language knowledge.

Answers should work on all major browsers except where denoted with “ECMA 5” (in which case they should work on all browsers except IE<9) . The number in parentheses indicates how many characters were in my solution, including semicolons but omitting returns and extra spaces.

I’ll post my solutions on Monday. Good luck! (Spoiler alert – some solutions in comments)

1.Variable f is an array of functions. One of them takes no formal parameters: Invoke it. (53 characters)

2. Variable a is an array. Make an array of the non-falsey (i.e. not undefined, null, 0 etc.) values in a. (ECMA 5) (18)

3. Variables a, b and c reference numbers. Verify b is exclusively bound by a and c without using <,> or arithmetic operators (+, -, *, /) (21) edit: my answer fails for multi-digit numbers

4. Verify that x is true. Don’t use true, false or any other variable, value or function (apart from x)Β  (12)

5. Swap the values of variables a and b without using another variable or property (13)

6. Is n an integer? (7)

7. x is an array of numbers. Get the maximum value in x (20)

8. If b is not a member of array a, add it to the end of the array (ECMA 5) (25)

9. Make a string consisting of string x repeated n times (23)

10. Concatenate arrays a and b without using concat (18)

73 thoughts on “A JS1K Byte-Saver Quiz!

  1. /* only tested in Chrome, but should work in all “major” afaics */

    1. i=f.length;while(i–)f[i].length||f[i]();
    2. [2,’a’,’g’,5]; // πŸ™‚
    3. with(Math)max(min(b,c),a)==b;
    4. x==!!(x+’.’);
    5. a=[b,b=a][0]; // credit to @abozhilov
    6. Math.floor(n)==n;
    7. Math.max.apply(1,x);
    8. a.indexOf(b)<0&&a.push(b);
    9. for(s='';n–;)s+='x';
    10.a.push.apply(a,b);

    1. 1. Beat me by 12 – congrats!
      2. cheating πŸ˜‰ rephrased question
      8. I squeezed out one more char with an evil hack
      9. Very nice! – beat me by 4 – was wondering if you wrote the version I cribbed!

  2. These answers, from the top of my head, untested, so some are probably bad :p
    1: f[n]();
    Why 54 chars? I must be misunderstanding the question.
    2: a.filter(function(x){if(x)return x});
    I’m guessing you’re using a different hack, can’t think of it though.
    3: ?
    No idea.
    4: !!x==!!x;
    An operator is no function. Without operators… I don’t know.
    5: b=[a,a=b][0];
    I’ve seen this trick elsewhere,7. SAme asnwer or a variant of it anyways.
    6: n==+n;
    Probably not sufficient.
    7: Math.max.apply(0,x);
    Possibly your answer.
    8: if(!~a.indexOf(b))a.push(b);
    Probably your answer.
    9: new Array(n+1).join(x);
    One of the very few things that stupid constructor is usefull for.
    10: a.push.apply(a,b);
    Probably a lot like your solution.

  3. #1 (40 chars)
    f.forEach(function(a){!a.length&&a();});

    #2 (18 chars)
    a.filter(Boolean);

    #3 (38 chars)
    Math.max(a,b,c)!=b&&Math.min(a,b,c)!=b

    #4 (3 chars)
    !!x

    #5 (16 chars)
    x^=y;y=x^y;x^=y;

    #6 (9 chars)
    n+’.’==n;

    #7 (20 chars)
    Math.max.apply(0,x);

    #8 (26 chars)
    a.indexOf(b)<0&&a.push(b);

    #9 (23 chars)
    new Array(n+1).join(x);

    #10 (18 chars)
    a.push.apply(a,b);

    1. 1. I guess I went for the more simple version of 1 – but you guys did much better
      4. !!x will always return true for truthies, false for falseys. We want to detect pure true values
      5. nice alternative! – though that would only work for numbers
      7. everyone is getting this one!
      8. still one character to shave off (love this one πŸ˜‰ )

  4. Note that solutions of #3 by something like:

    [a,b,c].sort()[1]==b

    does not work, because arrays are sorted lexicographically by default, not numerically.

      1. > 3. % is allowed – just the stated operators are not
        Exclusive or inclusive? <= and >= (got eaten above) are ok right?

        > 4. truthy implies not undefined, null, 0 etc.
        Yeah, so which…?

        4. 4 (truthy)
        4. 10 (`true`)

      2. 3. they are allowed
        4. I rephrased the question – no falseys allowed

        edit: oh wait – question 4 has to be pure true, not truthy

      3. > edit: my answer fails for multi-digit numbers

        Inclusive I guess.

        > 3. they are allowed

        3. 20

        Quizzes of this kind can get pretty awkward without proper test cases. πŸ˜‰

    1. Update:

      2. 18
      (12 was `a.map(Date);`. I interpreted the problem as “Make an array of non-falsy values with the same length as a.”)

      4. 9

  5. @kangax, in #3 you assume a < b < c, but what about if c < b < a

    a=3; b=2; c=1; with(Math)max(min(b,c),a)==b;
    false

  6. 1. f.map(function(_)_.length||_()) //31 – works on FF3+
    4. x===!!x //7
    6. n%n+n //5 – result is (int) n only if n is int
    7. a.sort().pop() //14
    8. a.indexOf(b)?a.push(b):0 //24

    1. 1. Nice but not allowed (ECMA 5, FF)
      2. Would work for false too
      6. result needs to be true or false
      7. won’t work for multi-digit numbers (nice though)
      8. logic fails – not found will return -1

      1. 5. Saw it too late πŸ™‚

        1. just needs {} but satyr already stated to have 32

        What’s wrong with 7., 8. and 9.?

  7. (I’m omitting trailing semicolons because they aren’t really part of the expression in question)

    1. for(i=0;j=f[i++];){j.length||j()}
    2. a.filter(Boolean)
    3. with(Math)min(max(a,b),c)==b
    4. x&&x===!!x
    5. a=[b,b=a][0]
    6. !(n%1) or n%1==0
    7. Math.max.apply(1,x)
    8. ~a.indexOf(b)||a.push(b)
    9. Array(n+1).join(x)
    10. a.push.apply(a,b)

    – Cowboy

    If you want to see some more minification fun: http://bit.ly/Organ1k

    1. Oops, I totally spaced on #1. After reading the comments I realize I could’ve lost the curly braces. Damn you, Crockford!

      1. for(i=0;j=f[i++];)j.length||j()

      Now that I’ve seen clarification of #3:

      3. with(Math)max(a,b,c)!=b&&min(a,b,c)!=b

      – Cowboy

  8. 1)
    i=f.length;while(i–)f[i].length||f[i]();
    f.map(function(z){z.length||z()}); // ECMA 5

    4)
    var x = ‘0’, y = true, z = ‘0’;
    y&!y!=y; // True
    x&&x===x; // Truthy
    z&&z===z; // truthy ‘0’????

    6) n%1===0

  9. 1.

    for (var i = f.length; f[--i].length;);
    f[i]();
    

    1.

    f.sort(function (a, b) { return a.length > b.length;})[0]();
    
  10. Here are my solutions:

    1. (50 characters)

    for (var i=0;i<f.length&&f[i].length||f[i]();i++);

    4. (10 characters)

    x===(x==x)

    9. (20 characters)

    for (s='';n--;s+=x);

    10. (18 characters)

    a.push.apply(a,b);

    I couldn’t work out the other answers in a reasonable size!

    Nice Quiz!

  11. 1.l=f.length;while(f[–l].length);f[l]() (38)

    (f.filter(function(i){return !i.length}))[0]() – ES5 and not only (46)

    2. a.filter(Boolean) (17)

    3. Didn’t understand first question at all (maybe because of English formulation). But then cheated a bit from kangax answer (of what is asking) ;D (there were no other cheatings. really :|)

    m=Math;m.max(a,m.min(b,c))==b

    Oh, and moreover, it’s not correct πŸ˜€ No more cheating πŸ˜‰

    4. x===!””

    5. a=[b,b=a][0] (12) (C) from c.l.js, don’t remember @abozhilov or somebody else

    6. ~~n===n (7) – not for all numbers
    Math.floor(n)==n (16)

    7. Math.max.apply(0,x) (19)

    8. a.indexOf(b)<0&&a.push(b) (25)

    9. Array(n+1).join(x) (18)

    10. (a+","+b).split() (17)

    1. 10. seems to be wrong

      var a = [1], b = [2];
      (a+","+b).split(); // ["1,2"] its an string instead of an array
      (a+","+b).split(',') //[1,2]
      (a+","+[","]).split(','); // doesnt work either ["1", "", ""]

      1. Yep, forgot “,”, should be .split(“,”). But that’s crappy quick solution which won’t work with other values.

        Also there is a typo in 6, should be ===: Math.floor(n)===n.

  12. This was fun but many of the initial questions were unclear and ambiguous and the test changed after people had already answered. You may want to run the test by a few people first before you post it next time, but thanks just the same.

      1. Actually I did have a reviewer and 90-95% of folks understood questions without ambiguity. Question 3 “bounded by” (inclusive or exclusive) was the one thing that was genuinely ambiguous (and I changed that wording after my reviewer saw it – so thats my fault πŸ™‚ )

        But offers appreciated anyway πŸ˜‰

  13. Cool idea, we should gather some more simliar questions, before we get bored

    //#1
    while(a=f.pop())a.length||a();

    //#2
    a.filter(Boolean);

    //#3
    with(Math)max(a,b,c)!=b&&min(a,b,c)!=b;

    //#4 Something wrong with this?
    x===(x==x);

    //#5
    a=[b,b=a][0];

    //#6
    ~~x===x;

    //#7
    Math.max.apply(0,x);

    //#8
    ~a.indexOf(b)||a.push(b);

    //#9
    Array(++n).join(x);

    //#10
    a.push.apply(a,b);

      1. Your logic is incorrect. Your loop calls EVERY function that has one formal parameter. It actually won’t call the function we want it to (the one with no params). The code you were correcting was already correct. πŸ™‚

        A slight variation can fix that (same length):

        while(a=f.pop(),a.length);a()

        Two things I think I will take away from this quiz:
        * using Boolean to filter
        * ~a.indexOf(b) is 1 byte shorter than a.indexOf(b)<0

      2. yes and these were the hardest two for folks to crack.

        There are other cool variations on the filter([[Type]]) idea
        e.g.
        [1, ‘foo’, 90.3, {bar:1}, 54].filter(Number)

      3. You are right, i kinda fooled my self. So for what the new version you proposed?

  14. I snuck away the trailing semicolons. Really liked Cowboy’s solution for #8, though.

    1. [39 bytes] for(i=f.length;i–;)f[i].length||f[i]()
    2. [17 bytes] a.filter(Boolean)
    3. [28 bytes] Math.min(Math.max(a,b),c)==b
    4. [10 bytes] x&&x===!!x
    5. [12 bytes] a=[b,b=a][0]
    6. [7 bytes] ~~n===n
    7. [19 bytes] Math.max.apply(0,x)
    8. [24 bytes] ~d.indexOf(b)||d.push(b)
    9. [18 bytes] for(s=”;n–;)s+=x
    10. [17 bytes] a.push.apply(a,b)

  15. Lots of cool answers. Just one thing: if the functions inside the array are anonymous, you can order them using the sort method, that will sort them according to the number of arguments they accept.
    1) f = [function(x){console.log(‘one’)},function(y, z){console.log(‘two’);},function(){console.log(‘zero’);}];
    f.sort()[0]() //13 characters
    Unfortunately, if the functions are not anonymous, the sort method will sort them elements by their names.

Leave a reply to Chris S Cancel reply