¿Yo Quiero jQuery?

8

2

The Setup

You are given a simple web page with 11 elements:

  • 10 input elements with IDs i1 thru i10, in order
  • one output element with ID out

The input elements have value attributes defined in the HTML source. The value of any given input may be any integer from 0 to 10 inclusive.

The webpage is equipped with the core jQuery 1.10.1 library (as seen in the fiddle), and executes a block of code as soon as the DOM is loaded.

The Challenge

Six specific challenges are presented below. In each case the objective is to compute some function of the inputs and place the computation result into the inner HTML of the output. Each challenge should be solved independently from the others. The solution to a challenge is the block of code that implements the computation/output (e.g. the code in the "Javascript" window in the fiddle). The length of a solution is the length (in bytes) of this block of code.

All this would seem very simple, if not for some rather interesting restrictions.

Your Code May...

  1. invoke the jQuery function $() and pass in arguments

  2. define and use variables

  3. use this

  4. read any property of any jQuery object (with .length being the most useful)

  5. define functions/lambdas, which may subsequently be invoked, stored in variables, and passed as arguments. Functions may accept arguments and return values if needed.

  6. invoke any of the jQuery DOM traversal methods

  7. invoke any of the jQuery DOM manipulation methods, excepting width, height, innerWidth, innerHeight, outerWidth, outerHeight, offset, position, replaceAll, replaceWith, scrollLeft, scrollTop, css, prop, removeProp, which may not be invoked

  8. use the operators: object creation {}; array creation / index reference / field reference [], function/method invocation (), string concatenation +, and assignment =

  9. use string literals

Your Code May Not...

  1. use any operators except for those listed above

  2. use any literals that are not string literals

  3. invoke any function/method other than those specifically excepted above

  4. use any control structure or keyword (e.g. for, while, try, if, with, etc.), excepting this, var, let, functions and lambdas

  5. manipulate the DOM in any way that results in the injection of code (see more below)

  6. access any non-user-defined variable or non-user-defined field/property excepting those listed above

The 6 Challenges

  1. Compute the sum of all input values that are even, placing the result in the inner HTML of the output.

  2. Compute the maximum of all input values, placing the result in the inner HTML of the output.

  3. Compute the product of all input values <= 2, placing the result in the inner HTML of the output. If all input values are > 2, place 0 into the inner HTML of the output.

  4. Compute the modal value (i.e. the value with greatest frequency) of all input values, placing the result in the inner HTML of the output. If the modal value is not unique, place any one of the modal values in the inner HTML of the output.

  5. Let I1 be the value of input i1, I2 be the value of input i2, etc. If the sequence of input values I1 .. I10 forms a fence with I1 < I2, place "TRUE" into the inner HTML out the output; otherwise place "FALSE" into the inner HTML of the output. Specifically, the fence condition is I1 < I2 > I3 < I4 > I5 < I6 > I7 < I8 > I9 < I10.

  6. Place a comma-separated list of all input values, sorted in ascending order, into the inner HTML of the output.

Scoring

The contest winner is the programmer who submits correct solutions to the greatest number of challenges. In the event of a tie, the winner is the programmer with the lowest total solution length (the sum of the lengths of all solutions). Hence this is a minor variant of code golf.

Important Notes

Solutions may mangle the DOM (e.g. delete inputs, create new elements that appear as visual detritus) so long as the final state of the DOM contains an output element with ID out and the correctly-computed value.

Solutions may make use of any advanced jQuery selectors and CSS3, excepting features that evaluate expressions or execute code.

Solutions may not modify the HTML source of the document. All DOM manipulation must occur in the script through jQuery.

Solutions may not inject code of any kind during DOM traversal/manipulation. This includes (but is not limited to) writing out script elements, writing out event attributes containing code, or exploiting the expression (IE) or calc features of CSS3. This challenge is about creative thinking using sets and trees, and masterful use of jQuery; it is not about sneaking code into the DOM or making end runs around the operator restrictions. I reserve the right to disqualify any solution on this basis.

All solutions are realizable, and each can be implemented in fewer than 400 bytes. Your solutions may of course exceed 400 bytes or be far shorter than 400 bytes. This is just my basic guarantee that all 6 problems are solvable using a reasonably small amount of code.

Finally: When in doubt, please ask. :)

Example

Consider the hypothetical challenge: "If 3 or more input values equal 5, place "TRUE" into the inner HTML of the output; otherwise place "FALSE" into the inner HTML of the output."

One valid solution is:

F = () => $('body').append( '<a>TRUE</a>' );
$('input').each( F );
F();
$('a:lt(3)').html( 'FALSE' );
$('#out').html( $('a:eq(' + $('input[value="5"]').length + ')') );

May the best jQuerier win! ;)

COTO

Posted 2014-10-03T09:08:22.357

Reputation: 3 701

