Order a array with distance between items - javascript

I have an array with a lot of items. For clarification, I will use an array of numbers:
[1, 2, 3, 4, 5, 6, 7, 8]
I also have an array with pair of items which should be distant from each other:
[[1, 3], [6, 8], [2, 5]]
I need to random this array, but ensure that this pair of items will have a distance of arr.length - pairs.length (3 on this case) between them.
On this case, some of the correct orders should be:
[1, 6, 4, 2, 3, 8, 7, 5]
[3, 4, 5, 8, 1, 7, 2, 6]
All pair items have a distance of 3+. I need a function to sort the array but follow this rule.
Can someone help me?
I created an algorithm but it isn't working and the loop is not stopping, even with the last value being valid according to the rules
const arr = [1, 2, 3, 4, 5, 6, 7, 8]
const pairs = [[1, 3], [6, 8], [2, 5]]
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
const distance = arr.length - pairs.length
const getDistance = (arr, a, b) => {
return Math.abs(arr.indexOf(a) - arr.indexOf(b))
}
const isValid = (arr) => {
for (const pair of pairs){
if (getDistance(arr, pair[0], pair[1]) < distance){
return false
}
}
return true
}
const similars = {}
for (const pair of pairs){
similars[pair[0]] = pair[1]
similars[pair[1]] = pair[0]
}
shuffleArray(arr)
let index = 0;
while (!isValid(arr)){
const item = arr[index]
if (getDistance(arr, item, similars[item]) < distance){
arr.push(item);
arr.splice(index, 1)
}
else {
index++
}
console.log(arr)
}
console.log(arr)

