Skip to content

Add Pancake Sort to the sorting algorithms #800

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions Sorts/PancakeSort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Unlike a traditional sorting algorithm, which attempts to sort with the fewest
* comparisons possible, the goal of pancake sort is to sort the sequence in as few reversals as
* possible. The idea is to do something similar to Selection Sort. We one by one place
* maximum element at the end and reduce the size of current array by one.
*
* Source: https://www.geeksforgeeks.org/pancake-sorting/
*
* This sorting algorithm is inspired by the pancake problem (hence the name),
* where a spatula can be placed anywhere between two pancakes and flip all pancakes
* above.
*
* The interesting about this algorithm (besides its name) is that instead of comparisons,
* the algorithm relies on flipping an array.
*
* Source: https://en.wikipedia.org/wiki/Pancake_sorting#The_original_pancake_problem
*
*/

/**
* Unlike Array.prototype.reverse, flipArray reverses only a subarray of the given
* array, determined by the parameters startIndex and endIndex
*
* @param {number[]} array The array to flip
* @param {number} startIndex The start of the subarray
* @param {number} endIndex The end of the subarray
* @returns The flipped array
*/
export function flipArray(array, startIndex, endIndex) {
while (startIndex < endIndex) {
// swap front and back of the subarray
const temp = array[startIndex]
array[startIndex] = array[endIndex]
array[endIndex] = temp

// essentialy reducing the problem to a smaller subarray
startIndex++
endIndex--
}

return array
}

/**
* Returns the index of the maximum number of a subarray in a given array
*
* @param {number[]} array The array to found the maximum number's index
* @param {*} startIndex The start of the subarray
* @param {*} endIndex The end of the subarray
* @returns The index of the maximum number
*/
export function findMax(array, startIndex, endIndex) {
let maxIndex = 0
for (let i = startIndex; i <= endIndex; i++) {
if (array[i] > array[maxIndex]) maxIndex = i
}

return maxIndex
}

/**
* The Pancake Sort algorithm.
*
* Note that even though it's a completely different concept of sorting an
* array, it's rather simple!
*
* @param {number[]} array The array to sort
* @returns The sorted array
*/
export function pancakeSort(array) {
for (let subarraySize = array.length; subarraySize > 1; subarraySize--) {
const maximumIndex = findMax(array, 0, subarraySize - 1)

if (maximumIndex !== subarraySize - 1) {
flipArray(array, 0, maximumIndex)
flipArray(array, 0, subarraySize - 1)
}
}

return array
}
24 changes: 24 additions & 0 deletions Sorts/test/PancakeSort.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { flipArray, findMax, pancakeSort } from '../PancakeSort'

describe('flipArray', () => {
it('should flip any subarray of any array', () => {
expect(flipArray([1, 2, 3, 4], 0, 3)).toEqual([4, 3, 2, 1])
expect(flipArray([1, 2, 3, 4, 5], 2, 4)).toEqual([1, 2, 5, 4, 3])
expect(flipArray([], 0, 0)).toEqual([])
})
})

describe('findMax', () => {
it('should find the index of the maximum value in any subarray of any array', () => {
expect(findMax([1, 3, 2, 5], 0, 3)).toEqual(3)
expect(findMax([1, 3, 2, 5], 0, 2)).toEqual(1)
})
})

describe('pancakeSort', () => {
it('should sort any array', () => {
expect(pancakeSort([4, 3, 2, 1])).toEqual([1, 2, 3, 4])
expect(pancakeSort([3, 1, 4, 2])).toEqual([1, 2, 3, 4])
expect(pancakeSort([100, 1000, 10, 1])).toEqual([1, 10, 100, 1000])
})
})