15-1 not enough jQuery – grc – 2014-10-03T10:06:48.170

3I'd totally use the answers to this question as production code followed by //La garantia soy yo – William Barbosa – 2014-10-03T14:57:38.880

Since the input fields are technically strings and it doesn't say we need to treat it as numbers, does "ascending order" mean alphabetically? – Ingo Bürk – 2014-10-03T16:48:42.133

1@IngoBürk: The input values will always be (the string representations of) integers from 0 to 10 inclusive. They should be sorted in order of their ascending values when interpreted as integers. This would actually produce the same order as a lexicographic sort, with the exception that 10 would come immediately after 1 in the latter. That should not be the case for a sort here. – COTO – 2014-10-03T16:54:31.537

Alright. Also, something slightly confusing: You write only string literals are allowed, but also that [] and {} are allowed. But these are, technically speaking, array and object literals. It's clear what you mean, though. – Ingo Bürk – 2014-10-03T16:57:49.037

Indeed. I've characterized these as admissible operators rather than admissible literals, even though they're operators that create literals. – COTO – 2014-10-03T17:04:01.213

Are the inputs following a 0 based index ? Which makes the first and third input on the page as even inputs (and likewise) – Optimizer – 2014-10-05T11:14:22.087

@COTO - As array creation is allowed, can I also use array methods like push etc ? – Optimizer – 2014-10-05T12:19:25.143

@COTO - Also , one last thing, can I create new strings like a = ''; and then latest do a+='B' ? – Optimizer – 2014-10-05T12:26:00.427

@Optimizer: Zero indexing is a mixed bag. If you're working with arguments, arrays, etc., indices are 0-based. Hence $('input').eq(1) would filter down to the second element, and x[1] would select the second element. However, in CSS indexing is 1-based. Hence $('input:eq(1)') would select the first element, and $('a:nth-child(3)') would select the 3rd child, etc. – COTO – 2014-10-05T14:33:47.960

Yeah, but what do you expect ? – Optimizer – 2014-10-05T14:36:17.670

@Optimizer: You can create arrays, but you cannot use any array methods. I've allowed array and object creation since they facilitate variable storage, but none of their greater functionality should be used. Finally, you can certainly create new strings like a = '';, the += operator is off-limits, but you can use a = a + 'B'; if needed. – COTO – 2014-10-05T14:37:28.527

Also, I get now what you're asking. The "even inputs" are 1-based, hence the second, fourth, sixth, eighth, and tenth are even. The first input is 1. Their IDs indicate their indices. – COTO – 2014-10-05T14:38:42.860

Let us continue this discussion in chat.

– Optimizer – 2014-10-05T18:02:57.883

One of the answers accesses the length property of arrays and strings. Those are definitely not jQuery objects. Note: "non-user-defined field/property excepting those listed above". If accessing the length property of any object / all objects of a predefined type is allowed, it should be made clear in the rules. – GOTO 0 – 2014-10-06T05:18:44.997

@GOTO0: The .length property of any non-jQuery object is not permitted. I've notified the poster. I've also addressed the .slice() method being invoked on a string (not permitted). – COTO – 2014-10-06T11:33:36.013

Answers

9

1. Sum of even inputs, 100 94 bytes

a=$();(e=$('*:odd')).map(i=>a=a.add(e.slice('0',e.eq(i).val()).clone()));$(out).html(a.length)

How it works :

  • a=$(); : Create a new object a
  • e=$('*:odd') : Get all odd elements on the page and assign it to e. Interestingly, all odd elements of page actualyl include all even input elements (amongst other things) ;)
  • (e=..).map(i=>...) : For each of the elements in the object e, run the given function where i is the index of the current element.
  • a=a.add(e.slice('0', e.eq(i).val()).clone()) : get the value of the ith element in e, slice out that many objects from e, clone them and put add them to a. Interestingly, again, e has more than 10 elements, so it works for all values of the input boxes. For non input elements in e, it just slices 0 elements from e.
  • $(out).html(a.length) : out is a global created by browsers for each element with an id. So we just put the length of a in the output element's html.

Note that jquery's $() acts as a set, but we are adding clones DOM elements, so it is accumulating and finally giving sum of all even input values.

2. Max of all, 79 70 bytes

a=[];(e=$('*')).map(i=>a[e.eq(i).val()]=e);$(a).map(_=>$(out).html(_))

How it works:

  • a=[]; : create a new array a
  • e=$('*') : Query all elements on the page and store it in e
  • (e=..).map(i=>...) : For each of the elements in the object e, run the given function where i is the index of the current element.
  • a[e.eq(i).val()]=e : Get the value of the ith element in e (say V) and put e in the Vth index of a. We use e here just to save a byte. Otherwise, a[e.eq(i).val()]='' would also work.
  • $(a).map(_=>$(out).html(_)) : This is basically putting each index of a into the html of the output element, overriding each time. This ends up with the output node having the value which corresponds to the last index of a which corresponds to the highest value in the inputs.