OK, this is a complicated one. The approach that I give here will top out somewhere between 20 and 30 pairs.
First, let's discuss conceptually what we want to do when choosing an element.
We'll have a freeValues list of values you can use at this point, a freePairs list of pairs we can use, and an upcoming that says when a particular value graduates from upcoming to available (namely after we've reached the right distance). So the idea is:
if decide to use free:
use a random freeValue
else:
pick a random pair
use one of its values, stick the other in upcoming
update upcoming
Using a random value is straightforward, the challenge is the decision.
But we can record the decisions in a simple string. To take your [1, 6, 4, 2, 3, 8, 7, 5] example above, the decisions were ppfpffff.
For the decisions we need to know how many ways there were of completing our permutation if we choose a free choice vs pair. Then we can make random decisions.
Count of how many ways to do a thing strongly suggests using dynamic programming. But actually we need not just counts, we also need some more information. Still we'll use that.
Dynamic programing comes in two flavors, top down and bottom up. Top down is always easier to write - you just write a recursive function and add caching logic to "memoize" it. So we'll do that.
Now what we will actually do is develop an analysis that looks like:
[count of options, further analysis, state]
Our count is just a count. Our further analysis is just a dictionary mapping choices (free/pair) to its own analysis (or undefined at the very end). Our state will be (countFree, countPairs, toFree) where the counts are just counts of freeValues and freePairs, and toFree is a bitpattern of when the other half of pairs come free. So, for example, if toFree was 5 that would represent a value coming free after this entry, none the entry after, and then another the entry after that.
An important note, the state is the state AFTER we make the choice that gets us there, And not before.
Now let's write code for that analysis.
function analyzePattern (values, pairs) {
let countPairs = pairs.length;
let countFree = values.length - 2 * countPairs;
return _analyzePattern(countFree, countPairs, countPairs, 0, {});
}
function _analyzePattern(countFree, countPairs, minDistance, toFree, cache) {
const key = `${countFree} ${countPairs}, ${toFree}`;
const state = [countFree, countPairs, toFree];
if (! cache[key]) {
if (0 == Math.max(countFree, countPairs)) {
if (toFree) {
cache[key] = [0, undefined, state];
}
else {
cache[key] = [1, undefined, state];
}
}
else {
const answer = {};
let total = 0;
if (toFree % 2) {
// We will be adding a free after this.
// Analyze using a free value here.
let result = _analyzePattern(countFree, countPairs, minDistance, toFree>>1, cache);
let countUseFree = result[0] * countFree;
total = countUseFree;
answer['free'] = [countUseFree, result[1], result[2]];
// Analyze using the first of a pair here.
if (countPairs) {
// Mark that there is an upcoming value to free.
toFree += 2**minDistance;
result = _analyzePattern(countFree+1, countPairs-1, minDistance, toFree>>1, cache);
let countUsePair = result[0] * 2 * countPairs;
total += countUsePair;
answer['pair'] = [countUsePair, result[1], result[2]];
}
}
else {
// We will not be adding a free after this.
if (countFree) {
let result = _analyzePattern(countFree-1, countPairs, minDistance, toFree>>1, cache);
let countUseFree = result[0] * countFree;
total = countUseFree;
answer['free'] = [countUseFree, result[1], result[2]];
}
// Analyze using the first of a pair here.
if (countPairs) {
// Mark that there is an upcoming value to free.
toFree += 2**minDistance;
let result = _analyzePattern(countFree, countPairs-1, minDistance, toFree>>1, cache);
let countUsePair = result[0] * 2 * countPairs;
total += countUsePair;
answer['pair'] = [countUsePair, result[1], result[2]];
}
}
cache[key] = [total, answer, state];
}
}
return cache[key];
}
That will produce our analysis. The next tricky bit is turning the analysis into a random pattern of f's and p's making each permutation equally likely. Note that we have to be careful to use the previous state to make the right random choices.
function randomPattern (analysis, state) {
if (!analysis) {
return '';
}
if (! state) {
state = analysis[2];
}
const total = analysis[0];
const remaining = analysis[1];
const nextState = analysis[2];
if (remaining) {
if (remaining['free']) {
const odds = remaining['free'][0] * state[0] / total;
if (Math.random() < odds) {
return 'f' + randomPattern(remaining['free'], state);
}
else {
return 'p' + randomPattern(remaining['pair'], state);
}
}
else {
return 'p' + randomPattern(remaining['pair'], state);
}
}
else {
return '';
}
}
And now we can finish.
function randomPermutation(values, pairs) {
let inPairs = {};
for (p of pairs) {
inPairs[p[0]] = 1;
inPairs[p[1]] = 1;
}
let freeValues = [];
for (v of values) {
if (! inPairs[v]) {
freeValues.push(v);
}
}
let freePairs = Array.from(pairs);
let distance = pairs.length;
let upcoming = {};
const pattern = randomPattern(analyzePattern(values, pairs));
let answer = []
for (c of pattern) {
if (c == 'f') {
let i = Math.floor(freeValues.length * Math.random());
let tmp = freeValues[i];
freeValues[i] = freeValues[freeValues.length-1];
freeValues[freeValues.length-1] = tmp;
answer.push(freeValues.pop())
}
else {
let i = Math.floor(freePairs.length * Math.random());
let tmp = freePairs[i];
freePairs[i] = freePairs[freePairs.length-1];
freePairs[freePairs.length-1] = tmp;
let pair = freePairs.pop();
if (0.5 < Math.random()) {
answer.push(pair[0]);
upcoming[pair[1]] = distance;
}
else {
answer.push(pair[1]);
upcoming[pair[0]] = distance;
}
}
// Now adjust upcoming.
nextUpcoming = {};
for (const [key, value] of Object.entries(upcoming)) {
if (value <= 1) {
freeValues.push(key-0);
}
else {
nextUpcoming[key] = value-1;
}
}
upcoming = nextUpcoming;
}
return answer;
}
And some test code to try it.
const values = [1, 2, 3, 4, 5, 6, 7, 8];
const pairs = [[1, 3], [6, 8], [2, 5]];
for (let i = 0; i < 10; i++) {
console.log(randomPermutation(values, pairs));
}

Related

How to return an array of indexes from the first array which is the intersection of indexes from two sorted arrays?

