├── .gitattributes ├── .gitignore ├── README.md ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── main └── kotlin │ ├── algos │ ├── arrays │ │ ├── BinarySearch.kt │ │ ├── CaesarCipher.kt │ │ ├── Fibonacci.kt │ │ ├── Palindrome.kt │ │ ├── Pivot.kt │ │ ├── ProductSum.kt │ │ ├── SmallestDifference.kt │ │ ├── TheeLargestNumbers.kt │ │ ├── TwoNumberSum.kt │ │ └── sorting │ │ │ ├── BubbleSort.kt │ │ │ ├── InsertionSort.kt │ │ │ ├── MergeSort.kt │ │ │ ├── QuickSort.kt │ │ │ ├── SelectionSort.kt │ │ │ └── ThreeNumberSum.kt │ ├── graph │ │ └── DFS.kt │ └── trees │ │ ├── BranchSum.kt │ │ └── bst │ │ └── ClosestValue.kt │ └── ds │ ├── graph │ └── Tree.kt │ └── linkedlist │ └── DoublyLinkedList.kt └── test └── kotlin └── algos └── arrays └── PivotTest.kt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IntelliJ 2 | .idea/ 3 | /out/ 4 | *.iml 5 | 6 | # Java class files 7 | *.class 8 | 9 | # Generated files 10 | bin/ 11 | gen/ 12 | out/ 13 | 14 | # Gradle files 15 | .gradle/ 16 | build/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Algos and data structures from around the world in Kotlin -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.71' 3 | 4 | repositories { 5 | mavenCentral() 6 | } 7 | dependencies { 8 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 9 | } 10 | } 11 | 12 | apply plugin: 'java' 13 | apply plugin: 'kotlin' 14 | 15 | sourceCompatibility = 1.8 16 | 17 | repositories { 18 | mavenCentral() 19 | } 20 | 21 | dependencies { 22 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 23 | testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" 24 | testCompile group: 'junit', name: 'junit', version: '4.12' 25 | } 26 | 27 | compileKotlin { 28 | kotlinOptions.jvmTarget = "1.8" 29 | } 30 | compileTestKotlin { 31 | kotlinOptions.jvmTarget = "1.8" 32 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esoxjem/Algorithms/375097050f4649eeb6cd9d72aae3b5824ca47d91/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed May 30 06:45:17 IST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'algorithms' 2 | 3 | -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/BinarySearch.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays 2 | 3 | class BinarySearch { 4 | 5 | /** 6 | * Time: O(log(n)) 7 | * Space: O(log(n)) 8 | */ 9 | fun search(arr: Array, target: Int): Int { 10 | return search(arr, 0, arr.lastIndex, target) 11 | } 12 | 13 | private fun search(arr: Array, start: Int, end: Int, target: Int): Int { 14 | if (start > end) { 15 | return -1 16 | } 17 | val mid = (start + end) / 2 18 | 19 | return when { 20 | arr[mid] == target -> mid 21 | mid < target -> search(arr, mid + 1, end, target) 22 | else -> search(arr, start, mid - 1, target) 23 | } 24 | } 25 | 26 | /** 27 | * time: O(log(n)) 28 | * space: O(1) 29 | */ 30 | fun searchIterative(arr: Array, target: Int): Int { 31 | var left = 0 32 | var right = arr.lastIndex 33 | 34 | while (left <= right) { 35 | val mid = (left + right) / 2 36 | when { 37 | arr[mid] == target -> return mid 38 | arr[mid] < target -> left = mid + 1 39 | else -> right = mid - 1 40 | } 41 | } 42 | 43 | return -1 44 | } 45 | } 46 | 47 | fun main(args: Array) { 48 | val arr = arrayOf(1, 2, 4, 10, 22) 49 | 50 | val bs = BinarySearch() 51 | println("index: " + bs.search(arr, 10)) 52 | println("index: " + bs.search(arr, 12)) 53 | 54 | println("index: " + bs.searchIterative(arr, 22)) 55 | println("index: " + bs.searchIterative(arr, 25)) 56 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/CaesarCipher.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays 2 | 3 | /** 4 | * 5 | * Given a non-empty string of lowercase letters and a non-negative integer 6 | * representing a key, write a function that returns a new string obtained by 7 | * shifting every letter in the input string by k positions in the alphabet, 8 | * where k is the key. 9 | * 10 | * Note that letters should "wrap" around the alphabet; in other words, the 11 | * letter shifted by one returns the letter 12 | */ 13 | class CaesarCipher { 14 | 15 | fun encrypt(string: String, key: Int): String { 16 | val arr = Array(string.length) { '-' } 17 | val newKey = key % 26 18 | 19 | string.forEachIndexed { index, c -> 20 | val ascii = c.toInt() 21 | val shifted = ascii + newKey 22 | 23 | val encrypted = if (shifted > 'z'.toInt()) { 24 | shifted - 26 25 | } else { 26 | shifted 27 | } 28 | 29 | arr[index] = encrypted.toChar() 30 | } 31 | 32 | return arr.contentToString() 33 | } 34 | } 35 | 36 | fun main() { 37 | println(CaesarCipher().encrypt("abc", 1)) 38 | println(CaesarCipher().encrypt("xyz", 1)) 39 | println(CaesarCipher().encrypt("xyz", 27)) 40 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/Fibonacci.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays 2 | 3 | class Fibonacci { 4 | 5 | fun nthFib(n: Int): Int { 6 | if(n == 0) return 0 7 | if(n == 1) return 1 8 | 9 | return nthFib(n-1) + nthFib(n-2) 10 | } 11 | 12 | } 13 | 14 | fun main(args: Array) { 15 | val fib = Fibonacci() 16 | 17 | val n = fib.nthFib(0) 18 | println("fib: $n") 19 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/Palindrome.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays 2 | 3 | class Palindrome { 4 | fun isPalindrome(str: String): Boolean { 5 | var start = 0 6 | var end = str.lastIndex 7 | 8 | while (start <= end) { 9 | if (str[start] != str[end]) { 10 | return false 11 | } 12 | start++ 13 | end-- 14 | } 15 | return true 16 | } 17 | } 18 | 19 | fun main() { 20 | val str = "malayalam" 21 | println(Palindrome().isPalindrome(str)) 22 | 23 | val str2 = "abcdefdcba" 24 | println(Palindrome().isPalindrome(str2)) 25 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/Pivot.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays 2 | 3 | 4 | /* 5 | Given an array of integers nums, write a method that returns the "pivot" index of this array. 6 | 7 | We define the pivot index as the index where the sum of the numbers to the left of the index is equal to 8 | the sum of the numbers to the right of the index. 9 | If no such index exists, we should return -1. If there are multiple pivot indexes, you should return the 10 | left-most pivot index. 11 | 12 | Example 1: 13 | Input: 14 | nums = [1, 7, 3, 6, 5, 6] 15 | Output: 3 16 | Explanation: 17 | The sum of the numbers to the left of index 3 (nums[3] = 6) is equal to the sum of numbers to the right 18 | of index 3. 19 | Also, 3 is the first index where this occurs. 20 | */ 21 | 22 | 23 | fun pivotIndex(nums: Array): Int { 24 | val start = 0 25 | val end = nums.size - 1 26 | return pivot(start, end, nums) 27 | } 28 | 29 | fun pivot(start: Int, end: Int, nums: Array): Int { 30 | var mid = (start + end) / 2 31 | val leftSum = sum(start, mid - 1, nums) 32 | val rightSum = sum(mid + 1, end, nums) 33 | 34 | if (leftSum == rightSum) return mid 35 | 36 | if (leftSum < rightSum) { 37 | mid++ 38 | return pivot(mid + 1, end, nums) 39 | } else if (leftSum > rightSum) { 40 | mid-- 41 | return pivot(start, mid - 1, nums) 42 | } 43 | 44 | return -1 45 | } 46 | 47 | fun sum(start: Int, end: Int, nums: Array): Int { 48 | var sum = 0 49 | for (i in start..end) { 50 | sum += nums[i] 51 | } 52 | 53 | return sum 54 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/ProductSum.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays 2 | 3 | import java.util.* 4 | 5 | 6 | /** 7 | * 8 | * Write a function that takes in a "special" array and returns its product sum. 9 | * A "special" array is a non-empty array that contains either integers or other 10 | * "special" arrays. The product sum of a "special" array is the sum of its 11 | * elements, where "special" arrays inside it are summed themselves and then 12 | * multiplied by their level of depth. 13 | * 14 | * For example, 15 | * the product sum of [x, y] is x + y; 16 | * the product sum of [x, [y, z]] x + 2y + 2z 17 | * 18 | * Sample input: [5, 2, [7, -1], 3, [6, [-13, 8], 4]] 19 | * Sample output: 12 20 | * calculated as: 5 + 2 + 2 * (7 - 1) + 3 + 2 * (6 + 3 * (-13 + 8) + 4) 21 | */ 22 | class ProductSum { 23 | 24 | /** 25 | * Time: O(n) 26 | * Space: O(depth) 27 | */ 28 | fun productSumHelper(list: List<*>, depth: Int = 1): Int { 29 | var sum = 0 30 | 31 | list.forEach { item -> 32 | if (item is Int) { 33 | sum += item 34 | } else { 35 | val inner = item as List<*> 36 | sum += productSumHelper(inner, depth + 1) 37 | } 38 | } 39 | 40 | return sum * depth 41 | } 42 | } 43 | 44 | fun main(args: Array) { 45 | val ps = ProductSum() 46 | val test: List = ArrayList(listOf(1, 2, ArrayList(listOf(3)), 4, 5)) 47 | 48 | println(ps.productSumHelper(test)) 49 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/SmallestDifference.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays 2 | 3 | import kotlin.math.absoluteValue 4 | 5 | /** 6 | * 7 | * Write a function that takes in two non-empty arrays of integers, finds the 8 | * pair of numbers (one from each array) whose absolute difference is closest to 9 | * zero, and returns an array containing these two numbers, with the number from 10 | * the first array in the first position. 11 | * 12 | */ 13 | class SmallestDifference { 14 | 15 | fun findPair(arrOne: Array, arrTwo: Array): Array { 16 | arrOne.sort() 17 | arrTwo.sort() 18 | var i = 0 19 | var j = 0 20 | var smallestDifference = Int.MAX_VALUE 21 | var pair: Array = emptyArray() 22 | 23 | while (i < arrOne.size && j < arrTwo.size) { 24 | val first = arrOne[i] 25 | val second = arrTwo[j] 26 | 27 | val currentDiff = (first - second).absoluteValue 28 | if (currentDiff < smallestDifference) { 29 | smallestDifference = currentDiff 30 | pair = arrayOf(first, second) 31 | } 32 | 33 | if (first == second) { 34 | return arrayOf(first, second) 35 | } else if (first < second) { 36 | i++ 37 | } else { 38 | j++ 39 | } 40 | } 41 | 42 | return pair 43 | } 44 | 45 | } 46 | 47 | fun main() { 48 | val b = arrayOf(-1, 5, 10, 20, 28, 3) 49 | val a = arrayOf(26, 134, 135, 15, 17) 50 | val pair = SmallestDifference().findPair(a, b) 51 | println(pair.contentToString()) 52 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/TheeLargestNumbers.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays 2 | 3 | class TheeLargestNumbers { 4 | 5 | /** 6 | * time: O(n) 7 | * space: O(1) 8 | */ 9 | fun findThreeLargest(array: Array): Array { 10 | val result = arrayOf(Int.MIN_VALUE, Int.MIN_VALUE, Int.MIN_VALUE) 11 | 12 | array.forEach { 13 | updateLargest(it, result) 14 | } 15 | 16 | return result 17 | } 18 | 19 | private fun updateLargest(num: Int, result: Array) { 20 | when { 21 | num > result[2] -> shiftLeft(result, num, 2) 22 | num > result[1] -> shiftLeft(result, num, 1) 23 | num > result[0] -> shiftLeft(result, num, 0) 24 | } 25 | } 26 | 27 | private fun shiftLeft(array: Array, num: Int, index: Int) { 28 | (0..index).forEach { i -> 29 | if (i == index) { 30 | array[i] = num 31 | } else { 32 | array[i] = array[i + 1] 33 | } 34 | } 35 | } 36 | } 37 | 38 | fun main(args: Array) { 39 | val arr = arrayOf(141, 1, 17, -7, -17, -27, 18, 541, 8, 7, 7) 40 | val program = TheeLargestNumbers() 41 | 42 | println(program.findThreeLargest(arr).contentToString()) 43 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/TwoNumberSum.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays 2 | 3 | import kotlin.collections.HashMap 4 | 5 | /** 6 | * 7 | * Write a function that takes in a non-empty array of distinct integers and an 8 | * integer representing a target sum. If any two numbers in the input array sum 9 | * up to the target sum, the function should return them in an array, in any 10 | * order. If no two numbers sum up to the target sum, the function should return 11 | * an empty array. 12 | */ 13 | class TwoNumberSum { 14 | 15 | /** 16 | * Space: O(n) 17 | * Time: O(n) 18 | */ 19 | fun findPair(array: Array, sum: Int): Array { 20 | val map = HashMap() 21 | 22 | array.forEach { num -> 23 | val complement = sum - num 24 | if (map.contains(complement)) { 25 | return arrayOf(num, complement) 26 | } else { 27 | map[num] = true 28 | map[complement] = true 29 | } 30 | } 31 | 32 | return emptyArray() 33 | } 34 | } 35 | 36 | fun main(args: Array) { 37 | val test = TwoNumberSum() 38 | val arr = arrayOf(1, 5, 7, 9, 11) 39 | val target = 10 40 | 41 | println(test.findPair(arr, target).contentToString()) 42 | 43 | println() 44 | 45 | val arr2 = arrayOf(-1, 5, 7, 8, 11) 46 | val target2 = 10 47 | 48 | println(test.findPair(arr2, target2).contentToString()) 49 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/sorting/BubbleSort.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays.sorting 2 | 3 | class BubbleSort { 4 | 5 | fun sort(array: Array): Array { 6 | if(array.isEmpty()) return emptyArray() 7 | 8 | var end = array.lastIndex 9 | 10 | while (end >= 0) { 11 | 12 | (0..end).forEach{ index -> 13 | if (index == array.lastIndex) return@forEach 14 | 15 | if (array[index] > array[index + 1]) { 16 | swap(array, index, index+1) 17 | } 18 | } 19 | 20 | end-- 21 | } 22 | 23 | return array; 24 | } 25 | 26 | 27 | private fun swap(arr: Array, i: Int, j: Int) { 28 | val temp = arr[i] 29 | arr[i] = arr[j] 30 | arr[j] = temp 31 | } 32 | } 33 | 34 | fun main(args: Array) { 35 | val arr = arrayOf(2, 1, 3) 36 | println(arr.contentToString()) 37 | 38 | BubbleSort().sort(arr) 39 | 40 | println("\nsorted:") 41 | println(arr.contentToString()) 42 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/sorting/InsertionSort.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays.sorting 2 | 3 | class InsertionSort { 4 | 5 | fun sort(array: Array): Array { 6 | if (array.isEmpty()) return array 7 | 8 | (1..array.lastIndex).forEach { i -> 9 | var j = i 10 | while (j > 0) { 11 | if (array[j] < array[j - 1]) { 12 | swap(array, j, j - 1) 13 | j-- 14 | } else { 15 | break 16 | } 17 | } 18 | } 19 | 20 | return array 21 | } 22 | 23 | private fun swap(array: Array, i: Int, j: Int) { 24 | val temp = array[j] 25 | array[j] = array[i] 26 | array[i] = temp 27 | } 28 | } 29 | 30 | fun main(args: Array) { 31 | val arr = arrayOf(4, 1, 6, 5, 2, 3) 32 | println(arr.contentToString()) 33 | 34 | InsertionSort().sort(arr) 35 | 36 | println("\nsorted:") 37 | println(arr.contentToString()) 38 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/sorting/MergeSort.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays.sorting 2 | 3 | class MergeSort { 4 | 5 | fun sort(arr: Array) { 6 | splitAndMerge(arr) 7 | } 8 | 9 | private fun splitAndMerge(arr: Array) { 10 | if(arr.size <= 1) return 11 | 12 | val mid = (arr.size / 2) 13 | 14 | val left = arr.sliceArray(0 until mid) 15 | val right = arr.sliceArray(mid..arr.lastIndex) 16 | 17 | splitAndMerge(left) 18 | splitAndMerge(right) 19 | 20 | merge(left, right, arr) 21 | } 22 | 23 | 24 | private fun merge(left: Array, right: Array, result: Array) { 25 | var i = 0 26 | var j = 0 27 | var k = 0 28 | 29 | // put values in sorted order 30 | while (i <= left.lastIndex && j <= right.lastIndex) { 31 | if (left[i] < right[j]) { 32 | result[k] = left[i] 33 | i++ 34 | k++ 35 | } else { 36 | result[k] = right[j] 37 | j++ 38 | k++ 39 | } 40 | } 41 | 42 | // put remaining values in left 43 | while (i <= left.lastIndex) { 44 | result[k] = left[i] 45 | i++ 46 | k++ 47 | } 48 | 49 | // put remaining values in right 50 | while (j <= right.lastIndex) { 51 | result[k] = right[j] 52 | j++ 53 | k++ 54 | } 55 | } 56 | } 57 | 58 | fun main(args: Array) { 59 | val arr = arrayOf(4, 1, 6, 5, 2, 3) 60 | println(arr.contentToString()) 61 | 62 | MergeSort().sort(arr) 63 | 64 | println("\nsorted:") 65 | println(arr.contentToString()) 66 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/sorting/QuickSort.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays.sorting 2 | 3 | /** 4 | * Dr. Rob Edwards - San Diego State University 5 | * https://www.youtube.com/watch?v=ZHVk2blR45Q 6 | */ 7 | class QuickSort { 8 | 9 | fun sort(array: Array) { 10 | quickSort(array, 0, array.lastIndex) 11 | } 12 | 13 | private fun quickSort(array: Array, left: Int, right: Int) { 14 | if (left >= right) return // exit condition 15 | 16 | val pi = partition(array, left, right) 17 | quickSort(array, left, pi - 1) 18 | quickSort(array, pi + 1, right) 19 | } 20 | 21 | private fun partition(array: Array, left: Int, right: Int): Int { 22 | val pivot = array[right] 23 | var pi = left 24 | var counter = left 25 | 26 | for(curr in left..right) { 27 | if (array[curr] < pivot) { 28 | swap(array, pi, curr) 29 | pi++ 30 | } 31 | counter = curr 32 | } 33 | 34 | swap(array, pi, counter) 35 | return pi 36 | } 37 | 38 | private fun swap(array: Array, a: Int, b: Int) { 39 | val temp = array[a] 40 | array[a] = array[b] 41 | array[b] = temp 42 | } 43 | } 44 | 45 | fun main(args: Array) { 46 | val arr = arrayOf(4, 1, 6, 5, 2, 3) 47 | println(arr.contentToString()) 48 | 49 | QuickSort().sort(arr) 50 | 51 | println("\nsorted:") 52 | println(arr.contentToString()) 53 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/sorting/SelectionSort.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays.sorting 2 | 3 | class SelectionSort { 4 | 5 | fun sort(array: Array) { 6 | array.forEachIndexed { index, _ -> 7 | val smallest = smallestIndex(array, index) 8 | swap(array, index, smallest) 9 | } 10 | } 11 | 12 | private fun smallestIndex(array: Array, start: Int): Int { 13 | var smallest = start 14 | 15 | (start..array.lastIndex).forEach { i -> 16 | if (array[i] < array[smallest]) 17 | smallest = i 18 | } 19 | 20 | return smallest 21 | } 22 | 23 | private fun swap(array: Array, i: Int, j: Int) { 24 | val temp = array[i] 25 | array[i] = array[j] 26 | array[j] = temp 27 | } 28 | } 29 | 30 | fun main() { 31 | val arr = arrayOf(4, 1, 6, 5, 2, 3) 32 | println(arr.contentToString()) 33 | 34 | SelectionSort().sort(arr) 35 | 36 | println("\nsorted:") 37 | println(arr.contentToString()) 38 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/arrays/sorting/ThreeNumberSum.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays.sorting 2 | 3 | /** 4 | * 5 | * Write a function that takes in a non-empty array of distinct integers and an 6 | * integer representing a target sum. The function should find all triplets in 7 | * the array that sum up to the target sum and return a two-dimensional array of 8 | * all these triplets. The numbers in each triplet should be ordered in ascending 9 | * order, and the triplets themselves should be ordered in ascending order with 10 | * respect to the numbers they hold. 11 | * 12 | */ 13 | class ThreeNumberSum { 14 | 15 | fun findTriplets(array: Array, targetSum: Int): List> { 16 | val result = mutableListOf>() 17 | array.sort() 18 | array.forEachIndexed { index, num -> 19 | var left = index 20 | var right = array.lastIndex 21 | 22 | while (left < right) { 23 | val currentSum = num + array[left] + array[right] 24 | if (currentSum == targetSum) { 25 | result.add(arrayOf(num, array[left], array[right])) 26 | left++ 27 | right-- 28 | } else if (currentSum < targetSum) { 29 | left++ 30 | } else { 31 | right-- 32 | } 33 | } 34 | } 35 | return result 36 | } 37 | 38 | } 39 | 40 | fun main() { 41 | val result = ThreeNumberSum().findTriplets(arrayOf(5, 1, 0, -5, 4 ,7, 9, -11, 2), 0) 42 | result.forEach { print(it.contentToString()) } 43 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/graph/DFS.kt: -------------------------------------------------------------------------------- 1 | package algos.graph 2 | 3 | import ds.graph.GraphNode 4 | 5 | /** 6 | * Implement func, which takes in an empty array, traverses the tree 7 | * using the Depth-first Search approach (specifically navigating the tree from 8 | * left to right), stores all of the nodes' names in the input array, and returns 9 | * it. 10 | */ 11 | class DFS { 12 | 13 | fun dfs(root: GraphNode, list: MutableList) { 14 | fill(root, list) 15 | } 16 | 17 | private fun fill(node: GraphNode, list: MutableList) { 18 | list.add(node.value) 19 | 20 | node.children.forEach { child -> 21 | fill(child, list) 22 | } 23 | } 24 | 25 | } 26 | 27 | fun main(args: Array) { 28 | 29 | val tree = GraphNode("A") 30 | tree.addChild("B").addChild("C").addChild("D") 31 | tree.children[0].addChild("E").addChild("F") 32 | tree.children[2].addChild("G").addChild("H") 33 | tree.children[0].children[1].addChild("I").addChild("J") 34 | tree.children[2].children[0].addChild("K") 35 | 36 | val list = mutableListOf() 37 | DFS().dfs(tree, list) 38 | 39 | print(list) 40 | 41 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/trees/BranchSum.kt: -------------------------------------------------------------------------------- 1 | package algos.trees 2 | 3 | /** 4 | * Write a function that takes in a Binary Tree and returns a list of its branch 5 | * sums ordered from leftmost branch sum to rightmost branch sum. 6 | */ 7 | class BranchSum { 8 | 9 | class BinaryTree(val value: Int) { 10 | var left: BinaryTree? = null 11 | var right: BinaryTree? = null 12 | } 13 | 14 | fun branchSums(root: BinaryTree): List { 15 | val total = mutableListOf() 16 | traverse(root, total, 0) 17 | return total 18 | } 19 | 20 | private fun traverse(node: BinaryTree?, total: MutableList, sum: Int) { 21 | if (node == null) return 22 | 23 | val newSum = sum + node.value 24 | if (node.left == null && node.right == null) { 25 | total.add(newSum) 26 | } 27 | 28 | traverse(node.left, total, newSum) 29 | traverse(node.right, total, newSum) 30 | } 31 | } 32 | 33 | fun main() { 34 | val a = BranchSum.BinaryTree(1) 35 | val b = BranchSum.BinaryTree(2) 36 | val c = BranchSum.BinaryTree(3) 37 | val d = BranchSum.BinaryTree(4) 38 | val e = BranchSum.BinaryTree(5) 39 | val f = BranchSum.BinaryTree(6) 40 | val g = BranchSum.BinaryTree(7) 41 | val h = BranchSum.BinaryTree(8) 42 | val i = BranchSum.BinaryTree(9) 43 | val j = BranchSum.BinaryTree(10) 44 | 45 | a.left = b 46 | a.right = c 47 | 48 | b.left = d 49 | b.right = e 50 | 51 | c.left = f 52 | c.right = g 53 | 54 | d.left = h 55 | d.right = i 56 | 57 | e.left = j 58 | 59 | println(BranchSum().branchSums(a)) // [15, 16, 18, 10, 11] 60 | } -------------------------------------------------------------------------------- /src/main/kotlin/algos/trees/bst/ClosestValue.kt: -------------------------------------------------------------------------------- 1 | package algos.trees.bst 2 | 3 | import kotlin.math.absoluteValue 4 | 5 | /** 6 | * Write a function that takes in a Binary Search Tree (BST) and a target integer 7 | * value and returns the closest value to that target value contained in the BST. 8 | */ 9 | class ClosestValue { 10 | 11 | /** 12 | * Time: O(log(n)) 13 | * Space: O(log(n)) : stack memory used by recursion 14 | */ 15 | fun findClosest(tree: BST, target: Int): Int { 16 | return find(tree, closestValue = Int.MAX_VALUE, target = target) 17 | } 18 | 19 | private fun find(node: BST?, closestValue: Int, target: Int): Int { 20 | if (node == null) return closestValue 21 | 22 | val smallestDiff = (target - closestValue).absoluteValue 23 | val diff = (target - node.value).absoluteValue 24 | 25 | val newClosestValue = if (diff < smallestDiff) { 26 | node.value 27 | } else { 28 | closestValue 29 | } 30 | 31 | return if (node.value < target) { 32 | find(node = node.right, closestValue = newClosestValue, target = target) 33 | } else { 34 | find(node = node.left, closestValue = newClosestValue, target = target) 35 | } 36 | } 37 | 38 | /** 39 | * Time: O(log(n)) 40 | * Space: O(1) 41 | */ 42 | fun findClosestIterative(tree: BST, target: Int): Int { 43 | var closest = Int.MAX_VALUE 44 | var curr: BST? = tree 45 | 46 | while (curr != null) { 47 | val diff = (target - curr.value).absoluteValue 48 | val smallestDiff = (target - closest).absoluteValue 49 | 50 | if (diff <= smallestDiff) { 51 | closest = curr.value 52 | } 53 | 54 | curr = if (curr.value < target) { 55 | curr.right 56 | } else { 57 | curr.left 58 | } 59 | } 60 | 61 | return closest 62 | } 63 | 64 | } 65 | 66 | class BST(var left: BST? = null, var right: BST? = null, var value: Int) 67 | 68 | fun main(args: Array) { 69 | 70 | val program = ClosestValue() 71 | 72 | val a = BST(value = 5) 73 | val b = BST(value = 3) 74 | val c = BST(value = 8) 75 | val d = BST(value = 0) 76 | val e = BST(value = 4) 77 | val f = BST(value = 7) 78 | val g = BST(value = 13) 79 | val h = BST(value = 11) 80 | val i = BST(value = 14) 81 | 82 | a.left = b 83 | a.right = c 84 | 85 | b.left = d 86 | b.right = e 87 | 88 | c.left = f 89 | c.right = g 90 | 91 | g.left = h 92 | g.right = i 93 | 94 | println("closest value to 8: " + program.findClosest(a, 10)) 95 | println("closest value to 8: " + program.findClosestIterative(a, 10)) 96 | } -------------------------------------------------------------------------------- /src/main/kotlin/ds/graph/Tree.kt: -------------------------------------------------------------------------------- 1 | package ds.graph 2 | 3 | class GraphNode(val value: T, val children: MutableList> = mutableListOf()) { 4 | 5 | fun addChild(node: GraphNode): GraphNode { 6 | children.add(node) 7 | return this 8 | } 9 | 10 | fun addChild(value: T): GraphNode { 11 | children.add(GraphNode(value)) 12 | return this 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/ds/linkedlist/DoublyLinkedList.kt: -------------------------------------------------------------------------------- 1 | package ds.linkedlist 2 | 3 | import java.lang.Exception 4 | import java.lang.IllegalArgumentException 5 | 6 | class DLLNode(val value: Int, var prev: DLLNode? = null, var next: DLLNode? = null) 7 | 8 | class DoublyLinkedList { 9 | 10 | private var head: DLLNode? = null 11 | private var tail: DLLNode? = null 12 | 13 | fun head(node: DLLNode) { 14 | if (head == null) { 15 | head = node 16 | tail = node 17 | return 18 | } 19 | 20 | head?.let { insertBefore(it, node) } 21 | 22 | } 23 | 24 | fun tail(node: DLLNode) { 25 | if (tail == null) { 26 | head = node 27 | tail = node 28 | return 29 | } 30 | 31 | tail?.let { insertAfter(it, node) } 32 | } 33 | 34 | fun insertAtPosition(position: Int, nodeToInsert: DLLNode) { 35 | var counter = 0 36 | var curr = head 37 | 38 | while (counter != position) { 39 | curr = curr?.next 40 | counter++ 41 | } 42 | 43 | curr?.let { insertBefore(it, nodeToInsert) } 44 | } 45 | 46 | fun insertAfter(node: DLLNode, nodeToInsert: DLLNode) { 47 | if (find(nodeToInsert)) { 48 | throw IllegalArgumentException("Cannot modify list. $nodeToInsert is already part of the list") 49 | } 50 | 51 | if (node == tail) { 52 | tail = nodeToInsert 53 | } else { 54 | val next = node.next 55 | next?.prev = nodeToInsert 56 | nodeToInsert.next = next 57 | } 58 | 59 | nodeToInsert.prev = node 60 | node.next = nodeToInsert 61 | } 62 | 63 | fun insertBefore(node: DLLNode, nodeToInsert: DLLNode) { 64 | if (find(nodeToInsert)) throw Exception("Cannot modify list. $nodeToInsert is already part of the list") 65 | 66 | if (node == head) { 67 | head = nodeToInsert 68 | } else { 69 | val prev = node.prev 70 | prev?.next = nodeToInsert 71 | nodeToInsert.prev = prev 72 | } 73 | 74 | nodeToInsert.next = node 75 | node.prev = nodeToInsert 76 | } 77 | 78 | /** 79 | * Tip: save next node while iterating as bindings are removed by remove() 80 | * and loop won't iterate till the end. 81 | * 82 | * Can use findAll() and remove() but that takes O(n) space while this 83 | * executes in-place. 84 | */ 85 | fun removeNodesWithValue(value: Int) { 86 | var curr = head 87 | 88 | while (curr != null) { 89 | val next = curr.next 90 | 91 | if (curr.value == value) { 92 | remove(curr) 93 | } 94 | 95 | curr = next 96 | } 97 | } 98 | 99 | fun find(node: DLLNode): Boolean { 100 | var curr = head 101 | while (curr != null) { 102 | if (curr == node) { 103 | return true 104 | } 105 | 106 | curr = curr.next 107 | } 108 | 109 | return false 110 | } 111 | 112 | /** 113 | * Tip: return when first result is found 114 | */ 115 | private fun find(value: Int): DLLNode? { 116 | var result: DLLNode? = null 117 | 118 | var curr = head 119 | while (curr != null) { 120 | if (curr.value == value) { 121 | result = curr 122 | break 123 | } 124 | 125 | curr = curr.next 126 | } 127 | 128 | return result 129 | } 130 | 131 | /** 132 | * Tip: special handling of head and tail cases 133 | */ 134 | fun remove(node: DLLNode) { 135 | if (node == head) { 136 | head = head?.next 137 | } 138 | 139 | if (node == tail) { 140 | tail = tail?.prev 141 | } 142 | 143 | removeBindings(node) 144 | } 145 | 146 | private fun removeBindings(node: DLLNode) { 147 | val next = node.next 148 | val prev = node.prev 149 | 150 | prev?.next = next 151 | next?.prev = prev 152 | 153 | node.next = null 154 | node.prev = null 155 | } 156 | 157 | 158 | fun containsNodeWithValue(value: Int): Boolean { 159 | val result = find(value) 160 | return result != null 161 | } 162 | 163 | fun print() { 164 | var curr = head 165 | print("[") 166 | while (curr != null) { 167 | if (curr.prev != null) { 168 | print("->") 169 | } 170 | 171 | print(" ${curr.value} ") 172 | 173 | if (curr.next != null) { 174 | print("<-") 175 | } 176 | curr = curr.next 177 | } 178 | print("]\n") 179 | } 180 | 181 | } 182 | 183 | fun main(args: Array) { 184 | val node1 = DLLNode(1) 185 | val node2 = DLLNode(2) 186 | val node3 = DLLNode(3) 187 | val node4 = DLLNode(4) 188 | val node5 = DLLNode(5) 189 | val node6 = DLLNode(1) 190 | 191 | val dll = DoublyLinkedList() 192 | dll.head(node1) 193 | dll.insertAfter(node1, node2) 194 | dll.insertAfter(node2, node3) 195 | dll.insertAfter(node3, node4) 196 | dll.insertAfter(node4, node5) 197 | dll.insertAfter(node5, node6) 198 | 199 | println("List:") 200 | dll.print() 201 | 202 | println("\nRemove 3:") 203 | dll.remove(node3) 204 | dll.print() 205 | 206 | println("\nRemove 1:") 207 | dll.removeNodesWithValue(1) 208 | dll.print() 209 | 210 | println("\ncontains 3: " + dll.containsNodeWithValue(3)) 211 | println("contains 5: " + dll.containsNodeWithValue(5)) 212 | 213 | println("\nInsert 1 before 2:") 214 | dll.insertBefore(node2, node1) 215 | dll.print() 216 | 217 | println("\nInsert 3 before 4:") 218 | dll.insertBefore(node4, node3) 219 | dll.print() 220 | 221 | println("\nInsert 7 after 5") 222 | dll.insertAfter(node5, DLLNode(7)) 223 | dll.print() 224 | 225 | println("\nInsert 6 after 5") 226 | dll.insertAfter(node5, DLLNode(6)) 227 | dll.print() 228 | 229 | println("\nInsert 0 at position 0") 230 | dll.insertAtPosition(0, DLLNode(0)) 231 | dll.print() 232 | 233 | println("\nSet head to -1") 234 | dll.head(DLLNode(-1)) 235 | dll.print() 236 | 237 | println("\nSet tail to -2") 238 | dll.tail(DLLNode(-2)) 239 | dll.print() 240 | 241 | } -------------------------------------------------------------------------------- /src/test/kotlin/algos/arrays/PivotTest.kt: -------------------------------------------------------------------------------- 1 | package algos.arrays 2 | 3 | import org.junit.Test 4 | import kotlin.test.assertEquals 5 | 6 | class PivotTest { 7 | 8 | @Test 9 | fun testPivotIndex() { 10 | assertEquals(expected = 3, actual = pivotIndex(arrayOf(1, 7, 3, 6, 5, 6))) 11 | } 12 | } 13 | --------------------------------------------------------------------------------