├── .github └── workflows │ ├── maven.yml │ ├── rust.yml │ └── scala.yml ├── .gitignore ├── .scalafmt.conf ├── Cargo.toml ├── README.md ├── algo └── src │ └── main │ └── scala │ └── djnz │ ├── codility │ └── MinNonNegativeOr1.scala │ ├── combinatorics │ └── nqueens │ │ └── NQueens.scala │ ├── fp │ └── transpose │ │ └── MatrixTranspose.scala │ ├── hackerrank │ ├── fp │ │ ├── a1intro │ │ │ ├── P10Length.scala │ │ │ ├── P11UpdateList.scala │ │ │ ├── P12EvalEx.scala │ │ │ ├── P13AreaUnderCurves.scala │ │ │ ├── P14Reduction1.scala │ │ │ ├── P15Reduction2.scala │ │ │ ├── P16Reduction3.scala │ │ │ ├── P17Reduction4.scala │ │ │ ├── P18EvalEx1.scala │ │ │ ├── P19EvalEx2.scala │ │ │ ├── P1SolveMeFirst.scala │ │ │ ├── P20EvalEx3.scala │ │ │ ├── P21EvalEx4.scala │ │ │ ├── P22EvalEx5.scala │ │ │ ├── P23FunctionsOrNot.scala │ │ │ ├── P24PolygonPerimeter.scala │ │ │ ├── P25PolygonArea.scala │ │ │ ├── P25PolygonAreaWorkout.scala │ │ │ ├── P2HelloWorld.scala │ │ │ ├── P3HelloWorldNTimes.scala │ │ │ ├── P4ListReplication.scala │ │ │ ├── P5FilterArrayLessThanN.scala │ │ │ ├── P6FilterOutOdd.scala │ │ │ ├── P7GenListOfN.scala │ │ │ ├── P8ReverseList.scala │ │ │ └── P9SumOfOdd.scala │ │ ├── a2recursion │ │ │ ├── P10Crosswords.scala │ │ │ ├── P11Prefix.scala │ │ │ ├── P12StringReduction.scala │ │ │ ├── P13SuperQueenMutable.scala │ │ │ ├── P13SuperQueenSlow.scala │ │ │ ├── P13SuperQueens.scala │ │ │ ├── P14SumOfPowers.scala │ │ │ ├── P14SumOfPowersCountOnly.scala │ │ │ ├── P15SequenceOfColors.scala │ │ │ ├── P16FilterElements.scala │ │ │ ├── P17SuperDigit.scala │ │ │ ├── P18TreeOfLife.scala │ │ │ ├── P19IsConcavePolygon.scala │ │ │ ├── P1GCD.scala │ │ │ ├── P2Fibonacci.scala │ │ │ ├── P3PascalTriangle.scala │ │ │ ├── P4Sierpinski.scala │ │ │ ├── P4_sierpinski.txt │ │ │ ├── P5StringMingling.scala │ │ │ ├── P6StringOPermute.scala │ │ │ ├── P7FractalTrees.scala │ │ │ ├── P8ConvexHull.scala │ │ │ └── P9Compression.scala │ │ ├── a3structures │ │ │ ├── P10StockPrediction.scala │ │ │ ├── P10StockPredictionNaive.scala │ │ │ ├── P11ConstructionSiteDP.scala │ │ │ ├── P12TreeManager.scala │ │ │ ├── P13FightingArmies.scala │ │ │ ├── P1SwapNodes.scala │ │ │ ├── P2MatrixRotation.scala │ │ │ ├── P3IsPreorderBST.scala │ │ │ ├── P4ListsAndGCD.scala │ │ │ ├── P5PrisonTransport.scala │ │ │ ├── P6SubstringKMP.scala │ │ │ ├── P7OrderExercises.scala │ │ │ ├── P8JohnAndFences.scala │ │ │ └── P9RangeMinimum.scala │ │ └── index.md │ └── index.md │ ├── interviews │ ├── README.md │ ├── agileengine │ │ └── Task1.scala │ ├── chi │ │ ├── SevenToPower.java │ │ └── SevenToPowerOfN.scala │ ├── chilipiper │ │ ├── airport │ │ │ ├── AirportLimousine.scala │ │ │ ├── data │ │ │ │ ├── input004.txt │ │ │ │ └── input005.txt │ │ │ └── desc │ │ │ │ ├── 1a.png │ │ │ │ └── 1b.png │ │ └── turn │ │ │ ├── Turnstile.scala │ │ │ ├── data │ │ │ └── input004.txt │ │ │ └── desc │ │ │ ├── 2a.png │ │ │ ├── 2b.png │ │ │ └── 2c.png │ ├── luxoft │ │ └── WhatTypeClassIs.scala │ └── nixa │ │ ├── Task1.scala │ │ ├── Task2.scala │ │ └── Task3.SQL │ └── tools │ ├── ASuite.scala │ ├── Console.scala │ └── StdInput.scala ├── build.sbt ├── play ├── pom.xml └── src │ ├── main │ ├── java │ │ ├── algorithms │ │ │ ├── _unpolished │ │ │ │ ├── IList.java │ │ │ │ ├── XLinedListApp.java │ │ │ │ ├── XLinkedList.java │ │ │ │ ├── XList.java │ │ │ │ └── XPriorityQueue.java │ │ │ ├── l01sort │ │ │ │ ├── BubbleSortBasic.java │ │ │ │ ├── BubbleSortImproved.java │ │ │ │ ├── GrahamConvexHull.java │ │ │ │ ├── HeapSort.java │ │ │ │ ├── InsertionSort.java │ │ │ │ ├── MergeSortClean.java │ │ │ │ ├── MergeSortCustomComparator.java │ │ │ │ ├── MergeSortExplained.java │ │ │ │ ├── MergeSortNoRecursion.java │ │ │ │ ├── QuickSort.java │ │ │ │ ├── QuickSort2.java │ │ │ │ ├── RadixSort.java │ │ │ │ ├── SelectionSort.java │ │ │ │ ├── ShellSort.java │ │ │ │ ├── Shuffle.java │ │ │ │ ├── Utils.java │ │ │ │ └── ideas │ │ │ │ │ ├── MergeSortBottomUp.java │ │ │ │ │ ├── MergeSortOptimized.java │ │ │ │ │ └── Stability.java │ │ │ ├── l02bitwise │ │ │ │ ├── BitShift.java │ │ │ │ ├── Crypt.java │ │ │ │ ├── IntegerOverflow.java │ │ │ │ ├── NegativeRepresentation.java │ │ │ │ ├── README.md │ │ │ │ ├── SyntaxAndNotation.java │ │ │ │ ├── conversion │ │ │ │ │ ├── BinToInt.java │ │ │ │ │ └── IntToBin.java │ │ │ │ ├── conversion2 │ │ │ │ │ ├── BinToDec.java │ │ │ │ │ ├── DecToBin.java │ │ │ │ │ ├── DecToBinV1.java │ │ │ │ │ ├── DecToBinV2.java │ │ │ │ │ └── DecToBinV3.java │ │ │ │ ├── shift │ │ │ │ │ └── ShiftApp.java │ │ │ │ └── usecases │ │ │ │ │ ├── Order.java │ │ │ │ │ ├── RealExampleShop.java │ │ │ │ │ └── RealExampleTaxi.java │ │ │ ├── l03recursion │ │ │ │ ├── ArraySumApp.java │ │ │ │ ├── FactorialApp.java │ │ │ │ ├── FibonacciApp.java │ │ │ │ ├── FibonacciApp2memo.java │ │ │ │ ├── XpowYbasic.java │ │ │ │ └── XpowYtailrec.java │ │ │ ├── l04linkedlist │ │ │ │ ├── DijkstraEval.java │ │ │ │ ├── GCDStackSafe.java │ │ │ │ ├── LinkedListJDKAPI.java │ │ │ │ ├── LinkedListListIterators.java │ │ │ │ ├── StackApp.java │ │ │ │ ├── XLinkedList.java │ │ │ │ ├── XLinkedListApp.java │ │ │ │ ├── XMerge.java │ │ │ │ ├── XMergeApp.java │ │ │ │ └── XQueueApp.java │ │ │ ├── l05binarysearch │ │ │ │ ├── BinarySearch1App.java │ │ │ │ ├── BinarySearch2App.java │ │ │ │ ├── BinarySearch3App.java │ │ │ │ ├── BinarySearchV1.java │ │ │ │ ├── BinarySearchV2.java │ │ │ │ └── BinarySearchV3.java │ │ │ ├── l06hash │ │ │ │ ├── IMap.java │ │ │ │ ├── ST.java │ │ │ │ ├── XHashMap.java │ │ │ │ └── XHashMapApp.java │ │ │ ├── l07tree │ │ │ │ ├── BST.java │ │ │ │ ├── BSTApp.java │ │ │ │ ├── RedBlackTree.java │ │ │ │ ├── TwoThreeTree.java │ │ │ │ ├── XTreeMap.java │ │ │ │ ├── XTreeMapApp.java │ │ │ │ ├── nodeRemoval.png │ │ │ │ └── rotation.png │ │ │ ├── l08graph │ │ │ │ ├── Tools.java │ │ │ │ ├── impls │ │ │ │ │ ├── AllReachableDFS.java │ │ │ │ │ ├── BFSIterative.java │ │ │ │ │ ├── CommonOperations.java │ │ │ │ │ ├── ConnectedComponents.java │ │ │ │ │ ├── DFS1RecursivePlain.java │ │ │ │ │ ├── DFS2IterativeManualStackHandling.java │ │ │ │ │ ├── DFS3IterativeQueueApproach.java │ │ │ │ │ ├── DFS4RecursiveFunctional.java │ │ │ │ │ ├── FirstPathDFS.java │ │ │ │ │ ├── HasCyclesImpl.java │ │ │ │ │ ├── IsConnectedBasic.java │ │ │ │ │ ├── IsConnectedMature.java │ │ │ │ │ ├── IsConnectedMatureChatty.java │ │ │ │ │ ├── TopologicalSortingImpl.java │ │ │ │ │ ├── TopologicalSortingImpl2.java │ │ │ │ │ └── thoughts │ │ │ │ │ │ ├── AreTheyIsomorphic.java │ │ │ │ │ │ ├── BridgesIslandsExactlyOnce.java │ │ │ │ │ │ ├── IsBiPartite.java │ │ │ │ │ │ └── IsPlanar.java │ │ │ │ ├── ops │ │ │ │ │ ├── AllPaths.java │ │ │ │ │ ├── AllReachable.java │ │ │ │ │ ├── AllReachableUpToDistance.java │ │ │ │ │ ├── AllReachableWithDistances.java │ │ │ │ │ ├── HasCycles.java │ │ │ │ │ ├── IsConnected.java │ │ │ │ │ ├── IsStronglyConnected.java │ │ │ │ │ ├── PathFromTo.java │ │ │ │ │ ├── ShortestPath.java │ │ │ │ │ ├── ShortestPathMultipleSource.java │ │ │ │ │ ├── SingleSourceReachability.java │ │ │ │ │ ├── TopologicalSorting.java │ │ │ │ │ ├── TopologicalSortingChainTo.java │ │ │ │ │ ├── Traverse.java │ │ │ │ │ ├── TraverseBFS.java │ │ │ │ │ └── TraverseDFS.java │ │ │ │ └── rep │ │ │ │ │ ├── AbstractGraphA.java │ │ │ │ │ ├── Edge.java │ │ │ │ │ ├── Edges.java │ │ │ │ │ ├── Graph.java │ │ │ │ │ ├── dir │ │ │ │ │ ├── Digraph.java │ │ │ │ │ ├── GraphA.java │ │ │ │ │ ├── GraphAL.java │ │ │ │ │ ├── GraphAS.java │ │ │ │ │ └── GraphM.java │ │ │ │ │ └── undir │ │ │ │ │ ├── GraphA.java │ │ │ │ │ ├── GraphAL.java │ │ │ │ │ ├── GraphAS.java │ │ │ │ │ └── GraphM.java │ │ │ ├── l09edgeweightedgraph │ │ │ │ ├── MSTTests.java │ │ │ │ ├── impl │ │ │ │ │ ├── KruskalMST.java │ │ │ │ │ └── PrimMST.java │ │ │ │ ├── ops │ │ │ │ │ ├── MinimalSpanningTree.java │ │ │ │ │ ├── mst1.png │ │ │ │ │ └── mst2.png │ │ │ │ └── rep │ │ │ │ │ ├── EWG.java │ │ │ │ │ ├── Edge.java │ │ │ │ │ └── EdgeWeightedGraph.java │ │ │ ├── l10ewdig │ │ │ │ ├── impl │ │ │ │ │ └── ShortestPathDijkstra1.java │ │ │ │ ├── ops │ │ │ │ │ └── ShortestPath.java │ │ │ │ ├── rep │ │ │ │ │ ├── DiEdge.java │ │ │ │ │ ├── EWDiG.java │ │ │ │ │ └── EdgeWeightedDiGraph.java │ │ │ │ └── test │ │ │ │ │ └── ShortestPathDesign.java │ │ │ ├── l11unionfind │ │ │ │ ├── impl │ │ │ │ │ ├── UnionFindV1.java │ │ │ │ │ ├── UnionFindV2.java │ │ │ │ │ ├── UnionFindV3.java │ │ │ │ │ └── UnionFindV4.java │ │ │ │ └── rep │ │ │ │ │ └── UnionFind.java │ │ │ ├── l12binaryheap │ │ │ │ ├── BinaryHeap.java │ │ │ │ ├── BinaryHeapApp.java │ │ │ │ ├── PriorityQueueApp.java │ │ │ │ └── PriorityQueueImpls.java │ │ │ ├── l13lee │ │ │ │ ├── LPoint.java │ │ │ │ ├── Lee.java │ │ │ │ ├── LeeDemoApp.java │ │ │ │ └── README.md │ │ │ └── quizz │ │ │ │ ├── AppleApp.java │ │ │ │ ├── PriorityQueueApp.java │ │ │ │ └── SetApp.java │ │ ├── c │ │ │ └── C1_general.md │ │ ├── common │ │ │ ├── RX.java │ │ │ └── Utils.java │ │ ├── core │ │ │ ├── BoxingUnboxing.java │ │ │ ├── generics_DIRTY │ │ │ │ ├── AList.java │ │ │ │ └── AListUsage.java │ │ │ ├── iterable │ │ │ │ ├── HiddenApp.java │ │ │ │ ├── HiddenData.java │ │ │ │ └── IterationWays.java │ │ │ └── memorymodel_DIRTY │ │ │ │ └── Person.java │ │ ├── dynamic │ │ │ └── GFG.java │ │ ├── links.md │ │ ├── math │ │ │ ├── AppCosinus.java │ │ │ └── AppMatrix.java │ │ └── warmup │ │ │ ├── ChangeCase.java │ │ │ ├── GetRidOfVowels.java │ │ │ ├── IsPalindromeNaive.java │ │ │ ├── IsPalindromeOptimized.java │ │ │ ├── MaxPalindrome10000x99999.java │ │ │ ├── Nth3and4.java │ │ │ ├── Randoms20Unique.java │ │ │ ├── ShortestAndLongestString.java │ │ │ ├── _tasks.txt │ │ │ ├── amazon │ │ │ ├── GCD.java │ │ │ ├── Houses.java │ │ │ ├── MinPairs.java │ │ │ ├── MinPairsSimple.java │ │ │ ├── Person.java │ │ │ └── Source.java │ │ │ ├── brackets │ │ │ └── BracketsNestingLevel.java │ │ │ ├── prime │ │ │ ├── PrimesDynamicApp.java │ │ │ ├── PrimesNaiveApp.java │ │ │ └── versions │ │ │ │ ├── IsPrimeNaive.java │ │ │ │ ├── IsPrimeOptimized.java │ │ │ │ └── PrimesDynamic.java │ │ │ └── shoes │ │ │ ├── ShoesGroups.java │ │ │ ├── ShoesGroupsOptimized.java │ │ │ └── _task.txt │ └── resources │ │ ├── ewdig.txt │ │ └── ewg.txt │ └── test │ └── java │ ├── algorithms │ ├── BoxingUnboxingTest.java │ ├── l02bitwise │ │ ├── BinToDecTest.java │ │ └── DecToBinTest.java │ └── l08graph │ │ ├── GraphASTest.java │ │ ├── ToolsTest.java │ │ ├── impls │ │ ├── AllReachableDFSTest.java │ │ ├── BFSIterativeTest.java │ │ ├── ConnectedComponentsUnDirectionalTest.java │ │ ├── DFS1Recursive1Test.java │ │ ├── DFS2IterativeManualStackHandlingTest.java │ │ ├── DFS3IterativeQueueApproachTest.java │ │ ├── DFS4RecursiveFunctionalTest.java │ │ ├── FirstPathDFSTest.java │ │ ├── GraphData.java │ │ ├── HasCyclesImplTest.java │ │ ├── MapData.java │ │ ├── TopologicalSortingImpl2Test.java │ │ └── TopologicalSortingImplTest.java │ │ └── rep │ │ └── AbstractGraphARepresentTest.java │ └── warmup │ ├── ChangeCaseTest.java │ ├── GetRidOfVowelsTest.java │ └── brackets │ ├── BracketsNestingLevelTest.java │ └── ShoesGroupsTest.java ├── project ├── build.properties └── plugins.sbt └── src ├── main.rs ├── sand ├── mod.rs └── sandbox1.rs └── tasks ├── README.md ├── mod.rs ├── t01 └── mod.rs ├── t02 └── mod.rs ├── t03 └── mod.rs ├── t04 ├── mod.rs └── rhombus.rs ├── t05 ├── envelope.rs └── mod.rs ├── t06 ├── gcd.rs └── mod.rs ├── t07 ├── mod.rs ├── tree1.rs └── tree2.rs ├── t08 ├── invert_the_case.rs └── mod.rs ├── t09 ├── is_prime.rs └── mod.rs ├── t10 ├── mod.rs └── rotate_string.rs ├── t11 ├── is_palindrome.rs └── mod.rs ├── t12 ├── adjacent_sum.rs └── mod.rs ├── t13 ├── distribute_shipments.rs ├── mod.rs └── shipments.png ├── t14 ├── mod.rs ├── rectangles.jpg └── rectangles.rs ├── t15 ├── gray_lazy.rs ├── gray_simple.rs └── mod.rs ├── t16 ├── img.png ├── mod.rs └── myxaslon.rs └── tasks.md /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Java CI with Maven 10 | 11 | on: 12 | push: 13 | branches: [ "master" ] 14 | pull_request: 15 | branches: [ "master" ] 16 | 17 | jobs: 18 | build: 19 | 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Set up JDK 17 25 | uses: actions/setup-java@v4 26 | with: 27 | java-version: '17' 28 | distribution: 'temurin' 29 | cache: maven 30 | - name: Build with Maven 31 | working-directory: play 32 | run: mvn -B package --file pom.xml 33 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Run tests 20 | run: cargo test --verbose 21 | -------------------------------------------------------------------------------- /.github/workflows/scala.yml: -------------------------------------------------------------------------------- 1 | name: Scala CI 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Set up JDK 17 20 | uses: actions/setup-java@v4 21 | with: 22 | java-version: '17' 23 | distribution: 'temurin' 24 | cache: 'sbt' 25 | - name: Run tests 26 | run: sbt algo/test 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .bloop 3 | .bsp 4 | target 5 | project/project 6 | *.iml 7 | Cargo.lock 8 | -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | // https://github.com/scalameta/scalafmt 2 | // https://scalameta.org/scalafmt/docs/configuration.html 3 | version = 3.8.2 4 | runner.dialect = scala213 5 | maxColumn = 200 6 | trailingCommas = preserve 7 | newlines { 8 | source = keep 9 | // don't squash lambda for onle liners 10 | afterCurlyLambdaParams = keep 11 | } 12 | 13 | // case class and def multiline definition: 2 spaces instead of 4 14 | continuationIndent.defnSite = 2 15 | 16 | align { 17 | // better indentation inside for 18 | preset = most 19 | // case class declaration 20 | openParenDefnSite = false 21 | 22 | tokens = ["%", "%%", "=>", "->", "<-", "//"] 23 | } 24 | // don't touch files don't belong to git 25 | project.git = true 26 | // don't touch my scaladoc 27 | docstrings { 28 | wrap = no 29 | } 30 | rewrite { 31 | rules = [ 32 | RedundantBraces 33 | RedundantParens 34 | ExpandImportSelectors 35 | AsciiSortImports 36 | PreferCurlyFors 37 | ] 38 | } 39 | rewriteTokens { 40 | "⇒" = "=>" 41 | "→" = "->" 42 | "←" = "<-" 43 | } 44 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-playground" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | colored = "2.1.0" 8 | rand = "^0.8.5" 9 | time = "0.3.36" 10 | regex = "1.11.0" 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### This repository related to algorithms topic 2 | 3 | This multilanguage repository is set up for writing code in: 4 | - Scala 5 | - Java 6 | - Rust 7 | 8 | ### Other related repositories: 9 | 10 | - [scala 99](https://github.com/djnzx/scala-99) 11 | - [rust course](https://github.com/djnzx/rust-course) 12 | - [main scala sandbox](https://github.com/djnzx/scala-course) 13 | - [main rust sandbox](https://github.com/djnzx/learning-rust) 14 | 15 | ### Copyright 16 | - 2017-2024 © Oleksiy Rykhalskyy. 17 | 18 | ![java](https://img.shields.io/badge/java-17.0.12-brightgreen) 19 | ![sbt](https://img.shields.io/badge/sbt-1.10.3-brightgreen) 20 | ![scala](https://img.shields.io/badge/scala-2.13.15-brightgreen) 21 | ![rust](https://img.shields.io/badge/rust-1.82.0-brightgreen) 22 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P10Length.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/fp-list-length/problem */ 4 | object P10Length { 5 | 6 | /** stdlib */ 7 | def f2(arr: List[Int]): Int = arr.length 8 | 9 | /** tail recursive */ 10 | def f1(arr: List[Int]): Int = { 11 | 12 | def go(xs: List[Int], acc: Int): Int = xs match { 13 | case _ :: t => go(t, acc + 1) 14 | case _ => acc 15 | } 16 | 17 | go(arr, 0) 18 | } 19 | 20 | /** classic recursive, but stack */ 21 | def f(arr: List[Int]): Int = arr match { 22 | case Nil => 0 23 | case _ :: t => 1 + f(t) 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P11UpdateList.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/fp-update-list/problem */ 4 | object P11UpdateList { 5 | 6 | /** tail recursive */ 7 | def f1(arr: List[Int]): List[Int] = { 8 | 9 | def go(xs: List[Int], acc: List[Int]): List[Int] = xs match { 10 | case h :: t => go(t, scala.math.abs(h) :: acc) 11 | case _ => acc 12 | } 13 | 14 | go(arr, List.empty[Int]).reverse 15 | } 16 | 17 | /** classic recursion */ 18 | def f(arr: List[Int]): List[Int] = arr match { 19 | case h :: t => scala.math.abs(h) :: f(t) 20 | case Nil => Nil 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P12EvalEx.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/eval-ex/problem */ 4 | object P12EvalEx { 5 | 6 | def next() = scala.io.StdIn.readLine().trim 7 | 8 | def fact(n: Int): Long = (1 to n).foldLeft(1: Long)((acc, x) => acc * x) 9 | def pow(x: Double, n: Int): Double = (1 to n).foldLeft(1.0)((acc, _) => acc * x) 10 | def ex(x: Double): Double = 1 + (1 to 9).foldLeft(0.0)((acc, n) => acc + pow(x, n) / fact(n)) 11 | 12 | def main(args: Array[String]): Unit = { 13 | val n = next().toInt 14 | (1 to n) 15 | .foreach { _ => 16 | val x = next().toDouble 17 | val r = ex(x) 18 | println("%.4f".format(r)) 19 | } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P14Reduction1.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/lambda-calculus-reductions-1/problem */ 4 | // https://en.wikipedia.org/wiki/Mathematical_operators_and_symbols_in_Unicode 5 | object P14Reduction1 { 6 | /* 7 | 8 | ((λx.(x y))(λz.z)) ≡ y 9 | 10 | */ 11 | } 12 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P15Reduction2.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/lambda-calculus-reductions-2/problem */ 4 | object P15Reduction2 { 5 | /* 6 | 7 | ((λx.((λy.(x y))x))(λz.w)) ≡ w 8 | 9 | */ 10 | } 11 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P16Reduction3.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/lambda-calculus-reductions-3/problem */ 4 | object P16Reduction3 { 5 | /* 6 | 7 | ((λx.(x x))(λx.(x x))) ≡ CAN'T REDUCE 8 | 9 | */ 10 | } 11 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P17Reduction4.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/lambda-calculus-reductions-4/problem */ 4 | object P17Reduction4 { 5 | /* 6 | 7 | (λg.((λf.((λx.(f (x x)))(λx.(f (x x))))) g)) ≡ g(g(g…)) 8 | 9 | CAN'T REDUCE 10 | 11 | */ 12 | } 13 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P18EvalEx1.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/lambda-calculus-getting-started/problem */ 4 | object P18EvalEx1 { 5 | /* 6 | 7 | (λx.x+1)3 ≡ 4 8 | 9 | */ 10 | } 11 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P19EvalEx2.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/lambda-calculus-understanding-the-syntax/problem */ 4 | object P19EvalEx2 { 5 | /* 6 | 7 | (λx.x+1)((λy.y+2)3) ≡ 6 8 | 1. y = 3 9 | 2. x = 5 10 | 11 | */ 12 | } 13 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P1SolveMeFirst.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/fp-solve-me-first/problem */ 4 | object P1SolveMeFirst { 5 | 6 | def main(args: Array[String]): Unit = { 7 | val xs = scala.io.Source.stdin.getLines().take(2) 8 | val sum = xs.map(_.toInt).sum 9 | println(sum) 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P20EvalEx3.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/lambda-calculus-evaluate-the-expression/problem */ 4 | object P20EvalEx3 { 5 | /* 6 | 7 | λx.λy.x^47y ≡ 47 8 | */ 9 | } 10 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P21EvalEx4.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/lambda-calculus-evaluate-the-expression-1/problem */ 4 | object P21EvalEx4 { 5 | /* 6 | 7 | λx.λy.x(xy) ≡ 2 8 | 9 | */ 10 | } 11 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P22EvalEx5.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/lambda-calculus-evaluate-the-expression-2/problem */ 4 | object P22EvalEx5 { 5 | /* 6 | 7 | λx.λy.y ≡ 0 8 | 9 | */ 10 | } 11 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P23FunctionsOrNot.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/functions-or-not/problem */ 4 | object P23FunctionsOrNot { 5 | 6 | /** 1. group by input 7 | * 2. if there is more output to one input the answer in NO 8 | */ 9 | def couldBeFunction1(in: Seq[(Int, Int)]): String = 10 | in.groupMapReduce { case (in, out) => in } { case (in, out) => Set(out) }(_ ++ _) 11 | .forall { case (_, outs) => outs.size == 1 } match { 12 | case true => "YES" 13 | case _ => "NO" 14 | } 15 | 16 | def couldBeFunction(in: Seq[(Int, Int)]): String = 17 | in.groupBy { case (in, out) => in } 18 | .map { case (in, outs) => in -> outs.map { case (in, out) => out }.toSet } 19 | .forall { case (_, outs) => outs.size == 1 } match { 20 | case true => "YES" 21 | case _ => "NO" 22 | } 23 | 24 | def next() = scala.io.StdIn.readLine() 25 | 26 | def main(args: Array[String]): Unit = 27 | (1 to next().toInt) 28 | .map { _ => 29 | (1 to next().toInt) 30 | .map(_ => next()) 31 | .map(_.split(" ")) 32 | .map(_.map(_.toInt)) 33 | .map { case Array(a, b) => (a, b) } 34 | } 35 | .foreach(couldBeFunction _ andThen println) 36 | 37 | } 38 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P24PolygonPerimeter.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | import scala.annotation.tailrec 4 | 5 | /** https://www.hackerrank.com/challenges/lambda-march-compute-the-perimeter-of-a-polygon/problem */ 6 | object P24PolygonPerimeter { 7 | 8 | case class Pt(x: Int, y: Int) 9 | 10 | def sq(x: Double): Double = x * x 11 | def distance(a: Pt, b: Pt): Double = scala.math.sqrt(sq(a.x - b.x) + sq(a.y - b.y)) 12 | 13 | def perimeter(points: List[Pt]): Double = { 14 | 15 | @tailrec 16 | def go(points: List[Pt], acc: Double): Double = points match { 17 | case a :: (t @ b :: _) => go(t, acc + distance(a, b)) 18 | case _ => acc 19 | } 20 | 21 | go(points.last :: points, 0) 22 | } 23 | 24 | def next = scala.io.StdIn.readLine() 25 | 26 | def main(p: Array[String]): Unit = { 27 | val points = (1 to next.toInt) 28 | .map(_ => next) 29 | .map(_.split(" ")) 30 | .map(_.map(_.toInt)) 31 | .map { case Array(x, y) => Pt(x, y) } 32 | .toList 33 | val p = perimeter(points) 34 | println(p) 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P25PolygonArea.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/lambda-march-compute-the-area-of-a-polygon/problem */ 4 | object P25PolygonArea { 5 | 6 | case class Pt(x: Double, y: Double) 7 | 8 | def sq(x: Double): Double = x * x 9 | def distance(a: Pt, b: Pt): Double = 10 | scala.math.sqrt(sq(a.x - b.x) + sq(a.y - b.y)) 11 | 12 | def area(ps: Seq[Pt]): Double = { 13 | val points = ps :+ ps.head 14 | val idx1 = points.indices 15 | val idx2 = points.indices.drop(1) 16 | 17 | val x2 = (idx1.iterator zip idx2.iterator) 18 | .map { case (i1, i2) => points(i1) -> points(i2) } 19 | .foldLeft(0.0) { case (sum, (p1, p2)) => sum + p1.x * p2.y - p1.y * p2.x } 20 | 21 | math.abs(x2 / 2) 22 | } 23 | 24 | def next = scala.io.StdIn.readLine() 25 | 26 | def main(p: Array[String]): Unit = { 27 | val points = (1 to next.toInt) 28 | .map(_ => next) 29 | .map(_.split(" ")) 30 | .map(_.map(_.toInt)) 31 | .map { case Array(x, y) => Pt(x, y) } 32 | val p = area(points) 33 | println(p) 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P2HelloWorld.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/fp-hello-world/problem */ 4 | object P2HelloWorld { 5 | 6 | def f() = println("Hello World") 7 | 8 | } 9 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P3HelloWorldNTimes.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/fp-hello-world-n-times/problem */ 4 | object P3HelloWorldNTimes { 5 | 6 | def f(n: Int) = 7 | (1 to n).foreach(_ => println("Hello World")) 8 | 9 | } 10 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P4ListReplication.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/fp-list-replication/problem */ 4 | object P4ListReplication { 5 | 6 | def f2(num: Int, arr: List[Int]): List[Int] = 7 | arr.flatMap(x => List.fill(num)(x)) 8 | 9 | def f(num: Int, arr: List[Int]): List[Int] = 10 | arr.flatMap(x => (1 to num).map(_ => x)) 11 | 12 | } 13 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P5FilterArrayLessThanN.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/fp-filter-array/problem */ 4 | object P5FilterArrayLessThanN { 5 | 6 | /** stdlib */ 7 | def f1(delim: Int, arr: List[Int]): List[Int] = 8 | arr.filter(_ < delim) 9 | 10 | /** pure FP, recursion */ 11 | def f(delim: Int, arr: List[Int]): List[Int] = arr match { 12 | case Nil => Nil 13 | case h :: t if h < delim => h :: f(delim, t) 14 | case _ :: t => f(delim, t) 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P6FilterOutOdd.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/fp-filter-positions-in-a-list/problem */ 4 | object P6FilterOutOdd { 5 | 6 | /** stdlib O(3*n) */ 7 | def f3(arr: List[Int]): List[Int] = 8 | arr.zipWithIndex 9 | .filter(_._2 % 2 != 0) 10 | .map(_._1) 11 | 12 | /** stdlib O(2*n) */ 13 | def f2(arr: List[Int]): List[Int] = 14 | arr.zipWithIndex 15 | .flatMap { 16 | case (n, idx) if idx % 2 != 0 => Some(n) 17 | case _ => None 18 | } 19 | 20 | /** stdlib, with state O(n) + reverse */ 21 | def f1(arr: List[Int]): List[Int] = 22 | arr.foldLeft(0 -> List.empty[Int]) { 23 | case ((idx, acc), x) if idx % 2 != 0 => (1 - idx) -> (x :: acc) 24 | case ((idx, acc), _) => (1 - idx) -> acc 25 | } match { 26 | case (_, acc) => acc.reverse 27 | } 28 | 29 | /** pure functional, O(n) */ 30 | def f(arr: List[Int]): List[Int] = { 31 | 32 | def go(idx: Int, xs: List[Int]): List[Int] = (idx, xs) match { 33 | case (1, h :: t) => h :: go(1 - idx, t) 34 | case (idx, _ :: t) => go(1 - idx, t) 35 | case _ => Nil 36 | } 37 | 38 | go(0, arr) 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P7GenListOfN.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/fp-array-of-n-elements/problem */ 4 | object P7GenListOfN { 5 | 6 | /** stdlib */ 7 | def f1(num: Int): List[Int] = 8 | Array.fill[Int](num)(1).toList 9 | 10 | /** stdlib */ 11 | def f2(num: Int): List[Int] = 12 | 1 to num toList 13 | 14 | /** pure functional without any magic numbers */ 15 | def f(num: Int): List[Int] = num match { 16 | case 0 => Nil 17 | case n => n :: f(n - 1) 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P8ReverseList.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | import scala.annotation.tailrec 4 | 5 | /** https://www.hackerrank.com/challenges/fp-reverse-a-list/problem */ 6 | object P8ReverseList { 7 | 8 | /** stdlib */ 9 | def f2(arr: List[Int]): List[Int] = arr.reverse 10 | 11 | /** classic recursive, but O(n^2^) */ 12 | def f1(arr: List[Int]): List[Int] = arr match { 13 | case Nil => Nil 14 | case h :: t => f1(t) :+ h 15 | } 16 | 17 | /** tail recursive */ 18 | def f(arr: List[Int]): List[Int] = { 19 | 20 | @tailrec 21 | def go(xs: List[Int], acc: List[Int]): List[Int] = xs match { 22 | case h :: t => go(t, h :: acc) 23 | case _ => acc 24 | } 25 | 26 | go(arr, Nil) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a1intro/P9SumOfOdd.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a1intro 2 | 3 | /** https://www.hackerrank.com/challenges/fp-sum-of-odd-elements/problem */ 4 | object P9SumOfOdd { 5 | 6 | /** stdlib foldLeft */ 7 | def f1(arr: List[Int]): Int = 8 | arr.foldLeft(0) { 9 | case (acc, x) if x % 2 != 0 => acc + x 10 | case (acc, _) => acc 11 | } 12 | 13 | def f(delim: Int, arr: List[Int]): List[Int] = arr match { 14 | case Nil => Nil 15 | case h :: t if h < delim => h :: f(delim, t) 16 | case _ :: t => f(delim, t) 17 | } 18 | 19 | def f(arr: List[Int]): Int = { 20 | 21 | def isOdd(x: Int) = x % 2 != 0 22 | 23 | def go(arr: List[Int], acc: Int): Int = arr match { 24 | case Nil => acc 25 | case h :: t if isOdd(h) => go(t, acc + h) 26 | case _ :: t => go(t, acc) 27 | } 28 | 29 | go(arr, 0) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P11Prefix.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | /** https://www.hackerrank.com/challenges/prefix-compression/problem */ 4 | object P11Prefix { 5 | 6 | /** classic recursion */ 7 | def findDiff1(s1: String, s2: String): Int = { 8 | def go(idx: Int): Int = 9 | if (idx < s1.length && idx < s2.length && s1(idx) == s2(idx)) go(idx + 1) 10 | else idx 11 | go(0) 12 | } 13 | 14 | /** stdlib, declarative, also lazy */ 15 | def findDiff(s1: String, s2: String): Int = 16 | s1.zip(s2).zipWithIndex 17 | .find { case ((c1, c2), _) => c1 != c2 } 18 | .fold(s1.length min s2.length) { case (_, idx) => idx } 19 | 20 | def show(idx: Int, s1: String, s2: String) = List( 21 | s"$idx ${s1.substring(0, idx)}", 22 | s"${s1.length - idx} ${s1.substring(idx)}", 23 | s"${s2.length - idx} ${s2.substring(idx)}", 24 | ).mkString("\n") 25 | 26 | def next() = scala.io.StdIn.readLine() 27 | 28 | def main(p: Array[String]): Unit = { 29 | val s1 = next() 30 | val s2 = next() 31 | val r = findDiff(s1, s2) 32 | val s = show(r, s1, s2) 33 | println(s) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P12StringReduction.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | /** https://www.hackerrank.com/challenges/string-reductions/problem */ 4 | object P12StringReduction { 5 | 6 | def solve(s: String) = { 7 | @scala.annotation.tailrec 8 | def go(tail: List[Char], acc: List[Char]): List[Char] = tail match { 9 | case Nil => acc.reverse 10 | case h :: t if acc.contains(h) => go(t, acc) 11 | case h :: t => go(t, h :: acc) 12 | } 13 | go(s.toList, Nil).mkString 14 | } 15 | 16 | def next() = scala.io.StdIn.readLine() 17 | 18 | def main(p: Array[String]): Unit = { 19 | val s = next() 20 | val r = solve(s) 21 | println(r) 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P13SuperQueenMutable.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | import scala.collection.mutable.ListBuffer 4 | 5 | object P13SuperQueenMutable extends App { 6 | case class Pos(x: Int, y: Int) 7 | def exa(free: List[Pos], queen: Pos): List[Pos] = { 8 | def isua(x: Int, y: Int) = 9 | x == queen.x || y == queen.y || 10 | (math.abs(x - queen.x) == math.abs(y - queen.y)) || 11 | (math.abs(queen.x - x) <= 2 && math.abs(queen.y - y) <= 2) 12 | free.foldLeft(new ListBuffer[Pos])((acc, p) => if (isua(p.x, p.y)) acc else acc.addOne(p)).toList 13 | } 14 | 15 | def solveNSuperQueens(N: Int) = { 16 | val range = (1 to N).toList 17 | val all = range.flatMap(x => range.map(y => Pos(x, y))) 18 | 19 | def solve(start: Pos) = { 20 | 21 | def doSolve(queens: List[Pos], free: List[Pos]): List[Set[Pos]] = 22 | if (queens.size == N) List(queens.toSet) 23 | else if (free.length + queens.length < N) List.empty 24 | else 25 | doSolve(free.head :: queens, exa(free, free.head)) ++ 26 | doSolve(queens, free.tail) 27 | 28 | doSolve(List(start), exa(all, start)) 29 | } 30 | 31 | range 32 | .map(Pos(_, 1)) 33 | .flatMap(solve) 34 | .size 35 | } 36 | 37 | (10 to 14) 38 | .foreach(x => println(solveNSuperQueens(x))) 39 | 40 | } 41 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P13SuperQueens.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | /** https://www.hackerrank.com/challenges/super-queens-on-a-chessboard/problem */ 4 | object P13SuperQueens { 5 | 6 | case class Pos(x: Int, y: Int) 7 | 8 | def noConflict(p: Pos, qs: List[Pos]): Boolean = qs.forall { q => 9 | val dx = p.x - q.x 10 | val dy = math.abs(p.y - q.y) 11 | val c1 = !(p.y == q.y) 12 | val c2 = !(dy == dx) 13 | val c3 = !(dx == 2 && dy == 1 || dx == 1 && dy == 2) 14 | c1 && c2 && c3 15 | } 16 | 17 | def solveNSuperQueens(n: Int): Int = { 18 | 19 | def go(rest: Int, acc: List[Pos]): Int = rest match { 20 | case 0 => 1 21 | case rest => 22 | (0 until n).map { y => 23 | val p = Pos(n - rest, y) 24 | noConflict(p, acc) match { 25 | case true => go(rest - 1, p :: acc) 26 | case _ => 0 27 | } 28 | }.sum 29 | } 30 | 31 | go(n, Nil) 32 | } 33 | 34 | def main(args: Array[String]): Unit = { 35 | val n = scala.io.StdIn.readInt() 36 | val x = solveNSuperQueens(n) 37 | println(x) 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P14SumOfPowersCountOnly.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | object P14SumOfPowersCountOnly { 4 | 5 | /** dynamic programming, only ways */ 6 | def numberOfWays(x: Int, n: Int): Int = { 7 | val max = math.floor(math.pow(x, 1.0 / n)).toInt 8 | val powers = (1 to max).map(c => math.pow(c, n).toInt).toList 9 | def count(s: Int, candidates: List[Int]): Int = candidates match { 10 | case Nil => 0 11 | case c :: cs => 12 | if (c == s) 1 13 | else if (c > s) count(s, cs) 14 | else count(s - c, cs) + count(s, cs) 15 | } 16 | 17 | count(x, powers) 18 | } 19 | 20 | def next() = scala.io.StdIn.readLine() 21 | 22 | def main(args: Array[String]): Unit = { 23 | val x = next().toInt 24 | val n = next().toInt 25 | val r = numberOfWays(x, n) 26 | println(r) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P15SequenceOfColors.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | /** https://www.hackerrank.com/challenges/sequence-full-of-colors/problem */ 4 | object P15SequenceOfColors { 5 | 6 | case class CC(r: Int, g: Int, y: Int, b: Int) { 7 | def process(c: Char): Option[CC] = { 8 | val cc = c match { 9 | case 'R' => this.copy(r = r + 1) 10 | case 'G' => this.copy(g = g + 1) 11 | case 'Y' => this.copy(y = y + 1) 12 | case 'B' => this.copy(b = b + 1) 13 | } 14 | val cond = (math.abs(cc.r - cc.g) <= 1) && (math.abs(cc.y - cc.b) <= 1) 15 | Option.when(cond)(cc) 16 | } 17 | } 18 | val cc0 = CC(0, 0, 0, 0) 19 | 20 | def processOne(s: String): Boolean = { 21 | 22 | def go(i: Int, cco: Option[CC]): Option[CC] = cco match { 23 | case None => None 24 | case Some(cc) => if (i < s.length) go(i + 1, cc.process(s(i))) else cco 25 | } 26 | 27 | go(0, Some(cc0)) match { 28 | case None => false 29 | case Some(CC(r, g, y, b)) => r == g && y == b 30 | } 31 | } 32 | 33 | def represent(value: Boolean): String = value.toString.capitalize 34 | 35 | def solve(data: List[String]) = data.map(processOne).map(represent) 36 | 37 | def next() = scala.io.StdIn.readLine() 38 | 39 | def main(args: Array[String]): Unit = { 40 | val N = next().toInt 41 | val list = (1 to N).map(_ => next()).toList 42 | solve(list) 43 | .foreach(println) 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P16FilterElements.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | /** https://www.hackerrank.com/challenges/filter-elements/problem */ 4 | object P16FilterElements { 5 | 6 | implicit class StringToOps(s: String) { 7 | def splitToInts = s.split(" ").map(_.toInt) 8 | } 9 | 10 | type TI = (Int, Int) 11 | 12 | def solve1(tc: TestCase) = 13 | tc.data.groupBy(identity) 14 | .filter(t => t._2.length >= tc.n) 15 | .keys.toArray 16 | .map(x => (x, tc.data.indexOf(x))) 17 | .sorted((x: TI, y: TI) => x._2 - y._2) 18 | .map(_._1) 19 | 20 | def solveN(data: List[TestCase]) = 21 | data 22 | .map(solve1) 23 | .map(l => if (l.nonEmpty) l.mkString(" ") else "-1") 24 | 25 | case class TestCase(n: Int, data: Array[Int]) 26 | 27 | def next() = scala.io.StdIn.readLine() 28 | def readOne = TestCase( 29 | next().splitToInts(1), 30 | next().splitToInts 31 | ) 32 | def readAll(n: Int, acc: List[TestCase]): List[TestCase] = n match { 33 | case 0 => acc.reverse 34 | case _ => readAll(n - 1, readOne :: acc) 35 | } 36 | 37 | def main(args: Array[String]): Unit = { 38 | val n = next().toInt 39 | val r = solveN(readAll(n, Nil)) 40 | r.foreach(println) 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P17SuperDigit.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | /** https://www.hackerrank.com/challenges/super-digit/problem */ 4 | object P17SuperDigit { 5 | 6 | def sum(s: String) = s.foldLeft(0) { case (a, c) => a + (c - '0') } 7 | 8 | def superDigit(n: String): Int = n.length match { 9 | case 1 => n.toInt 10 | case _ => superDigit(sum(n).toString) 11 | } 12 | 13 | def solve(n: String, k: Int) = { 14 | val sn = superDigit(n) 15 | val snk = sn * k 16 | superDigit(snk.toString) 17 | } 18 | 19 | def next() = scala.io.StdIn.readLine() 20 | 21 | def main(p: Array[String]): Unit = { 22 | val (n, k) = next().split(" ") match { 23 | case Array(n, k) => n -> k.toInt 24 | } 25 | val r = solve(n, k) 26 | println(r) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P1GCD.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | /** https://www.hackerrank.com/challenges/functional-programming-warmups-in-recursion---gcd/problem */ 4 | object P1GCD { 5 | 6 | def gcd(x: Int, y: Int): Int = (x, y) match { 7 | case (x, 0) => x 8 | case (x, y) if x > y => gcd(y, x % y) 9 | case (x, y) if y > x => gcd(x, y % x) 10 | case _ => x 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P2Fibonacci.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | import djnz.tools.ASuite 4 | 5 | /** https://www.hackerrank.com/challenges/functional-programming-warmups-in-recursion---fibonacci-numbers/problem */ 6 | object P2Fibonacci { 7 | 8 | /** classic recursion `unfold` based, with state of 2 numbers */ 9 | def f1(n: Int): Int = { 10 | 11 | case class S(n: Int, f1: Int, f2: Int) 12 | val s0 = S(n, 0, 1) 13 | 14 | LazyList.unfold(s0) { 15 | case S(0, _, _) => None 16 | case S(n, f1, f2) => Some((f1, S(n - 1, f2, f1 + f2))) 17 | }.last 18 | } 19 | 20 | /** classic recursion */ 21 | def f(n: Int): Int = { 22 | assert(n > 0) 23 | 24 | def go(n: Int, f1: Int, f2: Int): Int = n match { 25 | case 1 => f1 26 | case n => go(n - 1, f2, f1 + f2) 27 | } 28 | 29 | go(n, 0, 1) 30 | } 31 | 32 | } 33 | 34 | class P2Fibonacci extends ASuite { 35 | 36 | import P2Fibonacci._ 37 | 38 | test("1") { 39 | val testData = Table( 40 | "in" -> "out", 41 | 1 -> 0, 42 | 2 -> 1, 43 | 3 -> 1, 44 | 4 -> 2, 45 | 5 -> 3, 46 | 6 -> 5, 47 | 7 -> 8, 48 | 8 -> 13, 49 | 9 -> 21, 50 | 10 -> 34, 51 | 11 -> 55, 52 | ) 53 | 54 | forAll(testData) { case (in, out) => 55 | f1(in) shouldBe out 56 | f(in) shouldBe out 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P3PascalTriangle.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | /** https://www.hackerrank.com/challenges/pascals-triangle/problem */ 4 | object P3PascalTriangle { 5 | 6 | def fact(n: Int): Long = (1 to n).foldLeft(1L)((acc, x) => acc * x) 7 | def cell(row: Int, col: Int): Long = fact(row) / (fact(col) * fact(row - col)) 8 | 9 | def line(n_row: Int): List[Long] = { 10 | 11 | def go(n_col: Int, acc: List[Long]): List[Long] = 12 | if (n_col > n_row) acc.reverse 13 | else go(n_col + 1, cell(n_row, n_col) :: acc) 14 | 15 | go(0, Nil) 16 | } 17 | 18 | def pascalTriangle(rows: Int): List[List[Long]] = { 19 | 20 | def go(row: Int, acc: List[List[Long]]): List[List[Long]] = row match { 21 | case `rows` => acc.reverse 22 | case _ => go(row + 1, line(row) :: acc) 23 | } 24 | 25 | go(0, Nil) 26 | } 27 | 28 | def main(args: Array[String]): Unit = { 29 | val n = scala.io.StdIn.readInt() 30 | val s = pascalTriangle(n) 31 | .map(_.mkString(" ")) 32 | .mkString("\n") 33 | 34 | println(s) 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P4Sierpinski.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | /** https://www.hackerrank.com/challenges/functions-and-fractals-sierpinski-triangles/problem */ 4 | object P4Sierpinski { 5 | type Triangle = Array[String] 6 | 7 | val EMPTY = "_" 8 | val FILLED = "1" 9 | 10 | def base(n: Int): Triangle = { 11 | val h = 1 << n 12 | (1 to h).map { x => 13 | val pad = EMPTY * (h - x) 14 | pad + FILLED * (x * 2 - 1) + pad 15 | }.toArray 16 | } 17 | 18 | def scale(t: Triangle): Triangle = { 19 | val width = t(0).length 20 | val widthNew = width * 2 + 1 21 | val emptyWidth = (widthNew - width) / 2 22 | val emptyPart = EMPTY * emptyWidth 23 | val top = t.map(x => emptyPart + x + emptyPart) 24 | val bottom = t.map(x => x + EMPTY + x) 25 | top ++ bottom 26 | } 27 | 28 | def scale(n: Int, t: Triangle): Triangle = n match { 29 | case 0 => t 30 | case n => scale(n - 1, scale(t)) 31 | } 32 | 33 | def make(n: Int): Triangle = scale(n, base(5 - n)) 34 | 35 | def main(args: Array[String]): Unit = { 36 | val n = scala.io.StdIn.readInt() 37 | val t = make(n).mkString("\n") 38 | println(t) 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P5StringMingling.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | /** https://www.hackerrank.com/challenges/string-mingling/problem */ 4 | object P5StringMingling { 5 | 6 | def mingle(p: String, q: String): String = 7 | (p zip q) 8 | .map { case (a, b) => s"$a$b" } 9 | .mkString 10 | 11 | def main(args: Array[String]): Unit = { 12 | val p = scala.io.StdIn.readLine() 13 | val q = scala.io.StdIn.readLine() 14 | val r = mingle(p, q) 15 | println(r) 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P6StringOPermute.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | /** https://www.hackerrank.com/challenges/string-o-permute/problem */ 4 | object P6StringOPermute { 5 | 6 | /** classic recursion, but stack */ 7 | def permute2(s: String): String = { 8 | 9 | def go(s: List[Char]): List[Char] = s match { 10 | case a :: b :: cs => b :: a :: go(cs) 11 | case _ => Nil 12 | } 13 | 14 | go(s.toList).mkString 15 | } 16 | 17 | /** tail recursion, no stack consumption */ 18 | def permute(s: String): String = { 19 | val half = s.length / 2 20 | 21 | def go(i: Int, acc: List[Char]): List[Char] = i match { 22 | case `half` => acc 23 | case _ => go(i + 1, s(i * 2) :: s(i * 2 + 1) :: acc) 24 | } 25 | 26 | go(0, Nil).reverse.mkString 27 | } 28 | 29 | def next() = scala.io.StdIn.readLine() 30 | 31 | def main(args: Array[String]): Unit = { 32 | val n = next().toInt 33 | (1 to n) 34 | .map(_ => next()) 35 | .map(permute) 36 | .foreach(println) 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a2recursion/P9Compression.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a2recursion 2 | 3 | /** https://www.hackerrank.com/challenges/string-compression/problem */ 4 | object P9Compression { 5 | 6 | def solve(s: String): String = { 7 | type Item = (Char, Int) 8 | def go(tail: List[Char], curr: Option[Item], acc: List[Item]): List[Item] = (curr, tail) match { 9 | case (None, Nil) => Nil // nothing to collect 10 | case (None, h :: t) => go(t, Some(h -> 1), acc) // start collecting 11 | case (Some(itm), Nil) => (itm :: acc).reverse // done collecting 12 | case (Some((c, cnt)), h :: t) if h == c => go(t, Some(c -> (cnt + 1)), acc) // same char 13 | case (Some(itm), h :: t) => go(t, Some(h -> 1), itm :: acc) // new char 14 | } 15 | 16 | go(s.toList, None, Nil) 17 | .foldLeft("") { 18 | case (acc, (a, 1)) => s"$acc$a" 19 | case (acc, (a, n)) => s"$acc$a$n" 20 | } 21 | } 22 | 23 | def main(args: Array[String]): Unit = { 24 | val s = scala.io.StdIn.readLine() 25 | val r = solve(s) 26 | println(r) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a3structures/P3IsPreorderBST.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a3structures 2 | 3 | /** https://www.hackerrank.com/challenges/valid-bst/problem 4 | * https://www.geeksforgeeks.org/check-if-a-given-array-can-represent-preorder-traversal-of-binary-search-tree/ 5 | */ 6 | object P3IsPreorderBST { 7 | 8 | case class XState(stack: List[Int], root: Int, valid: Boolean = true) 9 | val s0 = XState(Nil, Integer.MIN_VALUE) 10 | 11 | def isBST(data: Vector[Int]): Boolean = data.foldLeft(s0) { 12 | case (st @ XState(_, _, false), _) => st 13 | case (st, x) if x < st.root => st.copy(valid = false) 14 | case (st, x) => 15 | def go(s0: List[Int], r0: Int): (List[Int], Int) = s0 match { 16 | case h :: t if h < x => go(t, h) 17 | case s0 => (s0, r0) 18 | } 19 | 20 | go(st.stack, st.root) match { 21 | case (s2, r2) => XState(x :: s2, r2) 22 | } 23 | } 24 | .valid 25 | 26 | def solve(line1: String, tree: String): Boolean = { 27 | val data = tree.split(" ").map(_.toInt).toVector 28 | 29 | isBST(data) 30 | } 31 | 32 | def next() = scala.io.StdIn.readLine() 33 | 34 | def main(p: Array[String]): Unit = 35 | (1 to next().toInt) 36 | .map(_ => solve(next(), next())) 37 | .map(if (_) "YES" else "NO") 38 | .foreach(println) 39 | 40 | } 41 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a3structures/P4ListsAndGCD.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a3structures 2 | 3 | /** https://www.hackerrank.com/challenges/lists-and-gcd/problem */ 4 | object P4ListsAndGCD { 5 | 6 | def toPairs(x: List[Int], acc: List[(Int, Int)]): List[(Int, Int)] = x match { 7 | case Nil => acc.reverse 8 | case a :: b :: tail => toPairs(tail, (a, b) :: acc) 9 | case _ => sys.error("we don't handle odd count of elements") 10 | } 11 | 12 | def process(data: List[List[Int]]) = { 13 | val maps = data.map(toPairs(_, Nil)).map(_.toMap) 14 | maps 15 | .foldLeft(Set.empty[Int])((set, x) => set ++ x.keys) 16 | .map(p => (p, maps.map(_.getOrElse(p, 0)).min)) 17 | .filter { case (_, b) => b > 0 } 18 | .toList 19 | .sorted 20 | .map { case (a, b) => s"$a $b" } 21 | .mkString(" ") 22 | } 23 | 24 | def next() = scala.io.StdIn.readLine() 25 | def read1() = next().split(" ").map(_.toInt).toList 26 | def readN(n: Int, acc: List[List[Int]]): List[List[Int]] = n match { 27 | case 0 => acc.reverse 28 | case _ => readN(n - 1, read1() :: acc) 29 | } 30 | 31 | def main(args: Array[String]): Unit = { 32 | val n = next().toInt 33 | val r = process(readN(n, Nil)) 34 | println(r) 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/fp/a3structures/P8JohnAndFences.scala: -------------------------------------------------------------------------------- 1 | package djnz.hackerrank.fp.a3structures 2 | 3 | /** https://www.hackerrank.com/challenges/john-and-fences/problem */ 4 | object P8JohnAndFences { 5 | 6 | def next() = scala.io.StdIn.readLine() 7 | 8 | def calcFence(fence: Vector[Int]) = { 9 | 10 | def pass1(i: Int, progress: List[Int], mx: Int): (List[Int], Int) = progress match { 11 | case _ if i == fence.length => (progress, mx) 12 | case Nil => pass1(i + 1, i :: progress, mx) 13 | case h :: _ if fence(i) > fence(h) => pass1(i + 1, i :: progress, mx) 14 | case h :: Nil => pass1(i, Nil, mx max fence(h) * i) 15 | case h :: (t @ g :: _) => pass1(i, t, mx max fence(h) * (i - 1 - g)) 16 | } 17 | 18 | pass1(0, Nil, 0) match { 19 | case (stack, mx) => 20 | stack.foldLeft(mx) { case (pmax, h) => 21 | pmax max fence(h) * (fence.length - 1 - h) 22 | } 23 | } 24 | 25 | } 26 | 27 | def main(args: Array[String]): Unit = { 28 | val _ = next() 29 | val fence = next().split(" ").map(_.toInt).toVector 30 | val max = calcFence(fence) 31 | println(max) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/hackerrank/index.md: -------------------------------------------------------------------------------- 1 | ### Main Dashboard 2 | https://www.hackerrank.com/dashboard 3 | 4 | https://www.hackerrank.com/domains/algorithms 5 | https://www.hackerrank.com/domains/fp 6 | https://www.hackerrank.com/domains/ai 7 | https://www.hackerrank.com/domains/java 8 | https://www.hackerrank.com/domains/sql 9 | https://www.hackerrank.com/domains/data-structures 10 | https://www.hackerrank.com/domains/databases 11 | https://www.hackerrank.com/domains/mathematics 12 | 13 | https://www.hackerrank.com/domains/tutorials 14 | https://www.hackerrank.com/domains/regex 15 | https://www.hackerrank.com/domains/shell 16 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/interviews/README.md: -------------------------------------------------------------------------------- 1 | ### 2020-08-25, Nixa 2 | 3 | - [task1](nixa/Task1.scala) 4 | - [task2](nixa/Task2.scala) 5 | - [task3](nixa/Task3.SQL) 6 | 7 | ### 2020-09-03, Luxoft 8 | 9 | - What Type Class Is [code](luxoft/WhatTypeClassIs.scala) 10 | 11 | ### 2021-02-16, Chili Piper 12 | 13 | - AirportLimousine [code](chilipiper/airport/AirportLimousine.scala) 14 | - Turnstile [code](chilipiper/turn/Turnstile.scala) 15 | 16 | ### 2020-11-10, Chi 17 | 18 | - The last digit of $5137^{100000000000}$ 19 | - [java code](chi/SevenToPower.java) 20 | - [scala code](chi/SevenToPowerOfN.scala) 21 | 22 | ### 2022-06-17, Agile Engine 23 | 24 | - [task](agileengine/Task1.scala) 25 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/interviews/agileengine/Task1.scala: -------------------------------------------------------------------------------- 1 | package djnz.interviews.agileengine 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers 5 | import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks 6 | 7 | /** Calculate the rightmost index in the given array 8 | * where the counts of occurrences of `x` and `y` are equal 9 | * when scanning from the start to that index. 10 | */ 11 | object Task1 { 12 | 13 | case class S(idx: Int, xc: Int, yc: Int, r: Int) 14 | val s0 = S(0, 0, 0, -1) 15 | 16 | def solution(x: Int, y: Int, aa: Array[Int]): Int = 17 | aa.foldLeft(s0) { case (S(idx, xc, yc, r), a) => 18 | val xc2 = xc + (if (x == a) 1 else 0) 19 | val yc2 = yc + (if (y == a) 1 else 0) 20 | val r2 = if (xc2 == yc2) idx else r 21 | S(idx + 1, xc2, yc2, r2) 22 | }.r 23 | 24 | } 25 | 26 | class Task1 extends AnyFunSuite with Matchers with ScalaCheckPropertyChecks { 27 | 28 | test("1") { 29 | 1 shouldBe 1 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/interviews/chi/SevenToPower.java: -------------------------------------------------------------------------------- 1 | package djnz.interviews.chi; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | public class SevenToPower { 6 | 7 | public static void main(String[] args) { 8 | int r = IntStream 9 | .rangeClosed(1, 1000001) 10 | .reduce(1, (a, b) -> a * 7 % 10); 11 | 12 | System.out.println(r); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/interviews/chilipiper/airport/data/input004.txt: -------------------------------------------------------------------------------- 1 | 20 2 | 20 3 | 1 0 1 0 -1 1 1 0 1 0 1 1 1 0 1 1 0 1 -1 1 4 | -1 0 0 1 1 1 -1 1 -1 1 1 0 0 0 1 1 0 1 -1 0 5 | 0 1 -1 0 1 -1 1 1 1 -1 0 -1 1 1 0 0 -1 -1 1 1 6 | 0 0 1 0 0 0 0 1 1 -1 1 1 1 1 1 0 1 1 0 1 7 | 1 0 1 0 1 1 1 1 1 1 0 1 1 0 0 1 1 1 -1 1 8 | 0 1 0 -1 1 0 0 1 0 0 1 -1 0 1 0 1 -1 1 1 1 9 | 1 1 0 0 1 0 1 0 1 1 0 0 0 1 0 1 1 1 1 0 10 | -1 1 1 1 -1 0 -1 1 0 1 0 1 1 0 1 -1 0 0 1 1 11 | 0 0 0 1 1 -1 1 1 -1 0 0 0 -1 1 0 0 0 0 1 -1 12 | 0 0 1 0 1 0 1 0 1 -1 1 1 1 0 1 1 1 0 -1 1 13 | 1 0 1 0 -1 0 0 -1 0 0 -1 1 1 1 1 0 0 1 1 0 14 | 1 1 1 1 0 1 0 0 0 0 -1 1 0 -1 0 0 0 0 1 1 15 | 0 0 0 1 0 1 1 0 1 -1 1 -1 0 1 1 0 -1 -1 -1 -1 16 | 1 1 0 0 1 1 1 0 0 -1 0 1 0 1 0 0 -1 1 0 1 17 | 0 1 -1 0 0 1 0 0 1 -1 -1 0 -1 1 -1 0 0 -1 0 -1 18 | 0 1 0 -1 0 -1 1 0 0 1 -1 0 0 0 1 -1 0 0 0 0 19 | 1 0 0 -1 1 1 0 0 1 0 1 -1 1 0 -1 0 0 1 1 0 20 | 0 1 1 -1 0 0 0 0 1 -1 0 -1 0 1 1 -1 1 1 0 0 21 | 1 0 1 1 1 1 0 1 0 0 1 0 0 0 0 1 1 0 1 0 22 | 1 1 0 0 0 1 0 0 1 0 1 1 1 1 1 -1 1 0 1 -1 -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/interviews/chilipiper/airport/desc/1a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/algo/src/main/scala/djnz/interviews/chilipiper/airport/desc/1a.png -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/interviews/chilipiper/airport/desc/1b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/algo/src/main/scala/djnz/interviews/chilipiper/airport/desc/1b.png -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/interviews/chilipiper/turn/data/input004.txt: -------------------------------------------------------------------------------- 1 | 10 2 | 3 3 | 3 4 | 3 5 | 4 6 | 4 7 | 5 8 | 6 9 | 6 10 | 7 11 | 8 12 | 10 13 | 1 14 | 1 15 | 0 16 | 1 17 | 0 18 | 0 19 | 0 20 | 1 21 | 0 22 | 0 23 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/interviews/chilipiper/turn/desc/2a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/algo/src/main/scala/djnz/interviews/chilipiper/turn/desc/2a.png -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/interviews/chilipiper/turn/desc/2b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/algo/src/main/scala/djnz/interviews/chilipiper/turn/desc/2b.png -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/interviews/chilipiper/turn/desc/2c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/algo/src/main/scala/djnz/interviews/chilipiper/turn/desc/2c.png -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/interviews/luxoft/WhatTypeClassIs.scala: -------------------------------------------------------------------------------- 1 | package djnz.interviews.luxoft 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | 5 | class WhatTypeClassIs extends AnyFunSuite { 6 | 7 | /** 1. define behavior */ 8 | trait Show[A] { 9 | def show(a: A): String 10 | } 11 | 12 | /** 2. create instances for types I want to attach my behavior */ 13 | implicit val ss: Show[String] = new Show[String] { 14 | override def show(a: String): String = s"I'm a String: $a" 15 | } 16 | implicit val si: Show[Int] = new Show[Int] { 17 | override def show(a: Int): String = s"I'm an Int: $a" 18 | } 19 | 20 | test("using without syntax") { 21 | ss.show("AAA") 22 | si.show(123) 23 | } 24 | 25 | /** 3. define syntax */ 26 | implicit class ShowSyntax[A: Show](a: A) { 27 | def show() = implicitly[Show[A]].show(a) 28 | } 29 | 30 | test("using with syntax") { 31 | "AAA".show() 32 | 123.show() 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/interviews/nixa/Task3.SQL: -------------------------------------------------------------------------------- 1 | create table if not exists department( 2 | id integer, 3 | name varchar, 4 | location varchar 5 | ); 6 | 7 | INSERT INTO department (id, name, location) VALUES (1, 'Executive', 'Kyiv'); 8 | INSERT INTO department (id, name, location) VALUES (2, 'Prod', 'Dnepr'); 9 | INSERT INTO department (id, name, location) VALUES (3, 'Res', 'Kyiv'); 10 | INSERT INTO department (id, name, location) VALUES (4, 'Tech', 'Texas'); 11 | INSERT INTO department (id, name, location) VALUES (5, 'Manag', 'Texas'); 12 | 13 | create table if not exists employee( 14 | id integer, 15 | name varchar, 16 | salary integer, 17 | dept_id integer 18 | ); 19 | 20 | INSERT INTO employee (id, name, salary, dept_id) VALUES (4, 'Max', 450, 1); 21 | INSERT INTO employee (id, name, salary, dept_id) VALUES (1, 'Jim', 500, 1); 22 | INSERT INTO employee (id, name, salary, dept_id) VALUES (3, 'Bob', 400, 4); 23 | INSERT INTO employee (id, name, salary, dept_id) VALUES (5, 'Serg', 700, 4); 24 | INSERT INTO employee (id, name, salary, dept_id) VALUES (2, 'Alex', 600, 2); 25 | 26 | select 27 | d.name, 28 | CASE when cnt IS NULL THEN 0 ELSE cnt END cnt0 29 | from 30 | department d 31 | left outer join 32 | (select count(*) as cnt, dept_id from employee group by 2) CNTG on (d.id = CNTG.dept_id) 33 | order by 34 | cnt0 desc, d.name 35 | 36 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/tools/ASuite.scala: -------------------------------------------------------------------------------- 1 | package djnz.tools 2 | 3 | import org.scalatest.funsuite.AnyFunSuite 4 | import org.scalatest.matchers.should.Matchers 5 | import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks 6 | 7 | trait ASuite extends AnyFunSuite with Matchers with ScalaCheckPropertyChecks 8 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/tools/Console.scala: -------------------------------------------------------------------------------- 1 | package djnz.tools 2 | 3 | import scala.collection.mutable 4 | import scala.io.StdIn 5 | 6 | trait Console { 7 | def readLine(): String 8 | def printLine(line: String): Unit 9 | } 10 | 11 | object Console { 12 | 13 | private object Real extends Console { 14 | 15 | override def readLine(): String = 16 | StdIn.readLine() 17 | 18 | override def printLine(line: String): Unit = 19 | println(line) 20 | 21 | } 22 | 23 | class Test(input: Iterable[String]) extends Console { 24 | private val it = 25 | input.iterator 26 | 27 | private val buffer = 28 | mutable.ListBuffer.empty[String] 29 | 30 | override def readLine(): String = 31 | it.nextOption().getOrElse("") 32 | 33 | override def printLine(line: String): Unit = 34 | buffer.append(line) 35 | 36 | def output: Seq[String] = 37 | buffer.toSeq 38 | 39 | } 40 | 41 | val real: Console = Real 42 | def test(input: Iterable[String]): Test = new Test(input) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /algo/src/main/scala/djnz/tools/StdInput.scala: -------------------------------------------------------------------------------- 1 | package djnz.tools 2 | 3 | trait StdInput { 4 | 5 | def next: String = scala.io.StdIn.readLine() 6 | def lines: Iterator[String] = scala.io.Source.stdin.getLines() 7 | 8 | } 9 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/_unpolished/IList.java: -------------------------------------------------------------------------------- 1 | package algorithms._unpolished; 2 | 3 | public interface IList { 4 | void add(int el); 5 | int get(int index); 6 | int size(); 7 | void remove(int index); 8 | void remove(); 9 | void print(); 10 | } 11 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/_unpolished/XLinedListApp.java: -------------------------------------------------------------------------------- 1 | package algorithms._unpolished; 2 | 3 | import java.util.LinkedList; 4 | 5 | public class XLinedListApp { 6 | 7 | LinkedList queue = new LinkedList<>(); 8 | 9 | void produce() { 10 | int el = (int) (Math.random()*100); 11 | queue.addFirst(el); 12 | } 13 | 14 | int get() { 15 | return queue.pollLast(); 16 | // queue.getLast(); // last or Exception 17 | // return queue.poll(); // 1-st or null 18 | // queue.remove(); // 1-st or Exception 19 | } 20 | 21 | void print() { 22 | System.out.println(queue); 23 | } 24 | 25 | public static void main(String[] args) { 26 | XLinedListApp app = new XLinedListApp(); 27 | for (int i = 0; i < 10; i++) { 28 | app.produce(); 29 | app.print(); 30 | if (app.queue.size()>2) { 31 | System.out.println(app.get()); 32 | app.print(); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l01sort/BubbleSortBasic.java: -------------------------------------------------------------------------------- 1 | package algorithms.l01sort; 2 | 3 | /** 4 | * Bubble sort basic implementation 5 | * complexity: O(n^2) 6 | */ 7 | public class BubbleSortBasic { 8 | 9 | public static void swap(int[] origin, int i, int j) { 10 | int tmp = origin[i]; 11 | origin[i] = origin[j]; 12 | origin[j] = tmp; 13 | } 14 | 15 | public static int[] sort(int[] origin) { 16 | // make a copy not to mutate original array 17 | int[] sorted = origin.clone(); 18 | // complexity: O(n^2) 19 | for (int i = 0; i < sorted.length; i++) { 20 | for (int j = 0; j < sorted.length; j++) { 21 | if (sorted[i] < sorted[j]) { 22 | swap(sorted, i , j); 23 | } 24 | } 25 | } 26 | return sorted; 27 | } 28 | 29 | public static void main(String[] args) { 30 | int[] data = Utils.create_random_data(10); 31 | int[] sorted = sort(data); 32 | System.out.println("Bubble sort, basic version: complexity: O(n^2)"); 33 | System.out.printf("Source array: %s\n", Utils.arrToString(data)); 34 | System.out.printf("Sorted array: %s\n", Utils.arrToString(sorted)); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l01sort/BubbleSortImproved.java: -------------------------------------------------------------------------------- 1 | package algorithms.l01sort; 2 | 3 | /** 4 | * Bubble sort improved implementation 5 | * complexity: O(n^2 / 2) 6 | */ 7 | public class BubbleSortImproved { 8 | 9 | public static void swap(int[] origin, int i, int j) { 10 | int tmp = origin[i]; 11 | origin[i] = origin[j]; 12 | origin[j] = tmp; 13 | } 14 | 15 | public static int[] sort(int[] origin) { 16 | // make a copy not to mutate original array 17 | int[] sorted = origin.clone(); 18 | // complexity: O(n^2 / 2) 19 | for (int i = 0; i < sorted.length; i++) { 20 | for (int j = i + 1; j < sorted.length; j++) { 21 | if (sorted[i] < sorted[j]) { 22 | swap(sorted, i , j); 23 | } 24 | } 25 | } 26 | return sorted; 27 | } 28 | 29 | public static void main(String[] args) { 30 | int[] data = Utils.create_random_data(10); 31 | int[] sorted = sort(data); 32 | System.out.println("Bubble sort, improved version: complexity: O(n^2 / 2)"); 33 | System.out.printf("Source array: %s\n", Utils.arrToString(data)); 34 | System.out.printf("Sorted array: %s\n", Utils.arrToString(sorted)); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l01sort/QuickSort.java: -------------------------------------------------------------------------------- 1 | package algorithms.l01sort; 2 | 3 | public class QuickSort { 4 | 5 | private static void swap(int[] a, int i, int j) { 6 | int t = a[i]; 7 | a[i] = a[j]; 8 | a[j] = t; 9 | } 10 | /** 11 | * sort in place 12 | */ 13 | private static void doSort(final int[] data, final int L, final int R) { 14 | if (L >= R) return; // we done 15 | int l = L; 16 | int r = R; 17 | // by design - middle of the array, it can be anything 18 | int pivot = l - (l - r) / 2; 19 | while (l < r) { 20 | while (data[l] <= data[pivot] && l < pivot) { l++; } // skip already sorted left side 21 | while (data[pivot] <= data[r] && pivot < r) { r--; } // skip already sorted right side 22 | // now, actually sort 23 | if (l < r) { 24 | swap(data, l, r); 25 | if (pivot == l) { pivot = r; } 26 | else if (pivot == r) { pivot = l; } 27 | } 28 | } 29 | doSort(data, L, pivot); 30 | doSort(data, pivot + 1, R); 31 | } 32 | 33 | public static void main(String[] args) { 34 | int[] data = Utils.create_random_data(24); 35 | int[] sorted = data.clone(); 36 | 37 | doSort(sorted, 0, sorted.length-1); 38 | 39 | System.out.printf("Source array: %s\n", Utils.arrToString(data)); 40 | System.out.printf("Sorted array: %s\n", Utils.arrToString(sorted)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l01sort/SelectionSort.java: -------------------------------------------------------------------------------- 1 | package algorithms.l01sort; 2 | 3 | /** 4 | * find the min (of the rest) 5 | * and swap with the current 6 | * 7 | * actually, it's a BubbleSort 8 | * but never call it BubbleSort! 9 | */ 10 | public class SelectionSort { 11 | 12 | private void swap(int[] a, int i, int j) { 13 | int t = a[i]; 14 | a[i] = a[j]; 15 | a[j] = t; 16 | } 17 | 18 | /** 19 | * finds the index of minimal value 20 | * in the range [i, j) 21 | */ 22 | private int findMinIdx(int[] a, int l, int r) { 23 | int minV = a[l]; 24 | int minI = l; 25 | for (int i = l+1; i < r; i++) { 26 | if (a[i] < minV) { 27 | minV = a[i]; 28 | minI = i; 29 | } 30 | } 31 | return minI; 32 | } 33 | 34 | public void sort(int[] a) { 35 | for (int i = 0; i < a.length - 1; i++) { // we don't need to touch the las one, it will be already in order 36 | int min_idx = findMinIdx(a, i, a.length); 37 | if (min_idx != i) swap(a, min_idx, i); 38 | } 39 | } 40 | 41 | public static void main(String[] args) { 42 | int[] data = Utils.create_random_data(10); 43 | int[] sorted = data.clone(); 44 | SelectionSort app = new SelectionSort(); 45 | // running sort 46 | app.sort(sorted); 47 | 48 | System.out.println("SelectionSort: complexity: O(n*n/2) ~ o(n^2)"); 49 | System.out.printf("Source array: %s\n", Utils.arrToString(data)); 50 | System.out.printf("Sorted array: %s\n", Utils.arrToString(sorted)); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l01sort/ShellSort.java: -------------------------------------------------------------------------------- 1 | package algorithms.l01sort; 2 | 3 | /** 4 | * Move more than one elements in a single pass 5 | * h-sort 6 | */ 7 | public class ShellSort { 8 | 9 | private void swap(int[] a, int i, int j) { 10 | int t = a[i]; 11 | a[i] = a[j]; 12 | a[j] = t; 13 | } 14 | 15 | public void sort(int[] a) { 16 | int N = a.length; 17 | int h = 1; 18 | while (h < N/3) h = h * 3 + 1; // 3n+1 (1,4,13,40) calculate the max point to partial sort 19 | while (h >= 1) { 20 | for (int i = h; i < N; i++) { 21 | for (int j = i; j >= h && a[j] < a[j - h]; j -=h ) { 22 | swap(a, j, j - h); 23 | } 24 | } 25 | h /= 3; 26 | } 27 | } 28 | 29 | public static void main(String[] args) { 30 | int[] data = Utils.create_random_data(10); 31 | int[] sorted = data.clone(); 32 | ShellSort app = new ShellSort(); 33 | // running sort 34 | app.sort(sorted); 35 | 36 | System.out.println("ShellSort: complexity: O( N^(3/2) )"); 37 | System.out.printf("Source array: %s\n", Utils.arrToString(data)); 38 | System.out.printf("Sorted array: %s\n", Utils.arrToString(sorted)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l01sort/Shuffle.java: -------------------------------------------------------------------------------- 1 | package algorithms.l01sort; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | /** 6 | * Effective Shuffling in O(N) 7 | */ 8 | public class Shuffle { 9 | 10 | private void swap(int[] a, int i, int j) { 11 | int t = a[i]; 12 | a[i] = a[j]; 13 | a[j] = t; 14 | } 15 | 16 | public int randomTo(int n) { 17 | return (int) (Math.random() * (n + 1)); 18 | } 19 | 20 | public void shuffle(int[] a) { 21 | IntStream.range(0, a.length).forEach(n -> swap(a, n, randomTo(n))); 22 | } 23 | 24 | public static void main(String[] args) { 25 | int[] data = IntStream.rangeClosed(1, 25).toArray(); 26 | int[] shuffled = data.clone(); 27 | Shuffle app = new Shuffle(); 28 | // running sort 29 | app.shuffle(shuffled); 30 | 31 | System.out.printf("Original array: %s\n", Utils.arrToString(data)); 32 | System.out.printf("Shuffled array: %s\n", Utils.arrToString(shuffled)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l01sort/Utils.java: -------------------------------------------------------------------------------- 1 | package algorithms.l01sort; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | import java.util.stream.Stream; 6 | 7 | public class Utils { 8 | public static int[] create_random_data(int amount) { 9 | Random r = new Random(); 10 | return Stream.generate(() -> r.nextInt(200)) 11 | .distinct() 12 | .limit(amount) 13 | // .sorted((o1, o2) -> o2-o1) 14 | .mapToInt(i -> i) 15 | .toArray(); 16 | } 17 | 18 | public static String arrToString(int[] data) { 19 | return arrToString(data, 0, data.length - 1); 20 | } 21 | 22 | public static String arrToString(int[] data, int l, int r) { 23 | int len = r - l + 1; 24 | if (data.length == len) return Arrays.toString(data); 25 | int[] slice = new int[len]; 26 | System.arraycopy(data, l, slice, 0, len); 27 | return Arrays.toString(slice); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l01sort/ideas/MergeSortBottomUp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l01sort.ideas; 2 | 3 | /** 4 | * start merging 5 | * from arrays size of one 6 | * and combine them 7 | * 8 | * No recursion! 9 | */ 10 | public class MergeSortBottomUp { 11 | } 12 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l01sort/ideas/MergeSortOptimized.java: -------------------------------------------------------------------------------- 1 | package algorithms.l01sort.ideas; 2 | 3 | /** 4 | * 1. check whether left and right parts already sorted 5 | * 2. don't copy, use different arrays for merge and sort 6 | */ 7 | public class MergeSortOptimized { 8 | } 9 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l01sort/ideas/Stability.java: -------------------------------------------------------------------------------- 1 | package algorithms.l01sort.ideas; 2 | 3 | /** 4 | * Stability: we SHOULD never change order elements with the same values 5 | * 6 | * 7 | * is about preserving initial ordering 8 | * of elements with the same values: 9 | * A1, B, A2, C => A1, A2, B, C, nothing else 10 | * 11 | * Merge Sort, Insertion Sort - YES 12 | * Selection Sort, Shell Sort - NO, they change elements to far from each other. 13 | * 14 | * never run unstable after stable, it can break initial ordering 15 | * 16 | */ 17 | public class Stability { 18 | } 19 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/BitShift.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise; 2 | 3 | import algorithms.l02bitwise.conversion2.DecToBin; 4 | 5 | public class BitShift { 6 | private DecToBin db = new DecToBin(); 7 | 8 | String formatted(int val) { 9 | return String.format("decimal: %11d converted to binary: %s\n", val, db.decToBin(val)); 10 | } 11 | 12 | void pf(int val) { 13 | System.out.print(formatted(val)); 14 | } 15 | 16 | public static void main(String[] args) { 17 | BitShift app = new BitShift(); 18 | byte x = 60; 19 | /** 20 | * there is no difference between '>>' and '>>>' 21 | * with positive numbers 22 | */ 23 | app.pf(x); // 60 24 | app.pf(x >> 2); // 15 25 | app.pf(x >>> 2); // 15 26 | app.pf(x << 2); // 240 27 | /** 28 | * but there is a BIG difference between '>>' and '>>>' 29 | * when it comes to negative numbers 30 | * >> - does care the sign 31 | * >>> - doesn't 32 | */ 33 | int y = -60; 34 | app.pf(y); // -60 35 | app.pf(y << 8); // -60*2^8=-15360 36 | app.pf(y >> 6); // -1 ... we preserve the sign and shift 37 | app.pf(y >>> 6); // 67108863 ... we don't care about sign, just move the bits 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/Crypt.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise; 2 | 3 | public class Crypt { 4 | static String encryptDecrypt(String origin, char key) { 5 | StringBuilder sb = new StringBuilder(); 6 | for (int i = 0; i < origin.length(); i++) { 7 | sb.append((char) (origin.charAt(i) ^ key)); 8 | } 9 | return sb.toString(); 10 | } 11 | 12 | public static void main(String[] args) { 13 | String origin = "IBA Tech Academy"; 14 | 15 | String encrypted = encryptDecrypt(origin, '5'); 16 | encrypted = encryptDecrypt(encrypted, 'X'); 17 | encrypted = encryptDecrypt(encrypted, 'Z'); 18 | 19 | System.out.printf("Encrypted String: %s\n", encrypted); 20 | 21 | String decrypted = encryptDecrypt(encrypted, '5'); 22 | decrypted = encryptDecrypt(decrypted, 'Z'); 23 | decrypted = encryptDecrypt(decrypted, 'X'); 24 | System.out.printf("Decrypted String: %s\n", decrypted); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/IntegerOverflow.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise; 2 | 3 | public class IntegerOverflow { 4 | 5 | int strictAdd_v1(int a, int b) { 6 | int r = a + b; 7 | if ((a < 0 && b < 0 && r > 0) || (a > 0 && b > 0 && r < 0)) 8 | throw new ArithmeticException("Integer Overflow #1"); 9 | return r; 10 | } 11 | 12 | int strictAdd_v2(int a, int b) { 13 | if ((a | b) < Integer.MAX_VALUE) 14 | throw new ArithmeticException("Integer Overflow #2"); 15 | return a + b; 16 | } 17 | 18 | int strictAdd_v3(int a, int b) { 19 | int r = a + b; 20 | if (((a ^ r) & (b ^ r)) < 0) { 21 | throw new ArithmeticException("integer overflow #3"); 22 | } 23 | return r; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/NegativeRepresentation.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise; 2 | 3 | import algorithms.l02bitwise.conversion.IntToBin; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | public class NegativeRepresentation { 9 | 10 | public static void main(String[] args) { 11 | // 0 - 00000000 12 | // 1 - 00000001 13 | // 2 - 00000010 14 | // 3 - 00000011 15 | // .. 16 | // 126 - 01111110 17 | // 127 - 01111111 18 | //-128 - 10000000 19 | //-127 - 10000001 20 | //-126 - 10000010 21 | // .. 22 | // -3 - 11111101 23 | // -2 - 11111110 24 | // -1 - 11111111 25 | IntToBin ib = new IntToBin(); 26 | 27 | Arrays.asList(0,1,2,3, 126,127,-128,-127,-126,-3,-2,-1) 28 | .forEach(n -> 29 | System.out.printf("Decimal:%4d, Binary:%s\n", n, ib.toBin(n)) 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/README.md: -------------------------------------------------------------------------------- 1 | ### Links 2 | 3 | - [ASCII Table](http://www.asciitable.com/index/asciifull.gif) 4 | - [ASCII Table #2](http://sticksandstones.kstrom.com/appen.html) 5 | - [Binary Bulbs](https://cdn.cs50.net/2016/x/psets/0/pset0/bulbs.html) 6 | - [One Complement representation](https://www.ntu.edu.sg/home/ehchua/programming/java/images/DataRep_OneComplement.png) 7 | - [Two Complement representation(Java)](https://www.ntu.edu.sg/home/ehchua/programming/java/images/DataRep_TwoComplement.png) 8 | - [2's](https://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html#twotwo) 9 | - [>>> vs >>](https://stackoverflow.com/questions/2811319/difference-between-and) 10 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/SyntaxAndNotation.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise; 2 | 3 | public class SyntaxAndNotation { 4 | 5 | public static void main(String[] args) { 6 | byte x1 = 127; // decimal 127 7 | byte x2 = 100; // decimal 100 8 | byte x3 = 00000100; // octal. decimal 64 9 | byte x4 = 0b00000100; // binary. decimal 8 10 | int x5 = 0x10; // hexadecimal. decimal 16 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/conversion/IntToBin.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise.conversion; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.stream.Collectors; 6 | import java.util.stream.IntStream; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; 9 | 10 | public class IntToBin { 11 | 12 | public String toBin2(int value) { 13 | String outcome = ""; 14 | for (int i = 7; i >= 0; i--) { 15 | int bit = (value >> i) & 0b00000001; 16 | outcome = outcome + bit; 17 | } 18 | return outcome; 19 | } 20 | 21 | public String toBin3(int value) { 22 | StringBuilder sb = new StringBuilder(); 23 | for (int i = 7; i >= 0; i--) { 24 | int bit = (value >> i) & 0b00000001; 25 | sb.append(bit); 26 | } 27 | return sb.toString(); 28 | } 29 | 30 | public String toBin(int value) { 31 | return IntStream.rangeClosed(0, 7) // 0..7 32 | .map(x -> 7 - x) // 7..0 33 | .map(i -> (value >> i) & 0b00000001) // 0 or 1 34 | .mapToObj(Integer::toString) 35 | .collect(Collectors.joining()); 36 | } 37 | 38 | } 39 | 40 | class IntToBinTest { 41 | 42 | private final IntToBin ib = new IntToBin(); 43 | 44 | @Test 45 | public void test1() { 46 | assertEquals("00000000", ib.toBin(0)); 47 | } 48 | 49 | @Test 50 | public void test2() { 51 | assertEquals("00000101", ib.toBin(5)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/conversion2/BinToDec.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise.conversion2; 2 | 3 | import java.util.Scanner; 4 | 5 | public class BinToDec { 6 | 7 | public int binToDec(String origin) { 8 | int result = 0; 9 | for (int i = 0; i < origin.length(); i++) { 10 | int charAt = origin.charAt(i); // '1' or '0' 11 | if (charAt < '0' || charAt > '1') throw new IllegalArgumentException(String.format("wrong char in the original data: '%c'", (char)charAt)); 12 | int digitAt = Character.digit(charAt, 2); // convert '0' -> 0, '1' -> 1 13 | int powerTo = origin.length() - i - 1; 14 | // way 1. math approach 15 | // int part = (int) (digitAt * Math.pow(2 , powerTo)); 16 | // way 2. bitwise representation 17 | int part = digitAt << powerTo; 18 | result += part; 19 | } 20 | return result; 21 | } 22 | 23 | public static void main(String[] args) { 24 | BinToDec app = new BinToDec(); 25 | System.out.print("Enter binary value to convert: "); 26 | String binary = new Scanner(System.in).next(); 27 | int decimal = app.binToDec(binary); 28 | System.out.printf("Binary value %s converted to decimal: %d\n", binary, decimal); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/conversion2/DecToBin.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise.conversion2; 2 | 3 | import java.util.Scanner; 4 | 5 | public class DecToBin { 6 | 7 | public String decToBin(int value) { 8 | // 8 - byte, 16 - short, 32 - int 9 | return decToBin(value, 32); 10 | } 11 | 12 | public String decToBin(int value, int SIZE) { 13 | StringBuilder sb = new StringBuilder(); 14 | final int MASK = 0b0000000000000001; 15 | 16 | for (int index = SIZE-1; index >= 0; index--) { 17 | int value_shifted = value >> index; 18 | int one_bit = value_shifted & MASK; // 0 or 1 only ! 19 | sb.append(one_bit); 20 | if ((index % 8 == 0)&&(index < SIZE)) sb.append(" "); 21 | } 22 | 23 | return sb.toString().trim(); 24 | } 25 | 26 | public static void main(String[] args) { 27 | DecToBin app = new DecToBin(); 28 | System.out.print("Enter decimal value to convert: "); 29 | int decimal = new Scanner(System.in).nextInt(); 30 | String binary = app.decToBin(decimal); 31 | System.out.printf("Decimal value %d converted to binary: %s\n", decimal, binary); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/conversion2/DecToBinV1.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise.conversion2; 2 | 3 | import java.util.Scanner; 4 | 5 | public class DecToBinV1 { 6 | public static void main(String[] args) { 7 | int value = new Scanner(System.in).nextInt(); // 12 8 | StringBuilder binary = new StringBuilder(); 9 | while (value > 0) { 10 | int rem = value % 2; 11 | binary.append(rem); 12 | value = value / 2; 13 | } 14 | System.out.println(binary.reverse().toString()); // 00001100 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/conversion2/DecToBinV2.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise.conversion2; 2 | 3 | import java.util.Scanner; 4 | 5 | public class DecToBinV2 { 6 | public static void main(String[] args) { 7 | int value = new Scanner(System.in).nextInt(); // 12 8 | StringBuilder binary = new StringBuilder(); 9 | while (value > 0) { 10 | int rem = value & 0b1; 11 | binary.append(rem); 12 | value = value >> 1; 13 | } 14 | System.out.println(binary.reverse().toString()); // 00001100 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/conversion2/DecToBinV3.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise.conversion2; 2 | 3 | public class DecToBinV3 { 4 | public static void main(String[] args) { 5 | // int value = new Scanner(System.in).nextInt(); // 17 6 | int value = 18; 7 | StringBuilder binary = new StringBuilder(); 8 | for (int i = 7; i >= 0 ; i--) { 9 | int part = value >> i; 10 | int bit = part & 0b00000001; 11 | binary.append(bit); 12 | } 13 | System.out.println(binary.toString()); // 00010010 14 | 15 | // 00010010 >> 0 => 00010010 16 | // 00010010 >> 1 => 00001001 17 | // 00010010 >> 2 => 00000100 18 | // 00010010 >> 3 => 00000010 19 | // 00010010 >> 4 => 00000001 20 | // 21 | // 0b00001001 22 | // & 0b00000001 23 | // ---------- 24 | // 0b00000001 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/shift/ShiftApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise.shift; 2 | 3 | public class ShiftApp { 4 | 5 | public static void main(String[] args) { 6 | System.out.println(16 >> 2); // 4 7 | System.out.println(16 >>> 2); // 4 8 | 9 | System.out.println(-16 >> 2); // -4 10 | System.out.println(-16 >>> 2);// 1073741820 11 | System.out.println("---"); 12 | System.out.println(Integer.toBinaryString(-16)); // 11111111111111111111111111110000 13 | System.out.println(Integer.toBinaryString(-16 >> 2)); // 11111111111111111111111111111100 14 | System.out.println(Integer.toBinaryString(-16 >>> 2));// 00111111111111111111111111111100 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/usecases/Order.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise.usecases; 2 | 3 | public class Order { 4 | private final static byte SMOKE = 0b00000001; 5 | private final static byte PET = 0b00000010; 6 | private final static byte AC = 0b00000100; 7 | private final static byte TOUR = 0b00001000; 8 | 9 | byte prop; 10 | 11 | public void setTouring() { 12 | prop = (byte)(prop | 0b00001000); 13 | } 14 | 15 | public void setTouring2() { 16 | prop = (byte)(prop | TOUR); 17 | } 18 | 19 | public boolean isSmoke() { 20 | return (prop & SMOKE) == SMOKE; 21 | } 22 | 23 | public boolean isPet() { 24 | return (prop & 0b00000010) == 0b00000010; 25 | } 26 | 27 | public boolean isPet3() { 28 | return ((prop >> 1) & 0b00000001) == 0b00000001; 29 | } 30 | 31 | public boolean isAC() { 32 | return ((prop >> 2) & 0b00000001) == 0b00000001; 33 | } 34 | 35 | public boolean isPet2() { 36 | return (prop & PET) == PET; 37 | } 38 | 39 | // lazy, up to first TRUE 40 | public boolean qwe1(boolean a, boolean b, boolean c) { 41 | return a || b || c; 42 | } 43 | 44 | // lazy, up to first FALSE 45 | public boolean qwe1a(boolean a, boolean b, boolean c) { 46 | return a && b && c; 47 | } 48 | 49 | public int qwe1(int a, int b, int c) { 50 | return a | b | c; 51 | } 52 | 53 | public int qwe1a(int a, int b, int c) { 54 | return a & b & c; 55 | } 56 | 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/usecases/RealExampleShop.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise.usecases; 2 | 3 | public class RealExampleShop { 4 | 5 | final static int MASK_INSTOCK = 0b000001; 6 | final static int MASK_VIP = 0b000010; 7 | final static int MASK_OPTION3 = 0b000100; 8 | 9 | public static void main(String[] args) { 10 | int flag1 = MASK_OPTION3 | MASK_INSTOCK; 11 | System.out.println(flag1); // 101 -> 5 12 | 13 | int flag2 = MASK_OPTION3 | MASK_VIP; 14 | System.out.println(flag2); // 110 -> 6 15 | 16 | boolean checked_vip1 = (flag2 & MASK_VIP) > 0; // true 17 | boolean checked_vip2 = (flag1 & MASK_VIP) > 0; // false 18 | 19 | System.out.println(checked_vip1); 20 | System.out.println(checked_vip2); 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l02bitwise/usecases/RealExampleTaxi.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise.usecases; 2 | 3 | public class RealExampleTaxi { 4 | 5 | final static int MASK_BIG = 0b00000001; 6 | final static int MASK_NONSMOKING = 0b00000010; 7 | final static int MASK_AIRCOND = 0b00000100; 8 | final static int MASK_ANIMALS = 0b00001000; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l03recursion/FactorialApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l03recursion; 2 | 3 | public class FactorialApp { 4 | 5 | // tail recursive implementation 6 | static int fact_tr(int number, int acc) { 7 | if (number == 1) return acc; 8 | return fact_tr(number - 1, number * acc); 9 | } 10 | 11 | // tail recursive runner 12 | static int fact_tr(int number) { 13 | return fact_tr(number, 1); 14 | } 15 | 16 | // head recursive implementation 17 | static int fact_hr(int number) { 18 | if (number == 1) return 1; 19 | int f1 = fact_hr(number - 1); 20 | return number * f1; 21 | } 22 | 23 | // iterative approach 24 | public static int fact_iter(int number) { 25 | if (number < 0) throw new IllegalArgumentException("number less than zero given"); 26 | int result = 1; 27 | for (int next = 2; next <= number; next++) { 28 | result = result * next; 29 | } 30 | return result; 31 | } 32 | 33 | public static void main(String[] args) { 34 | int N = 5; 35 | System.out.printf("Iterative :%d\n", fact_iter(N)); // 60 36 | System.out.printf("Head recursion:%d\n", fact_hr(N)); 37 | System.out.printf("Tail recursion:%d\n", fact_tr(N)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l03recursion/FibonacciApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l03recursion; 2 | 3 | public class FibonacciApp { 4 | 5 | // head recursive implementation 6 | static int fibo(int n) { 7 | // termination condition 8 | if (n == 1 || n == 2) return 1; 9 | // recursive call #1 10 | int f1 = fibo(n-1); 11 | // recursive call #2 12 | int f2 = fibo(n-2); 13 | // combining result 14 | int fn = f1 + f2; 15 | return fn; 16 | } 17 | 18 | public static void main(String[] args) { 19 | int N = 10; 20 | int f10 = fibo(N); 21 | System.out.println(f10); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l03recursion/FibonacciApp2memo.java: -------------------------------------------------------------------------------- 1 | package algorithms.l03recursion; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class FibonacciApp2memo { 7 | private static final Map memo = new HashMap<>(); 8 | 9 | private static boolean has(int number) { 10 | return memo.containsKey(number); 11 | } 12 | 13 | private static void put(int pos, int value) { 14 | memo.put(pos, value); 15 | } 16 | 17 | private static int get(int pos) { 18 | return memo.get(pos); 19 | } 20 | 21 | static int fibo_basic(int n) { 22 | if (n == 1 || n == 2) return 1; 23 | return fibo_basic(n - 1 ) + fibo_basic(n - 2); 24 | } 25 | 26 | static int fibo(int n) { 27 | int nth; 28 | 29 | if (n == 1 || n == 2) { 30 | nth = 1; 31 | } else if (has(n)) { 32 | nth = get(n); 33 | } else { 34 | nth = fibo(n - 1 ) + fibo(n - 2); 35 | } 36 | // put element into memo 37 | put(n, nth); 38 | return nth; 39 | } 40 | 41 | public static void main(String[] args) { 42 | int N = 55; 43 | int fibo45th = fibo(N); 44 | System.out.println(fibo45th); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l03recursion/XpowYbasic.java: -------------------------------------------------------------------------------- 1 | package algorithms.l03recursion; 2 | 3 | public class XpowYbasic { 4 | 5 | static int pow(int number, int to) { 6 | if (to == 1) return number; 7 | return number * pow(number, to - 1); 8 | } 9 | 10 | public static void main(String[] args) { 11 | int N = 5; 12 | int POW = 3; 13 | int result = pow(N, POW); // 125 14 | System.out.println(result); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l03recursion/XpowYtailrec.java: -------------------------------------------------------------------------------- 1 | package algorithms.l03recursion; 2 | 3 | public class XpowYtailrec { 4 | 5 | static int pow(int number, int to, int acc) { 6 | if (to == 0) return acc; 7 | return pow(number, to - 1, acc * number); 8 | } 9 | 10 | static int pow(int number, int to) { 11 | return pow(number, to, 1); 12 | } 13 | 14 | public static void main(String[] args) { 15 | int N = 5; 16 | int POW = 3; 17 | int result = pow(N, POW); // 125 18 | System.out.println(result); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l04linkedlist/GCDStackSafe.java: -------------------------------------------------------------------------------- 1 | package algorithms.l04linkedlist; 2 | 3 | import static common.RX.NI; 4 | 5 | public class GCDStackSafe { 6 | /** 7 | * can easily lead to stack overflow 8 | */ 9 | public int gcdx(int a, int b) { 10 | if (b == 0) return a; 11 | return gcdx(b, a % b); 12 | } 13 | 14 | /** 15 | * own version with manual stack 16 | * should be implemented 17 | */ 18 | public int gcd(int a, int b) { 19 | if (b == 0) return a; 20 | throw NI; 21 | } 22 | 23 | public static void main(String[] args) { 24 | GCDStackSafe g = new GCDStackSafe(); 25 | System.out.println(g.gcdx(24, 36)); 26 | System.out.println(g.gcdx(36, 24)); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l04linkedlist/LinkedListJDKAPI.java: -------------------------------------------------------------------------------- 1 | package algorithms.l04linkedlist; 2 | 3 | import java.util.Arrays; 4 | import java.util.Deque; 5 | import java.util.LinkedList; 6 | 7 | public class LinkedListJDKAPI { 8 | public static void main(String[] args) { 9 | Deque ll = new LinkedList<>(); 10 | // add 11 | ll.addFirst(1); 12 | ll.addLast(2); 13 | ll.add(3); // addLast 14 | ll.addAll(Arrays.asList(5,6,7)); 15 | 16 | ll.offerFirst(3); 17 | ll.offerLast(4); 18 | ll.offer(5); // offerLast(4); 19 | 20 | // Retrieves, but does not remove - NULL if empty 21 | ll.peekFirst(); 22 | ll.peekLast(); 23 | ll.peek(); // peekFirst() 24 | 25 | // Retrieves, but does not remove - EXCEPTION 26 | ll.getFirst(); 27 | ll.getLast(); 28 | 29 | // Retrieves and removes - NULL if empty 30 | ll.pollFirst(); 31 | ll.pollLast(); 32 | ll.poll(); // pollFirst() 33 | 34 | // Retrieves and removes - EXCEPTION 35 | ll.removeFirst(); 36 | ll.removeLast(); 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l04linkedlist/StackApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l04linkedlist; 2 | 3 | import java.util.Stack; 4 | 5 | public class StackApp { 6 | public static void main(String[] args) { 7 | Stack s = new Stack<>(); 8 | s.push(1); 9 | s.push(2); 10 | s.push(3); 11 | /* 12 | * prints internal implementation 13 | * the same story with the PriorityQueue 14 | */ 15 | System.out.println(s); 16 | 17 | /* 18 | * prints in a way intended to use 19 | */ 20 | while (!s.isEmpty()) System.out.print(s.pop()); 21 | System.out.println(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l04linkedlist/XLinkedListApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l04linkedlist; 2 | 3 | public class XLinkedListApp { 4 | public static void main(String[] args) { 5 | XLinkedList xl = new XLinkedList(); 6 | xl.add(11); 7 | xl.add(22); 8 | xl.add(33); 9 | xl.add(44); 10 | boolean found11 = xl.contains(11); 11 | boolean found33 = xl.contains(33); 12 | boolean found55 = xl.contains(55); 13 | System.out.println(found11); // true 14 | System.out.println(found33); // true 15 | System.out.println(found55); // false 16 | System.out.println(xl.toString()); // 11,22,33,44 17 | xl.remove(22); 18 | System.out.println(xl.toString()); // 11,33,44 19 | xl.remove(33); 20 | System.out.println(xl.toString()); // 11,44 21 | xl.remove(44); 22 | System.out.println(xl.toString()); // 11 23 | xl.remove(11); 24 | System.out.println(xl.toString()); // [] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l04linkedlist/XMerge.java: -------------------------------------------------------------------------------- 1 | package algorithms.l04linkedlist; 2 | 3 | public class XMerge { 4 | XLinkedList.XItem merge(XLinkedList xl1, 5 | XLinkedList xl2) { 6 | XLinkedList.XItem current1 = xl1.getHead(); 7 | XLinkedList.XItem current2 = xl2.getHead(); 8 | XLinkedList.XItem head; 9 | XLinkedList.XItem current; 10 | 11 | if (current1.value <= current2.value) { 12 | head = current1; 13 | current1 = current1.next; 14 | } else { 15 | head = current2; 16 | current2 = current2.next; 17 | } 18 | current = head; 19 | 20 | while (current1 != null && current2 != null) { 21 | if (current1.value <= current2.value) { 22 | current.next = current1; 23 | current1 = current1.next; 24 | } else { 25 | current.next = current2; 26 | current2 = current2.next; 27 | } 28 | current = current.next; 29 | } 30 | 31 | if (current1 != null) { 32 | current.next = current1; 33 | } 34 | 35 | if (current2 != null) { 36 | current.next = current2; 37 | } 38 | return head; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l04linkedlist/XMergeApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l04linkedlist; 2 | 3 | public class XMergeApp { 4 | public static void main(String[] args) { 5 | XMerge app = new XMerge(); 6 | XLinkedList xl1 = new XLinkedList(); 7 | XLinkedList xl2 = new XLinkedList(); 8 | xl1.add(1); 9 | xl1.add(4); 10 | xl1.add(5); 11 | xl1.add(7); 12 | xl1.add(9); 13 | xl1.add(100); 14 | xl1.add(200); 15 | xl2.add(2); 16 | xl2.add(3); 17 | xl2.add(6); 18 | xl2.add(8); 19 | System.out.println(xl1.toString()); 20 | System.out.println(xl2.toString()); 21 | XLinkedList.XItem merged = app.merge(xl1, xl2); 22 | System.out.println(xl1.toStringFrom(merged)); 23 | System.out.println(xl1.toString()); 24 | System.out.println(xl2.toString()); 25 | xl1.remove(5); 26 | System.out.println(xl1.toString()); 27 | System.out.println(xl2.toString()); 28 | xl1.remove(1); 29 | System.out.println(xl1.toString()); 30 | System.out.println(xl2.toString()); 31 | System.out.println(xl1.toStringFrom(merged)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l04linkedlist/XQueueApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l04linkedlist; 2 | 3 | /** 4 | * Stack and Queue are actually just a Linked List: 5 | * 6 | * Stack: LIFO 7 | * - push 8 | * - pop 9 | * - isEmpty 10 | * 11 | * Queue: FIFO 12 | * - enqueue 13 | * - dequeue 14 | * - isEmpty 15 | * 16 | * Stack Implementation: 17 | * - consider usage Linked List or Arrays (with resize, or what to deal with overflow). 18 | * and make them available for usage in different implementations. 19 | * 20 | * in pop() implementation - consider data[n--] = null to allow GC 21 | * in array resizing consider "erasing" an array 22 | * on pop() if (n<=size/4) resize/2 23 | * 24 | * Queue based on Linked List, 25 | * but holding first and end pointers 26 | * 27 | * SO => we need to have Queue and Stack, 28 | * and we (highly probable) don't need to use Linked List directly. 29 | * TASK1 => implement Linked List 30 | * TASK2 => implement Stack by using (array and LinkedList) 31 | * TASK3 => implement Queue by using (array and LinkedList) 32 | */ 33 | public class XQueueApp { 34 | } 35 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l05binarysearch/BinarySearch1App.java: -------------------------------------------------------------------------------- 1 | package algorithms.l05binarysearch; 2 | 3 | import algorithms.l01sort.Utils; 4 | 5 | import java.util.Arrays; 6 | 7 | public class BinarySearch1App { 8 | public static void main(String[] args) { 9 | int[] data = Utils.create_random_data(30); // 1..100 10 | int val_random = (int) (Math.random() * 100); 11 | int val_existed = data[(int) (Math.random() * 30)]; 12 | BinarySearchV1 bs = new BinarySearchV1(); 13 | 14 | Arrays.sort(data); 15 | System.out.println(Arrays.toString(data)); 16 | 17 | int idx1 = bs.find(data, val_random); 18 | System.out.println(idx1 == -1 ? 19 | String.format("Value %d is not found", val_random) : 20 | String.format("Value %d is found at index %d", val_random, idx1) 21 | ); 22 | System.out.printf("number of iteration %d\n", bs.counter); 23 | System.out.println(); 24 | 25 | int idx2 = bs.find(data, val_existed); 26 | System.out.println(idx2 == -1 ? 27 | String.format("Value %d not found", val_existed) : 28 | String.format("Value %d is found at index %d", val_existed, idx2) 29 | ); 30 | System.out.printf("number of iteration %d\n", bs.counter); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l05binarysearch/BinarySearch2App.java: -------------------------------------------------------------------------------- 1 | package algorithms.l05binarysearch; 2 | 3 | import algorithms.l01sort.Utils; 4 | 5 | import java.util.Arrays; 6 | 7 | public class BinarySearch2App { 8 | public static void main(String[] args) { 9 | int[] data = Utils.create_random_data(30); // 1..100 10 | int val_random = (int) (Math.random() * 100); 11 | int val_existed = data[(int) (Math.random() * 30)]; 12 | 13 | Arrays.sort(data); 14 | System.out.println(Arrays.toString(data)); 15 | 16 | BinarySearchV2.Result result1 = BinarySearchV2.find(data, val_random); 17 | BinarySearchV2.Result result2 = BinarySearchV2.find(data, val_existed); 18 | 19 | System.out.println(!result1.found ? 20 | String.format("Value %d not found", val_random) : 21 | String.format("Value %d is found at index %d", val_random, result1.index) 22 | ); 23 | System.out.printf("number of iteration %d\n", result1.counter); 24 | System.out.println(); 25 | 26 | System.out.println(!result2.found ? 27 | String.format("Value %d not found", val_existed) : 28 | String.format("Value %d is found at index %d", val_existed, result2.index) 29 | ); 30 | System.out.printf("number of iteration %d\n", result2.counter); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l05binarysearch/BinarySearch3App.java: -------------------------------------------------------------------------------- 1 | package algorithms.l05binarysearch; 2 | 3 | import algorithms.l01sort.Utils; 4 | import java.util.Arrays; 5 | 6 | public class BinarySearch3App { 7 | public static void main(String[] args) { 8 | int[] data = Utils.create_random_data(30); // 1..100 9 | int val_random = (int) (Math.random() * 100); 10 | int val_existed = data[(int) (Math.random() * 30)]; 11 | 12 | Arrays.sort(data); 13 | System.out.println(Arrays.toString(data)); 14 | 15 | BinarySearchV3.Result result1 = BinarySearchV3.find(data, val_random); 16 | BinarySearchV3.Result result2 = BinarySearchV3.find(data, val_existed); 17 | 18 | String message1 = result1.index 19 | .map(idx -> String.format("Value %d is found at index %d", val_random, idx)) 20 | .orElse(String.format("Value %d not found", val_random)); 21 | System.out.println(message1); 22 | System.out.printf("number of iteration %d\n", result1.counter); 23 | System.out.println(); 24 | 25 | String message2 = result2.index 26 | .map(idx -> String.format("Value %d is found at index %d", val_existed, idx)) 27 | .orElse(String.format("Value %d not found", val_existed)); 28 | System.out.println(message2); 29 | System.out.printf("number of iteration %d\n", result2.counter); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l05binarysearch/BinarySearchV1.java: -------------------------------------------------------------------------------- 1 | package algorithms.l05binarysearch; 2 | 3 | public class BinarySearchV1 { 4 | 5 | public int counter = 0; 6 | 7 | /** 8 | * find the given element in the sorted array 9 | * by using binary search algorithms 10 | * -1 if not found 11 | */ 12 | public int find(int[] data, int value) { 13 | counter = 0; 14 | int left = 0; 15 | int right = data.length - 1; 16 | if (value < data[left]) return -1; 17 | if (value > data[right]) return -1; 18 | while (left <= right) { 19 | counter++; 20 | int middle = (left + right) / 2; 21 | if (value > data[middle]) left = middle + 1; 22 | else if (value < data[middle]) right = middle - 1; 23 | else return middle; 24 | } 25 | return -1; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l05binarysearch/BinarySearchV2.java: -------------------------------------------------------------------------------- 1 | package algorithms.l05binarysearch; 2 | 3 | public class BinarySearchV2 { 4 | 5 | public static class Result { 6 | public final boolean found; 7 | public final int index; 8 | public final int counter; 9 | 10 | private Result(boolean found, int index, int counter) { 11 | this.found = found; 12 | this.index = index; 13 | this.counter = counter; 14 | } 15 | 16 | public static Result found(int index, int counter) { 17 | return new Result(true, index, counter); 18 | } 19 | 20 | public static Result notFound(int counter) { 21 | return new Result(false, -1, counter); 22 | } 23 | } 24 | 25 | public static Result find(int[] data, int value) { 26 | int counter = 0; 27 | int left = 0; 28 | int right = data.length - 1; 29 | if (value < data[left]) return Result.notFound(counter); 30 | if (value > data[right]) return Result.notFound(counter); 31 | while (left <= right) { 32 | counter++; 33 | int middle = (left + right) / 2; 34 | if (value > data[middle]) left = middle + 1; 35 | else if (value < data[middle]) right = middle - 1; 36 | else return Result.found(middle, counter); 37 | } 38 | return Result.notFound(counter); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l05binarysearch/BinarySearchV3.java: -------------------------------------------------------------------------------- 1 | package algorithms.l05binarysearch; 2 | 3 | import java.util.Optional; 4 | 5 | public class BinarySearchV3 { 6 | public final static class Result { 7 | public final Optional index; 8 | public final int counter; 9 | 10 | private Result(Optional index, int counter) { 11 | this.index = index; 12 | this.counter = counter; 13 | } 14 | 15 | public static Result found(int index, int counter) { 16 | return new Result(Optional.of(index), counter); 17 | } 18 | 19 | public static Result notFound(int counter) { 20 | return new Result(Optional.empty(), counter); 21 | } 22 | } 23 | 24 | public static Result find(final int[] data, final int value) { 25 | return find(data, value, 0, data.length - 1, 1); 26 | } 27 | 28 | public static Result find(final int[] data, final int value, final int left, final int right, final int counter) { 29 | if (left > right || value < data[left] || value > data[right]) 30 | return Result.notFound(counter); 31 | 32 | final int middle = (left + right) / 2; 33 | if (value == data[middle]) return Result.found(middle, counter); 34 | 35 | final int left2 = value > data[middle] ? middle + 1 : left; 36 | final int right2 = value < data[middle] ? middle - 1 : right; 37 | 38 | return find(data, value, left2, right2, counter+1); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l06hash/IMap.java: -------------------------------------------------------------------------------- 1 | package algorithms.l06hash; 2 | 3 | public interface IMap { 4 | void put(K key, V val); 5 | V get(K key); 6 | } 7 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l06hash/ST.java: -------------------------------------------------------------------------------- 1 | package algorithms.l06hash; 2 | 3 | public class ST,V> { 4 | 5 | private K[] keys; 6 | private V[] values; 7 | private final int N; 8 | 9 | @SuppressWarnings("unchecked") 10 | public ST(int size) { 11 | N = size; 12 | keys = (K[])new Comparable[N]; 13 | values = (V[])new Object[N]; 14 | } 15 | 16 | /** 17 | * binary: 18 | * search - LogN 19 | * insert - N 20 | * plain array: 21 | * search - N 22 | * insert - N 23 | */ 24 | private int rank (K key) { 25 | int lo = 0; 26 | int hi = N-1; 27 | while (lo <= hi) { 28 | int mid = lo + (hi - lo) / 2; 29 | int cmp = key.compareTo(keys[mid]); 30 | if (cmp<0) hi = mid - 1; 31 | else if (cmp>0) lo = mid + 1; 32 | else return mid; 33 | } 34 | return lo; 35 | } 36 | 37 | public V get(K key) { 38 | if (isEmpty()) return null; 39 | int idx = rank(key); 40 | if (idx < N && keys[idx].compareTo(key) == 0) return values[idx]; 41 | else return null; 42 | } 43 | 44 | public boolean isEmpty() { 45 | return false; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l06hash/XHashMapApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l06hash; 2 | 3 | public class XHashMapApp { 4 | public static void main1(String[] args) { 5 | XHashMap map = new XHashMap(); 6 | map.put(1, "Dima"); 7 | map.put(2, "Lena"); 8 | System.out.println(map.get(1)); 9 | System.out.println(map.get(2)); 10 | System.out.println(map.get(3)); 11 | } 12 | 13 | public static void main(String[] args) { 14 | XHashMap map = new XHashMap(100); 15 | map.put(1, "Dima"); 16 | map.put(17, "Lena"); 17 | map.put(33, "Ira"); 18 | System.out.println(map.get(1)); 19 | System.out.println(map.get(17)); 20 | System.out.println(map.get(33)); 21 | // System.out.println(map.get(65)); // element with key 65 not found(tail) 22 | // System.out.println(map.get(66)); // element with key 66 not found (1st) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l07tree/TwoThreeTree.java: -------------------------------------------------------------------------------- 1 | package algorithms.l07tree; 2 | 3 | public class TwoThreeTree { 4 | } 5 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l07tree/XTreeMapApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l07tree; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | import java.util.stream.IntStream; 7 | 8 | public class XTreeMapApp { 9 | 10 | public static void main(String[] args) { 11 | XTreeMap xt = new XTreeMap<>(); 12 | 13 | List data = IntStream.rangeClosed(1, 3).boxed().collect(Collectors.toList()); 14 | // Collections.shuffle(data); 15 | data.forEach(xt::putB); 16 | System.out.println(xt); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l07tree/nodeRemoval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/play/src/main/java/algorithms/l07tree/nodeRemoval.png -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l07tree/rotation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/play/src/main/java/algorithms/l07tree/rotation.png -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/Tools.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | 5 | import java.util.Collection; 6 | import java.util.LinkedList; 7 | import java.util.function.Supplier; 8 | import java.util.stream.IntStream; 9 | 10 | public class Tools { 11 | 12 | public static LinkedList toLL(Collection data) { 13 | return data instanceof LinkedList ? (LinkedList)data : new LinkedList<>(data); 14 | } 15 | 16 | public static void print_visited_array(boolean[] visited) { 17 | // print indices 18 | System.out.print("Indices:"); 19 | IntStream.range(0, visited.length).forEach(i -> 20 | System.out.printf("%3d", i) 21 | ); 22 | System.out.println(); 23 | 24 | // print values 25 | System.out.print("Values: "); 26 | IntStream.range(0, visited.length).forEach(i -> 27 | System.out.printf("%3s", visited[i] ? "*" : "") 28 | ); 29 | System.out.println(); 30 | } 31 | 32 | public static Graph copyGraph(Graph orig, Supplier constructorRef) { 33 | Graph copy = constructorRef.get(); 34 | IntStream.range(0, orig.v()) 35 | .forEach(src -> 36 | orig.children(src).forEach(dst -> 37 | copy.addEdge(src, dst))); 38 | 39 | return copy; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/AllReachableDFS.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.AllReachable; 4 | import algorithms.l08graph.rep.Graph; 5 | 6 | import java.util.Collection; 7 | import java.util.LinkedList; 8 | import java.util.stream.Collectors; 9 | import java.util.stream.IntStream; 10 | 11 | import static algorithms.l08graph.Tools.toLL; 12 | 13 | public class AllReachableDFS implements AllReachable { 14 | 15 | private final Graph g; 16 | 17 | public AllReachableDFS(Graph g) { 18 | this.g = g; 19 | } 20 | 21 | @Override 22 | public Collection allReachable(int src) { 23 | return dfs(src); 24 | } 25 | 26 | private Collection dfs(int src) { 27 | boolean[] visited = new boolean[g.v()]; 28 | LinkedList process = new LinkedList<>(); 29 | process.add(src); 30 | 31 | while (!process.isEmpty()) { 32 | int curr = process.poll(); 33 | if (visited[curr]) continue; 34 | visited[curr] = true; 35 | Collection children = g.children(curr); 36 | toLL(children).descendingIterator() 37 | .forEachRemaining(process::addFirst); 38 | } 39 | 40 | return IntStream.range(0, visited.length) 41 | .filter(x -> visited[x]) 42 | .boxed() 43 | .collect(Collectors.toList()); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/BFSIterative.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.TraverseBFS; 4 | import algorithms.l08graph.rep.Graph; 5 | 6 | import java.util.Arrays; 7 | import java.util.Collection; 8 | import java.util.LinkedList; 9 | 10 | /** 11 | * BFS 12 | * Iterative 13 | * with Loop Detection 14 | */ 15 | public class BFSIterative implements TraverseBFS { 16 | 17 | private final Graph g; 18 | private final boolean[] visited; 19 | 20 | public BFSIterative(Graph g) { 21 | this.g = g; 22 | visited = new boolean[g.v()]; 23 | } 24 | 25 | @Override 26 | public Collection traverse(int src) { 27 | // prepare 28 | Arrays.fill(visited, false); 29 | LinkedList outcome = new LinkedList<>(); 30 | LinkedList process = new LinkedList<>(); 31 | process.push(src); 32 | // run the algorithm 33 | bfs(process, outcome); 34 | // return the result 35 | return outcome; 36 | } 37 | 38 | private void bfs(LinkedList process, Collection outcome) { 39 | while (!process.isEmpty()) { 40 | int curr = process.pop(); 41 | 42 | if (!visited[curr]) { 43 | 44 | visited[curr] = true; 45 | outcome.add(curr); 46 | 47 | Collection curr_children = g.children(curr); 48 | process.addAll(curr_children); 49 | } 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/CommonOperations.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | 5 | public class CommonOperations { 6 | 7 | public int degree(Graph g, int v) { 8 | int d = 0; 9 | for (int w: g.children(v)) d++; 10 | return d; 11 | } 12 | 13 | public int maxDegree(Graph g) { 14 | int max = 0; 15 | for (int v = 0; v < g.v(); v++) 16 | max = Math.max(max, degree(g, v)); 17 | return max; 18 | } 19 | 20 | public int numberOfSelfLoops(Graph g) { 21 | int cnt = 0; 22 | for (int v = 0; v < g.v(); v++) { 23 | for (int w: g.children(v)) { 24 | cnt += w == v ? 1 : 0; 25 | } 26 | } 27 | return cnt / 2; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/DFS1RecursivePlain.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.TraverseDFS; 4 | import algorithms.l08graph.rep.Graph; 5 | 6 | import java.util.Arrays; 7 | import java.util.Collection; 8 | import java.util.LinkedList; 9 | 10 | /** 11 | * DFS traverse 12 | * recursive version 13 | * WITH LOOPS DETECTION 14 | */ 15 | public class DFS1RecursivePlain implements TraverseDFS { 16 | 17 | private final Graph g; 18 | private final boolean[] visited; 19 | 20 | public DFS1RecursivePlain(Graph g) { 21 | this.g = g; 22 | visited = new boolean[g.v()]; 23 | } 24 | 25 | @Override 26 | public Collection traverse(int src) { 27 | Arrays.fill(visited, false); 28 | LinkedList outcome = new LinkedList<>(); 29 | dfs(src, outcome); 30 | return outcome; 31 | } 32 | 33 | private void dfs(int curr, LinkedList seq) { 34 | if (visited[curr]) return; 35 | 36 | visited[curr] = true; 37 | seq.add(curr); 38 | 39 | Collection curr_children = g.children(curr); 40 | for (int child: curr_children) 41 | dfs(child, seq); 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/DFS3IterativeQueueApproach.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.TraverseDFS; 4 | import algorithms.l08graph.rep.Graph; 5 | 6 | import java.util.*; 7 | 8 | import static algorithms.l08graph.Tools.toLL; 9 | 10 | /** 11 | * DFS traverse 12 | * Iterative version (Queue) 13 | * WITH LOOPS DETECTION 14 | */ 15 | public class DFS3IterativeQueueApproach implements TraverseDFS { 16 | 17 | private final Graph g; 18 | private final boolean[] visited; 19 | 20 | public DFS3IterativeQueueApproach(Graph g) { 21 | this.g = g; 22 | visited = new boolean[g.v()]; 23 | } 24 | 25 | @Override 26 | public Collection traverse(int src) { 27 | Arrays.fill(visited, false); 28 | LinkedList outcome = new LinkedList<>(); 29 | dfs(src, outcome); 30 | return outcome; 31 | } 32 | 33 | private void dfs(int src, LinkedList outcome) { 34 | LinkedList process = new LinkedList<>(); 35 | process.add(src); 36 | while (!process.isEmpty()) { 37 | int curr = process.poll(); 38 | if (visited[curr]) continue; 39 | visited[curr] = true; 40 | outcome.add(curr); 41 | Collection children = g.children(curr); 42 | // add in front of queue, because we need DEPTH FIRTH 43 | toLL(children).descendingIterator().forEachRemaining(process::addFirst); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/DFS4RecursiveFunctional.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.TraverseDFS; 4 | import algorithms.l08graph.rep.Graph; 5 | 6 | import java.util.*; 7 | 8 | /** 9 | * DFS traverse 10 | * recursive version 11 | * WITH LOOPS DETECTION 12 | * almost functional (according to java syntax) 13 | * - no global variables 14 | */ 15 | public class DFS4RecursiveFunctional implements TraverseDFS { 16 | 17 | private final Graph g; 18 | 19 | public DFS4RecursiveFunctional(Graph g) { 20 | this.g = g; 21 | } 22 | 23 | @Override 24 | public Collection traverse(int src) { 25 | return dfs( 26 | src, 27 | new boolean[g.v()] 28 | ); 29 | } 30 | 31 | /** 32 | * strictly saying, 33 | * visited[] should be returned also from dfs, 34 | * because dfs modifies the visited list also. 35 | */ 36 | private Collection dfs(int curr, boolean[] visited) { 37 | if (visited[curr]) return Collections.emptyList(); 38 | Collection out = new LinkedList() {{ add(curr); }}; 39 | visited[curr] = true; 40 | g.children(curr).forEach(chi -> out.addAll(dfs(chi, visited))); 41 | return out; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/FirstPathDFS.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.PathFromTo; 4 | import algorithms.l08graph.rep.Graph; 5 | 6 | import java.util.Collection; 7 | import java.util.Optional; 8 | import java.util.Stack; 9 | 10 | public class FirstPathDFS implements PathFromTo { 11 | 12 | private final Graph g; 13 | 14 | public FirstPathDFS(Graph g) { 15 | this.g = g; 16 | } 17 | 18 | @Override 19 | public Optional> path(int src, int dst) { 20 | return path(src, dst, new boolean[g.v()], new Stack<>()); 21 | } 22 | 23 | private Optional> path(int src, int dst, boolean[] visited, Stack trace) { 24 | // quit condition to detect loops 25 | if (visited[src]) return Optional.empty(); 26 | // mark vertex as visited 27 | visited[src] = true; 28 | // push current to save the path for further usage 29 | trace.push(src); 30 | // quit condition if we reached destination 31 | if (src == dst) return Optional.of(trace); 32 | // iterate over all children 33 | Collection children = g.children(src); 34 | for (int child: children) { 35 | Optional> found = path(child, dst, visited, trace); 36 | // quit if we found the solution 37 | if (found.isPresent()) return found; 38 | } 39 | // pop current because nothing found 40 | trace.pop(); 41 | // return empty 42 | return Optional.empty(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/HasCyclesImpl.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.HasCycles; 4 | import algorithms.l08graph.rep.Graph; 5 | 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | import java.util.stream.IntStream; 9 | 10 | public class HasCyclesImpl implements HasCycles { 11 | 12 | private final Graph g; 13 | 14 | public HasCyclesImpl(Graph g) { 15 | this.g = g; 16 | } 17 | 18 | private boolean hasCycles(int src, boolean[] visited, Set path) { 19 | visited[src] = true; 20 | path.add(src); 21 | 22 | for (int child: g.children(src)) { 23 | if (!visited[child]) { 24 | if (hasCycles(child, visited, path)) return true; 25 | } else if (path.contains(child)) { 26 | return true; 27 | } 28 | } 29 | 30 | path.remove(src); 31 | return false; 32 | } 33 | 34 | @Override 35 | public boolean hasCycles() { 36 | boolean[] visited = new boolean[g.v()]; 37 | Set path = new HashSet<>(); 38 | 39 | return IntStream.range(0, g.v()) 40 | .filter(v -> !visited[v]) 41 | .anyMatch(v -> hasCycles(v, visited, path)); 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/IsConnectedBasic.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.IsConnected; 4 | import algorithms.l08graph.rep.Graph; 5 | 6 | import java.util.Collection; 7 | 8 | /** 9 | * basic recursive 10 | * DFS implementation 11 | * NO LOOPS DETECTION 12 | * will hang on loops 13 | */ 14 | public class IsConnectedBasic implements IsConnected { 15 | 16 | private final Graph g; 17 | 18 | public IsConnectedBasic(Graph g) { 19 | this.g = g; 20 | } 21 | 22 | @Override 23 | public boolean isConnected(int src, int dst) { 24 | // we reached the final point 25 | if (src == dst) return true; 26 | // get the children from the 'from' vertex 27 | Collection children = g.children(src); 28 | // iterate over them 29 | for (int child: children) { 30 | // try to find through the children 31 | if (isConnected(dst, child)) return true; 32 | } 33 | // no way from current is found - return false 34 | return false; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/IsConnectedMature.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.IsConnected; 4 | import algorithms.l08graph.rep.Graph; 5 | 6 | import java.util.Collection; 7 | 8 | /** 9 | * plain recursive 10 | * DFS 11 | * with Loop Detection 12 | */ 13 | public class IsConnectedMature implements IsConnected { 14 | 15 | private final Graph g; 16 | 17 | public IsConnectedMature(Graph g) { 18 | this.g = g; 19 | } 20 | 21 | private boolean dfs(int src, int dst, boolean[] visited) { 22 | if (src == dst) return true; 23 | if (visited[src]) return false; // to solve cycles 24 | visited[src] = true; // we need only these two lines 25 | Collection children = g.children(src); 26 | for (int child: children) { 27 | if (dfs(child, dst, visited)) return true; 28 | } 29 | return false; 30 | } 31 | 32 | @Override 33 | public boolean isConnected(int src, int dst) { 34 | return dfs(src, dst, new boolean[g.v()]); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/IsConnectedMatureChatty.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.IsConnected; 4 | import algorithms.l08graph.rep.Graph; 5 | 6 | import java.util.Collection; 7 | 8 | import static algorithms.l08graph.Tools.print_visited_array; 9 | 10 | /** 11 | * plain recursive 12 | * DFS 13 | * with Loop Detection 14 | */ 15 | public class IsConnectedMatureChatty implements IsConnected { 16 | 17 | private final Graph g; 18 | 19 | public IsConnectedMatureChatty(Graph g) { 20 | this.g = g; 21 | } 22 | 23 | private boolean dfs(int src, int dst, boolean[] visited) { 24 | System.out.printf("tracing path from %d to %d\n", src, dst); 25 | print_visited_array(visited); 26 | if (src == dst) { 27 | System.out.println("from == to. returning because we reached destination"); 28 | return true; 29 | } 30 | if (visited[src]) return false; 31 | visited[src] = true; 32 | Collection children = g.children(src); 33 | System.out.printf("looking for path to destination via: %s\n", children); 34 | for (int child: children) { 35 | if (dfs(child, dst, visited)) return true; 36 | } 37 | System.out.printf("looking for path to destination via: %s - NOT FOUND\n", children); 38 | return false; 39 | } 40 | 41 | @Override 42 | public boolean isConnected(int src, int dst) { 43 | return dfs(src, dst, new boolean[g.v()]); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/TopologicalSortingImpl2.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.TopologicalSorting; 4 | import algorithms.l08graph.rep.Graph; 5 | 6 | import java.util.*; 7 | import java.util.stream.IntStream; 8 | 9 | /** 10 | * This implementation implies 11 | * - having no cycles 12 | * - having no empty vertices 13 | * Actually DFS reversed. 14 | */ 15 | public class TopologicalSortingImpl2 implements TopologicalSorting { 16 | 17 | private final Graph g; 18 | private Stack reversePost; 19 | 20 | public TopologicalSortingImpl2(Graph g) { 21 | this.g = g; 22 | } 23 | 24 | @Override 25 | public Optional> topologicalSorting() { 26 | reversePost = new Stack<>(); 27 | boolean[] marked = new boolean[g.v()]; 28 | IntStream.range(0, g.v()) 29 | .filter(v -> !marked[v]) 30 | .forEach(v -> dfs(marked, v)); 31 | 32 | Collections.reverse(reversePost); 33 | return Optional.of(reversePost); 34 | } 35 | 36 | private void dfs(boolean[] marked, int v) { 37 | marked[v] = true; 38 | g.children(v).forEach(w -> { 39 | if (!marked[w]) dfs(marked, w); 40 | }); 41 | if (!g.children(v).isEmpty()) 42 | reversePost.push(v); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/thoughts/AreTheyIsomorphic.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls.thoughts; 2 | 3 | /** 4 | * n! 5 | * - No one knows 6 | */ 7 | public class AreTheyIsomorphic { 8 | } 9 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/thoughts/BridgesIslandsExactlyOnce.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls.thoughts; 2 | 3 | /** 4 | * Euler tour: 5 | * - all vertices exactly once 6 | * 7 | * BridgesIslandsExactlyOnce 8 | * - all vertices have even degree 9 | * 10 | * Hamilton tour: 11 | * - all edges visited exactly once 12 | * - classical NP-complete problem 13 | * - unlikely to have a polynomial time algorithm 14 | * - intractable 15 | */ 16 | public class BridgesIslandsExactlyOnce { 17 | } 18 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/thoughts/IsBiPartite.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls.thoughts; 2 | 3 | /** 4 | * Categories: 5 | * 6 | * - any 7 | * - diligent 8 | * - expert 9 | * - intractable 10 | * - no one knows 11 | * - impossible 12 | */ 13 | public class IsBiPartite { 14 | } 15 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/impls/thoughts/IsPlanar.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls.thoughts; 2 | 3 | /** 4 | * Tarjan 1970s 5 | * DFS based 6 | * - expert level 7 | */ 8 | public class IsPlanar { 9 | } 10 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/AllPaths.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | import java.util.Collection; 4 | 5 | public interface AllPaths { 6 | Collection> allPaths(int src, int dst); 7 | } 8 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/AllReachable.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | import java.util.Collection; 4 | 5 | public interface AllReachable { 6 | Collection allReachable(int src); 7 | } 8 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/AllReachableUpToDistance.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | import java.util.Collection; 4 | 5 | public interface AllReachableUpToDistance { 6 | 7 | class Distance { 8 | public final int vertex; 9 | public final int distance; 10 | 11 | public Distance(int vertex, int distance) { 12 | this.vertex = vertex; 13 | this.distance = distance; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return String.format("Dist[V=%d, d=%d]", vertex, distance); 19 | } 20 | } 21 | 22 | Collection allReachableWithDistances(int src, int max_dist); 23 | } 24 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/AllReachableWithDistances.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | import java.util.Collection; 4 | 5 | public interface AllReachableWithDistances { 6 | 7 | class Distance { 8 | public final int vertex; 9 | public final int distance; 10 | 11 | public Distance(int vertex, int distance) { 12 | this.vertex = vertex; 13 | this.distance = distance; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return String.format("Dist[V=%d, d=%d]", vertex, distance); 19 | } 20 | } 21 | 22 | Collection allReachableWithDistances(int src); 23 | } 24 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/HasCycles.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | public interface HasCycles { 4 | boolean hasCycles(); 5 | } 6 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/IsConnected.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | public interface IsConnected { 4 | boolean isConnected(int src, int dst); 5 | } 6 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/IsStronglyConnected.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | /** 4 | * DFS twice 5 | * Kosaraju - Sharir 6 | */ 7 | public interface IsStronglyConnected { 8 | boolean isStronglyConnected(int src, int dst); 9 | } 10 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/PathFromTo.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | import java.util.Collection; 4 | import java.util.Optional; 5 | 6 | public interface PathFromTo { 7 | Optional> path(int src, int dst); 8 | } 9 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/ShortestPath.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | import java.util.Collection; 4 | 5 | public interface ShortestPath { 6 | Collection shortestPath(int src, int dst); 7 | } 8 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/ShortestPathMultipleSource.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | import java.util.Collection; 4 | import java.util.Set; 5 | 6 | /** 7 | * find the shortest path from the given in thw set 8 | * to the rest of the graph vertices 9 | * 10 | * given { 1,2,3 } and graph { 1.2.3.4.5.6 } 11 | * 12 | * 1-4:x 13 | * 1-5:x 14 | * 1-6:x 15 | * 16 | * 2-4:x 17 | * 2-5:x 18 | * 2-6:x 19 | * 20 | * 3-4:x 21 | * 3-5:x 22 | * 3-6:x 23 | * 24 | * BFS, just enqueue with many sources 25 | */ 26 | public interface ShortestPathMultipleSource { 27 | 28 | class Distance { 29 | public final int src; 30 | public final int dst; 31 | public final int len; 32 | 33 | public Distance(int src, int dst, int len) { 34 | this.src = src; 35 | this.dst = dst; 36 | this.len = len; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return String.format("Dist[src=%d, dst=%d, len=%d]", src, dst, len); 42 | } 43 | } 44 | 45 | Collection shortestPathMultipleSource(Set sources); 46 | } 47 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/SingleSourceReachability.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | public interface SingleSourceReachability { 4 | } 5 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/TopologicalSorting.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | import java.util.Collection; 4 | import java.util.Optional; 5 | 6 | /** 7 | * Graph should be Directional 8 | * Graph mustn't contain cycles 9 | * if graph contains cycles we return Optional.empty 10 | */ 11 | public interface TopologicalSorting { 12 | Optional> topologicalSorting(); 13 | } 14 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/TopologicalSortingChainTo.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | import java.util.Collection; 4 | import java.util.Optional; 5 | 6 | /** 7 | * Graph should be Directional 8 | * Graph mustn't contain cycles 9 | * if graph contains cycles we return Optional.empty 10 | */ 11 | public interface TopologicalSortingChainTo { 12 | Optional> chainTo(int to); 13 | } 14 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/Traverse.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | import java.util.Collection; 4 | 5 | public interface Traverse { 6 | Collection traverse(int src); 7 | } 8 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/TraverseBFS.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | public interface TraverseBFS extends Traverse { 4 | } 5 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/ops/TraverseDFS.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.ops; 2 | 3 | public interface TraverseDFS extends Traverse { 4 | } 5 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/rep/Edge.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep; 2 | 3 | import java.util.Objects; 4 | 5 | public class Edge { 6 | public final int s; 7 | public final int d; 8 | 9 | public Edge(int s, int d) { 10 | this.s = s; 11 | this.d = d; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return String.format("%d -> %d", s, d); 17 | } 18 | 19 | @Override 20 | public boolean equals(Object o) { 21 | if (this == o) return true; 22 | if (o == null || getClass() != o.getClass()) return false; 23 | Edge edge = (Edge) o; 24 | return s == edge.s 25 | && d == edge.d; 26 | } 27 | 28 | @Override 29 | public int hashCode() { 30 | return Objects.hash(s, d); 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/rep/Edges.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep; 2 | 3 | import java.util.Collection; 4 | import java.util.Objects; 5 | import java.util.stream.Collectors; 6 | 7 | public class Edges { 8 | public final int src; 9 | public final Collection dst; 10 | 11 | public Edges(int src, Collection dst) { 12 | this.src = src; 13 | this.dst = dst; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return String.format("[%d -> %s]", src, 19 | dst.stream().map(Objects::toString).collect(Collectors.joining(",")) 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/rep/Graph.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep; 2 | 3 | import java.util.Collection; 4 | 5 | /** 6 | * we represent Vertices 7 | * as integers from 0 to V-1 8 | */ 9 | public interface Graph { 10 | /** number of vertices in the graph */ 11 | int v(); 12 | /** add an edge from v to w */ 13 | void addEdge(int v, int w); 14 | void removeEdge(int v, int w); 15 | /** get a List of vertices connected directly to the given vertex */ 16 | Collection children(int v); 17 | } 18 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/rep/dir/Digraph.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep.dir; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | 5 | public interface Digraph extends Graph { 6 | Digraph reverse(); 7 | } 8 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/rep/dir/GraphA.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep.dir; 2 | 3 | import algorithms.l08graph.rep.AbstractGraphA; 4 | 5 | import java.util.Arrays; 6 | import java.util.Collection; 7 | import java.util.function.Supplier; 8 | 9 | /** 10 | * I intentionally made it abstract to force user 11 | * to create a new instance with the new underlying structure 12 | * by declaring the new class and further usage it 13 | */ 14 | public abstract class GraphA> extends AbstractGraphA { 15 | 16 | public GraphA(int v, Supplier constructorRef) { 17 | super(v, constructorRef); 18 | } 19 | 20 | public GraphA(int v, Supplier constructorRef, int[][] edges) { 21 | this(v, constructorRef); 22 | Arrays.stream(edges).forEach(e -> addEdge(e[0], e[1])); 23 | } 24 | 25 | /** 26 | * I don't care if given v index 27 | * isn't in my array 28 | */ 29 | @Override 30 | public void addEdge(int v, int w) { 31 | adj[v].add(w); 32 | } 33 | 34 | @Override 35 | public void removeEdge(int v, int w) { 36 | adj[v].remove(w); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/rep/dir/GraphAL.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep.dir; 2 | 3 | import java.util.LinkedList; 4 | 5 | /** 6 | * adjacency based implementation 7 | * adjacency list stored in the LinkedList 8 | * we DO guarantee the order of vertices 9 | */ 10 | public class GraphAL extends GraphA> { 11 | 12 | public GraphAL(int v) { 13 | super(v, LinkedList::new); 14 | } 15 | 16 | public GraphAL(int v, int[][] edges) { 17 | super(v, LinkedList::new, edges); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/rep/dir/GraphAS.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep.dir; 2 | 3 | import java.util.HashSet; 4 | 5 | /** 6 | * adjacency based implementation 7 | * adjacency list stored in the Set 8 | * we CAN'T guarantee the order of vertices 9 | */ 10 | public class GraphAS extends GraphA> { 11 | 12 | public GraphAS(int v) { 13 | super(v, HashSet::new); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/rep/dir/GraphM.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep.dir; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | 5 | import java.util.Collection; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.IntStream; 8 | 9 | /** 10 | * matrix based implementation 11 | */ 12 | public class GraphM implements Graph { 13 | 14 | private final int v; 15 | // first index - src vertex 16 | // second index - dst vertex 17 | // if we want to work with path cost 18 | // we need to change it to int[][] 19 | private final boolean[][] m; 20 | 21 | public GraphM(int v) { 22 | this.v = v; 23 | this.m = new boolean[v][v]; 24 | } 25 | 26 | @Override 27 | public int v() { 28 | return this.v; 29 | } 30 | 31 | @Override 32 | public void addEdge(int v, int w) { 33 | m[v][w] = true; 34 | } 35 | 36 | @Override 37 | public void removeEdge(int v, int w) { 38 | m[v][w] = false; 39 | } 40 | 41 | @Override 42 | public Collection children(int v) { 43 | return IntStream.range(0, v) 44 | .filter(w -> m[v][w]) 45 | .boxed() 46 | .collect(Collectors.toList()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/rep/undir/GraphA.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep.undir; 2 | 3 | import algorithms.l08graph.rep.AbstractGraphA; 4 | 5 | import java.util.Collection; 6 | import java.util.function.Supplier; 7 | 8 | /** 9 | * I intentionally made it abstract to force user 10 | * to create a new instance with the new underlying structure 11 | * by declaring the new class and further usage it 12 | */ 13 | public abstract class GraphA> extends AbstractGraphA { 14 | 15 | public GraphA(int v, Supplier constructorRef) { 16 | super(v, constructorRef); 17 | } 18 | 19 | /** 20 | * I don't care if given v index 21 | * isn't in my array 22 | */ 23 | @Override 24 | public void addEdge(int v, int w) { 25 | adj[v].add(w); 26 | adj[w].add(v); 27 | } 28 | 29 | @Override 30 | public void removeEdge(int v, int w) { 31 | adj[v].remove(w); 32 | adj[w].remove(v); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/rep/undir/GraphAL.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep.undir; 2 | 3 | import java.util.LinkedList; 4 | 5 | /** 6 | * adjacency based implementation 7 | * adjacency list stored in the LinkedList 8 | * we DO guarantee the order of vertices 9 | */ 10 | public class GraphAL extends GraphA> { 11 | 12 | public GraphAL(int v) { 13 | super(v, LinkedList::new); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/rep/undir/GraphAS.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep.undir; 2 | 3 | import java.util.HashSet; 4 | 5 | /** 6 | * adjacency based implementation 7 | * adjacency list stored in the Set 8 | * we CAN'T guarantee the order of vertices 9 | */ 10 | public class GraphAS extends GraphA> { 11 | 12 | public GraphAS(int v) { 13 | super(v, HashSet::new); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l08graph/rep/undir/GraphM.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep.undir; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | 5 | import java.util.Collection; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.IntStream; 8 | 9 | /** 10 | * matrix based implementation 11 | */ 12 | public class GraphM implements Graph { 13 | 14 | private final int v; 15 | // first index - src vertex 16 | // second index - dst vertex 17 | // if we want to work with path cost 18 | // we need to change it to int[][] 19 | private final boolean[][] m; 20 | 21 | public GraphM(int v) { 22 | this.v = v; 23 | this.m = new boolean[v][v]; 24 | } 25 | 26 | @Override 27 | public int v() { 28 | return this.v; 29 | } 30 | 31 | @Override 32 | public void addEdge(int v, int w) { 33 | m[v][w] = true; 34 | m[w][v] = true; 35 | } 36 | 37 | @Override 38 | public void removeEdge(int v, int w) { 39 | m[v][w] = false; 40 | m[w][v] = false; 41 | } 42 | 43 | @Override 44 | public Collection children(int v) { 45 | return IntStream.range(0, v) 46 | .filter(w -> m[v][w]) 47 | .boxed() 48 | .collect(Collectors.toList()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l09edgeweightedgraph/impl/KruskalMST.java: -------------------------------------------------------------------------------- 1 | package algorithms.l09edgeweightedgraph.impl; 2 | 3 | import algorithms.l09edgeweightedgraph.ops.MinimalSpanningTree; 4 | import algorithms.l09edgeweightedgraph.rep.EWG; 5 | import algorithms.l09edgeweightedgraph.rep.Edge; 6 | import algorithms.l11unionfind.impl.UnionFindV4; 7 | import algorithms.l11unionfind.rep.UnionFind; 8 | 9 | import java.util.Comparator; 10 | import java.util.LinkedList; 11 | import java.util.PriorityQueue; 12 | import java.util.stream.Collectors; 13 | 14 | public class KruskalMST implements MinimalSpanningTree { 15 | private final EWG g; 16 | 17 | public KruskalMST(EWG g) { 18 | this.g = g; 19 | } 20 | 21 | private boolean isConnected(UnionFind uf, Edge e) { 22 | int v = e.either(); 23 | int w = e.other(v); 24 | return uf.isConnected(v, w); 25 | } 26 | 27 | @Override 28 | public Iterable minSpanTree() { 29 | UnionFind uf = new UnionFindV4(g.v()); 30 | 31 | PriorityQueue edges = 32 | g.edgesStream() 33 | .collect(Collectors.toCollection(() -> new PriorityQueue<>(Comparator.comparingDouble(e -> e.weight)))); 34 | 35 | LinkedList mst = new LinkedList<>(); 36 | while (!edges.isEmpty() && mst.size() < g.v() - 1) { 37 | Edge e = edges.remove(); 38 | if (isConnected(uf, e)) continue; 39 | mst.add(e); 40 | int v = e.either(); 41 | int w = e.other(v); 42 | uf.union(v, w); 43 | } 44 | return mst; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l09edgeweightedgraph/impl/PrimMST.java: -------------------------------------------------------------------------------- 1 | package algorithms.l09edgeweightedgraph.impl; 2 | 3 | import algorithms.l09edgeweightedgraph.ops.MinimalSpanningTree; 4 | import algorithms.l09edgeweightedgraph.rep.EWG; 5 | import algorithms.l09edgeweightedgraph.rep.Edge; 6 | import algorithms.l11unionfind.impl.UnionFindV4; 7 | import algorithms.l11unionfind.rep.UnionFind; 8 | 9 | import java.util.Comparator; 10 | import java.util.LinkedList; 11 | import java.util.PriorityQueue; 12 | 13 | public class PrimMST implements MinimalSpanningTree { 14 | private final EWG g; 15 | 16 | public PrimMST(EWG g) { 17 | this.g = g; 18 | } 19 | 20 | @Override 21 | public Iterable minSpanTree() { 22 | PriorityQueue edges = new PriorityQueue<>(Comparator.comparingDouble(e -> e.weight)); 23 | LinkedList mst = new LinkedList<>(); 24 | boolean[] visited = new boolean[g.v()]; 25 | UnionFind uf = new UnionFindV4(g.v()); 26 | 27 | int pt = 0; 28 | g.adj(pt).forEach(edges::add); 29 | 30 | while (!edges.isEmpty() && mst.size() < g.v() - 1 ) { 31 | for (Edge ex : g.adj(pt)) 32 | if (!visited[ex.other(pt)]) edges.add(ex); 33 | 34 | visited[pt] = true; 35 | 36 | Edge e = edges.remove(); 37 | 38 | int v = e.either(); 39 | int w = e.other(v); 40 | 41 | if (uf.isConnected(v, w)) continue; 42 | mst.add(e); 43 | uf.union(v, w); 44 | 45 | pt = visited[v] ? w : v; 46 | } 47 | 48 | return mst; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l09edgeweightedgraph/ops/MinimalSpanningTree.java: -------------------------------------------------------------------------------- 1 | package algorithms.l09edgeweightedgraph.ops; 2 | 3 | import algorithms.l09edgeweightedgraph.rep.Edge; 4 | 5 | public interface MinimalSpanningTree { 6 | Iterable minSpanTree(); 7 | } 8 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l09edgeweightedgraph/ops/mst1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/play/src/main/java/algorithms/l09edgeweightedgraph/ops/mst1.png -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l09edgeweightedgraph/ops/mst2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/play/src/main/java/algorithms/l09edgeweightedgraph/ops/mst2.png -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l09edgeweightedgraph/rep/EWG.java: -------------------------------------------------------------------------------- 1 | package algorithms.l09edgeweightedgraph.rep; 2 | 3 | import java.util.stream.Stream; 4 | 5 | public interface EWG { 6 | int v(); 7 | void addEdge(Edge e); 8 | Iterable adj(int v); 9 | Iterable edges(); 10 | Stream edgesStream(); 11 | } 12 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l09edgeweightedgraph/rep/Edge.java: -------------------------------------------------------------------------------- 1 | package algorithms.l09edgeweightedgraph.rep; 2 | 3 | import java.util.Objects; 4 | 5 | public class Edge { 6 | private final int v; 7 | private final int w; 8 | public final double weight; 9 | 10 | public Edge(int v, int w, double weight) { 11 | this.v = v; 12 | this.w = w; 13 | this.weight = weight; 14 | } 15 | 16 | public int either() { 17 | return v; 18 | } 19 | 20 | public int other(int vx) { 21 | return vx == v ? w : v; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return String.format("Edge[%d - %d : %.2f]", v, w, weight); 27 | } 28 | 29 | @Override 30 | public boolean equals(Object o) { 31 | if (this == o) return true; 32 | if (o == null || getClass() != o.getClass()) return false; 33 | Edge edge = (Edge) o; 34 | return v == edge.v && 35 | w == edge.w && 36 | Double.compare(edge.weight, weight) == 0; 37 | } 38 | 39 | @Override 40 | public int hashCode() { 41 | return Objects.hash(v, w, weight); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l10ewdig/ops/ShortestPath.java: -------------------------------------------------------------------------------- 1 | package algorithms.l10ewdig.ops; 2 | 3 | import algorithms.l10ewdig.rep.DiEdge; 4 | 5 | import java.util.Optional; 6 | 7 | /** 8 | * properties: 9 | * 10 | */ 11 | public interface ShortestPath { 12 | Optional> shortestPathTo(int s, int v); 13 | Optional distanceTo(int s, int v); 14 | } 15 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l10ewdig/rep/DiEdge.java: -------------------------------------------------------------------------------- 1 | package algorithms.l10ewdig.rep; 2 | 3 | public class DiEdge { 4 | public final int from; 5 | public final int to; 6 | public final double weight; 7 | 8 | public DiEdge(int from, int to, double weight) { 9 | this.from = from; 10 | this.to = to; 11 | this.weight = weight; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return String.format("DiEdge[%d -> %d : %.2f]", from, to, weight); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l10ewdig/rep/EWDiG.java: -------------------------------------------------------------------------------- 1 | package algorithms.l10ewdig.rep; 2 | 3 | import java.util.stream.Stream; 4 | 5 | public interface EWDiG { 6 | int v(); 7 | void addEdge(DiEdge e); 8 | Iterable adj(int v); 9 | Stream adjStream(int v); 10 | Iterable edges(); 11 | Stream edgesStream(); 12 | } 13 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l10ewdig/test/ShortestPathDesign.java: -------------------------------------------------------------------------------- 1 | package algorithms.l10ewdig.test; 2 | 3 | import algorithms.l10ewdig.impl.ShortestPathDijkstra1; 4 | import algorithms.l10ewdig.rep.EWDiG; 5 | 6 | public class ShortestPathDesign { 7 | 8 | public void test(EWDiG g, int s) { 9 | ShortestPathDijkstra1 sp = new ShortestPathDijkstra1(g); 10 | for (int v = 0; v < g.v(); v++) { 11 | int vf = v; 12 | sp.distanceTo(s, v).ifPresent(dist -> System.out.printf("%d -> %d (%.2f)", s, vf, dist)); 13 | sp.shortestPathTo(s, v).ifPresent(path -> path.forEach(System.out::print)); 14 | 15 | System.out.println(); 16 | } 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l11unionfind/impl/UnionFindV1.java: -------------------------------------------------------------------------------- 1 | package algorithms.l11unionfind.impl; 2 | 3 | import algorithms.l11unionfind.rep.UnionFind; 4 | 5 | /** 6 | * 1. Naive Implementation. 7 | * 8 | * easy to implement 9 | * but to expensive: 10 | * 11 | * union - O(N) 12 | * check - O(1) 13 | * 14 | * quadratic algorithms don't scale. 15 | */ 16 | public class UnionFindV1 implements UnionFind { 17 | private final int[] ids; 18 | 19 | public UnionFindV1(int size) { 20 | this.ids = new int[size]; 21 | for (int i = 0; i < size; i++) { 22 | ids[i] = i; 23 | } 24 | } 25 | 26 | @Override 27 | public int v() { 28 | return ids.length; 29 | } 30 | 31 | @Override 32 | public void union(int p, int q) { 33 | int pid = ids[p]; 34 | int qid = ids[q]; 35 | for (int i = 0; i < ids.length; i++) { 36 | if(ids[i] == pid) ids[i] = qid; 37 | } 38 | } 39 | 40 | @Override 41 | public boolean isConnected(int p, int q) { 42 | return ids[p] == ids[q]; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l11unionfind/impl/UnionFindV2.java: -------------------------------------------------------------------------------- 1 | package algorithms.l11unionfind.impl; 2 | 3 | import algorithms.l11unionfind.rep.UnionFind; 4 | 5 | /** 6 | * 2. Tree based implementation. 7 | * 8 | * trees can get tall and long 9 | * so, connected is too expensive 10 | * 11 | * union - O(1..N) 12 | * check - O(1..N) 13 | */ 14 | public class UnionFindV2 implements UnionFind { 15 | private final int[] ids; 16 | 17 | public UnionFindV2(int size) { 18 | this.ids = new int[size]; 19 | for (int i = 0; i < size; i++) { 20 | ids[i] = i; 21 | } 22 | } 23 | 24 | private int root(int i) { 25 | while (i != ids[i]) { 26 | i = ids[i]; 27 | } 28 | return i; 29 | } 30 | 31 | @Override 32 | public int v() { 33 | return ids.length; 34 | } 35 | 36 | @Override 37 | public void union(int p, int q) { 38 | int i = root(p); 39 | int j = root(q); 40 | ids[i] = j; 41 | } 42 | 43 | @Override 44 | public boolean isConnected(int p, int q) { 45 | return root(p) == root(q); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l11unionfind/impl/UnionFindV3.java: -------------------------------------------------------------------------------- 1 | package algorithms.l11unionfind.impl; 2 | 3 | import algorithms.l11unionfind.rep.UnionFind; 4 | 5 | /** 6 | * 3. improvement #1. 7 | * connect smaller to bigger. 8 | * 9 | * we will keep number of element in each tree 10 | * and ALWAYS connect smaller tree to a larger one 11 | * so, we can guarantee that tree isn't tall 12 | */ 13 | public class UnionFindV3 implements UnionFind { 14 | private final int[] id; 15 | private final int[] sz; 16 | 17 | public UnionFindV3(int size) { 18 | this.id = new int[size]; 19 | this.sz = new int[size]; 20 | 21 | for (int i = 0; i < size; i++) { 22 | id[i] = i; 23 | sz[i] = 1; 24 | } 25 | } 26 | 27 | /** O(c) */ 28 | private int root(int i) { 29 | while (i != id[i]) { 30 | i = id[i]; 31 | } 32 | return i; 33 | } 34 | 35 | @Override 36 | public int v() { 37 | return id.length; 38 | } 39 | 40 | /** O(lg N) */ 41 | @Override 42 | public void union(int p, int q) { 43 | int i = root(p); 44 | int j = root(q); 45 | if (i == j) return; 46 | if (sz[i] < sz[j]) { id[i] = j; sz[j] += sz[i]; } 47 | else { id[j] = i; sz[i] += sz[j]; } 48 | } 49 | 50 | /** O(lg N) */ 51 | @Override 52 | public boolean isConnected(int p, int q) { 53 | return root(p) == root(q); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l11unionfind/impl/UnionFindV4.java: -------------------------------------------------------------------------------- 1 | package algorithms.l11unionfind.impl; 2 | 3 | import algorithms.l11unionfind.rep.UnionFind; 4 | 5 | /** 6 | * 4. improvement 2. 7 | * path compression. 8 | * 9 | * each time we are looking for item, 10 | * we rewrite the parent. 11 | */ 12 | public class UnionFindV4 implements UnionFind { 13 | private final int[] id; 14 | private final int[] sz; 15 | 16 | public UnionFindV4(int size) { 17 | this.id = new int[size]; 18 | this.sz = new int[size]; 19 | 20 | for (int i = 0; i < size; i++) { 21 | id[i] = i; 22 | sz[i] = 1; 23 | } 24 | } 25 | 26 | /** O(c) */ 27 | private int root(int i) { 28 | while (i != id[i]) { 29 | // only one line, rewrite the path 30 | id[i] = id[id[i]]; 31 | i = id[i]; 32 | } 33 | return i; 34 | } 35 | 36 | @Override 37 | public int v() { 38 | return id.length; 39 | } 40 | 41 | /** O(lg N) */ 42 | public void union(int p, int q) { 43 | int i = root(p); 44 | int j = root(q); 45 | if (i == j) return; 46 | if (sz[i] < sz[j]) { id[i] = j; sz[j] += sz[i]; } 47 | else { id[j] = i; sz[i] += sz[j]; } 48 | } 49 | 50 | /** O(lg N) */ 51 | @Override 52 | public boolean isConnected(int p, int q) { 53 | return root(p) == root(q); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l11unionfind/rep/UnionFind.java: -------------------------------------------------------------------------------- 1 | package algorithms.l11unionfind.rep; 2 | 3 | public interface UnionFind { 4 | int v(); 5 | void union(int p, int q); 6 | boolean isConnected(int p, int q); 7 | } 8 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l12binaryheap/BinaryHeapApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l12binaryheap; 2 | 3 | import java.util.stream.Stream; 4 | 5 | /** 6 | * In the binary heap - 7 | * children must be smaller than their parents 8 | * 9 | * the root is the max value 10 | * 11 | * we represent tree in an array: 12 | * parent of K is k/2 13 | * children of K are 2k and 2k+1 14 | * (indices) 15 | * 16 | * actually, it's a PriorityQueue with: 17 | * - O(logN) insertion 18 | * - O(logN) deletion 19 | * - O(1) peek 20 | */ 21 | public class BinaryHeapApp { 22 | 23 | public static void main(String[] args) { 24 | BinaryHeap bh = new BinaryHeap<>(30); 25 | 26 | System.out.println("adding"); 27 | Stream.generate(() -> String.valueOf((char)(Math.random()*('Z'-'A')+'A'))) 28 | .distinct().limit(20) 29 | .forEach(x -> { 30 | bh.insert(x); 31 | System.out.println(bh); 32 | }); 33 | 34 | System.out.println("removing"); 35 | while (!bh.isEmpty()) { 36 | bh.delMax(); 37 | System.out.println(bh); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l12binaryheap/PriorityQueueApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l12binaryheap; 2 | 3 | import java.util.PriorityQueue; 4 | 5 | public class PriorityQueueApp { 6 | public static void main(String[] args) { 7 | PriorityQueue pq = new PriorityQueue<>(); 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l12binaryheap/PriorityQueueImpls.java: -------------------------------------------------------------------------------- 1 | package algorithms.l12binaryheap; 2 | 3 | /** 4 | * we can easily implement PQ with 5 | * 6 | * - sorted array / linked list 7 | * - insert O(N) 8 | * - peek O(1) 9 | * - delete O(1) 10 | * 11 | * - unsorted array 12 | * - insert O(1) 13 | * - peek O(N) 14 | * - delete O(N) 15 | * 16 | * - but we want look at the {@linkplain BinaryHeap}: 17 | * - insert O(logN) 18 | * - peek O(1) 19 | * - delete O(logN) 20 | */ 21 | public class PriorityQueueImpls { 22 | } 23 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l13lee/LPoint.java: -------------------------------------------------------------------------------- 1 | package algorithms.l13lee; 2 | 3 | public class LPoint { 4 | public final int x; 5 | public final int y; 6 | 7 | public LPoint(int x, int y) { 8 | this.x = x; 9 | this.y = y; 10 | } 11 | 12 | public static LPoint of(int x, int y) { 13 | return new LPoint(x, y); 14 | } 15 | 16 | LPoint move(int dx, int dy) { 17 | return LPoint.of(x + dx, y + dy); 18 | } 19 | 20 | @Override 21 | public boolean equals(Object o) { 22 | if (this == o) return true; 23 | if (o == null || getClass() != o.getClass()) return false; 24 | LPoint that = (LPoint) o; 25 | return this.x == that.x && this.y == that.y; 26 | } 27 | 28 | @Override 29 | public int hashCode() { 30 | return x << 16 + y; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return String.format("[%d:%d]", x, y); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l13lee/LeeDemoApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.l13lee; 2 | 3 | import java.util.List; 4 | import java.util.Optional; 5 | import java.util.stream.Collectors; 6 | import java.util.stream.IntStream; 7 | import java.util.stream.Stream; 8 | 9 | public class LeeDemoApp { 10 | 11 | public static void main(String[] args) { 12 | Lee lee = new Lee(15, 10); 13 | 14 | List obstacles = Stream.of( 15 | IntStream.rangeClosed(0, 7).mapToObj(y -> new LPoint(5, y)), 16 | IntStream.rangeClosed(2, 9).mapToObj(y -> new LPoint(10, y)) 17 | ).flatMap(a -> a).collect(Collectors.toList()); 18 | 19 | LPoint start = LPoint.of(0, 0); 20 | LPoint finish = LPoint.of(14, 9); 21 | 22 | Optional> path = lee.trace(start, finish, obstacles, true); 23 | System.out.println(path); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/l13lee/README.md: -------------------------------------------------------------------------------- 1 | ### Links 2 | 3 | - [My YouTube explanation](https://www.youtube.com/watch?v=Tebc6J0qxNA) 4 | - [Wikipedia English](https://en.wikipedia.org/wiki/Lee_algorithm) 5 | - [Wikipedia Russian](https://ru.wikipedia.org/wiki/Алгоритм_Ли) 6 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/quizz/AppleApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.quizz; 2 | 3 | public class AppleApp { 4 | public static void main(String[] args) { 5 | System.out.println("Apple" + 6 | " costs " + 7 | + '2' 8 | +" USD"); // Apple costs 50 USD 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/quizz/PriorityQueueApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.quizz; 2 | 3 | import java.util.PriorityQueue; 4 | import java.util.Random; 5 | import java.util.stream.Collectors; 6 | 7 | public class PriorityQueueApp { 8 | public static void main(String[] args) { 9 | PriorityQueue pq = new Random().ints(10, 100) 10 | .limit(20) 11 | .boxed() 12 | .collect(Collectors.toCollection(PriorityQueue::new)); 13 | 14 | System.out.println(pq.toString()); 15 | while (!pq.isEmpty()) { 16 | System.out.printf("%d, ",pq.poll()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /play/src/main/java/algorithms/quizz/SetApp.java: -------------------------------------------------------------------------------- 1 | package algorithms.quizz; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class SetApp { 7 | public static void main(String[] args) { 8 | Set set = new HashSet<>(); 9 | for (short i = 0; i < 100; i++) { 10 | set.add(i); 11 | set.remove(i+1); 12 | } 13 | System.out.println(set.size()); // 100 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /play/src/main/java/c/C1_general.md: -------------------------------------------------------------------------------- 1 | ### module C short description 2 | 3 | - data structures: stack, queue, priority queue, map, set 4 | - linked list 5 | - sorting algorithms: bubble / quick sort / merge sort 6 | - algorithms 7 | - bitwise operation: encoding / decoding ! & || 8 | - graphs: search / unidirectional / bidirectional / loops / BFS / DFS 9 | - trees: binary, red-and-black, AVL, balanced, semi/partial, unbalanced 10 | - binary search 11 | - recursion non-tail/tail: sum/len 12 | - stack problems 13 | - topological sort 14 | - snake challenge 15 | -------------------------------------------------------------------------------- /play/src/main/java/common/RX.java: -------------------------------------------------------------------------------- 1 | package common; 2 | 3 | public class RX { 4 | public static RuntimeException NI = new RuntimeException("hasn't implementer yet ;)"); 5 | public static RuntimeException NE = new RuntimeException("shouldn't be empty"); 6 | } 7 | -------------------------------------------------------------------------------- /play/src/main/java/common/Utils.java: -------------------------------------------------------------------------------- 1 | package common; 2 | 3 | import java.util.Arrays; 4 | import java.util.stream.Collectors; 5 | import java.util.stream.IntStream; 6 | 7 | public class Utils { 8 | 9 | public static String spaces(int n) { 10 | byte[] bytes = new byte[n]; 11 | Arrays.fill(bytes, (byte) 0x20); 12 | return new String(bytes); 13 | } 14 | 15 | public static String indexes(int before, int from, int count, int width) { 16 | String indexes = "Indexes:"; 17 | String format = "%"+String.format("%d", width)+"d"; 18 | return indexes + spaces(before-indexes.length()) + IntStream.range(from, from+count) 19 | .mapToObj(n -> String.format(format, n)).collect(Collectors.joining()); 20 | } 21 | 22 | public static String centered(String content, int width) { 23 | int occupied = content.length(); 24 | int left_size = (width - occupied) >> 1; 25 | int right_size = width - left_size - occupied; 26 | return String.format("%s%s%s", spaces(left_size), content, spaces(right_size)); 27 | } 28 | 29 | public static int widthByLevelDepth(int level, int depth, int SIZE) { 30 | return SIZE << (depth - level); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /play/src/main/java/core/BoxingUnboxing.java: -------------------------------------------------------------------------------- 1 | package core; 2 | 3 | public class BoxingUnboxing { 4 | 5 | public Integer boxing(int val) { 6 | return val; 7 | } 8 | 9 | public int unboxing(Integer val) { 10 | return val; 11 | } 12 | 13 | public static void main(String[] args) { 14 | 15 | // primitive 16 | int i51 = 51; 17 | 18 | // class wrapper 19 | Integer i52 = new Integer(5); 20 | 21 | // auto-boxing 22 | Integer i53 = 53; 23 | 24 | // unboxing 25 | int i54 = i52; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /play/src/main/java/core/generics_DIRTY/AList.java: -------------------------------------------------------------------------------- 1 | package core.generics_DIRTY; 2 | 3 | public class AList { 4 | private final T[] data; 5 | 6 | public AList(int size) { 7 | this.data = (T[]) new Object[size]; 8 | } 9 | 10 | void put(int index, T val) { 11 | data[index] = val; 12 | } 13 | 14 | T get(int index) { 15 | return data[index]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /play/src/main/java/core/generics_DIRTY/AListUsage.java: -------------------------------------------------------------------------------- 1 | package core.generics_DIRTY; 2 | 3 | import java.util.function.Function; 4 | import java.util.function.Predicate; 5 | import java.util.stream.Stream; 6 | 7 | public class AListUsage { 8 | public static void main(String[] args) { 9 | AList aa = new AList<>(10); 10 | aa.put(1, 5); 11 | aa.put(2, 6); 12 | 13 | int i1 = aa.get(1); 14 | 15 | Function f_to_int = (s) -> Integer.parseInt(s); 16 | int x5 = f_to_int.apply("5"); 17 | 18 | Stream.of(1,2,3).map(new Function() { 19 | @Override 20 | public Integer apply(Integer x) { 21 | return x * 2; 22 | } 23 | }); 24 | 25 | Predicate test4 = new Predicate() { 26 | @Override 27 | public boolean test(Integer x) { 28 | return x > 4; 29 | } 30 | }; 31 | Predicate test41 = x -> x > 4; 32 | Predicate test42 = (Integer x) -> x > 4; 33 | 34 | 35 | Stream.of(1,2,3).map(x -> x * 2).filter(new Predicate() { 36 | @Override 37 | public boolean test(Integer x) { 38 | return x > 4; 39 | } 40 | }); 41 | Stream.of(1,2,3).map(x -> x * 2).filter(x -> x > 4); 42 | Stream.of(1,2,3).map(x -> x * 2).filter(test4); 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /play/src/main/java/core/iterable/HiddenApp.java: -------------------------------------------------------------------------------- 1 | package core.iterable; 2 | 3 | import java.util.Iterator; 4 | 5 | public class HiddenApp { 6 | public static void main(String[] args) { 7 | HiddenData data = new HiddenData(); 8 | 9 | for (String s: data) { 10 | System.out.println(s); 11 | } 12 | data.forEach(s -> System.out.println(s)); 13 | 14 | Iterator it2 = data.iterator_data2(); 15 | while (it2.hasNext()) { 16 | System.out.println(it2.next()); 17 | } 18 | 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /play/src/main/java/core/iterable/HiddenData.java: -------------------------------------------------------------------------------- 1 | package core.iterable; 2 | 3 | import java.util.Arrays; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | public final class HiddenData implements Iterable { 8 | 9 | private final List data = Arrays.asList( 10 | "Winter", "Summer", "Spring", "Autumn" 11 | ); 12 | 13 | @Override 14 | public Iterator iterator() { 15 | return data.iterator(); 16 | } 17 | 18 | private final int[] data2 = new int[] {1,2,3,4}; 19 | 20 | public Iterator iterator_data2() { 21 | // Iterator iterator1 = data.iterator(); 22 | // Iterator iterator2 = data2.iterator(); 23 | 24 | Iterator myIterator = new Iterator() { 25 | int current = 0; 26 | 27 | @Override 28 | public boolean hasNext() { 29 | return current < data2.length; 30 | } 31 | 32 | @Override 33 | public Integer next() { 34 | // Integer current_element = 35 | return data2[current++]; 36 | // current++; 37 | // return String.format("<%d>", current_element); 38 | } 39 | }; 40 | 41 | return myIterator; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /play/src/main/java/dynamic/GFG.java: -------------------------------------------------------------------------------- 1 | package dynamic; 2 | 3 | public class GFG { 4 | static int minCoins(int coins[], int m, int V) { 5 | // table[i] will be storing 6 | // the minimum number of coins 7 | // required for i value. So 8 | // table[V] will have result 9 | int[] table = new int[V + 1]; 10 | 11 | table[0] = 0; 12 | 13 | for (int i = 1; i <= V; i++) { 14 | table[i] = Integer.MAX_VALUE; 15 | } 16 | 17 | for (int i = 1; i <= V; i++) { 18 | // Go through all coins smaller than i 19 | for (int j = 0; j < m; j++) 20 | if (coins[j] <= i) { 21 | int sub_res = table[i - coins[j]]; 22 | if (sub_res != Integer.MAX_VALUE 23 | && sub_res + 1 < table[i]) { 24 | table[i] = sub_res + 1; 25 | } 26 | } 27 | } 28 | return table[V]; 29 | } 30 | 31 | public static void main(String[] args) { 32 | int[] coins = {9, 6, 5, 1}; 33 | int m = coins.length; 34 | int V = 11; 35 | System.out.printf("Minimum coins required is %d\n", minCoins(coins, m, V)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /play/src/main/java/links.md: -------------------------------------------------------------------------------- 1 | Links on [Coursera](https://www.coursera.org) I'd recommend 2 | - [Algorithms #1](https://www.coursera.org/learn/algorithms-part1) 3 | - [Algorithms #2](https://www.coursera.org/learn/algorithms-part2) 4 | 5 | Slideshare link 6 | - [Radix and Shell Sort](https://www.slideshare.net/hannatamayao/radix-and-shell-sort-84534274) 7 | -------------------------------------------------------------------------------- /play/src/main/java/math/AppMatrix.java: -------------------------------------------------------------------------------- 1 | package math; 2 | 3 | import java.util.Scanner; 4 | 5 | public class AppMatrix { 6 | public static void main(String[] args) { 7 | int ch,n,i,j,max=0,j_max,i_max; 8 | System.out.print("Please, enter a size of matrix\n"); 9 | Scanner in = new Scanner(System.in); 10 | n = in.nextInt(); 11 | int[][] a = new int[n][n]; 12 | System.out.print("rand or not(1,0) \n"); 13 | 14 | for (i = 0; i < n; i++) { 15 | for (j = 0; j < n; j++) { 16 | a[i][j] = (int)(Math.random()*100); 17 | } 18 | } 19 | 20 | System.out.print("Matrix before: \n"); 21 | for (i = 0; i < n; i++) { 22 | for (j = 0; j < n; j++) { 23 | System.out.printf("%2d ", a[i][j]); 24 | } 25 | System.out.println(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/ChangeCase.java: -------------------------------------------------------------------------------- 1 | package warmup; 2 | 3 | public class ChangeCase { 4 | public String invert(String origin) { 5 | byte[] bytes = origin.getBytes(); 6 | for (int i = 0; i < bytes.length; i++) { 7 | bytes[i] ^= 0x20; 8 | } 9 | return new String(bytes); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/GetRidOfVowels.java: -------------------------------------------------------------------------------- 1 | package warmup; 2 | 3 | public class GetRidOfVowels { 4 | public String filter(String origin) { 5 | return origin.chars() 6 | .mapToObj(value -> (char)value) 7 | .filter(ch -> !java.util.Arrays.asList('A','E','O','I','U') 8 | .contains(Character.toUpperCase(ch))) 9 | .map(String::valueOf) 10 | .collect(java.util.stream.Collectors.joining()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/IsPalindromeNaive.java: -------------------------------------------------------------------------------- 1 | package warmup; 2 | 3 | public class IsPalindromeNaive { 4 | boolean check(int number) { 5 | String s = String.valueOf(number); 6 | return s.contentEquals(new StringBuilder(s).reverse()); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/IsPalindromeOptimized.java: -------------------------------------------------------------------------------- 1 | package warmup; 2 | 3 | public class IsPalindromeOptimized { 4 | boolean check(int number) { 5 | int[] digits = new int[10]; 6 | int count = 0; 7 | while (number > 0) { 8 | digits[count++] = number % 10; 9 | number /= 10; 10 | } 11 | for (int i = 0; i < count / 2; i++) { 12 | if (digits[count-i-1] != digits[i]) return false; 13 | } 14 | return true; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/MaxPalindrome10000x99999.java: -------------------------------------------------------------------------------- 1 | package warmup; 2 | 3 | public class MaxPalindrome10000x99999 { 4 | } 5 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/Nth3and4.java: -------------------------------------------------------------------------------- 1 | package warmup; 2 | 3 | import java.util.Scanner; 4 | 5 | public class Nth3and4 { 6 | 7 | public static String fmt(int m) { 8 | if (m<=0) throw new IllegalArgumentException("number is supposed to be more than zero"); 9 | if (m==1) return "%d-st"; 10 | if (m==2) return "%d-nd"; 11 | if (m==3) return "%d-rd"; 12 | return "%d-th"; 13 | } 14 | 15 | public static void main(String[] args) { 16 | Scanner in = new Scanner(System.in); 17 | System.out.print("Enter the number:"); 18 | int m = in.nextInt(); 19 | System.out.printf(fmt(m), m); 20 | int mth = 0; 21 | while ((m > 0) && ((mth+=1) > 0)) { 22 | if (mth % 3 == 0 || mth % 4 == 0) { m-=1; } 23 | } 24 | System.out.printf(" number is:%d\n", mth); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/Randoms20Unique.java: -------------------------------------------------------------------------------- 1 | package warmup; 2 | 3 | import java.util.HashSet; 4 | 5 | public class Randoms20Unique { 6 | 7 | public static void main(String[] args) { 8 | HashSet set = new HashSet<>(); 9 | while (set.size() < 20) { 10 | set.add((int) (Math.random()*21)-10); 11 | } 12 | System.out.println(set); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/amazon/GCD.java: -------------------------------------------------------------------------------- 1 | package warmup.amazon; 2 | 3 | public class GCD { 4 | public int gcd_brute_force(int num, int[] arr) { 5 | int min = arr[0]; 6 | for (int i = 1; i < num; i++) { 7 | min = Math.min(min, arr[i]); 8 | } 9 | 10 | int gcd_max = 1; 11 | int gcd = min; 12 | while (gcd > 1) { 13 | boolean ok = true; 14 | for (int i=0; i < num; i++) { 15 | if (arr[i] % gcd != 0) { 16 | ok = false; 17 | break; 18 | } 19 | } 20 | if (ok) { 21 | gcd_max = gcd; 22 | break; 23 | } 24 | gcd--; 25 | } 26 | return gcd_max; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/amazon/Houses.java: -------------------------------------------------------------------------------- 1 | package warmup.amazon; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Houses { 7 | public List cellCompete(int[] states, int days) { 8 | int len = states.length; 9 | boolean[] full = new boolean[states.length + 2]; 10 | for (int i=0; i 0) { 14 | boolean[] next = new boolean[full.length]; 15 | for(int i=1; i<=states.length; i++) { 16 | next[i] = full[i-1] ^ full[i+1]; 17 | } 18 | days--; 19 | full = next; 20 | } 21 | ArrayList result = new ArrayList<>(); 22 | for (int i=0; i data = 8 | Source.random_int_from_range(0, 100, 30); 9 | 10 | int min_idx = -1; 11 | int min_sum = Integer.MAX_VALUE; 12 | 13 | for (int idx=0; idx < data.size()-1; idx++) { 14 | int sum = data.get(idx) + data.get(idx+1); 15 | if (sum < min_sum) { 16 | min_idx = idx; 17 | min_sum = sum; 18 | } 19 | } 20 | System.out.printf("Array: %s\n", data); 21 | System.out.printf("Left index: %d\n", min_idx); 22 | System.out.printf("Right index: %d\n", min_idx+1); 23 | System.out.printf("The sum: %d\n", min_sum); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/amazon/Person.java: -------------------------------------------------------------------------------- 1 | package warmup.amazon; 2 | 3 | public class Person implements Comparable{ 4 | private final int age; 5 | private final int rate; 6 | private final CharSequence name; 7 | 8 | public Person(int age, int rate, CharSequence name) { 9 | this.age = age; 10 | this.rate = rate; 11 | this.name = name; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return String.format("warmup.amazon.Person:[name: %-8s, age:%d, rate:%d]", this.name, this.age, this.rate); 17 | } 18 | 19 | public void printMe() { 20 | System.out.println(this.toString()); 21 | } 22 | 23 | @Override 24 | public int compareTo(Person o) { 25 | return this.age-o.age; 26 | } 27 | 28 | public int age() { 29 | return this.age; 30 | } 31 | 32 | public int rate() { 33 | return this.rate; 34 | } 35 | 36 | public CharSequence name() { 37 | return this.name; 38 | } 39 | 40 | @Override 41 | public int hashCode() { 42 | return (name.hashCode()*31+rate)*31+age; 43 | } 44 | 45 | @Override 46 | public boolean equals(Object that_) { 47 | if (that_ == null) return false; 48 | if (that_ == this) return true; 49 | if (!(that_ instanceof Person)) return false; 50 | 51 | Person that = (Person)that_; 52 | return this.age==that.age 53 | && this.rate==that.rate 54 | && this.name.equals(that.name); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/brackets/BracketsNestingLevel.java: -------------------------------------------------------------------------------- 1 | package warmup.brackets; 2 | 3 | class BracketsNestingLevel { 4 | 5 | int calc(String origin) { 6 | int depth = 0; 7 | int max_depth = 0; 8 | for (int i = 0; i < origin.length(); i++) { 9 | switch (origin.charAt(i)) { 10 | case '(': depth++; break; 11 | case ')': depth--; break; 12 | default : throw new IllegalArgumentException(String.format("Unexpected symbol: %s", origin.charAt(i))); 13 | } 14 | if (depth < 0) throw new IllegalArgumentException("Opening and closing parenthesis aren't corresponding to each other"); 15 | max_depth = Math.max(depth, max_depth); 16 | } 17 | if (depth > 0) throw new IllegalArgumentException("Opening and closing parenthesis aren't corresponding to each other"); 18 | return max_depth; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/prime/PrimesDynamicApp.java: -------------------------------------------------------------------------------- 1 | package warmup.prime; 2 | 3 | import warmup.prime.versions.PrimesDynamic; 4 | 5 | import java.util.Arrays; 6 | 7 | public class PrimesDynamicApp { 8 | private final static int MIN = 10000; 9 | private final static int MAX = 99999; 10 | 11 | public static void main(String[] args) { 12 | int[] primes = new PrimesDynamic(MIN, MAX).data(); 13 | System.out.printf("Primes length:%d\n", primes.length); 14 | System.out.printf("Primes:%s\n", Arrays.toString(primes)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/prime/PrimesNaiveApp.java: -------------------------------------------------------------------------------- 1 | package warmup.prime; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class PrimesNaiveApp { 6 | private final static int MIN = 10000; 7 | private final static int MAX = 99999; 8 | private static long counter = 0; 9 | 10 | static boolean check(int origin) { 11 | if (origin == 2) return true; 12 | for (int i = 2; i <= Math.sqrt(origin); i++) { 13 | counter++; 14 | if (origin % i == 0) return false; 15 | } 16 | return true; 17 | } 18 | 19 | public static void main(String[] args) { 20 | ArrayList primes_a = new ArrayList<>(); 21 | for (int i = 10000; i < 100000; i++) { 22 | if (check(i)) primes_a.add(i); 23 | } 24 | System.out.printf("Iteration count:%d\n", counter); // 2_628_167 vs 744_435 25 | System.out.printf("Count of numbers generated:%d\n", primes_a.size()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/prime/versions/IsPrimeNaive.java: -------------------------------------------------------------------------------- 1 | package warmup.prime.versions; 2 | 3 | public class IsPrimeNaive { 4 | boolean check(int origin) { 5 | if (origin == 2) return true; 6 | for (int i = 2; i < origin; i++) { 7 | if (origin % i == 0) return false; 8 | } 9 | return true; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/prime/versions/IsPrimeOptimized.java: -------------------------------------------------------------------------------- 1 | package warmup.prime.versions; 2 | 3 | public class IsPrimeOptimized { 4 | boolean check(int origin) { 5 | if (origin == 2) return true; 6 | for (int i = 2; i < Math.sqrt(origin); i++) { 7 | if (origin % i == 0) return false; 8 | } 9 | return true; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/prime/versions/PrimesDynamic.java: -------------------------------------------------------------------------------- 1 | package warmup.prime.versions; 2 | 3 | import java.util.Arrays; 4 | 5 | public class PrimesDynamic { 6 | private final int max; 7 | private final int min; 8 | private int[] primes; 9 | private int process_size = 0; 10 | private int counter = 0; 11 | 12 | public PrimesDynamic(int mn, int mx) { 13 | max = mx; 14 | min = mn; 15 | // this is very rough estimation 16 | primes = new int[this.max/10]; 17 | } 18 | 19 | boolean is_prime(int value) { 20 | if (value == 1) return false; 21 | if (value == 2) return true; 22 | int maxToAnalyze = (int) Math.sqrt(value); 23 | for (int idx = 0; idx < process_size; idx++) { 24 | if (primes[idx] <= maxToAnalyze) { 25 | counter++; 26 | if(value % primes[idx] == 0) return false; 27 | } 28 | } 29 | return true; 30 | } 31 | 32 | public int[] data() { 33 | for (int value = 1; value <= max; value++) { 34 | if (is_prime(value)) primes[process_size++] = value; 35 | } 36 | int index_of_min = 0; 37 | while (index_of_min < process_size && primes[index_of_min] < min) index_of_min++; 38 | System.out.println(counter); 39 | return Arrays.copyOfRange(primes, index_of_min, process_size); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/shoes/ShoesGroups.java: -------------------------------------------------------------------------------- 1 | package warmup.shoes; 2 | 3 | import java.util.Stack; 4 | 5 | public class ShoesGroups { 6 | public int calc(String origin) { 7 | int groups = 0; 8 | Stack tail = new Stack<>(); 9 | tail.push(origin.charAt(0)); 10 | 11 | for (int i = 1; i < origin.length(); i++) { 12 | char c = origin.charAt(i); 13 | if (!(c == 'L' || c == 'R')) throw new IllegalArgumentException(String.format("Wrong char encountered: '%c'", c)); 14 | if (tail.isEmpty()) { 15 | tail.push(c); 16 | continue; 17 | } 18 | switch (c) { 19 | case 'L': switch (tail.peek()) { 20 | case 'L': tail.push('L'); break; 21 | case 'R': tail.pop(); break; 22 | } 23 | break; 24 | case 'R': switch (tail.peek()) { 25 | case 'L': tail.pop(); break; 26 | case 'R': tail.push('R'); break; 27 | } 28 | break; 29 | } 30 | if (tail.isEmpty()) groups++; 31 | } 32 | if (!tail.isEmpty()) throw new IllegalArgumentException("pairs aren't corresponding"); 33 | return groups; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /play/src/main/java/warmup/shoes/ShoesGroupsOptimized.java: -------------------------------------------------------------------------------- 1 | package warmup.shoes; 2 | 3 | public class ShoesGroupsOptimized { 4 | public int calc(String origin) { 5 | int groups = 0; 6 | int count = 0; 7 | 8 | for (int i = 0; i < origin.length(); i++) { 9 | char c = origin.charAt(i); 10 | switch (c) { 11 | case 'L': count++; break; 12 | case 'R': count--; break; 13 | } 14 | if (count == 0) groups++; 15 | } 16 | return groups; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /play/src/main/resources/ewdig.txt: -------------------------------------------------------------------------------- 1 | 0-7 20 2 | 0-6 9 3 | 6-7 8 4 | 0-4 4 5 | 4-5 5 6 | 5-7 6 7 | 0-1 1 8 | 1-2 2 9 | 2-3 3 10 | 3-7 4 11 | 2-5 0.5 12 | -------------------------------------------------------------------------------- /play/src/main/resources/ewg.txt: -------------------------------------------------------------------------------- 1 | 0-7 0.16 2 | 2-3 0.17 3 | 1-7 0.19 4 | 0-2 0.26 5 | 5-7 0.28 6 | 1-3 0.29 7 | 1-5 0.32 8 | 2-7 0.34 9 | 4-5 0.35 10 | 1-2 0.36 11 | 4-7 0.37 12 | 0-4 0.38 13 | 6-2 0.40 14 | 3-6 0.52 15 | 6-0 0.58 16 | 6-4 0.93 17 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/BoxingUnboxingTest.java: -------------------------------------------------------------------------------- 1 | package algorithms; 2 | 3 | import core.BoxingUnboxing; 4 | import org.junit.jupiter.api.BeforeEach; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class BoxingUnboxingTest { 10 | 11 | private BoxingUnboxing bx; 12 | 13 | @BeforeEach 14 | void setup() { 15 | this.bx = new BoxingUnboxing(); 16 | } 17 | 18 | @Test 19 | void boxing() { 20 | assertEquals(new Integer(5), bx.boxing(5)); 21 | } 22 | 23 | @Test 24 | void unboxing() { 25 | assertEquals(5, bx.unboxing(new Integer(5))); 26 | } 27 | 28 | // @Test 29 | void absurd() { 30 | assertEquals(true, false); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l02bitwise/BinToDecTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise; 2 | 3 | import algorithms.l02bitwise.conversion2.BinToDec; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import static org.junit.jupiter.api.Assertions.*; 9 | 10 | class BinToDecTest { 11 | 12 | private BinToDec c; 13 | 14 | @BeforeEach 15 | void setUp() { 16 | this.c = new BinToDec(); 17 | } 18 | 19 | @Test 20 | void binToDec1() { 21 | assertEquals(0, c.binToDec("")); 22 | } 23 | 24 | @Test 25 | void binToDec2() { 26 | assertEquals(0, c.binToDec("0")); 27 | } 28 | 29 | @Test 30 | void binToDec3() { 31 | assertEquals(1, c.binToDec("1")); 32 | } 33 | 34 | @Test 35 | void binToDec4() { 36 | assertEquals(10, c.binToDec("1010")); 37 | } 38 | 39 | @Test 40 | void binToDec5() { 41 | assertEquals(255, c.binToDec("11111111")); 42 | } 43 | 44 | @Test 45 | void binToDec7() { 46 | Assertions.assertThrows(IllegalArgumentException.class, () -> c.binToDec("1a")); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l02bitwise/DecToBinTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l02bitwise; 2 | 3 | import algorithms.l02bitwise.conversion2.DecToBin; 4 | import org.junit.jupiter.api.BeforeEach; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.*; 8 | 9 | class DecToBinTest { 10 | 11 | private DecToBin c; 12 | 13 | @BeforeEach 14 | void before() { 15 | this.c = new DecToBin(); 16 | } 17 | 18 | @Test 19 | void decToBin1() { 20 | assertEquals("00000000", c.decToBin(0, 8)); 21 | } 22 | 23 | @Test 24 | void decToBin2() { 25 | assertEquals("00001111", c.decToBin(15,8)); 26 | } 27 | 28 | @Test 29 | void decToBin3() { 30 | assertEquals("11111111", c.decToBin(255,8)); 31 | } 32 | 33 | @Test 34 | void decToBin4() { 35 | assertEquals("01000010", c.decToBin(66,8)); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/GraphASTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | import algorithms.l08graph.rep.undir.GraphAS; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import java.util.Arrays; 9 | 10 | import static org.junit.jupiter.api.Assertions.*; 11 | 12 | class GraphASTest { 13 | 14 | private Graph g; 15 | 16 | @BeforeEach 17 | void create() { 18 | g = new GraphAS(10); 19 | } 20 | 21 | @Test 22 | void v() { 23 | assertEquals(10, g.v()); 24 | } 25 | 26 | @Test 27 | void children() { 28 | g.addEdge(0,5); 29 | g.addEdge(0,6); 30 | 31 | assertIterableEquals(Arrays.asList(5, 6), g.children(0)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/ToolsTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | import algorithms.l08graph.rep.dir.GraphAL; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static algorithms.l08graph.Tools.copyGraph; 8 | 9 | class ToolsTest { 10 | 11 | @Test 12 | void copyGraphTest() { 13 | GraphAL g1 = new GraphAL(6, new int[][]{ 14 | {0, 1}, 15 | {1, 2}, 16 | {1, 3}, 17 | {1, 4}, 18 | {2, 5}, 19 | {3, 5}, 20 | {4, 5}, 21 | }); 22 | Graph g2 = copyGraph( 23 | g1, 24 | () -> new GraphAL(g1.v()) 25 | ); 26 | g1.addEdge(0, 5); 27 | g2.addEdge(0, 4); 28 | System.out.println(g1); 29 | System.out.println(); 30 | System.out.println(g2); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/impls/AllReachableDFSTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.AllReachable; 4 | import algorithms.l08graph.rep.Graph; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.Arrays; 8 | 9 | import static org.junit.jupiter.api.Assertions.*; 10 | 11 | class AllReachableDFSTest { 12 | 13 | private final Graph g = MapData.graph(); 14 | private final AllReachable ar = new AllReachableDFS(g); 15 | 16 | @Test 17 | void allReachable1() { 18 | assertIterableEquals( 19 | Arrays.asList(0,1,2,3,4,5,6,7,8,9), 20 | ar.allReachable(0) 21 | ); 22 | } 23 | 24 | @Test 25 | void allReachable2() { 26 | assertIterableEquals( 27 | Arrays.asList(2, 4, 6, 8, 9), 28 | ar.allReachable(4) 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/impls/BFSIterativeTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertIterableEquals; 7 | 8 | class BFSIterativeTest { 9 | 10 | private final Graph g = GraphData.graph2_bfs; 11 | private final BFSIterative bfs = new BFSIterative(g); 12 | 13 | @Test 14 | void traverse() { 15 | assertIterableEquals( 16 | GraphData.graph2_bfs_expected, 17 | bfs.traverse(0) 18 | ); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/impls/DFS1Recursive1Test.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | import org.junit.jupiter.api.BeforeEach; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertIterableEquals; 8 | 9 | class DFS1Recursive1Test { 10 | 11 | private final Graph g = GraphData.graph1_dfs; 12 | private final DFS1RecursivePlain dfs = new DFS1RecursivePlain(g); 13 | 14 | @Test 15 | void traverse() { 16 | assertIterableEquals( 17 | GraphData.graph1_dfs_expected, 18 | dfs.traverse(0) 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/impls/DFS2IterativeManualStackHandlingTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertIterableEquals; 7 | 8 | class DFS2IterativeManualStackHandlingTest { 9 | 10 | private final Graph g = GraphData.graph1_dfs; 11 | private final DFS2IterativeManualStackHandling dfs = new DFS2IterativeManualStackHandling(g);; 12 | 13 | @Test 14 | void traverse() { 15 | assertIterableEquals( 16 | GraphData.graph1_dfs_expected, 17 | dfs.traverse(0) 18 | ); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/impls/DFS3IterativeQueueApproachTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertIterableEquals; 7 | 8 | class DFS3IterativeQueueApproachTest { 9 | 10 | private final Graph g = GraphData.graph1_dfs; 11 | private final DFS3IterativeQueueApproach dfs = new DFS3IterativeQueueApproach(g); 12 | 13 | @Test 14 | void traverse() { 15 | assertIterableEquals( 16 | GraphData.graph1_dfs_expected, 17 | dfs.traverse(0) 18 | ); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/impls/DFS4RecursiveFunctionalTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertIterableEquals; 7 | 8 | class DFS4RecursiveFunctionalTest { 9 | private final Graph g = GraphData.graph1_dfs; 10 | private final DFS4RecursiveFunctional dfs = new DFS4RecursiveFunctional(g); 11 | 12 | @Test 13 | void traverse() { 14 | assertIterableEquals( 15 | GraphData.graph1_dfs_expected, 16 | dfs.traverse(0) 17 | ); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/impls/FirstPathDFSTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | class FirstPathDFSTest { 9 | 10 | private final Graph g = GraphData.graph3_path; 11 | private final FirstPathDFS path = new FirstPathDFS(g); 12 | 13 | @Test 14 | void path1() { 15 | assertEquals( 16 | path.path(0, 15), 17 | GraphData.graph3_path0to15 18 | ); 19 | } 20 | 21 | @Test 22 | void path2() { 23 | assertEquals( 24 | path.path(6, 13), 25 | GraphData.graph3_path6to13 26 | ); 27 | } 28 | 29 | @Test 30 | void path3() { 31 | assertEquals( 32 | path.path(2, 3), 33 | GraphData.graph3_path2to3 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/impls/HasCyclesImplTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | 7 | class HasCyclesImplTest { 8 | 9 | @Test 10 | void hasCycles1() { 11 | assertEquals( 12 | new HasCyclesImpl(GraphData.graph41_cycles).hasCycles(), 13 | GraphData.graph41_hasCycles 14 | ); 15 | } 16 | 17 | @Test 18 | void hasCycles2() { 19 | assertEquals( 20 | new HasCyclesImpl(GraphData.graph42_cycles).hasCycles(), 21 | GraphData.graph42_hasCycles 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/impls/MapData.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.rep.Graph; 4 | import algorithms.l08graph.rep.dir.GraphAL; 5 | 6 | import java.util.Arrays; 7 | import java.util.stream.IntStream; 8 | 9 | public class MapData { 10 | 11 | public static final String[] cities = { 12 | "Київ", "Житомир", "Лубни", "Бориспіль", "Фастів", "Ніжин", "Умань", "Суми", "Хмельницький", "Миколаїв"}; 13 | // 0 1 2 3 4 5 6 7 8 9 14 | 15 | public static final int[][] map = { 16 | /* 0 Київ => ... */ {1, 5, 7, 8, 9}, 17 | /* 1 Житомир => ... */ {0, 2, 8}, 18 | /* 2 Лубни => ... */ {4, 9}, 19 | /* 3 Бориспіль => ... */ {2, 5}, 20 | /* 4 Фастів => ... */ {9}, 21 | /* 5 Ніжин => ... */ {0, 3}, 22 | /* 6 Умань => ... */ {8, 9}, 23 | /* 7 Суми => ... */ {0, 2, 6}, 24 | /* 8 Хмельн. => ... */ {6}, 25 | /* 9 Миколаїв => .. */ {2, 6} 26 | }; 27 | 28 | public static Graph graph() { 29 | Graph g = new GraphAL(10); 30 | 31 | IntStream.range(0, map.length).forEach(src -> 32 | Arrays.stream(map[src]).forEach(dst -> 33 | g.addEdge(src, dst) 34 | ) 35 | ); 36 | 37 | return g; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/impls/TopologicalSortingImpl2Test.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.TopologicalSorting; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | class TopologicalSortingImpl2Test { 9 | 10 | // @Test 11 | void topologicalSortingOK() { 12 | TopologicalSorting ts = new TopologicalSortingImpl2(GraphData.graph51_topological); 13 | 14 | assertEquals( 15 | GraphData.graph51_topological_exp, 16 | ts.topologicalSorting() 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/impls/TopologicalSortingImplTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.impls; 2 | 3 | import algorithms.l08graph.ops.TopologicalSorting; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | 8 | class TopologicalSortingImplTest { 9 | 10 | @Test 11 | void topologicalSortingOK() { 12 | TopologicalSorting ts = new TopologicalSortingImpl(GraphData.graph51_topological); 13 | 14 | assertEquals( 15 | GraphData.graph51_topological_exp, 16 | ts.topologicalSorting() 17 | ); 18 | } 19 | 20 | @Test 21 | void topologicalSortingFAILED() { 22 | TopologicalSorting ts = new TopologicalSortingImpl(GraphData.graph52_topological); 23 | 24 | assertEquals( 25 | GraphData.graph52_topological_exp, 26 | ts.topologicalSorting() 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /play/src/test/java/algorithms/l08graph/rep/AbstractGraphARepresentTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.l08graph.rep; 2 | 3 | import algorithms.l08graph.rep.dir.GraphAL; 4 | import org.junit.jupiter.api.BeforeEach; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.Arrays; 8 | import java.util.stream.Collectors; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertEquals; 11 | import static org.junit.jupiter.api.Assertions.assertIterableEquals; 12 | 13 | class AbstractGraphARepresentTest { 14 | 15 | private GraphAL g; 16 | 17 | @BeforeEach 18 | void create() { 19 | g = new GraphAL(10); 20 | g.addEdge(0,5); 21 | g.addEdge(0,6); 22 | g.addEdge(6,7); 23 | } 24 | 25 | @Test 26 | void represent() { 27 | assertIterableEquals( 28 | Arrays.asList(new Edge(0, 5), new Edge(0, 6), new Edge(6, 7)), 29 | g.represent().collect(Collectors.toList()) 30 | ); 31 | } 32 | 33 | @Test 34 | void testToString() { 35 | assertEquals( 36 | "0 -> 5\n0 -> 6\n6 -> 7", 37 | g.toString() 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /play/src/test/java/warmup/ChangeCaseTest.java: -------------------------------------------------------------------------------- 1 | package warmup; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | 8 | class ChangeCaseTest { 9 | 10 | private ChangeCase c; 11 | 12 | @BeforeEach 13 | void setUp() { 14 | this.c = new ChangeCase(); 15 | } 16 | 17 | @Test 18 | void invert1() { 19 | assertEquals("", c.invert("")); 20 | } 21 | 22 | @Test 23 | void invert2() { 24 | assertEquals("abc", c.invert("ABC")); 25 | } 26 | 27 | @Test 28 | void invert3() { 29 | assertEquals("DEF", c.invert("def")); 30 | } 31 | 32 | @Test 33 | void invert4() { 34 | assertEquals("xYz", c.invert("XyZ")); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /play/src/test/java/warmup/GetRidOfVowelsTest.java: -------------------------------------------------------------------------------- 1 | package warmup; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | 8 | class GetRidOfVowelsTest { 9 | 10 | private GetRidOfVowels c; 11 | 12 | @BeforeEach 13 | public void a() { 14 | c = new GetRidOfVowels(); 15 | } 16 | 17 | @Test 18 | void filter() { 19 | assertEquals("qwrty", c.filter("qwerty") ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /play/src/test/java/warmup/brackets/BracketsNestingLevelTest.java: -------------------------------------------------------------------------------- 1 | package warmup.brackets; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.BeforeEach; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class BracketsNestingLevelTest { 10 | 11 | private BracketsNestingLevel app; 12 | 13 | @BeforeEach 14 | void before() { 15 | this.app = new BracketsNestingLevel(); 16 | } 17 | 18 | @Test 19 | void calc1_should_ok() { 20 | assertEquals(1, 21 | app.calc("()()()()()")); 22 | } 23 | 24 | @Test 25 | void calc2_should_ok() { 26 | assertEquals(2, 27 | app.calc("(()()()()())")); 28 | } 29 | 30 | @Test 31 | void calc3_should_ok() { 32 | assertEquals(3, 33 | app.calc("()((()()))()(())")); 34 | } 35 | 36 | @Test 37 | void calc4_should_throw() { 38 | Assertions.assertThrows(IllegalArgumentException.class, () -> app.calc("z")); 39 | } 40 | 41 | @Test 42 | void calc5_should_throw() { 43 | Assertions.assertThrows(IllegalArgumentException.class, () -> app.calc("(()")); 44 | } 45 | 46 | @Test 47 | void calc6_should_throw() { 48 | Assertions.assertThrows(IllegalArgumentException.class, () -> app.calc(")")); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /play/src/test/java/warmup/brackets/ShoesGroupsTest.java: -------------------------------------------------------------------------------- 1 | package warmup.brackets; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | import warmup.shoes.ShoesGroups; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class ShoesGroupsTest { 10 | 11 | private ShoesGroups c; 12 | 13 | @BeforeEach 14 | void setUp() { 15 | this.c = new ShoesGroups(); 16 | } 17 | 18 | @Test 19 | void calc1() { 20 | assertEquals(4, c.calc("RLRRLLRLRRLL")); 21 | } 22 | 23 | @Test 24 | void calc2() { 25 | assertEquals(4, c.calc("RLLLRRRLLR")); 26 | } 27 | 28 | @Test 29 | void calc3() { 30 | assertEquals(1, c.calc("LLRLRLRLRLRLRR")); 31 | } 32 | 33 | @Test 34 | void calc4() { 35 | assertEquals(2,c.calc("LRLR")); 36 | } 37 | 38 | @Test 39 | void calc5() { 40 | assertEquals(3,c.calc("LRRRLRLLLR")); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.10.7 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | /** actually they aren't required but they are useful */ 2 | addDependencyTreePlugin 3 | 4 | /** https://github.com/scalameta/sbt-scalafmt */ 5 | addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") 6 | 7 | /** https://github.com/scalacenter/bloop */ 8 | addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "2.0.0") 9 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | mod sand; 2 | mod tasks; 3 | 4 | fn main() { 5 | println!("Hello, world!"); 6 | } 7 | -------------------------------------------------------------------------------- /src/sand/mod.rs: -------------------------------------------------------------------------------- 1 | mod sandbox1; 2 | -------------------------------------------------------------------------------- /src/sand/sandbox1.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn test1() { 3 | assert_eq!(1 + 1, 2); 4 | } 5 | 6 | #[ignore] 7 | #[test] 8 | fn test2() { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/tasks/README.md: -------------------------------------------------------------------------------- 1 | ### Tasks for students solved 2 | 3 | - https://github.com/djnzx/rust-tasks-solved 4 | -------------------------------------------------------------------------------- /src/tasks/mod.rs: -------------------------------------------------------------------------------- 1 | mod t01; 2 | mod t02; 3 | mod t03; 4 | mod t04; 5 | mod t05; 6 | mod t06; 7 | mod t07; 8 | mod t08; 9 | mod t09; 10 | mod t10; 11 | mod t11; 12 | mod t12; 13 | mod t13; 14 | mod t14; 15 | mod t15; 16 | mod t16; 17 | -------------------------------------------------------------------------------- /src/tasks/t01/mod.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/src/tasks/t01/mod.rs -------------------------------------------------------------------------------- /src/tasks/t02/mod.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/src/tasks/t02/mod.rs -------------------------------------------------------------------------------- /src/tasks/t03/mod.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/src/tasks/t03/mod.rs -------------------------------------------------------------------------------- /src/tasks/t04/mod.rs: -------------------------------------------------------------------------------- 1 | mod rhombus; 2 | -------------------------------------------------------------------------------- /src/tasks/t04/rhombus.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn test1() { 3 | const SIZE: u32 = 11; 4 | let half = SIZE / 2; 5 | let inv = |x: u32| SIZE - 1 - x; 6 | for y in 0..SIZE { 7 | for x in 0..SIZE { 8 | let q1 = x + y < half; 9 | let q2 = inv(x) + y < half; 10 | let q3 = inv(x) + inv(y) < half; 11 | let q4 = x + inv(y) < half; 12 | let c = if q1 || q2 || q3 || q4 { ' ' } else { '*' }; 13 | print!("{c}"); 14 | } 15 | println!(); 16 | } 17 | } 18 | 19 | #[test] 20 | fn test2() { 21 | const SIZE: u32 = 11; 22 | let half = SIZE / 2; 23 | let inv = |x: u32| SIZE - 1 - x; 24 | for j in 0..SIZE * SIZE { 25 | let y = j / SIZE; 26 | let x = j % SIZE; 27 | let q1 = x + y < half; 28 | let q2 = inv(x) + y < half; 29 | let q3 = inv(x) + inv(y) < half; 30 | let q4 = x + inv(y) < half; 31 | let c = if q1 || q2 || q3 || q4 { ' ' } else { '*' }; 32 | print!("{c}"); 33 | if x == SIZE - 1 { 34 | println!(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/tasks/t05/envelope.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn envelope() { 3 | const W: u32 = 30; 4 | const H: u32 = 15; 5 | let k = W as f32 / H as f32; 6 | 7 | fn mul(a: u32, k: f32) -> u32 { 8 | (a as f32 * k).ceil() as u32 9 | } 10 | 11 | for y in 1..=H { 12 | for x in 1..=W { 13 | let is_diag = mul(y, k) == x; 14 | let is_co_diag = mul(y, k) == W - x + 1; 15 | 16 | let c = match (y, x) { 17 | (1 | H, _) => "*", 18 | (_, 1 | W) => "*", 19 | _ if is_diag || is_co_diag => "*", 20 | _ => " ", 21 | }; 22 | print!("{}", c); 23 | } 24 | println!() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/tasks/t05/mod.rs: -------------------------------------------------------------------------------- 1 | mod envelope; 2 | -------------------------------------------------------------------------------- /src/tasks/t06/gcd.rs: -------------------------------------------------------------------------------- 1 | fn gcd1(a: u32, b: u32) -> u32 { 2 | if b == 0 { a } else { gcd1(b, a % b) } 3 | } 4 | 5 | fn gcd2(a: u32, b: u32) -> u32 { 6 | match (a, b) { 7 | (a, 0) => a, 8 | (a, b) => gcd2(b, a % b) 9 | } 10 | } 11 | 12 | fn gcd(a: u32, b: u32) -> u32 { 13 | gcd2(a, b) 14 | } 15 | 16 | #[test] 17 | fn test() { 18 | let data = 19 | [ 20 | ((24, 60), 12), 21 | ((15, 9), 3), 22 | ((15, 6), 3), 23 | ((140, 40), 20), 24 | ((24, 16), 8), 25 | ((100, 10), 10), 26 | ((120, 80), 40), 27 | ((80, 120), 40), 28 | ((100, 20), 20), 29 | ((37, 11), 1), 30 | ((120, 90), 30), 31 | ]; 32 | 33 | for ((a, b), exp) in data.iter() { 34 | assert_eq!(*exp, gcd2(*a, *b)); 35 | assert_eq!(*exp, gcd2(*b, *a)); 36 | } 37 | } -------------------------------------------------------------------------------- /src/tasks/t06/mod.rs: -------------------------------------------------------------------------------- 1 | mod gcd; -------------------------------------------------------------------------------- /src/tasks/t07/mod.rs: -------------------------------------------------------------------------------- 1 | mod tree1; 2 | mod tree2; 3 | -------------------------------------------------------------------------------- /src/tasks/t07/tree1.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn tree1() { 3 | const W: u32 = 11; 4 | const H: u32 = 6; 5 | const N: u32 = 3; 6 | 7 | let mirror = |x: u32| W - 1 - x; 8 | 9 | for n in 0..N { 10 | for y in 0..H { 11 | for x in 0..W { 12 | let q1 = x + y < W / 2; 13 | let q2 = mirror(x) + y < W / 2; 14 | let c = if q1 || q2 { ' ' } else { '*' }; 15 | print!("{c}"); 16 | } 17 | println!(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/tasks/t08/invert_the_case.rs: -------------------------------------------------------------------------------- 1 | fn invert_the_case(s: String) -> String { 2 | s.chars() 3 | .map(|c| match c { 4 | c if c.is_lowercase() => c.to_uppercase().next().unwrap(), 5 | c if c.is_uppercase() => c.to_lowercase().next().unwrap(), 6 | c => c, 7 | }) 8 | .collect() 9 | } 10 | 11 | #[test] 12 | fn test() { 13 | let data = 14 | [ 15 | ("Hello", "hELLO"), 16 | ("Привет", "пРИВЕТ"), 17 | ]; 18 | 19 | data 20 | .iter() 21 | .for_each(|(a, b)| { 22 | assert_eq!( 23 | invert_the_case(a.to_string()), 24 | b.to_string() 25 | ); 26 | assert_eq!( 27 | invert_the_case(b.to_string()), 28 | a.to_string() 29 | ); 30 | }); 31 | } -------------------------------------------------------------------------------- /src/tasks/t08/mod.rs: -------------------------------------------------------------------------------- 1 | mod invert_the_case; -------------------------------------------------------------------------------- /src/tasks/t09/is_prime.rs: -------------------------------------------------------------------------------- 1 | fn is_prime(n: &u32) -> bool { 2 | let limit = (*n as f64).sqrt().ceil() as u32; 3 | match n { 4 | 0 | 1 => false, 5 | 2 => true, 6 | n => (2..=limit).all(|x| n % x != 0) 7 | } 8 | } 9 | 10 | #[test] 11 | fn test_is_prime() { 12 | let test_data = [ 13 | (0, false), 14 | (1, false), 15 | (2, true), 16 | (3, true), 17 | (4, false), 18 | (5, true), 19 | (100, false), 20 | (10007, true), 21 | ]; 22 | 23 | test_data 24 | .iter() 25 | .for_each(|(n, prime)| 26 | assert_eq!(is_prime(n), *prime) 27 | ) 28 | } 29 | -------------------------------------------------------------------------------- /src/tasks/t09/mod.rs: -------------------------------------------------------------------------------- 1 | mod is_prime; -------------------------------------------------------------------------------- /src/tasks/t10/mod.rs: -------------------------------------------------------------------------------- 1 | mod rotate_string; 2 | -------------------------------------------------------------------------------- /src/tasks/t10/rotate_string.rs: -------------------------------------------------------------------------------- 1 | fn rotate(s: String, n: isize) -> String { 2 | match s.len() as isize { 3 | 0 => s, 4 | len => match n % len { 5 | n if n > 0 => match s.split_at((len - n) as usize) { 6 | (p1, p2) => p2.to_string() + p1, 7 | }, 8 | n if n < 0 => match s.split_at(-n as usize) { 9 | (p1, p2) => p2.to_string() + p1, 10 | }, 11 | _ => s, 12 | }, 13 | } 14 | } 15 | 16 | fn rotateV2(s: String, n: isize) -> String { 17 | match s.len() as isize { 18 | 0 => s, 19 | len => { 20 | let at = if n % len > 0 { len - n } else { -n } as usize; 21 | match at { 22 | 0 => s, 23 | at => match s.split_at(at) { 24 | (p1, p2) => p2.to_string() + p1, 25 | }, 26 | } 27 | } 28 | } 29 | } 30 | 31 | fn rotate2(s: &str, n: &i32) -> String { 32 | rotate(s.to_owned(), *n as isize) 33 | } 34 | 35 | #[test] 36 | fn test() { 37 | let s = "abcdefgh"; 38 | let shifts = [ 39 | (0, "abcdefgh"), 40 | (8, "abcdefgh"), 41 | (-8, "abcdefgh"), 42 | (1, "habcdefg"), 43 | (2, "ghabcdef"), 44 | (10, "ghabcdef"), 45 | (-1, "bcdefgha"), 46 | (-2, "cdefghab"), 47 | (-10, "cdefghab"), 48 | ]; 49 | 50 | shifts 51 | .iter() 52 | .for_each(|(n, exp)| 53 | assert_eq!(rotate2(s, n), exp.to_string()) 54 | ); 55 | } 56 | -------------------------------------------------------------------------------- /src/tasks/t11/is_palindrome.rs: -------------------------------------------------------------------------------- 1 | fn is_palindrome(x: u32) -> bool { 2 | let s = x.to_string(); 3 | s.chars().rev().collect::() == s 4 | } 5 | 6 | #[test] 7 | fn test() { 8 | let data = 9 | [ 10 | (123, false), 11 | (121, true), 12 | (1221, true), 13 | ]; 14 | 15 | data 16 | .iter() 17 | .for_each(|(n, exp)| { 18 | assert_eq!(is_palindrome(*n), *exp); 19 | }); 20 | } -------------------------------------------------------------------------------- /src/tasks/t11/mod.rs: -------------------------------------------------------------------------------- 1 | mod is_palindrome; -------------------------------------------------------------------------------- /src/tasks/t12/mod.rs: -------------------------------------------------------------------------------- 1 | mod adjacent_sum; 2 | -------------------------------------------------------------------------------- /src/tasks/t13/distribute_shipments.rs: -------------------------------------------------------------------------------- 1 | use rand::Rng; 2 | 3 | fn gen_shipments(n: usize) -> Vec { 4 | let mut tr = rand::thread_rng(); 5 | let mut next = || tr.gen_range(1..10); 6 | 7 | let mut data = Vec::new(); 8 | for _ in 0..n - 1 { 9 | data.push(next()); 10 | } 11 | 12 | let total_without_last = data 13 | .iter() 14 | .sum::(); 15 | let avg = total_without_last as f64 / (n - 1) as f64; 16 | let avg_ceil = avg.ceil() as u32; 17 | let total = avg_ceil * n as u32; 18 | let last = total - total_without_last; 19 | data.push(last); 20 | data 21 | } 22 | 23 | fn count_permutation(shipments: &Vec) -> usize { 24 | let total = shipments 25 | .iter() 26 | .sum::() as i32; 27 | 28 | let avg = total / shipments.len() as i32; 29 | 30 | shipments 31 | .iter() 32 | .map(|x| avg - (*x as i32)) 33 | .filter(|x| *x > 0) 34 | .sum::() as usize 35 | } 36 | 37 | #[test] 38 | fn test() { 39 | let xs = gen_shipments(5); 40 | println!("{:?}", xs); 41 | println!( 42 | "avg:{}", 43 | xs.iter() 44 | .sum::() 45 | / xs.len() as u32 46 | ); 47 | let count = count_permutation(&xs); 48 | println!("{:?}", count); 49 | } 50 | -------------------------------------------------------------------------------- /src/tasks/t13/mod.rs: -------------------------------------------------------------------------------- 1 | mod distribute_shipments; 2 | -------------------------------------------------------------------------------- /src/tasks/t13/shipments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/src/tasks/t13/shipments.png -------------------------------------------------------------------------------- /src/tasks/t14/mod.rs: -------------------------------------------------------------------------------- 1 | mod rectangles; 2 | -------------------------------------------------------------------------------- /src/tasks/t14/rectangles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/src/tasks/t14/rectangles.jpg -------------------------------------------------------------------------------- /src/tasks/t15/gray_lazy.rs: -------------------------------------------------------------------------------- 1 | // https://aperiodic.net/pip/scala/s-99/#p49 2 | 3 | fn gray(n: u8) -> Box> { 4 | match n { 5 | 0 => Box::new([""].iter().map(|s| s.to_string())), 6 | n => 7 | Box::new(gray(n - 1) 8 | .flat_map(move |s| 9 | vec!(0, 1) 10 | .iter() 11 | .map(|v| s.clone() + v.to_string().as_str()) 12 | .collect::>() 13 | )) 14 | } 15 | } 16 | 17 | #[test] 18 | fn test() { 19 | let test_data = 20 | [ 21 | (0, vec!("")), 22 | (1, vec!("0", "1")), 23 | (2, vec!("00", "01", "10", "11")), 24 | (3, vec!("000", "001", "010", "011", "100", "101", "110", "111")), 25 | (4, vec!("0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111")), 26 | ]; 27 | 28 | test_data 29 | .iter() 30 | .for_each(|(n, out)| { 31 | println!("n: {:?}, out: {:?}", n, out); 32 | let real = gray(*n).collect::>(); 33 | let expected = out; 34 | assert_eq!(real, *expected); 35 | }); 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/tasks/t15/gray_simple.rs: -------------------------------------------------------------------------------- 1 | // https://aperiodic.net/pip/scala/s-99/#p49 2 | 3 | fn gray(n: u8) -> Vec { 4 | let mut a = vec![String::new()]; 5 | for _ in 0..n { 6 | let a0 = a.iter().map(|s| format!("0{s}")); 7 | let a1 = a.iter().map(|s| format!("1{s}")); 8 | a = a0.chain(a1).collect::>(); 9 | } 10 | a 11 | } 12 | 13 | #[test] 14 | fn test() { 15 | let test_data = 16 | [ 17 | (0, vec!("")), 18 | (1, vec!("0", "1")), 19 | (2, vec!("00", "01", "10", "11")), 20 | (3, vec!("000", "001", "010", "011", "100", "101", "110", "111")), 21 | (4, vec!("0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111")), 22 | ]; 23 | 24 | test_data 25 | .iter() 26 | .for_each(|(n, out)| 27 | assert_eq!(gray(*n), *out) 28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /src/tasks/t15/mod.rs: -------------------------------------------------------------------------------- 1 | mod gray_lazy; 2 | mod gray_simple; -------------------------------------------------------------------------------- /src/tasks/t16/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djnzx/algorithms/156b3dcf978477c76ba6fa6c4c4cfcbb690f194c/src/tasks/t16/img.png -------------------------------------------------------------------------------- /src/tasks/t16/mod.rs: -------------------------------------------------------------------------------- 1 | mod myxaslon; 2 | --------------------------------------------------------------------------------