I wrote a solution that allows me to get an array of indexes from the first array which is the intersection of indexes from two sorted arrays and I'd like to know why this solution is wrong. When I check it I get the correct array of indexes from the first array but the interviewer told me that this is wrong.
Thanks a lot for the help and explanations. I have no commercial experience yet. Sorry for some mistakes in English, as I am from Ukraine and I improve this language.
// first example of input:
// const arr1 = [1, 2, 2, 2];
// const arr2 = [1, 1, 2, 2];
// second example of input:
const arr1 = [1, 2, 2, 3, 4, 5, 6, 7, 9, 9, 20];
const arr2 = [1, 2, 3, 3, 5, 8, 9, 9, 21];
// first example of output:
// - [0, 1, 2]
// - [0, 1, 3]
// - [0, 2, 3]
// second example of output:
// - [0, 1, 3, 5, 8, 9]
// - [0, 2, 3, 5, 8, 9]
//function compareItemsFn, length1, length2 - from conditions to this task
const compareItemsFn = (index1, index2) => {
switch (true) {
case arr1[index1] === arr2[index2]: return 0;
case arr1[index1] < arr2[index2]: return -1;
case arr1[index1] > arr2[index2]: return 1;
default: return undefined;
}
};
const length1 = arr1.length;
const length2 = arr2.length;
// function intersectionIndexes - my solution
function intersectionIndexes(compareItemsFn, length1, length2) {
let indexesIntersectionArray = [];
let i = 0;
let j = 0;
while (i < length1 && j < length2) {
if (compareItemsFn (i, j) === 0) {
indexesIntersectionArray.push(i);
i++;
j++;
} else if (compareItemsFn (i, j) === 1) {
j++;
} else {
i++;
}
}
return indexesIntersectionArray;
};
const result = intersectionIndexes(compareItemsFn, length1, length2);
If you are certain that your solution works then perhaps it was not wrong in the sense that it gave the wrong answer but rather in the way you solved the problem.
The following code is a simplification of your solution. It takes the two arrays as parameters instead of the value of their length property so the solution isn't tied to the global variables arr1 and arr2. You should always favor implementing solutions that are generalised.
In place of your compareItemsFn function, the Math.sign() method from the standard library is used. Some times in interview situations you can be asked to implement functionality which can be found in the standard library and what the interviewer is looking to see is if you are aware of it.
function simplified(arrayOne, arrayTwo) {
let result = [];
let indexOne = 0;
let indexTwo = 0;
while (indexOne < arrayOne.length && indexTwo < arrayTwo.length) {
let signCheck = Math.sign(arrayOne[indexOne] - arrayTwo[indexTwo]);
if (signCheck == 0) {
result.push(indexOne);
indexOne++;
indexTwo++;
}
else if ( signCheck > 0) {
indexTwo++;
}
else {
indexOne++;
}
}
return result;
}

Can this selection sort implementation be made more efficient or elegant?

I have made a basic implementation of Selection sort, using Math.min() of javascript. Can anyone point out ways in which one can make this more efficient or elegant? Something that I could have avoided doing, etc? Thanks everyone, the code is below:
let arr = [2, 0, 5, 1, 3, 2, 6, 4, 9, 0, 10, 2, 14, 8];
function selectionSort(array) {
let workingArr = [...array]; //don't want to modify original array
let sortedArr = []; //this will be returned as result
for (let i = 0; i < array.length; i++) {
let sliced = workingArr.slice(0);
let min = Math.min(...sliced); //minimum of the slice
sortedArr[i] = min;
let index = workingArr.indexOf(min);
workingArr.splice(index, 1);
}
return sortedArr;
}
let x = selectionSort(arr);
console.log(x);
document.body.innerHTML = x;
I am not sure about the definition of selection sort being used here but here you have two versions of your code where: 1) you remove unnecessary copies of arrays (space inefficient) and 2) you have a more elegant solution.
Your original solution optimised
function selectionSort(array) {
const localArr = [...array];
const res = [];
for (let i = 0; i < localArr.length; i++) {
const min = Math.min(...localArr);
localArr.splice(localArr.indexOf(min), 1);
i--;
res.push(min);
}
return res;
}
Use Array.prototype.reduce
function selectionSort(array) {
const localArr = [...array];
return array.reduce((acc) => {
const min = Math.min(...localArr);
localArr.splice(localArr.indexOf(min), 1);
return acc.concat(min);
}, []);
}
Note: in your original version of the function you seemed to care about immutability. Then in the body of the function you use Array.prototype.splice and Array.prototype.push which both contravene the FP principle of immutability. I am not using a pure FP approach here just for brevity but you should look into other arrays methods that are more 'reliable' so to speak.
It seems nobody found anything here. But I finally found something that could have been avoided in original code. I figured out that there is no need to make slices of the array named workingArr in code above (in the question). Here is the modified code which is simpler.
let arr = [2, 0, 5, 1, 3, 2, 6, 4, 9, 0, 10, 2, 14, 8];
function selectionSort(array) {
let workingArr = [...array]; //don't want to modify original array
let sortedArr = []; //this will be returned as result
for (let i = 0; i < array.length; i++) {
//run upto full length of original array
let min = Math.min(...workingArr); //minimum of the slice
sortedArr[i] = min; //minimum found inserted into sortedArr
let index = workingArr.indexOf(min); //find inserted ele's position in original input array's copy, so that we can use it to removed ele from that same array (otherwise in next pass that element will still come out as min)
workingArr.splice(index, 1);
}
return sortedArr; //return resulting array
}
let x = selectionSort(arr);
console.log(x);
console.log(x.reverse()); //for descending sort

