├── .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 | 
19 | 
20 | 
21 | 
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 |
--------------------------------------------------------------------------------