3. Product, 152 141 133 132 bytes

f=(i,g=_=>p=$(i1))=>$('[value='+i+']').map(g);h=p=$();f('1');f('2');f('2',_=>p=p.add(p.clone()));f('0',_=>p=h);$(out).html(p.length)

141 -> 133 reduction thanks to GOTO0 :)

4. Modal, 116 115 102 bytes

a=[];(e=$('*')).map(i=>(v=e.eq(i).val(),a[$('[value='+v+']').length]=v));$(out).html($(a).last()['0'])

5. Fence, 158 bytes

s="TRUE";g=_=>$("*").slice(A.val(),B.val()).map(_=>s="FALSE");f=a=>(A=$(a),B=A.prev(),g(),A=$(a),B=A.next(),g());f(i2);f(i4);f(i6);f(i8);f(i10);$(out).html(s)

6. Sorted comma separated values, 133 85 86 bytes

$('*').map(i=>$('[value='+i+']').map(_=>$(out).append(i+'<a>,')));$("a:last").remove()

How this works:

  • $('*').map(i=>...) : Take out all elements from the page and run the method for all of them where i is the index of the element.
  • $('[value='+i+']').map(_=>...) : For each i, get all elements whose value is i and run the method for each one of them.
  • $(out).append(i+'<a>,') : Append i and an anchor tag with , in it to the output element for each element whose value is i.
  • $("a:last").remove() : Remove the last anchor tag to remove the trailing ,

This works as it picks out all elements with values i = 0 through 19 (19 being total number of elements on page) and appends i, to the output element the number of times an element with value i appears. This takes care of all input element, sorting them in increasing order.


Run them on the given JS fiddle page on a latest Firefox.

Please comment if anything is violating rules.

Optimizer

Posted 2014-10-03T09:08:22.357

Reputation: 25 836

Positive. A hint is that .parents() can be a useful way to compute < or >. – COTO – 2014-10-06T11:16:21.337

Looks good. Unless somebody else rises to give you a run for the money, it looks like you'll be 100 rep richer by the end of the week. – COTO – 2014-10-06T20:22:16.663

+1 Could you explain your solutions please? – soktinpk – 2014-10-07T21:29:43.393

@soktinpk - Sure, after the bounty ends ;) – Optimizer – 2014-10-08T15:32:41.193

1The bounty is yours. You are the jQuery king. ;) – COTO – 2014-10-10T12:47:08.243

Nice. Maybe you could save 2 bytes in the third solution if you move p=$() outside the argument list and use $(f('1'),f('2')).map... rather than the add method. – GOTO 0 – 2014-10-10T16:26:05.643

@GOTO0 - $(f('1'),f('2')) gives 0 length object when there are no input with value 1 – Optimizer – 2014-10-10T16:39:43.757

1This one is tested - 135 bytes: f=i=>$('[value='+i+']').map(_=>p=g());p=$();f('1',g=_=>$(i1));f('2');f('2',g=_=>p.add(p.clone()));f('0',g=_=>$());$(out).html(p.length) – GOTO 0 – 2014-10-11T06:46:21.303

2

Interesting challenge! Here are the first few to start us off:

1. Sum, 122 112 bytes

e=$('*')
e.map(i=>e.slice('0',n=e.eq(i).val()).map(x=>e.eq(n).append('<a>')))
e.text($(':not(a):even>a').length)

For each input n, append n <a> elements to the nth <input> element. Then count the <a> elements in every odd <input> element.

2. Maximum, 91 79 bytes

e=$('*')
s=$()
e.map(i=>(s=s.add(e.slice('0',e.eq(i).val()))))
e.text(s.length)

For each input n, join the first n <input> elements with the set s. Then count the elements in the set.

3. Product, 157 bytes

e=$(s='[value=0],[value=1],[value=2],#out')
f=x=>e.slice('0',x.val()).each(i=>f(x.nextAll(s).first().append('<a>')))
f(e.first())
e.text($('#out a').length);

A recursive function that, given an element with value n, calls itself with the next element n times and appends an <a> to that next element. Then count the <a> elements in <output>.

Let me know if there are any mistakes or rule breaches.

grc

Posted 2014-10-03T09:08:22.357

Reputation: 18 565

Everything looks kosher except for the zero literal in #2. Very nice solutions BTW. – COTO – 2014-10-03T14:57:32.410

@grc - Aren't we supposed to put the answer in the <output> element instead of the <html> element ? – Optimizer – 2014-10-05T14:30:32.983

@Optimizer Yes, you're right. It seems my last edit broke the first two. I'm really busy right now, but it should just be a matter of replacing e.text with $('#out').text. I'll fix it tomorrow if I get time. – grc – 2014-10-05T15:12:11.437