How do I filter all items that occur once into one list and all items that occur multiple times into a different one?

I'm currently working on a project but I'm stuck with removing all the duplicates.
I need to remove all the duplicate names and put into a separate file
This is an example of what Im trying to achieve:
So I have an array of numbers (1,2,2,3,3,4,5) and I would like to remove all of the duplicates from the array to result in (1,4,5).
For loop the array and place each value into a hash map that tracks the number of times that number is recorded. Then loop through your hash map and create a new array with only the values that have a record of 1.
const arr = [1, 2, 2, 3, 3, 4, 5];
function removeDuplicates(arr) {
var hashMap = {};
for(let i of arr) {
if(hashMap[i]){
hashMap[i] += 1
} else {
hashMap[i] = 1
}
}
var newArray = [];
for(let [key, value] of Object.entries(hashMap)){
if(value === 1) {
newArray.push(parseInt(key));
} else {
// If you want to do something with values recorded more
// than once, you can do that here.
}
}
return newArray;
}
Without using any external libraries - I am sure there are more concise ways to do it, but this should work:
var numbers = [1, 2, 2, 3, 3, 4, 5];
function removeDuplicates(array) {
var existingValues = []; // Holds all values that exist at least once
var duplicates = []; // Holds all values that are duplicates
array.forEach(function(num) {
if (existingValues.indexOf(num) === -1) {
existingValues.push(num);
} else {
duplicates.push(num);
}
});
// Filter out the values from existingValues that are in the duplicates array
return existingValues.filter(function(i) {
return duplicates.indexOf(i) === -1;
});
}
console.log(removeDuplicates(numbers)); // [1,4,5]
Will the array always be sorted?
no , but that might be something to consider #Thomas
OK, this would have allowed for something like this:
Just looking at the neighbors to determine wether a value is single or has multiple occurances.
const array = [1,2,2,3,3,4,5];
const single = [];
const multiple = [];
for (let i = 0, length = array.length; i < length; ++i) {
let value = array[i];
const isDupe = i > 0 && value === array[i - 1]
|| i + 1 < length && value === array[i + 1];
if (isDupe) {
multiple.push(value);
} else {
single.push(value);
}
}
console.log("singles", single);
console.log("multiple", multiple);
If the data ain't guaranteed to be sorted we need to do a count pass first the check which items are unique in that array and which ones are not. And in a secnd pass we can add them to the result arrays.
const array = [3, 2, 4, 2, 5, 1, 3];
const single = [];
const multiple = [];
const count = {};
for (let i = 0; i<array.length; ++i) {
let value = array[i];
count[value] = (count[value] || 0) + 1;
}
for (let i = 0; i<array.length; ++i) {
let value = array[i];
if (count[value] > 1) {
multiple.push(value);
} else {
single.push(value);
}
}
console.log("singles", single);
console.log("multiple", multiple);
Based on the input you gave: [1, 2, 2, 3, 3, 4, 5] and the fact you said you wanted two outputs: one with the unique values, [1,4,5], and one with duplicates [2,2,3,3].
The below function will give you two arrays as outputs, one with the unique values, and one with the duplicates.
const getUniqueAndDuplicates = (arr) =>{
//use a JavaScript object as a map to count frequency
const map={};
for(let i=0;i<arr.length;i++){
if(map[arr[i]]){map[arr[i]]++;}
else{map[arr[i]]=1;}
}
const uniqueArray=[];
const duplicateArray=[];
for(let key in map){
//get the frequency count
let freq=map[key];
if(freq===1){uniqueArray.push(key);}
else{
for(let i=0;i<freq;i++){
duplicateArray.push(key);
}
}
}
return [uniqueArray,duplicateArray];
}
There's many ways to remove duplication in array. Here's some samples.
Using Set()
Set objects are collections of values. You can iterate through the
elements of a set in insertion order. A value in the Set may only
occur once
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
const duplicated = [1,2,3,2,3,4,3,5];
const uniqSet = new Set(duplicated);
console.log([...uniqSet]) // Should be [1, 2, 3, 4, 5]
Using lodash uniq() method
Document: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
const _ = require('lodash');
const duplicated = [1,2,3,2,3,4,3,5];
const uniq = _.uniq(duplicated);
console.log(uniq) // Should be [1, 2, 3, 4, 5]
Scratch
const duplicated = [1,2,3,2,3,4,3,5];
const uniq = [];
for (const e of duplicated) {
if (!uniq.includes(e)) {
uniq.push(e)
}
}
console.log(uniq) // Should be [1,2,3,4,5]

