selection sort in javascript via Khan Academy - javascript

I am not sure what Im doing wrong in my code, but it sorts the numbers correctly, but also leaves this output:
Array after sorting: ,,,,,,,7,,9,,11,,,,,,,,,,,22,,,,,,,,,,,,,,,,,,,,42,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,88,,,,,,,,,,,99
Please help me troubleshoot my code!
var swap = function(array, firstIndex, secondIndex) {
var temp = array[firstIndex];
array[firstIndex] = array[secondIndex];
array[secondIndex] = temp;
};
var indexOfMinimum = function(array, startIndex) {
var minValue = array[startIndex];
var minIndex = startIndex;
for(var i = minIndex + 1; i < array.length; i++) {
if(array[i] < minValue) {
minIndex = i;
minValue = array[i];
}
}
return minIndex;
};
var selectionSort = function(array) {
var length = array.length;
for(var i = 0; i < length; i++){
var min = indexOfMinimum(array,array[i]);
swap(array, i, min);
}
};
var array = [22, 11, 99, 88, 9, 7, 42];
selectionSort(array);
println("Array after sorting: " + array);
Program.assertEqual(array, [7, 9, 11, 22, 42, 88, 99]);

You don't want the value at index i, you just want i itself.
var min = indexOfMinimum(array, array[i]);
should be
var min = indexOfMinimum(array, i);

var selectionSort = function(array) {
var length = array.length;
for(var i = 0; i < length; i++){
var min = indexOfMinimum(array,i);
swap(array, i, min);
}
}

