# ¿Yo Quiero jQuery?

## 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.

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! ;) • -1 not enough jQuery – grc Oct 3 '14 at 10:06 • I'd totally use the answers to this question as production code followed by //La garantia soy yo – William Barbosa Oct 3 '14 at 14:57 • 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 Oct 3 '14 at 16:48 • @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 Oct 3 '14 at 16:54 • 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 Oct 3 '14 at 16:57 ## 2 Answers ## 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.

• Positive. A hint is that .parents() can be a useful way to compute < or >. – COTO Oct 6 '14 at 11:16
• 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 Oct 6 '14 at 20:22
• +1 Could you explain your solutions please? – soktinpk Oct 7 '14 at 21:29
• The bounty is yours. You are the jQuery king. ;) – COTO Oct 10 '14 at 12:47
• This 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 Oct 11 '14 at 6:46 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>')))
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. • Everything looks kosher except for the zero literal in #2. Very nice solutions BTW. – COTO Oct 3 '14 at 14:57 • @grc - Aren't we supposed to put the answer in the <output> element instead of the <html> element ? – Optimizer Oct 5 '14 at 14:30 • @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 Oct 5 '14 at 15:12