1
1
(language-specific challenge)
Specification:
Language: ECMAScript, any version[1]
Challenge: Somewhat like python's itertools.groupBy: Your function Array.group(f)
should take as input an "equivalence function" f
whose output defines our notion of an "equivalence key" for array elements (like a sort key). The return value of .group(f)
should be an array of arrays in the same order, split whenever the value of the keyfunc parameter changes (in the ===
sense).
Object.defineProperties(Array.prototype, {
group: {
value: function(f) {/*
CODE GOES HERE
*/}
}
});
Examples / test cases:
> ['a','c','E','G','n'].group(x => x==x.toUpperCase())
[['a','c'], ['E','G'], ['n']]
> [1,1,'1'].group(x=>x)
[[1,1],['1']]
> [3,1,'1',10,5,5].group(x=>x+2)
[[3], [1], ['1'], [10], [5,5]]
> [{a:1,b:2,c:3}, {b:2,a:1,c:0}, {c:5}].group(x => JSON.stringify([x.a, x.b]))
[[{a:1,b:2,c:3},{b:2,a:1,c:0}], [{c:5}]]
> [].group(x=>x)
[]
Scoring criteria:
score = # of characters that replace comment above (lower is better), with easements that:
- whitespace and statement-separating semicolons don't count towards total[2]
- variable names and keywords each count as exactly 1 characters towards total per use[3]; this includes builtins, so
Array.map.apply
would be 5 'characters' (however, builtins count their full length as tiebreakers) - -5 bonus points if
f
being undefined has same result as the identity functionx=>x
- you may modify the construct
function(f) {...}
for recursion/combinator purposes while keeping it as afunction
respecting rule #5, but must subtract from your score the extra characters incurred (i.e. imagine the scoring began earlier)
Disallowances:
- no side-effects which affect anything other than your code (such as modifying
this
,window
, the prototype, etc.); as a corollary, all definitions must stay local to the.group
function (e.g.x=5
would be disallowed, butvar x=5
is fine)
minor notes:
[1] draft specs fine if in any major browser, proprietary extensions fine if in 2+ major browsers;
[2] as long as you don't try to compile a few megabytes-long whitespace ;-)
[3] as long as reflection is not used to abuse code-in-variable-names ;-)
Errata:
Answer may do anything reasonable with regards to sparse arrays. e.g. arr=[1,1]; arr[4]=1; arr
-> [1, 1, empty × 2, 1]
. Possibilities include ignoring them (like .map
and friends do), or treating them as undefined
(like an incremental for-loop would), or anything reasonable. For example arr.group(x=>x)
might return [[1,1],[undefined,undefined],[1]]
, or [[1,1,1]]
, or even more dubious things like [[1,1],null,[1]]
if it makes sense. You may also assume sparse arrays do not exist.
edit: #2 now applies to keywords.
You may find the following snippet useful to estimate score (the rules supercede this snippet though):
var code = `......`;
console.log('score estimate:', code.replace(/\w+/g,'X').replace(/[\s;]/g,'').replace(/X(?=X)/g,'X ').length, '-5?');
Do you mean
Array.prototype.group
instead ofArray.group
? – tsh – 2018-10-13T16:19:33.807Should one just submit the function body or a function (which should assigned to
Array#group
later) or the full shim including assignment? What if one want change the signature of the function? (e.g, function name, more (optional) parameters, default value forf
) – tsh – 2018-10-13T16:21:45.550Yes, I was writing it as shorthand for
Array.prototype.group
. You can change the signature of the function as long as it still conforms to the test cases; for example, adding the parametergroup(f,state) {
will incur a mere -2 penalty to score (since it is 2 'characters' longer, the comma and variable name). Submit whatever seems cleanest. – ninjagecko – 2018-10-13T16:24:59.960You had mentioned that the submission cannot pollute the globalThis (
window
in browser /global
in node). Is pollutethis
valid through? – tsh – 2018-10-13T16:28:28.757No, it is invalid to pollute
this
. Thanks for checking. I should clarify; I will edit the wording of rule #5 since no one has answered this yet. – ninjagecko – 2018-10-13T16:31:54.227Is
group()
operate in-place and returnthis
, or return an new array without modifingthis
? – tsh – 2018-10-13T16:31:57.070@tsh: returns a new array – ninjagecko – 2018-10-13T16:34:30.137
Let us continue this discussion in chat.
– tsh – 2018-10-13T16:36:00.213So as to possibly avoid the need for such clarifications, I'm suggesting using the sandbox next time! :-)
– Erik the Outgolfer – 2018-10-13T19:43:13.927Why does
x => x==x.toUpperCase()
result in[['a','c']..]
thoughx=>x+2
results in[[3], [1]..]
? – guest271314 – 2018-10-13T21:19:25.543