Try this:
var selectionSort = function(array) {
var minIdx;
for(var i = 0; i < array.length - 1; i++){
minIdx = indexOfMinimum(array, i);
swap(array, minIdx, i);
}
return array;

Related

Reverse whole string while keeping the spaces at the same position

This is the code I have tried. If we input "We are farmers!" it should return "!s rem raferaeW" however the code I have returns "!s remr aferaeW"
function reverseStr(input){
var array1 = [];
var array2 = [];
var nWord;
for (var i = 0; i < input.length; i++) {
array1.push(input[i]);
}
var spaces = [];
for (var i = 0; i < array1.length; i++) {
if(array1[i] == " ") {
spaces.push(i);
}
}
console.log(array1);
console.log(spaces);
array2 = array1.slice().reverse();
var spaces2 = [];
for (var i = 0; i < array1.length; i++) {
if(array2[i] == " ") {
spaces2.push(i);
}
}
console.log(spaces2);
for (var i = spaces2.length - 1; i >=0; i--) {
array2.splice(spaces2[i], 1);
}
console.log(array2);
nWord = array2.join('');
console.log(nWord);
var array3 = [];
for (var i = 0; i < nWord.length; i++) {
array3.push(nWord[i]);
}
console.log(array3);
for (var i = spaces.length - 1; i >=0; i = i - 1) {
array3.splice(spaces[i], 0, " ");
}
console.log(array3);
var anWord = array3.join('');
return anWord;
}
var input = "We are farmers!";
reverseStr(input);
First I pushed each letter of the input into an array at "array1". Then I made an array for the indexes of the spaces of "array1" called "spaces."
Then "array2" is an array of "array1" reversed.
Then "spaces2" is an array of the indexes for "array2" and then I used a for loop to splice out the spaces in array2. Then "nWord" is "array2" combined to form a new word.
Then "array3" is an array for all of nWord's letters and I used a reverse for loop for try to input spaces into "array3" and using the indexes of the "spaces" array. Unfortunately, it is not returning "!s rem raferaeW" and IS returning "!s remr aferaeW".
I am trying to know how I can use the indexes of the "spaces" array to create spaces in "array3" at indexes 2 and 7.
You just need to make following change
//for (var i = spaces.length - 1; i >=0; i = i - 1) {
// array3.splice(spaces[i], 0, " ");
//}
for (var i = 0; i < spaces.length; i = i + 1) {
array3.splice(spaces[i], 0, " ");
}
You are reading spaces array in reverse but as the problem stated spaces should be at same place. Reading it from start to finish fixed the issue.
function reverseStr(input){
var array1 = [];
var array2 = [];
var nWord;
for (var i = 0; i < input.length; i++) {
array1.push(input[i]);
}
var spaces = [];
for (var i = 0; i < array1.length; i++) {
if(array1[i] == " ") {
spaces.push(i);
}
}
console.log(array1);
console.log(spaces);
array2 = array1.slice().reverse();
var spaces2 = [];
for (var i = 0; i < array1.length; i++) {
if(array2[i] == " ") {
spaces2.push(i);
}
}
console.log(spaces2);
for (var i = spaces2.length - 1; i >=0; i--) {
array2.splice(spaces2[i], 1);
}
console.log(array2);
nWord = array2.join('');
console.log(nWord);
var array3 = [];
for (var i = 0; i < nWord.length; i++) {
array3.push(nWord[i]);
}
console.log(array3);
//for (var i = spaces.length - 1; i >=0; i = i - 1) {
// array3.splice(spaces[i], 0, " ");
//}
for (var i = 0; i < spaces.length; i = i + 1) {
array3.splice(spaces[i], 0, " ");
}
console.log(array3);
var anWord = array3.join('');
return anWord;
}
var input = "We are farmers!";
reverseStr(input);
Here is my best crack at it.
const reverseStr = (input) => {
const revArr = input.replaceAll(' ', '').split('').reverse();
for (let i = 0; i < revArr.length; i++) {
if (input[i] === ' ') revArr.splice(i, 0, ' ');
}
return revArr.join('');
}
let words="Today Is A Good Day";
let splitWords=words.split(' ')
console.log(splitWords)
let r=[]
let ulta=splitWords.map((val,ind,arr)=>{
// console.log(val.split('').reverse().join(''))
return r.push(val.split('').reverse().join(''))
})
console.log(r.join(' '))

JavaScript - find the same first element using for loop

I've got to create var with few elements:
var arrNum = [4,7,5,3,4,5,6,7,8,10]
I need to find first number that is the same in array using for loop. So it will be "4" and "4"
I need to create var sameIndex and adjust the same number to sameIndex and print after for loop
So I did loop
for(var i = 0; i < arrNum.length; i++){
console.log("")
console.log("Loop number is " + i)
if(arrNum[i] === arrNum[i]{
break
sameIndex = going[i]
}
}
console.log(sameIndex)
It's not working.
One way would be to use Array#indexOf. It returns the first index of the given element in the array:
var arrNum = [4, 7, 5, 3, 4, 5, 6, 7, 8, 10];
var i;
var sameIndex = -1;
for (i = 0; i < arrNum.length; i++) {
if (arrNum.indexOf(arrNum[i]) !== i) {
console.log('This is the second occurrence of', arrNum[i]);
sameIndex = arrNum.indexOf(arrNum[i]);
break;
}
}
console.log('The indices are', sameIndex, 'and', i);
If you're looking to get the first duplicate, then use :
var arrNum = [4,7,5,3,4,5,6,7,8,10];
function firstDuplicate(array){
var history = [];
for(var element of array){
if(history.indexOf(element)<0)
//not in the history yet
history.push(element);
else
return element;
}
return null; //or any distinctive value
}
var fDup = firstDuplicate(arrNum);
You could take a hash table and display the value.
var array = [4, 7, 5, 3, 4, 5, 6, 7, 8, 10],
hash = Object.create(null),
i;
for (i = 0; i < array.length; i++) {
if (hash[array[i]]) {
console.log('first dupe: ' + array[i]);
break;
}
hash[array[i]] = true;
}
A working script:
var arrNum = [4,7,5,3,4,5,6,7,8,10];
var sameIndex = -1, going = new Array();
for(var j = 0; j < arrNum.length; j++) {
for(var i = 1; i < arrNum.length; i++){
console.log("Loop number is " + j + ", " + i)
if(arrNum[i] === arrNum[j]){
sameIndex = i;
break;
}
}
if(sameIndex > 0) {
console.log(j, sameIndex)
break;
}
}
var arrNum = [4,7,5,3,4,5,6,7,8,10];
for(var i = 0; i < arrNum.length; i++){
for(var j = i+1; j < arrNum.length; j++) {
if(arrNum[i] === arrNum[j]) {
console.log('value: '+arrNum[i]+' index1: '+i+' index2: '+j);
}
}
}
Iterate over the original array and if the value is not in a comparison array - push it into a common numbers array. The first item in that common numbers array is the target.
var origArray = [4,7,5,3,4,5,6,7,8,10];
var newArray = [];
var commonNums = [];
origArray.forEach(function(item,i) {
newArray.indexOf(item) == -1
? newArray.push(item)
: commonNums.push({item: item, index:i});
})
if(commonNums.length > 0) {
var firstCommonNum = commonNums[0].item;
var firstCommonNumIndex = commonNums[0].index;
console.log("common number " + firstCommonNum);
console.log("Loop number is " + firstCommonNumIndex);
}

Output the sorted array to main element

I am new to javascript and working with DOM, so please bear with me.
I have an array called num that I want to sort and display. The sort is a selection sort that returns the number of moves it took.
I can display the unsorted array but can't figure out how to call my sort function and then display the sorted array to the screen. My code is below:
function fn(a, b) {
if (a < b)
return true;
}
function selection(list, fun) {
var min, temp, count,
len = list.length;
for (var i = 0; i < len; i++) {
min = i;
for (var j = i + 1; j < len; j++) {
if (fun(list[j], list[min])) {
min = j;
}
}
temp = list[i];
list[i] = list[min];
listlist
list[min] = temp;
count += 3;
}
return count;
}
var num = [10, 1, 3, 5, 2, 9, 8, 6, 7, 4];
var demoP = document.getElementById("content");
{
var html = "";
html += "Original:" + num + "<br>";
selection(num, fn);
html += "Sorted:" + num + "<br>";
}
demoP.innerHTML = html;
<div id="content"></div>
arr is undefined, you should use list instead. Returning count returns the number of operations (after it's been initialized), return list instead. And as list is local to the function, you need to set num to the return value of the function call.
<span id='content'/>
<script>
function fn(a, b) {
if (a < b)
return true;
}
function selection(list, fun) {
var min, temp, count=0,
len = list.length;
for (var i = 0; i < len; i++) {
min = i;
for (var j = i + 1; j < len; j++) {
if (fun(list[j], list[min])) {
min = j;
}
}
temp = list[i];
list[i] = list[min];
list[min] = temp;
count += 3;
}
return list;
}
var num = [10, 1, 3, 5, 2, 9, 8, 6, 7, 4];
var demoP = document.getElementById("content");
var html = "";
html += "Original:" + num + "<br>";
num= selection(num, fn);
html += "Sorted:" + num + "<br>";
demoP.innerHTML = html;
</script>

swap array elements in nested loop with delay

I wanna my divs to be sorted but in this code it only goes through for loop once. How can i make this to end both loops and my divs sorted?
var arr = [4, 7, 1, 9, 8, 13, 6, 11];
function showarray() {
for (var i = 0; i < arr.length; i++) {
var divSort = document.createElement("div");
divSort.style.width = 30 + "px";
divSort.style.height = 30 + "px";
divSort.style.background = "yellow";
divSort.style.display = "inline-block";
divSort.style.margin = "10px";
divSort.id = arr[i];
divSort.innerHTML = arr[i];
document.body.appendChild(divSort);
}
}
showarray();
function func() {
for (var j = (arr.length - 1); j >= 0; j--) {
for (var i = 1; i <= j; i++) {
if (arr[i] < arr[i - 1]) {
doSetTimeout(i, j);
};
};
}
function doSetTimeout(i, j) {
setTimeout(function() {
$("#" + arr[i]).insertBefore("#" + arr[i - 1]);
}, j * i * 100);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="func()">Click</button>
It looks like you are only iterating one time because you aren't changing the array indexes, you are just updating the div positions, so everytime you iterate the array, it hasn't changed (just your divs). So you are always iterating the same array, doing the same changes over and over again. You need to change the array values and also change the div positions:
var arr = [4, 7, 1, 9, 8, 13, 6, 11];
var counter = 0;
function showarray() {
for (var i = 0; i < arr.length; i++) {
var divSort = document.createElement("div");
divSort.style.width = 30 + "px";
divSort.style.height = 30 + "px";
divSort.style.background = "yellow";
divSort.style.display = "inline-block";
divSort.style.margin = "10px";
divSort.id = arr[i];
divSort.innerHTML = arr[i];
document.body.appendChild(divSort);
}
}
showarray();
function func() {
for (var j = arr.length; j > 0; j--) {
for (var i = 0; i < (arr.length-1); i++) {
if (arr[i] > arr[i + 1]) {
swap(i+1, i);
}
};
}
function swap(smaller, bigger) {
var tmpBigger = arr[bigger];
var tmpSmaller = arr[smaller];
arr[bigger] = tmpSmaller
arr[smaller] = tmpBigger;
setTimeout(function() {
$("#" + tmpSmaller).insertBefore("#" + tmpBigger);
}, ++counter * 500);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="func()">Click</button>

Return Sorted Array Without Modifying Original Array

I'm having trouble with a function returning the original array as opposed to the sorted array. I tried to slice the array and return the sorted but it is not working. Any ideas on how to fix this?
function sortArr( comparator, array ){
var newArray = array.slice();
for(var i = 0; i < newArray.size; i++)
{
var min = i;
for(var x = i; x < newArray.size; x++)
{
if(comparator(newArray[min],newArray[x]) == true)
{
min = x;
}
}
var temp = newArray[i];
newArray[i] = newArray[min];
newArray[min] = temp;
}
return newArray;
}
I fixed the function:
function sortArr( comparator, array ){
/*your code here*/
var i, x;
var min;
var newArray = array.slice();
for(i = 0; i < newArray.length - 1; i++)
{
min = i;
for(x = i + 1; x < newArray.length; x++)
{
if(comparator(newArray[min],newArray[x]) == true)
{
min = x;
}
}
if(min != i){
var temp = newArray[i];
newArray[i] = newArray[min];
newArray[min] = temp;
}
}
return newArray;
}
Copy the array with slice and then use native sort:
function sortArr(comparator, array) {
return array.slice().sort(function(a,b) {
return comparator(a,b) * 2 - 1;
});
}
Your sorting algorithm doesn't look quite right. For a start the swapping of values should be inside the if statement. I would also advise to look at #Oriol's solution which is far more elegant.
function sortArr( comparator, array ){
var newArray = array.slice();
for(var i = 0; i < newArray.size; i++)
{
var min = i;
for(var x = i; x < newArray.size; x++)
{
if(comparator(newArray[min],newArray[x]) == true)
{
var temp = newArray[i];
newArray[i] = newArray[min];
newArray[min] = temp;
min = x;
}
}
}
return newArray;
}
{"index.js":"var globalArray = [5, 6, 3, 2, 9];
function nonMutatingSort(arr) {
let newArr = globalArray.slice();\n let emptyArr = [];
return emptyArr.concat(newArr).sort();
}
nonMutatingSort(globalArray);"}

Categories