Algorithm to return all combinations of 3 combinations from a array of length 6 without the number appearing with the same set of numbers

I was trying to write a algorithm in javascript that returns all the possible 3 digit numbers numbers from a given array of length 6
For Example
var arr = [1, 2, 3, 4, 5, 6];
I have already got the combinations with the same sets of numbers in different positions in the 2D array.
(The code which I took the help of)
If I have the same numbers in different combinations then I would like to remove them form the array. like I have [1, 2, 3] at index i in the array comtaining all the possible combinations then I would like to remove other combination with the same numbers like [2, 1, 3], [1, 3, 2] and so on..
Note the array also contains numbers repeated like [3, 3, 3], [2, 2, 2], [3, 2, 3] and so on
I expect an 2d array which has the values : [[1,2,3],[1,2,4],[1,2,5],[1,2,6],[1,3,4]] and so on (24 possibilities)
Is there any way to do this?
Extending the answer you linked, just filter out the results with the help of a Set.
Sort an individual result, convert them into a String using join(), check if it's present in set or not, and if not, then store them in the final result.
function cartesian_product(xs, ys) {
var result = [];
for (var i = 0; i < xs.length; i++) {
for (var j = 0; j < ys.length; j++) {
// transform [ [1, 2], 3 ] => [ 1, 2, 3 ] and append it to result []
result.push([].concat.apply([], [xs[i], ys[j]]));
}
}
return result;
}
function cartesian_power(xs, n) {
var result = xs;
for (var i = 1; i < n; i++) {
result = cartesian_product(result, xs)
}
return result;
}
function unique_cartesian_power(xs, n) {
var result = cartesian_power(xs, n);
var unique_result = [];
const set = new Set();
result.forEach(function(value) {
var representation = value.sort().join(' ');
if (!set.has(representation)) {
set.add(representation);
unique_result.push(value);
}
});
return unique_result;
}
console.log(unique_cartesian_power([1, 2, 3, 4, 5, 6], 3));
const arr = [1, 2, 3, 4, 5, 6];
const result = arr.reduce((a, v) => arr.reduce((a, v2) => {
arr.reduce((a, v3) => {
const current = [v, v2, v3].sort().join(",");
!a.find(_ => _.sort().join() === current) && a.push([v, v2, v3]);
return a;
}, a);
return a;
}, a), []);
console.log(result.length);
console.log(...result.map(JSON.stringify));
You could take an iterative and recursive approach by sorting the index and a temporary array for the collected values.
Because of the nature of going upwards with the index, no duplicate set is created.
function getCombination(array, length) {
function iter(index, right) {
if (right.length === length) return result.push(right);
if (index === array.length) return;
for (let i = index, l = array.length - length + right.length + 1; i < l; i++) {
iter(i + 1, [...right, array[i]]);
}
}
var result = [];
iter(0, []);
return result;
}
var array = [1, 2, 3, 4, 5, 6],
result = getCombination(array, 3);
console.log(result.length);
result.forEach(a => console.log(...a));
.as-console-wrapper { max-height: 100% !important; top: 0; }
This is a good example, that it is usually worthwhile not asking for a specific answer for a generic problem shown with a specific question; however as you've requested - if you really have the above constraints which kind of don't make much sense to me, you could do it like that:
function combine(firstDigits, secondDigits, thirdDigits) {
let result = [];
firstDigits.forEach(firstDigit => {
// combine with all secondDigitPermutations
secondDigits.forEach(secondDigit => {
// combine with all thirdDigitPermutations
thirdDigits.forEach(thirdDigit => {
result.push([firstDigit, secondDigit, thirdDigit])
})
})
});
// now we have all permutations and simply need to filter them
// [1,2,3] is the same as [2,3,1]; so we need to sort them
// and check them for equality (by using a hash) and memoize them
// [1,2,3] => '123'
function hashCombination(combination) {
return combination.join('ಠ_ಠ');
}
return result
// sort individual combinations to make them equal
.map(combination => combination.sort())
.reduce((acc, currentCombination) => {
// transform the currentCombination into a "hash"
let hash = hashCombination(currentCombination);
// and look it up; if it is not there, add it to cache and result
if (!(hash in acc.cache)) {
acc.cache[hash] = true;
acc.result.push(currentCombination);
}
return acc;
}, {result: [], cache: {}})
.result;
}
console.log(combine([1,2,3,4,5,6],[1,2,3,4,5,6],[1,2,3,4,5,6]).length);
console.log(...combine([1,2,3,4,5,6],[1,2,3,4,5,6],[1,2,3,4,5,6]).map(JSON.stringify));
This does not include some super-clever assumptions about some index, but it does abuse the fact, that it's all about numbers. It is deliberately using no recursion, because this would easily explode, if the amount of combinations is going to be bigger and because recursion in itself is not very readable.
For a real world problem™ - you'd employ a somewhat similar strategy though; generating all combinations and then filter them. Doing both at the same time, is an exercise left for the astute reader. For finding combinations, that look different, but are considered to be the same you'd also use some kind of hashing and memoizing.
let arr1 = [1,2,3,4,5,6];
function getCombination(arr){
let arr2 = [];
for(let i=0; i<arr.length; i++){
for(let j=i; j<arr.length; j++){
for(let k=j; k<arr.length; k++){
arr2.push([arr[i],arr[j],arr[k]]);
}
}
}
return arr2;
}
console.log(getCombination(arr1));

