-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path2) CodeWars.js
More file actions
397 lines (338 loc) · 11.4 KB
/
2) CodeWars.js
File metadata and controls
397 lines (338 loc) · 11.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
//Task 10
//Create the function prefill that returns an array of n elements that all have the same value v.
//See if you can do this without using a loop.
//You have to validate input:
// - v can be anything (primitive or otherwise)
// - if v is ommited, fill the array with undefined
// - if n is 0, return an empty array
// - if n is anything other than an integer or integer-formatted string (e.g. '123') that is >=0, throw a TypeError
//When throwing a TypeError, the message should be n is invalid, where you replace n for the actual value passed to the function.
//Code Examples
// prefill(3,1) --> [1,1,1]
// prefill(2,"abc") --> ['abc','abc']
// prefill("1", 1) --> [1]
// prefill(3, prefill(2,'2d')) --> [['2d','2d'],['2d','2d'],['2d','2d']]
// prefill("xyz", 1) --> throws TypeError with message "xyz is invalid"
function prefill(n, v) {
if(typeof n === 'boolean' || ~~n != n || +n < 0) throw new TypeError(n + " is invalid");
n = parseInt(n, 10);
let arr = [];
arr.length = n;
arr[n - 1] = "";
return arr.fill(v);
}
//Task 11
//Checking for palidromes
function palindrome(str) {
str = str.replace(/[\W_]/g, "").toLowerCase().split("");
// we include underscore because \W excludes it
// see what it is equivalent to; that would be [^A-Za-z0-9_]; alternative: /[^A-Za-z0–9]/g
return str.join("") === str.reverse().join("");
}
//alternative
function palindrome(str) {
var re = /[^A-Za-z0-9]/g;
str = str.toLowerCase().replace(re, '');
var len = str.length;
for (var i = 0; i < len/2; i++) {
if (str[i] !== str[len - 1 - i]) {
return false;
}
}
return true;
}
//Task 12
//do note the use of spread operator here
const lostSheep = (f,s,t) => t - [...f,...s].reduce((a,b) => a + b,0);
lostSheep([12, 20, 30], [1,2,3], 120);
//Task 13
// Your goal in this kata is to implement a difference function, which subtracts
// one list from another and returns the result.
// It should remove all values from list a, which are present in list b.
// array_diff([1,2],[1]) == [2]
// If a value is present in b, all of its occurrences must be removed from
// the other:
// array_diff([1,2,2,2,3],[2]) == [1,3]
// beware stupid solution below!!!
function array_diff(a, b) {
for(let i = 0; i < a.length; i++) {
for(let j = 0; j < b.length; j++) {
if(a[i] === b[j]) {
a.splice(i, 1);
i = -1; //do note that we have to set i to -1 to be able to access the 0 element
}
}
}
return a;
}
// good
function array_diff(a, b) {
return a.filter((val) => {
return b.every((v) => val !== v);
});
}
//alt good
function array_diff(a, b) {
return a.filter((val) => b.indexOf(val) === -1);
}
//Task 14
// Baby is getting his frst tooth. This means more sleepless nights, but with the fun of feeling round his gums and trying to guess which will be first out!
// Probably best have a sweepstake with your friends - because you have the best chance of knowing. You can feel the gums and see where the raised bits are - most raised, most likely tooth to come through first!
// Given an array of numbers (t) to represent baby's gums, you need to return the index of the lump that is most pronounced.
// The most pronounced lump is the one that has the biggest differential to its surrounding values. e.g.:
// [1, 2, 4] = 2
// index 0 has a differential of -1 to its right (it is lower so the figure is negative)
// index 1 has a differential of +1 to its left, and -2 to its right. Total is -1.
// index 2 has a differential of +2 to its left, and nothing to its right,
// If there is no distinct highest value (more than one occurence of the largest differential), return -1.
function firstTooth(t = []) {
let previous = 0;
let vals = 0;
let diff = [];
for(let i = 0; i < t.length; i++) {
if(t[i+1]) {
vals = t[i] - t[i+1];
diff.push(previous + vals);
previous = vals * (-1);
} else {
diff.push(previous);
}
}
// NEVER EVER DO ANY CHANGES TO ARRAYS WITHOUT SLIIIIIIIIIIIIIIIIIIIIIIIICE!!!!!!!!!!!!!!!!!!
const diffOrd = diff.slice().sort((a, b) => a - b);
let lens = diffOrd.length - 1;
return (diffOrd[lens] !== diffOrd[lens - 1])? diff.indexOf(diffOrd[lens]) : -1;
}
// alternative
function firstTooth(t) {
var d = t.map((v,i) => (i ? v-t[i-1] : 0)+(i!=t.length-1 ? v-t[i+1] : 0));
var m = Math.max.apply(null, d);
return d.filter(v => v==m).length!=1 ? -1 : d.findIndex(v => v==m);
}
//Task 15
// We want to create a function, which returns an array of functions, which return their index in the array.
// For better understanding, here an example:
// var callbacks = createFunctions(5); // create an array, containing 5 functions
// callbacks[0](); // must return 0
// callbacks[3](); // must return 3
// We already implemented that function, but when we actually run the code, the result doesn't look like what we expected.
// Can you spot, what's wrong with it? A test fixture is also available
function createFunctions(n) {
var callbacks = [];
for (var i=0; i<n; i++) {
let ises = i; //let being used here is definetely the only reason this solution passes
callbacks.push(function() {
return ises;
});
}
return callbacks;
}
//do note, however, how easily we could fix that if we were to just replace var x to let x in the for loop
function createFunctions(n) {
var callbacks = [];
for (let i=0; i<n; i++) { //the original example had 'vari=0;' here
callbacks.push(function() {
return i;
});
}
return callbacks;
}
//here is the original:
// function createFunctions(n) {
// var callbacks = [];
// for (var i=0; i<n; i++) {
// callbacks.push(function() {
// return i;
// });
// }
// return callbacks;
// }
//alternative:
function createFunctions(n) {
var callbacks = [];
var factory = function(x){
return function(){
return x;
};
};
for (var i=0; i<n; i++) {
callbacks.push(factory(i));
}
return callbacks;
}
//alternative with IIFE
function createFunctions(n) {
var callbacks = [];
for (var i=0; i<n; i++) {
var oneCall = (function(x) {
return function() {
return x;
}
})(i);
callbacks.push(oneCall);
}
return callbacks;
}
//Task 16
// Function composition is a mathematical operation that mainly presents itself in lambda calculus and computability.
// It is explained well here, but this is my explanation, in simple mathematical notation:
// f3 = compose( f1 f2 )
// Is equivalent to...
// f3(a) = f1( f2( a ) )
// Your task is to create a compose function to carry out this task, which will be passed two functions or lambdas.
// Ruby functions will be passed, and should return, either a proc or a lambda.
// Remember that the resulting composed function may be passed multiple arguments!
// compose(f , g)(x)
// => f( g( x ) )
// This kata is not available in haskell; that would be too easy!
// const add1 = function(a){return a + 3};
// const add2 = function(a){return a - 1};
// const add3 = function(a){return a};
// const add4 = function(a, b, c){return a + b - c};
// console.log(compose(add1, add2, add3, add4)(2,3,4)); //expected output 3
// My Solution
function compose(...args) {
return function(...num) {
if(args.length === 0) {
return num[0];
}
const len = args.length - 1;
let result = args[len](...num);
for(let i = len; i > 0; i--) {
result = args[i-1](result);
}
return result;
};
}
// Alternatives ( both work with only 2 functions )
function compose(f, g) {
return (...args) => f(g(...args));
}
function compose(f, g) {
return function() {
return f(g.apply(null, arguments));
};
}
//the last one can be rewritten like so
// function compose(f, g) {
// return function(...args) {
// return f(g(...args));
// };
// }
// More Alternatives ( all work with 2+ functions)
function compose(...args) {
return function(num) {
args.reverse().forEach((val) => num = val(num));
return num;
}
}
const compose = (...fns) => arg => fns.reduceRight((res, fn) => fn(res), arg);
//Task 17
// Array.prototype.length will give you the number of top-level elements in an array.
// Your task is to create a function deepCount that returns the number of ALL elements within an array,including any within inner-level arrays.
// For example:
// deepCount([1, 2, 3]);
// //>>>>> 3
// deepCount(["x", "y", ["z"]]);
// //>>>>> 4
// deepCount([1, 2, [3, 4, [5]]]);
// //>>>>> 7
// The input will always be an array.
const deepCount = function(arrays) {
let count = 0;
const result = function name(arr) {
count += arr.length;
for(let i = 0; i < arr.length; i++) {
if(typeof arr[i] === "object") {
name(arr[i]);
}
}
return count;
}
return result(arrays);
};
//alternatives
function deepCount(a){
let count = a.length;
for (let i=0; i<a.length; i++) if (Array.isArray(a[i])) count += deepCount(a[i]);
return count;
}
function deepCount(a){
return a.reduce((s,e)=>s+(Array.isArray(e)?deepCount(e):0),a.length);
}
//Task 18
// Reversing A String
// One of my co-workers recently told me about a whiteboard question that he’d been asked in an
// interview, and I thought it was kind of a fun problem.
// Write a function that accepts a string a reverses it. Recursively.
function reverse( str ) {
if ( str.length <= 1 ) {
return str;
}
return reverse( str.substr( 1 ) ) + str[ 0 ];
}
//Task 19
//create a function that turns an array of numbers into an array where each value is the sum of all the other numbers
// [1,2,3] => [5,4,3] (1: 2 + 3; 2: 1 + 3; 3: 1 + 2)
function sumOfOther(arr = []) {
const result = arr.map((v, i, a) => a.slice().reduce((t,v,ind) => t += ind !== i ? v : 0, 0));
// do note what happens in the line above t += ind !== i ? v : 0
// first we check whether ind is not equal to i or not. If it is not we add v to t or else we add 0 to t
return result;
}
//Task 20
// create a function that takes arguments until u pass another function as an argument. As soon as a function is passed as an argument
// return the result of that function being implemented with each of the previously passed arguments
const make = (function() {
let result;
let argsList = [];
return function name(...args) {
if(typeof args[0] === "function") {
result = argsList.reduce(args[0]);
argsList = [];
return result;
} else {
argsList.push(...args);
return name;
}
}
})();
function add(a, b) {
return a + b;
}
function extract(a, b) {
return a - b;
}
function multiply(a, b) {
return a * b;
}
function division(a, b) {
return a / b;
}
console.log(make(15)(34, 24, 777)(41)(add)); //891
console.log(make(100)(10, 10, 10)(2, 3, 3, 2, 3)(7)(10)(extract)); //40
console.log(make(2)(2,2)(multiply)); //8
console.log(make(120)(2)(10)(3, 1, 2)(0.5, 1)(division)); //2
// another proposed alternative man
const make = function(...fArgs) {
return (function name(args){
const memory = args;
return function(...newArgs) {
if(newArgs[0] instanceof Function) {
const fn = newArgs[0];
const neededArity = fn.length - 1;
if(neededArity === 0) throw new Error('Shouldn\'t be a unary Function!!!');
const argsComp = [memory.shift()];
let i = 0;
while(memory[((i + 1) * neededArity) - 1]) {
argsComp.push(memory.slice(i * neededArity, (i + 1) * neededArity));
i += 1;
}
return argsComp.reduce((t, v) => fn(t, ...v));
} else {
const local = [...memory, ...newArgs];
return name(local);
}
};
})(fArgs);
};