JavaScript codewars task

For the past few hours I have been trying to solve one of the CodeWars challenge - but without any luck - so that is the Task -
https://www.codewars.com/kata/554ca54ffa7d91b236000023/train/javascript - link to the task
Task
Given a list lst and a number N, create a new list that contains each number of lst at most N times without reordering. For example if N = 2, and the input is [1,2,3,1,2,1,2,3], you take [1,2,3,1,2], drop the next [1,2] since this would lead to 1 and 2 being in the result 3 times, and then take 3, which leads to [1,2,3,1,2,3].
and that is an example --
Example
deleteNth ([1,1,1,1],2) // return [1,1]
deleteNth ([20,37,20,21],1) // return [20,37,21]
function deleteNth(arr,x){
for (var i = 0; i<arr.length; i++){
for(var j = i+1; j<arr.length; j++){
var crr = 1;
if(arr[i]===arr[j])
crr =+ 1;
while(crr>=x){
arr.splice(arr[j], 1);
crr--;
}
}
return arr;
}
That is my code and idea - As I am a beginner in JS can you give me suggestions and tell me if my idea is good or not. Also I know that i have made some mistakes - so if possible - point them out
totals object will keep a counter for each value of the array.
function deleteNth(arr, x) {
let totals = {};
return arr.filter(o => (totals[o] = ++totals[o] || 0) < x);
}
console.log(deleteNth([1, 1, 1, 1], 2));
console.log(deleteNth([20, 37, 20, 21], 1));
A simple approach will be:
const deleteNth = (lst, N) => {
const res = [];
const countNums = {};
lst.forEach((el, idx) => {
countNums[el] = countNums[el] ? countNums[el] + 1 : 1;
if(countNums[el] <= N) {
res.push(el);
}
})
return res;
}
console.log(deleteNth([1,2,1, 3,1,2,3,3, 5], 2))
result => [ 1, 2, 1, 3, 2, 3, 5 ]

Categories