Repository: careercup/CtCI-6th-Edition
Branch: master
Commit: 59018cfcb902
Files: 592
Total size: 76.0 MB
Directory structure:
gitextract_k4kr__1r/
├── .classpath
├── .gitignore
├── .gitmodules
├── .project
├── Java/
│ ├── Big O/
│ │ ├── Example_16/
│ │ │ └── Example.java
│ │ └── QVI_11_Print_Sorted_Strings/
│ │ └── Question.java
│ ├── Ch 01. Arrays and Strings/
│ │ ├── Q1_01_Is_Unique/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── Tester.java
│ │ ├── Q1_02_Check_Permutation/
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q1_03_URLify/
│ │ │ └── Question.java
│ │ ├── Q1_04_Palindrome_Permutation/
│ │ │ ├── Common.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ ├── Q1_05_One_Away/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── Tester.java
│ │ ├── Q1_06_String_Compression/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ ├── Q1_07_Rotate_Matrix/
│ │ │ └── Question.java
│ │ ├── Q1_08_Zero_Matrix/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── Tester.java
│ │ └── Q1_09_String_Rotation/
│ │ └── Question.java
│ ├── Ch 02. Linked Lists/
│ │ ├── Q2_01_Remove_Dups/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ ├── Q2_02_Return_Kth_To_Last/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.cpp
│ │ │ ├── QuestionC.java
│ │ │ ├── QuestionD.java
│ │ │ └── Tester.java
│ │ ├── Q2_03_Delete_Middle_Node/
│ │ │ └── Question.java
│ │ ├── Q2_04_Partition/
│ │ │ ├── Question.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ ├── Q2_05_Sum_Lists/
│ │ │ ├── PartialSum.java
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q2_06_Palindrome/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ ├── Q2_07_Intersection/
│ │ │ └── Question.java
│ │ └── Q2_08_Loop_Detection/
│ │ └── Question.java
│ ├── Ch 03. Stacks and Queues/
│ │ ├── Introduction/
│ │ │ ├── MyQueue.java
│ │ │ ├── MyStack.java
│ │ │ ├── QueueTester.java
│ │ │ └── StackTester.java
│ │ ├── Q3_01_Three_in_One/
│ │ │ ├── FixedMultiStack.java
│ │ │ ├── FullStackException.java
│ │ │ ├── MultiStack.java
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q3_02_Stack_Min/
│ │ │ ├── NodeWithMin.java
│ │ │ ├── Question.java
│ │ │ ├── StackWithMin.java
│ │ │ └── StackWithMin2.java
│ │ ├── Q3_03_Stack_of_Plates/
│ │ │ ├── Node.java
│ │ │ ├── Question.java
│ │ │ ├── SetOfStacks.java
│ │ │ └── Stack.java
│ │ ├── Q3_04_Queue_via_Stacks/
│ │ │ ├── MyQueue.java
│ │ │ └── Question.java
│ │ ├── Q3_05_Sort_Stack/
│ │ │ └── Question.java
│ │ └── Q3_06_Animal_Shelter/
│ │ ├── Animal.java
│ │ ├── AnimalQueue.java
│ │ ├── Cat.java
│ │ ├── Dog.java
│ │ └── Question.java
│ ├── Ch 04. Trees and Graphs/
│ │ ├── Introduction/
│ │ │ └── Traversals.java
│ │ ├── Q4_01_Route_Between_Nodes/
│ │ │ ├── Graph.java
│ │ │ ├── Node.java
│ │ │ └── Question.java
│ │ ├── Q4_02_Minimal_Tree/
│ │ │ └── Question.java
│ │ ├── Q4_03_List_of_Depths/
│ │ │ ├── QuestionBFS.java
│ │ │ └── QuestionDFS.java
│ │ ├── Q4_04_Check_Balanced/
│ │ │ ├── QuestionBrute.java
│ │ │ └── QuestionImproved.java
│ │ ├── Q4_05_Validate_BST/
│ │ │ ├── IntWrapper.java
│ │ │ ├── Question.java
│ │ │ └── QuestionB.java
│ │ ├── Q4_06_Successor/
│ │ │ └── Question.java
│ │ ├── Q4_07_Build_Order/
│ │ │ ├── DFS/
│ │ │ │ ├── Graph.java
│ │ │ │ ├── Project.java
│ │ │ │ └── Question.java
│ │ │ └── EdgeRemoval/
│ │ │ ├── Graph.java
│ │ │ ├── Project.java
│ │ │ └── Question.java
│ │ ├── Q4_08_First_Common_Ancestor/
│ │ │ ├── Question.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ ├── QuestionD.java
│ │ │ ├── QuestionE.java
│ │ │ ├── QuestionEBad.java
│ │ │ ├── QuestionF.java
│ │ │ └── Tester.java
│ │ ├── Q4_09_BST_Sequences/
│ │ │ └── Question.java
│ │ ├── Q4_10_Check_Subtree/
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q4_11_Random_Node/
│ │ │ ├── Question.java
│ │ │ ├── Tree.java
│ │ │ └── TreeNode.java
│ │ └── Q4_12_Paths_with_Sum/
│ │ ├── QuestionA.java
│ │ ├── QuestionB.java
│ │ └── Tester.java
│ ├── Ch 05. Bit Manipulation/
│ │ ├── Q5_01_Insertion/
│ │ │ └── Question.java
│ │ ├── Q5_02_Binary_to_String/
│ │ │ └── Question.java
│ │ ├── Q5_03_Flip_Bit_to_Win/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ ├── QuestionD.java
│ │ │ └── Tester.java
│ │ ├── Q5_04_Next_Number/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ ├── Q5_06_Conversion/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── Tester.java
│ │ ├── Q5_07_Pairwise_Swap/
│ │ │ └── Question.java
│ │ ├── Q5_08_Draw_Line/
│ │ │ └── Question.java
│ │ └── Sample_Code/
│ │ ├── RightShifts.java
│ │ └── Sample_Code.java
│ ├── Ch 06. Math and Logic Puzzles/
│ │ ├── Introduction/
│ │ │ ├── PrimeNumbers.java
│ │ │ └── SieveOfEratosthenes.java
│ │ ├── Q6_05_Egg_Drop/
│ │ │ └── Question.java
│ │ ├── Q6_07_The_Apocalypse/
│ │ │ └── Question.java
│ │ └── Q6_10_Test_Strips/
│ │ ├── Bottle.java
│ │ ├── QuestionA.java
│ │ ├── QuestionB.java
│ │ ├── QuestionC.java
│ │ └── TestStrip.java
│ ├── Ch 07. Object-Oriented Design/
│ │ ├── Q7_01_Deck_of_Cards/
│ │ │ ├── BlackJackCard.java
│ │ │ ├── BlackJackGameAutomator.java
│ │ │ ├── BlackJackHand.java
│ │ │ ├── Card.java
│ │ │ ├── Deck.java
│ │ │ ├── Hand.java
│ │ │ ├── Question.java
│ │ │ └── Suit.java
│ │ ├── Q7_02_Call_Center/
│ │ │ ├── Call.java
│ │ │ ├── CallHandler.java
│ │ │ ├── Caller.java
│ │ │ ├── Director.java
│ │ │ ├── Employee.java
│ │ │ ├── Manager.java
│ │ │ ├── Rank.java
│ │ │ ├── Respondent.java
│ │ │ └── Test.java
│ │ ├── Q7_03_Jukebox/
│ │ │ ├── CD.java
│ │ │ ├── CDPlayer.java
│ │ │ ├── JukeBox.java
│ │ │ ├── Playlist.java
│ │ │ ├── Song.java
│ │ │ ├── SongSelector.java
│ │ │ └── User.java
│ │ ├── Q7_04_Parking_Lot/
│ │ │ ├── Bus.java
│ │ │ ├── Car.java
│ │ │ ├── Level.java
│ │ │ ├── Motorcycle.java
│ │ │ ├── ParkingLot.java
│ │ │ ├── ParkingSpot.java
│ │ │ ├── Question.java
│ │ │ ├── Vehicle.java
│ │ │ └── VehicleSize.java
│ │ ├── Q7_05_Online_Book_Reader/
│ │ │ ├── Book.java
│ │ │ ├── Display.java
│ │ │ ├── Library.java
│ │ │ ├── OnlineReaderSystem.java
│ │ │ ├── User.java
│ │ │ └── UserManager.java
│ │ ├── Q7_06_Jigsaw/
│ │ │ ├── Edge.java
│ │ │ ├── Orientation.java
│ │ │ ├── Piece.java
│ │ │ ├── Puzzle.java
│ │ │ ├── Question.java
│ │ │ └── Shape.java
│ │ ├── Q7_07_Chat_Server/
│ │ │ ├── AddRequest.java
│ │ │ ├── Conversation.java
│ │ │ ├── GroupChat.java
│ │ │ ├── Message.java
│ │ │ ├── PrivateChat.java
│ │ │ ├── RequestStatus.java
│ │ │ ├── System.java
│ │ │ ├── User.java
│ │ │ ├── UserManager.java
│ │ │ ├── UserStatus.java
│ │ │ └── UserStatusType.java
│ │ ├── Q7_08_Othello/
│ │ │ ├── Automator.java
│ │ │ ├── Board.java
│ │ │ ├── Color.java
│ │ │ ├── Direction.java
│ │ │ ├── Game.java
│ │ │ ├── Location.java
│ │ │ ├── Piece.java
│ │ │ ├── Player.java
│ │ │ └── Question.java
│ │ ├── Q7_09_Circular_Array/
│ │ │ ├── CircularArray.java
│ │ │ └── Question.java
│ │ ├── Q7_10_Minesweeper/
│ │ │ ├── Board.java
│ │ │ ├── Cell.java
│ │ │ ├── Game.java
│ │ │ ├── Question.java
│ │ │ ├── UserPlay.java
│ │ │ └── UserPlayResult.java
│ │ ├── Q7_11_File_System/
│ │ │ ├── Directory.java
│ │ │ ├── Entry.java
│ │ │ ├── File.java
│ │ │ └── Question.java
│ │ └── Q7_12_Hash_Table/
│ │ ├── Dummy.java
│ │ ├── Hasher.java
│ │ └── Question.java
│ ├── Ch 08. Recursion and Dynamic Programming/
│ │ ├── Introduction/
│ │ │ ├── FibonacciA.java
│ │ │ ├── FibonacciB.java
│ │ │ ├── FibonacciC.java
│ │ │ └── FibonacciD.java
│ │ ├── Q8_01_Triple_Step/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── Tester.java
│ │ ├── Q8_02_Robot_in_a_Grid/
│ │ │ ├── Point.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── Tester.java
│ │ ├── Q8_03_Magic_Index/
│ │ │ ├── Question.java
│ │ │ └── QuestionB.java
│ │ ├── Q8_04_Power_Set/
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q8_05_Recursive_Multiply/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ ├── QuestionD.java
│ │ │ └── Tester.java
│ │ ├── Q8_06_Towers_of_Hanoi/
│ │ │ ├── Question.java
│ │ │ └── Tower.java
│ │ ├── Q8_07_Permutations_Without_Dups/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── QuestionC.java
│ │ ├── Q8_08_Permutations_With_Dups/
│ │ │ └── Question.java
│ │ ├── Q8_09_Parens/
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q8_10_Paint_Fill/
│ │ │ └── Question.java
│ │ ├── Q8_11_Coins/
│ │ │ ├── Question.java
│ │ │ ├── QuestionB.java
│ │ │ └── Tester.java
│ │ ├── Q8_12_Eight_Queens/
│ │ │ └── Question.java
│ │ ├── Q8_13_Stack_of_Boxes/
│ │ │ ├── Box.java
│ │ │ ├── BoxComparator.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ └── Q8_14_Boolean_Evaluation/
│ │ ├── Others.java
│ │ ├── QuestionA.java
│ │ ├── QuestionB.java
│ │ ├── QuestionC.java
│ │ └── Tester.java
│ ├── Ch 09. Scalability and Memory Limits/
│ │ ├── Q9_02_Social_Network/
│ │ │ ├── BFSData.java
│ │ │ ├── Machine.java
│ │ │ ├── PathNode.java
│ │ │ ├── Person.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── Server.java
│ │ │ └── Tester.java
│ │ └── Q9_05_Cache/
│ │ ├── Cache.java
│ │ ├── Node.java
│ │ └── Question.java
│ ├── Ch 10. Sorting and Searching/
│ │ ├── Introduction/
│ │ │ ├── BinarySearch.java
│ │ │ ├── MergeSort.java
│ │ │ └── Quicksort.java
│ │ ├── Q10_01_Sorted_Merge/
│ │ │ └── Question.java
│ │ ├── Q10_02_Group_Anagrams/
│ │ │ ├── AnagramComparator.java
│ │ │ ├── Question.java
│ │ │ └── QuestionB.java
│ │ ├── Q10_03_Search_in_Rotated_Array/
│ │ │ └── Question.java
│ │ ├── Q10_04_Sorted_Search_No_Size/
│ │ │ └── Arrayish/
│ │ │ ├── Listy.java
│ │ │ └── Question.java
│ │ ├── Q10_05_Sparse_Search/
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q10_07_Missing_Int/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── input.txt
│ │ ├── Q10_08_Find_Duplicates/
│ │ │ ├── BitSet.java
│ │ │ └── Question.java
│ │ ├── Q10_09_Sorted_Matrix_Search/
│ │ │ ├── Coordinate.java
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q10_10_Rank_from_Stream/
│ │ │ ├── IntComparable.java
│ │ │ ├── Question.java
│ │ │ └── RankNode.java
│ │ └── Q10_11_Peaks_and_Valleys/
│ │ ├── QuestionA.java
│ │ ├── QuestionB.java
│ │ ├── QuestionC.java
│ │ └── Tester.java
│ ├── Ch 13. Java/
│ │ ├── Introduction/
│ │ │ ├── Ambiguous.java
│ │ │ ├── Circle.java
│ │ │ ├── Introduction.java
│ │ │ ├── IntroductionCollections.java
│ │ │ ├── IntroductionOverriding.java
│ │ │ ├── Shape.java
│ │ │ └── Square.java
│ │ ├── Q13_01_Private_Constructor/
│ │ │ └── Question.java
│ │ ├── Q13_05_TreeMap_HashMap_LinkedHashMap/
│ │ │ └── Question.java
│ │ ├── Q13_06_Object_Reflection/
│ │ │ ├── Question.java
│ │ │ └── Rectangle.java
│ │ ├── Q13_07_Lambda_Expressions/
│ │ │ ├── Country.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ └── Q13_08_Lambda_Random/
│ │ ├── QuestionA.java
│ │ ├── QuestionB.java
│ │ └── QuestionC.java
│ ├── Ch 15. Threads and Locks/
│ │ ├── IntroductionA/
│ │ │ ├── ExampleA.java
│ │ │ └── RunnableThreadExample.java
│ │ ├── IntroductionB/
│ │ │ ├── ExampleB.java
│ │ │ └── ThreadExample.java
│ │ ├── IntroductionLocks/
│ │ │ ├── Intro.java
│ │ │ ├── LockedATM.java
│ │ │ ├── MyClass.java
│ │ │ └── NoLockATM.java
│ │ ├── IntroductionSynchronization/
│ │ │ ├── Intro.java
│ │ │ ├── MyClass.java
│ │ │ └── MyObject.java
│ │ ├── IntroductionSynchronizedBlocks/
│ │ │ ├── Intro.java
│ │ │ ├── MyClass.java
│ │ │ └── MyObject.java
│ │ ├── IntroductionWaitNotify/
│ │ │ ├── Intro.java
│ │ │ ├── MyClass.java
│ │ │ └── MyObject.java
│ │ ├── Q15_03_Dining_Philosophers/
│ │ │ ├── QuestionA/
│ │ │ │ ├── Chopstick.java
│ │ │ │ ├── Philosopher.java
│ │ │ │ └── Question.java
│ │ │ └── QuestionB/
│ │ │ ├── Chopstick.java
│ │ │ ├── Philosopher.java
│ │ │ └── Question.java
│ │ ├── Q15_04_Deadlock_Free_Class/
│ │ │ ├── LockFactory.java
│ │ │ ├── LockNode.java
│ │ │ └── Question.java
│ │ ├── Q15_05_Call_In_Order/
│ │ │ ├── Foo.java
│ │ │ ├── FooBad.java
│ │ │ ├── MyThread.java
│ │ │ └── Question.java
│ │ ├── Q15_06_Synchronized_Methods/
│ │ │ ├── Foo.java
│ │ │ ├── MyThread.java
│ │ │ └── Question.java
│ │ └── Q15_07_FizzBuzz/
│ │ ├── FBThread.java
│ │ ├── FizzBuzzThread.java
│ │ ├── NumberThread.java
│ │ ├── QuestionA.java
│ │ ├── QuestionB.java
│ │ └── QuestionC.java
│ ├── Ch 16. Moderate/
│ │ ├── Q16_01_Number_Swapper/
│ │ │ └── Question.java
│ │ ├── Q16_02_Word_Frequencies/
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q16_03_Intersection/
│ │ │ ├── Line.java
│ │ │ ├── Point.java
│ │ │ ├── Question.java
│ │ │ └── Tester.java
│ │ ├── Q16_04_Tic_Tac_Win/
│ │ │ ├── Piece.java
│ │ │ ├── Position.java
│ │ │ ├── PositionIterator.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ ├── QuestionD.java
│ │ │ ├── QuestionE.java
│ │ │ ├── QuestionF.java
│ │ │ ├── QuestionG.java
│ │ │ ├── QuestionH.java
│ │ │ └── Tester.java
│ │ ├── Q16_05_Factorial_Zeros/
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q16_06_Smallest_Difference/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ ├── Q16_07_Number_Max/
│ │ │ └── Question.java
│ │ ├── Q16_08_English_Int/
│ │ │ └── Question.java
│ │ ├── Q16_09_Operations/
│ │ │ └── Question.java
│ │ ├── Q16_10_Living_People/
│ │ │ ├── Person.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ ├── QuestionD.java
│ │ │ └── Tester.java
│ │ ├── Q16_11_Diving_Board/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ ├── Q16_12_XML_Encoding/
│ │ │ ├── Attribute.java
│ │ │ ├── Element.java
│ │ │ ├── QuestionOO.java
│ │ │ └── QuestionString.java
│ │ ├── Q16_13_Bisect_Squares/
│ │ │ ├── Line.java
│ │ │ ├── Point.java
│ │ │ ├── Question.java
│ │ │ ├── Square Cut Tester - Q16_13.xlsx
│ │ │ └── Square.java
│ │ ├── Q16_14_Best_Line/
│ │ │ ├── GraphPoint.java
│ │ │ ├── Line.java
│ │ │ └── Question.java
│ │ ├── Q16_15_Master_Mind/
│ │ │ ├── Question.java
│ │ │ ├── Result.java
│ │ │ └── Tester.java
│ │ ├── Q16_16_Sub_Sort/
│ │ │ ├── Question.java
│ │ │ ├── QuestionB.java
│ │ │ ├── Range.java
│ │ │ └── Tester.java
│ │ ├── Q16_17_Contiguous_Sequence/
│ │ │ └── Question.java
│ │ ├── Q16_18_Pattern_Matcher/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ ├── QuestionD.java
│ │ │ └── Tester.java
│ │ ├── Q16_19_Pond_Sizes/
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q16_20_T9/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── QuestionC.java
│ │ ├── Q16_21_Sum_Swap/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ ├── QuestionD.java
│ │ │ └── Tester.java
│ │ ├── Q16_22_Langtons_Ant/
│ │ │ ├── Ant.java
│ │ │ ├── Board.java
│ │ │ ├── Grid.java
│ │ │ ├── Orientation.java
│ │ │ ├── Position.java
│ │ │ └── Question.java
│ │ ├── Q16_23_Rand7_From_Rand5/
│ │ │ ├── Question.java
│ │ │ └── QuestionB.java
│ │ ├── Q16_24_Pairs_With_Sum/
│ │ │ ├── Pair.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ ├── Q16_25_LRU_Cache/
│ │ │ ├── Cache.java
│ │ │ └── Question.java
│ │ └── Q16_26_Calculator/
│ │ ├── Operator.java
│ │ ├── QuestionA.java
│ │ ├── QuestionB.java
│ │ └── Term.java
│ ├── Ch 17. Hard/
│ │ ├── Q17_01_Add_Without_Plus/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── Tester.java
│ │ ├── Q17_02_Shuffle/
│ │ │ └── Question.java
│ │ ├── Q17_03_Random_Set/
│ │ │ ├── Question.java
│ │ │ └── QuestionAlternate.java
│ │ ├── Q17_04_Missing_Number/
│ │ │ ├── BitInteger.java
│ │ │ └── Question.java
│ │ ├── Q17_05_Letters_and_Numbers/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── Tester.java
│ │ ├── Q17_06_Count_of_2s/
│ │ │ ├── Question.java
│ │ │ └── QuestionBrute.java
│ │ ├── Q17_07_Baby_Names/
│ │ │ ├── Graph.java
│ │ │ ├── GraphNode.java
│ │ │ ├── NameSet.java
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q17_08_Circus_Tower/
│ │ │ ├── HtWt.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionOld.java
│ │ │ └── Tester.java
│ │ ├── Q17_09_Kth_Multiple/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── QuestionC.java
│ │ ├── Q17_10_Majority_Element/
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q17_11_Word_Distance/
│ │ │ ├── LocationPair.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── Tester.java
│ │ ├── Q17_12_BiNode/
│ │ │ ├── BiNode.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── QuestionC.java
│ │ ├── Q17_13_ReSpace/
│ │ │ ├── ParseResult.java
│ │ │ ├── QuestionA.java
│ │ │ └── QuestionB.java
│ │ ├── Q17_14_Smallest_K/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ ├── QuestionD.java
│ │ │ └── Tester.java
│ │ ├── Q17_15_Longest_Word/
│ │ │ ├── LengthComparator.java
│ │ │ └── Question.java
│ │ ├── Q17_16_The_Masseuse/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ ├── QuestionD.java
│ │ │ └── Tester.java
│ │ ├── Q17_17_Multi_Search/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ ├── Trie.java
│ │ │ └── TrieNode.java
│ │ ├── Q17_18_Shortest_Supersequence/
│ │ │ ├── HeapNode.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ ├── QuestionD.java
│ │ │ ├── QuestionE.java
│ │ │ ├── Range.java
│ │ │ └── Tester.java
│ │ ├── Q17_19_Missing_Two/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ └── QuestionC.java
│ │ ├── Q17_20_Continuous_Median/
│ │ │ ├── MaxHeapComparator.java
│ │ │ ├── MinHeapComparator.java
│ │ │ └── Question.java
│ │ ├── Q17_21_Volume_of_Histogram/
│ │ │ ├── HistogramData.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ ├── Q17_22_Word_Transformer/
│ │ │ ├── BFSData.java
│ │ │ ├── PathNode.java
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ └── Tester.java
│ │ ├── Q17_23_Max_Black_Square/
│ │ │ ├── Question.java
│ │ │ ├── QuestionEff.java
│ │ │ ├── SquareCell.java
│ │ │ └── Subsquare.java
│ │ ├── Q17_24_Max_Submatrix/
│ │ │ ├── QuestionA.java
│ │ │ ├── QuestionB.java
│ │ │ ├── QuestionC.java
│ │ │ ├── Range.java
│ │ │ ├── SubMatrix.java
│ │ │ └── Tester.java
│ │ ├── Q17_25_Word_Rectangle/
│ │ │ ├── Question.java
│ │ │ ├── Rectangle.java
│ │ │ └── WordGroup.java
│ │ └── Q17_26_Sparse_Similarity/
│ │ ├── DocPair.java
│ │ ├── Document.java
│ │ ├── QuestionA.java
│ │ ├── QuestionB.java
│ │ ├── QuestionC.java
│ │ └── Tester.java
│ ├── CtCILibrary/
│ │ └── CtCILibrary/
│ │ ├── AssortedMethods.java
│ │ ├── BTreePrinter.java
│ │ ├── BitVector.java
│ │ ├── HashMapList.java
│ │ ├── LinkedListNode.java
│ │ ├── TreeNode.java
│ │ ├── Trie.java
│ │ └── TrieNode.java
│ └── Introduction/
│ ├── Big_O/
│ │ ├── Ex_01.java
│ │ ├── Ex_02.java
│ │ ├── Ex_03.java
│ │ ├── Ex_04.java
│ │ ├── Ex_05.java
│ │ ├── Ex_06.java
│ │ ├── Ex_07.java
│ │ ├── Ex_08.java
│ │ ├── Ex_09.java
│ │ ├── Ex_10.java
│ │ ├── Ex_11.java
│ │ ├── Ex_14.java
│ │ ├── Ex_15.java
│ │ ├── Ex_16.java
│ │ ├── Ex_17.java
│ │ ├── Ex_18.java
│ │ ├── Ex_19.java
│ │ ├── Ex_20.java
│ │ ├── Q_01.java
│ │ ├── Q_02.java
│ │ ├── Q_03.java
│ │ ├── Q_04.java
│ │ ├── Q_05.java
│ │ ├── Q_06.java
│ │ ├── Q_09.java
│ │ ├── Q_10.java
│ │ ├── Q_11.java
│ │ └── Q_12.java
│ ├── CompareBinaryToHex/
│ │ └── CompareBinaryToHex.java
│ └── SwapMinMax/
│ └── SwapMinMax.java
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .classpath
================================================
================================================
FILE: .gitignore
================================================
bin/
================================================
FILE: .gitmodules
================================================
[submodule "php"]
path = php
url = https://github.com/careercup/CtCI-6th-Edition-php.git
[submodule "cpp"]
path = cpp
url = https://github.com/careercup/CtCI-6th-Edition-cpp.git
[submodule "Clojure"]
path = Clojure
url = https://github.com/careercup/CtCI-6th-Edition-Clojure.git
[submodule "Groovy"]
path = Groovy
url = https://github.com/careercup/CtCI-6th-Edition-Groovy.git
[submodule "Python"]
path = Python
url = https://github.com/careercup/CtCI-6th-Edition-Python.git
[submodule "Swift"]
path = Swift
url = https://github.com/careercup/CtCI-6th-Edition-Swift.git
[submodule "Haskell"]
path = Haskell
url = https://github.com/careercup/CtCI-6th-Edition-Haskell.git
[submodule "JavaScript"]
path = JavaScript
url = https://github.com/careercup/CtCI-6th-Edition-JavaScript.git
[submodule "JavaScript-ES2015"]
path = JavaScript-ES2015
url = https://github.com/careercup/CtCI-6th-Edition-JavaScript-ES2015.git
[submodule "Go"]
path = Go
url = https://github.com/careercup/CtCI-6th-Edition-Go.git
[submodule "CtCI-6th-Edition-CSharp"]
path = CSharp
url = https://github.com/careercup/CtCI-6th-Edition-CSharp.git
[submodule "c"]
path = c
url = https://github.com/careercup/CtCI-6th-Edition-C.git
[submodule "Objective-C"]
path = Objective-C
url = https://github.com/careercup/CtCI-6th-Edition-Objective-C.git
[submodule "Julia"]
path = Julia
url = https://github.com/careercup/CtCI-6th-Edition-Julia.git
[submodule "Ruby"]
path = Ruby
url = https://github.com/careercup/CtCI-6th-Edition-Ruby.git
[submodule "Kotlin"]
path = Kotlin
url = https://github.com/careercup/CtCI-6th-Edition-Kotlin.git
================================================
FILE: .project
================================================
CtCIv6
org.eclipse.jdt.core.javabuilder
org.eclipse.jdt.core.javanature
================================================
FILE: Java/Big O/Example_16/Example.java
================================================
package Example_16;
public class Example {
public static int powersOf2(int n) {
if (n < 1) {
return 0;
} else if (n == 1) {
System.out.println(1);
return 1;
} else {
int prev = powersOf2(n / 2);
int curr = prev * 2;
System.out.println(curr);
return curr;
}
}
public static void main(String[] args) {
powersOf2(4);
}
}
================================================
FILE: Java/Big O/QVI_11_Print_Sorted_Strings/Question.java
================================================
package QVI_11_Print_Sorted_Strings;
public class Question {
public static int numChars = 26;
public static void printSortedStrings(int remaining) {
printSortedStrings(remaining, "");
}
public static void printSortedStrings(int remaining, String prefix) {
if (remaining == 0) {
if (isInOrder(prefix)) {
System.out.println(prefix);
}
} else {
for (int i = 0; i < numChars; i++) {
char c = ithLetter(i);
printSortedStrings(remaining - 1, prefix + c);
}
}
}
public static boolean isInOrder(String s) {
boolean isInOrder = true;
for (int i = 1; i < s.length(); i++) {
int prev = ithLetter(s.charAt(i - 1));
int curr = ithLetter(s.charAt(i));
if (prev > curr) {
isInOrder = false;
}
}
return isInOrder;
}
public static char ithLetter(int i) {
return (char) (((int) 'a') + i);
}
public static void main(String[] args) {
printSortedStrings(5);
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_01_Is_Unique/QuestionA.java
================================================
package Q1_01_Is_Unique;
public class QuestionA {
public static boolean isUniqueChars(String str) {
if (str.length() > 128) {
return false;
}
boolean[] char_set = new boolean[128];
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i);
if (char_set[val]) return false;
char_set[val] = true;
}
return true;
}
public static void main(String[] args) {
String[] words = {"abcde", "hello", "apple", "kite", "padle"};
for (String word : words) {
System.out.println(word + ": " + isUniqueChars(word));
}
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_01_Is_Unique/QuestionB.java
================================================
package Q1_01_Is_Unique;
public class QuestionB {
/* Assumes only letters a through z. */
public static boolean isUniqueChars(String str) {
if (str.length() > 26) { // Only 26 characters
return false;
}
int checker = 0;
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i) - 'a';
if ((checker & (1 << val)) > 0) return false;
checker |= (1 << val);
}
return true;
}
public static void main(String[] args) {
String[] words = {"abcde", "hello", "apple", "kite", "padle"};
for (String word : words) {
System.out.println(word + ": " + isUniqueChars(word));
}
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_01_Is_Unique/Tester.java
================================================
package Q1_01_Is_Unique;
public class Tester {
public static void main(String[] args) {
String[] words = {"abcde", "hello", "apple", "kite", "padle"};
for (String word : words) {
boolean wordA = QuestionA.isUniqueChars(word);
boolean wordB = QuestionB.isUniqueChars(word);
if (wordA == wordB) {
System.out.println(word + ": " + wordA);
} else {
System.out.println(word + ": " + wordA + " vs " + wordB);
}
}
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_02_Check_Permutation/QuestionA.java
================================================
package Q1_02_Check_Permutation;
public class QuestionA {
public static String sort(String s) {
char[] content = s.toCharArray();
java.util.Arrays.sort(content);
return new String(content);
}
public static boolean permutation(String s, String t) {
return sort(s).equals(sort(t));
}
public static void main(String[] args) {
String[][] pairs = {{"apple", "papel"}, {"carrot", "tarroc"}, {"hello", "llloh"}};
for (String[] pair : pairs) {
String word1 = pair[0];
String word2 = pair[1];
boolean anagram = permutation(word1, word2);
System.out.println(word1 + ", " + word2 + ": " + anagram);
}
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_02_Check_Permutation/QuestionB.java
================================================
package Q1_02_Check_Permutation;
public class QuestionB {
public static boolean permutation(String s, String t) {
if (s.length() != t.length()) return false; // Permutations must be same length
int[] letters = new int[128]; // Assumption: ASCII
for (int i = 0; i < s.length(); i++) {
letters[s.charAt(i)]++;
}
for (int i = 0; i < t.length(); i++) {
letters[t.charAt(i)]--;
if (letters[t.charAt(i)] < 0) {
return false;
}
}
return true; // letters array has no negative values, and therefore no positive values either
}
public static void main(String[] args) {
String[][] pairs = {{"apple", "papel"}, {"carrot", "tarroc"}, {"hello", "llloh"}};
for (String[] pair : pairs) {
String word1 = pair[0];
String word2 = pair[1];
boolean anagram = permutation(word1, word2);
System.out.println(word1 + ", " + word2 + ": " + anagram);
}
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_03_URLify/Question.java
================================================
package Q1_03_URLify;
import CtCILibrary.AssortedMethods;
public class Question {
// Assume string has sufficient free space at the end
public static void replaceSpaces(char[] str, int trueLength) {
int spaceCount = 0, index, i = 0;
for (i = 0; i < trueLength; i++) {
if (str[i] == ' ') {
spaceCount++;
}
}
index = trueLength + spaceCount * 2;
if (trueLength < str.length) str[trueLength] = '\0';
for (i = trueLength - 1; i >= 0; i--) {
if (str[i] == ' ') {
str[index - 1] = '0';
str[index - 2] = '2';
str[index - 3] = '%';
index = index - 3;
} else {
str[index - 1] = str[i];
index--;
}
}
}
public static int findLastCharacter(char[] str) {
for (int i = str.length - 1; i >= 0; i--) {
if (str[i] != ' ') {
return i;
}
}
return -1;
}
public static void main(String[] args) {
String str = "Mr John Smith ";
char[] arr = str.toCharArray();
int trueLength = findLastCharacter(arr) + 1;
replaceSpaces(arr, trueLength);
System.out.println("\"" + AssortedMethods.charArrayToString(arr) + "\"");
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation/Common.java
================================================
package Q1_04_Palindrome_Permutation;
public class Common {
public static int getCharNumber(Character c) {
int a = Character.getNumericValue('a');
int z = Character.getNumericValue('z');
int val = Character.getNumericValue(c);
if (a <= val && val <= z) {
return val - a;
}
return -1;
}
public static int[] buildCharFrequencyTable(String phrase) {
int[] table = new int[Character.getNumericValue('z') - Character.getNumericValue('a') + 1];
for (char c : phrase.toCharArray()) {
int x = getCharNumber(c);
if (x != -1) {
table[x]++;
}
}
return table;
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation/QuestionA.java
================================================
package Q1_04_Palindrome_Permutation;
public class QuestionA {
public static boolean checkMaxOneOdd(int[] table) {
boolean foundOdd = false;
for (int count : table) {
if (count % 2 == 1) {
if (foundOdd) {
return false;
}
foundOdd = true;
}
}
return true;
}
public static boolean isPermutationOfPalindrome(String phrase) {
int[] table = Common.buildCharFrequencyTable(phrase);
return checkMaxOneOdd(table);
}
public static void main(String[] args) {
String pali = "Rats live on no evil star";
System.out.println(isPermutationOfPalindrome(pali));
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation/QuestionB.java
================================================
package Q1_04_Palindrome_Permutation;
public class QuestionB {
public static boolean isPermutationOfPalindrome(String phrase) {
int countOdd = 0;
int[] table = new int[Character.getNumericValue('z') - Character.getNumericValue('a') + 1];
for (char c : phrase.toCharArray()) {
int x = Common.getCharNumber(c);
if (x != -1) {
table[x]++;
if (table[x] % 2 == 1) {
countOdd++;
} else {
countOdd--;
}
}
}
return countOdd <= 1;
}
public static void main(String[] args) {
String pali = "Ratzs live on no evil starz";
System.out.println(isPermutationOfPalindrome(pali));
String pali2 = "Zeus was deified, saw Suez";
System.out.println(isPermutationOfPalindrome(pali2));
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation/QuestionC.java
================================================
package Q1_04_Palindrome_Permutation;
public class QuestionC {
/* Toggle the ith bit in the integer. */
public static int toggle(int bitVector, int index) {
if (index < 0) return bitVector;
int mask = 1 << index;
if ((bitVector & mask) == 0) {
bitVector |= mask;
} else {
bitVector &= ~mask;
}
return bitVector;
}
/* Create bit vector for string. For each letter with value i,
* toggle the ith bit. */
public static int createBitVector(String phrase) {
int bitVector = 0;
for (char c : phrase.toCharArray()) {
int x = Common.getCharNumber(c);
bitVector = toggle(bitVector, x);
}
return bitVector;
}
/* Check that at most one bit is set by subtracting one from the
* integer and ANDing it with the original integer. */
public static boolean checkAtMostOneBitSet(int bitVector) {
return (bitVector & (bitVector - 1)) == 0;
}
public static boolean isPermutationOfPalindrome(String phrase) {
int bitVector = createBitVector(phrase);
return checkAtMostOneBitSet(bitVector);
}
public static void main(String[] args) {
String pali = "Rats live on no evil star";
System.out.println(isPermutationOfPalindrome(pali));
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation/Tester.java
================================================
package Q1_04_Palindrome_Permutation;
public class Tester {
public static void main(String[] args) {
String[] strings = {"Rats live on no evil star",
"A man, a plan, a canal, panama",
"Lleve",
"Tacotac",
"asda"};
for (String s : strings) {
boolean a = QuestionA.isPermutationOfPalindrome(s);
boolean b = QuestionB.isPermutationOfPalindrome(s);
boolean c = QuestionC.isPermutationOfPalindrome(s);
System.out.println(s);
if (a == b && b == c) {
System.out.println("Agree: " + a);
} else {
System.out.println("Disagree: " + a + ", " + b + ", " + c);
}
System.out.println();
}
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_05_One_Away/QuestionA.java
================================================
package Q1_05_One_Away;
public class QuestionA {
public static boolean oneEditReplace(String s1, String s2) {
boolean foundDifference = false;
for (int i = 0; i < s1.length(); i++) {
if (s1.charAt(i) != s2.charAt(i)) {
if (foundDifference) {
return false;
}
foundDifference = true;
}
}
return true;
}
/* Check if you can insert a character into s1 to make s2. */
public static boolean oneEditInsert(String s1, String s2) {
int index1 = 0;
int index2 = 0;
while (index2 < s2.length() && index1 < s1.length()) {
if (s1.charAt(index1) != s2.charAt(index2)) {
if (index1 != index2) {
return false;
}
index2++;
} else {
index1++;
index2++;
}
}
return true;
}
public static boolean oneEditAway(String first, String second) {
if (first.length() == second.length()) {
return oneEditReplace(first, second);
} else if (first.length() + 1 == second.length()) {
return oneEditInsert(first, second);
} else if (first.length() - 1 == second.length()) {
return oneEditInsert(second, first);
}
return false;
}
public static void main(String[] args) {
String a = "pse";
String b = "pale";
boolean isOneEdit = oneEditAway(a, b);
System.out.println(a + ", " + b + ": " + isOneEdit);
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_05_One_Away/QuestionB.java
================================================
package Q1_05_One_Away;
public class QuestionB {
public static boolean oneEditAway(String first, String second) {
/* Length checks. */
if (Math.abs(first.length() - second.length()) > 1) {
return false;
}
/* Get shorter and longer string.*/
String s1 = first.length() < second.length() ? first : second;
String s2 = first.length() < second.length() ? second : first;
int index1 = 0;
int index2 = 0;
boolean foundDifference = false;
while (index2 < s2.length() && index1 < s1.length()) {
if (s1.charAt(index1) != s2.charAt(index2)) {
/* Ensure that this is the first difference found.*/
if (foundDifference) return false;
foundDifference = true;
if (s1.length() == s2.length()) { // On replace, move shorter pointer
index1++;
}
} else {
index1++; // If matching, move shorter pointer
}
index2++; // Always move pointer for longer string
}
return true;
}
public static void main(String[] args) {
String a = "palee";
String b = "pale";
boolean isOneEdit1 = oneEditAway(a, b);
System.out.println(a + ", " + b + ": " + isOneEdit1);
String c = "pale";
String d = "pkle";
boolean isOneEdit2 = oneEditAway(c, d);
System.out.println(c + ", " + d + ": " + isOneEdit2);
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_05_One_Away/Tester.java
================================================
package Q1_05_One_Away;
public class Tester {
public static void test(String a, String b, boolean expected) {
boolean resultA = QuestionA.oneEditAway(a, b);
boolean resultB = QuestionB.oneEditAway(a, b);
if (resultA == expected && resultB == expected) {
System.out.println(a + ", " + b + ": success");
} else {
System.out.println(a + ", " + b + ": error");
}
}
public static void main(String[] args) {
String[][] tests = {{"a", "b", "true"},
{"", "d", "true"},
{"d", "de", "true"},
{"pale", "pse", "false"},
{"acdsfdsfadsf", "acdsgdsfadsf", "true"},
{"acdsfdsfadsf", "acdsfdfadsf", "true"},
{"acdsfdsfadsf", "acdsfdsfads", "true"},
{"acdsfdsfadsf", "cdsfdsfadsf", "true"},
{"adfdsfadsf", "acdfdsfdsf", "false"},
{"adfdsfadsf", "bdfdsfadsg", "false"},
{"adfdsfadsf", "affdsfads", "false"},
{"pale", "pkle", "true"},
{"pkle", "pable", "false"}};
for (int i = 0; i < tests.length; i++) {
String[] test = tests[i];
String a = test[0];
String b = test[1];
boolean expected = test[2].equals("true");
test(a, b, expected);
test(b, a, expected);
}
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_06_String_Compression/QuestionA.java
================================================
package Q1_06_String_Compression;
public class QuestionA {
public static String compressBad(String str) {
String compressedString = "";
int countConsecutive = 0;
for (int i = 0; i < str.length(); i++) {
countConsecutive++;
/* If next character is different than current, append this char to result.*/
if (i + 1 >= str.length() || str.charAt(i) != str.charAt(i + 1)) {
compressedString += "" + str.charAt(i) + countConsecutive;
countConsecutive = 0;
}
}
return compressedString.length() < str.length() ? compressedString : str;
}
public static void main(String[] args) {
String str = "aa";
System.out.println(str);
System.out.println(compressBad(str));
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_06_String_Compression/QuestionB.java
================================================
package Q1_06_String_Compression;
public class QuestionB {
public static String compress(String str) {
StringBuilder compressed = new StringBuilder();
int countConsecutive = 0;
for (int i = 0; i < str.length(); i++) {
countConsecutive++;
/* If next character is different than current, append this char to result.*/
if (i + 1 >= str.length() || str.charAt(i) != str.charAt(i + 1)) {
compressed.append(str.charAt(i));
compressed.append(countConsecutive);
countConsecutive = 0;
}
}
return compressed.length() < str.length() ? compressed.toString() : str;
}
public static void main(String[] args) {
String str = "aa";
System.out.println(str);
System.out.println(compress(str));
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_06_String_Compression/QuestionC.java
================================================
package Q1_06_String_Compression;
public class QuestionC {
public static String compress(String str) {
int finalLength = countCompression(str);
if (finalLength >= str.length()) return str;
StringBuffer compressed = new StringBuffer(finalLength); // initialize capacity
int countConsecutive = 0;
for (int i = 0; i < str.length(); i++) {
countConsecutive++;
/* If next character is different than current, append this char to result.*/
if (i + 1 >= str.length() || str.charAt(i) != str.charAt(i + 1)) {
compressed.append(str.charAt(i));
compressed.append(countConsecutive);
countConsecutive = 0;
}
}
return compressed.toString();
}
public static int countCompression(String str) {
int compressedLength = 0;
int countConsecutive = 0;
for (int i = 0; i < str.length(); i++) {
countConsecutive++;
/* If next character is different than current, append this char to result.*/
if (i + 1 >= str.length() || str.charAt(i) != str.charAt(i + 1)) {
compressedLength += 1 + String.valueOf(countConsecutive).length();
countConsecutive = 0;
}
}
return compressedLength;
}
public static void main(String[] args) {
String str = "aa";
System.out.println(str);
System.out.println(compress(str));
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_06_String_Compression/Tester.java
================================================
package Q1_06_String_Compression;
public class Tester {
public static void main(String[] args) {
String str = "aaaaabbbbaaaabbddc";
System.out.println(str);
System.out.println(QuestionA.compressBad(str));
System.out.println(QuestionB.compress(str));
System.out.println(QuestionC.compress(str));
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix/Question.java
================================================
package Q1_07_Rotate_Matrix;
import CtCILibrary.*;
public class Question {
public static boolean rotate(int[][] matrix) {
if (matrix.length == 0 || matrix.length != matrix[0].length) return false; // Not a square
int n = matrix.length;
for (int layer = 0; layer < n / 2; layer++) {
int first = layer;
int last = n - 1 - layer;
for(int i = first; i < last; i++) {
int offset = i - first;
int top = matrix[first][i]; // save top
// left -> top
matrix[first][i] = matrix[last-offset][first];
// bottom -> left
matrix[last-offset][first] = matrix[last][last - offset];
// right -> bottom
matrix[last][last - offset] = matrix[i][last];
// top -> right
matrix[i][last] = top; // right <- saved top
}
}
return true;
}
public static void main(String[] args) {
int[][] matrix = AssortedMethods.randomMatrix(3, 3, 0, 9);
AssortedMethods.printMatrix(matrix);
rotate(matrix);
System.out.println();
AssortedMethods.printMatrix(matrix);
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_08_Zero_Matrix/QuestionA.java
================================================
package Q1_08_Zero_Matrix;
import CtCILibrary.AssortedMethods;
public class QuestionA {
public static void nullifyRow(int[][] matrix, int row) {
for (int j = 0; j < matrix[0].length; j++) {
matrix[row][j] = 0;
}
}
public static void nullifyColumn(int[][] matrix, int col) {
for (int i = 0; i < matrix.length; i++) {
matrix[i][col] = 0;
}
}
public static void setZeros(int[][] matrix) {
boolean[] row = new boolean[matrix.length];
boolean[] column = new boolean[matrix[0].length];
// Store the row and column index with value 0
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length;j++) {
if (matrix[i][j] == 0) {
row[i] = true;
column[j] = true;
}
}
}
// Nullify rows
for (int i = 0; i < row.length; i++) {
if (row[i]) {
nullifyRow(matrix, i);
}
}
// Nullify columns
for (int j = 0; j < column.length; j++) {
if (column[j]) {
nullifyColumn(matrix, j);
}
}
}
public static boolean matricesAreEqual(int[][] m1, int[][] m2) {
if (m1.length != m2.length || m1[0].length != m2[0].length) {
return false;
}
for (int k = 0; k < m1.length; k++) {
for (int j = 0; j < m1[0].length; j++) {
if (m1[k][j] != m2[k][j]) {
return false;
}
}
}
return true;
}
public static int[][] cloneMatrix(int[][] matrix) {
int[][] c = new int[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
c[i][j] = matrix[i][j];
}
}
return c;
}
public static void main(String[] args) {
int nrows = 10;
int ncols = 15;
int[][] matrix = AssortedMethods.randomMatrix(nrows, ncols, -10, 10);
AssortedMethods.printMatrix(matrix);
setZeros(matrix);
System.out.println();
AssortedMethods.printMatrix(matrix);
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_08_Zero_Matrix/QuestionB.java
================================================
package Q1_08_Zero_Matrix;
import CtCILibrary.AssortedMethods;
public class QuestionB {
public static void nullifyRow(int[][] matrix, int row) {
for (int j = 0; j < matrix[0].length; j++) {
matrix[row][j] = 0;
}
}
public static void nullifyColumn(int[][] matrix, int col) {
for (int i = 0; i < matrix.length; i++) {
matrix[i][col] = 0;
}
}
public static void setZeros(int[][] matrix) {
boolean rowHasZero = false;
boolean colHasZero = false;
// Check if first row has a zero
for (int j = 0; j < matrix[0].length; j++) {
if (matrix[0][j] == 0) {
rowHasZero = true;
break;
}
}
// Check if first column has a zero
for (int i = 0; i < matrix.length; i++) {
if (matrix[i][0] == 0) {
colHasZero = true;
break;
}
}
// Check for zeros in the rest of the array
for (int i = 1; i < matrix.length; i++) {
for (int j = 1; j < matrix[0].length;j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = 0;
matrix[0][j] = 0;
}
}
}
// Nullify rows based on values in first column
for (int i = 1; i < matrix.length; i++) {
if (matrix[i][0] == 0) {
nullifyRow(matrix, i);
}
}
// Nullify columns based on values in first row
for (int j = 1; j < matrix[0].length; j++) {
if (matrix[0][j] == 0) {
nullifyColumn(matrix, j);
}
}
// Nullify first row
if (rowHasZero) {
nullifyRow(matrix, 0);
}
// Nullify first column
if (colHasZero) {
nullifyColumn(matrix, 0);
}
}
public static boolean matricesAreEqual(int[][] m1, int[][] m2) {
if (m1.length != m2.length || m1[0].length != m2[0].length) {
return false;
}
for (int k = 0; k < m1.length; k++) {
for (int j = 0; j < m1[0].length; j++) {
if (m1[k][j] != m2[k][j]) {
return false;
}
}
}
return true;
}
public static int[][] cloneMatrix(int[][] matrix) {
int[][] c = new int[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
c[i][j] = matrix[i][j];
}
}
return c;
}
public static void main(String[] args) {
int nrows = 10;
int ncols = 15;
int[][] matrix = AssortedMethods.randomMatrix(nrows, ncols, -10, 10);
AssortedMethods.printMatrix(matrix);
setZeros(matrix);
System.out.println();
AssortedMethods.printMatrix(matrix);
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_08_Zero_Matrix/Tester.java
================================================
package Q1_08_Zero_Matrix;
import CtCILibrary.AssortedMethods;
public class Tester {
public static boolean matricesAreEqual(int[][] m1, int[][] m2) {
if (m1.length != m2.length || m1[0].length != m2[0].length) {
return false;
}
for (int k = 0; k < m1.length; k++) {
for (int j = 0; j < m1[0].length; j++) {
if (m1[k][j] != m2[k][j]) {
return false;
}
}
}
return true;
}
public static int[][] cloneMatrix(int[][] matrix) {
int[][] c = new int[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
c[i][j] = matrix[i][j];
}
}
return c;
}
public static void main(String[] args) {
int nrows = 10;
int ncols = 15;
int[][] matrix1 = AssortedMethods.randomMatrix(nrows, ncols, -10, 10);
int[][] matrix2 = cloneMatrix(matrix1);
AssortedMethods.printMatrix(matrix1);
QuestionA.setZeros(matrix1);
QuestionB.setZeros(matrix2);
System.out.println();
AssortedMethods.printMatrix(matrix1);
System.out.println();
AssortedMethods.printMatrix(matrix2);
if (matricesAreEqual(matrix1, matrix2)) {
System.out.println("Equal");
} else {
System.out.println("Not Equal");
}
}
}
================================================
FILE: Java/Ch 01. Arrays and Strings/Q1_09_String_Rotation/Question.java
================================================
package Q1_09_String_Rotation;
public class Question {
public static boolean isSubstring(String big, String small) {
if (big.indexOf(small) >= 0) {
return true;
} else {
return false;
}
}
public static boolean isRotation(String s1, String s2) {
int len = s1.length();
/* check that s1 and s2 are equal length and not empty */
if (len == s2.length() && len > 0) {
/* concatenate s1 and s1 within new buffer */
String s1s1 = s1 + s1;
return isSubstring(s1s1, s2);
}
return false;
}
public static void main(String[] args) {
String[][] pairs = {{"apple", "pleap"}, {"waterbottle", "erbottlewat"}, {"camera", "macera"}};
for (String[] pair : pairs) {
String word1 = pair[0];
String word2 = pair[1];
boolean is_rotation = isRotation(word1, word2);
System.out.println(word1 + ", " + word2 + ": " + is_rotation);
}
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_01_Remove_Dups/QuestionA.java
================================================
package Q2_01_Remove_Dups;
import java.util.HashSet;
import CtCILibrary.LinkedListNode;
public class QuestionA {
public static void deleteDups(LinkedListNode n) {
HashSet set = new HashSet();
LinkedListNode previous = null;
while (n != null) {
if (set.contains(n.data)) {
previous.next = n.next;
} else {
set.add(n.data);
previous = n;
}
n = n.next;
}
}
public static void main(String[] args) {
LinkedListNode first = new LinkedListNode(0, null, null); //AssortedMethods.randomLinkedList(1000, 0, 2);
LinkedListNode head = first;
LinkedListNode second = first;
for (int i = 1; i < 8; i++) {
second = new LinkedListNode(i % 2, null, null);
first.setNext(second);
second.setPrevious(first);
first = second;
}
System.out.println(head.printForward());
deleteDups(head);
System.out.println(head.printForward());
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_01_Remove_Dups/QuestionB.java
================================================
package Q2_01_Remove_Dups;
import CtCILibrary.LinkedListNode;
public class QuestionB {
public static void deleteDups(LinkedListNode head) {
LinkedListNode current = head;
while (current != null) {
/* Remove all future nodes that have the same value */
LinkedListNode runner = current;
while (runner.next != null) {
if (runner.next.data == current.data) {
runner.next = runner.next.next;
} else {
runner = runner.next;
}
}
current = current.next;
}
}
public static void main(String[] args) {
LinkedListNode first = new LinkedListNode(0, null, null); //AssortedMethods.randomLinkedList(1000, 0, 2);
LinkedListNode head = first;
LinkedListNode second = first;
for (int i = 1; i < 8; i++) {
second = new LinkedListNode(i % 2, null, null);
first.setNext(second);
second.setPrevious(first);
first = second;
}
System.out.println(head.printForward());
deleteDups(head);
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_01_Remove_Dups/QuestionC.java
================================================
package Q2_01_Remove_Dups;
import CtCILibrary.LinkedListNode;
public class QuestionC {
public static void deleteDups(LinkedListNode head) {
if (head == null) return;
LinkedListNode previous = head;
LinkedListNode current = previous.next;
while (current != null) {
// Look backwards for dups, and remove any that you see.
LinkedListNode runner = head;
while (runner != current) {
if (runner.data == current.data) {
LinkedListNode tmp = current.next;
previous.next = tmp;
current = tmp;
/* We know we can't have more than one dup preceding
* our element since it would have been removed
* earlier. */
break;
}
runner = runner.next;
}
/* If runner == current, then we didn't find any duplicate
* elements in the previous for loop. We then need to
* increment current.
* If runner != current, then we must have hit the �break�
* condition, in which case we found a dup and current has
* already been incremented.*/
if (runner == current) {
previous = current;
current = current.next;
}
}
}
public static void main(String[] args) {
LinkedListNode first = new LinkedListNode(0, null, null); //AssortedMethods.randomLinkedList(1000, 0, 2);
LinkedListNode head = first;
LinkedListNode second = first;
for (int i = 1; i < 8; i++) {
second = new LinkedListNode(i % 2, null, null);
first.setNext(second);
second.setPrevious(first);
first = second;
}
System.out.println(head.printForward());
deleteDups(head);
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_01_Remove_Dups/Tester.java
================================================
package Q2_01_Remove_Dups;
import CtCILibrary.LinkedListNode;
public class Tester {
public static void main(String[] args) {
LinkedListNode first = new LinkedListNode(0, null, null); //AssortedMethods.randomLinkedList(1000, 0, 2);
LinkedListNode head = first;
LinkedListNode second = first;
for (int i = 1; i < 8; i++) {
second = new LinkedListNode(i % 2, null, null);
first.setNext(second);
second.setPrevious(first);
first = second;
}
System.out.println(head.printForward());
LinkedListNode cloneA = head.clone();
LinkedListNode cloneB = head.clone();
LinkedListNode cloneC = head.clone();
QuestionA.deleteDups(cloneA);
QuestionA.deleteDups(cloneB);
QuestionA.deleteDups(cloneC);
System.out.println(cloneA.printForward());
System.out.println(cloneB.printForward());
System.out.println(cloneC.printForward());
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_02_Return_Kth_To_Last/QuestionA.java
================================================
package Q2_02_Return_Kth_To_Last;
import CtCILibrary.*;
public class QuestionA {
public static int printKthToLast(LinkedListNode head, int k) {
if (head == null) {
return 0;
}
int index = printKthToLast(head.next, k) + 1;
if (index == k) {
System.out.println(k + "th to last node is " + head.data);
}
return index;
}
public static void main(String[] args) {
int[] array = {0, 1, 2, 3, 4, 5, 6};
LinkedListNode head = AssortedMethods.createLinkedListFromArray(array);
for (int i = 0; i <= array.length + 1; i++) {
printKthToLast(head, i);
}
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_02_Return_Kth_To_Last/QuestionB.cpp
================================================
#include
using namespace std;
struct node {
node * next;
int data;
};
node* nthToLast(node* head, int k, int& i) {
if (head == NULL) {
return NULL;
}
node * nd = nthToLast(head->next, k, i);
i = i + 1;
if (i == k) {
return head;
}
return nd;
}
node* nthToLast(node* head, int k) {
int i = 0;
return nthToLast(head, k, i);
}
node* createList(int count) {
node* head = new node();
head->data = 0;
node* last = head;
for (int i = 1; i < count; i++) {
node* n = new node();
n->data = i;
last->next = n;
last = n;
}
return head;
}
void printList(node* head) {
while (head != NULL) {
printf("%d", head->data);
head = head->next;
}
}
int main() {
int count = 5;
node* head = createList(count);
printList(head);
printf("\n");
for (int k = 0; k <= count; k++) {
node* n = nthToLast(head, k);
if (n != NULL) {
int data = n->data;
printf("%d: ", k);
printf("%d", n->data);
printf("\n");
}
}
return 0;
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_02_Return_Kth_To_Last/QuestionC.java
================================================
package Q2_02_Return_Kth_To_Last;
import CtCILibrary.*;
public class QuestionC {
public static class Index {
public int value = 0;
}
public static LinkedListNode kthToLast(LinkedListNode head, int k) {
Index idx = new Index();
return kthToLast(head, k, idx);
}
public static LinkedListNode kthToLast(LinkedListNode head, int k, Index idx) {
if (head == null) {
return null;
}
LinkedListNode node = kthToLast(head.next, k, idx);
idx.value = idx.value + 1;
if (idx.value == k) {
return head;
}
return node;
}
public static void main(String[] args) {
int[] array = {0, 1, 2, 3, 4, 5, 6};
LinkedListNode head = AssortedMethods.createLinkedListFromArray(array);
for (int i = 0; i <= array.length + 1; i++) {
LinkedListNode node = kthToLast(head, i);
String nodeValue = node == null ? "null" : "" + node.data;
System.out.println(i + ": " + nodeValue);
}
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_02_Return_Kth_To_Last/QuestionD.java
================================================
package Q2_02_Return_Kth_To_Last;
import CtCILibrary.*;
public class QuestionD {
public static LinkedListNode nthToLast(LinkedListNode head, int k) {
LinkedListNode p1 = head;
LinkedListNode p2 = head;
/* Move p1 k nodes into the list.*/
for (int i = 0; i < k; i++) {
if (p1 == null) return null; // Out of bounds
p1 = p1.next;
}
/* Move them at the same pace. When p1 hits the end,
* p2 will be at the right element. */
while (p1 != null) {
p1 = p1.next;
p2 = p2.next;
}
return p2;
}
public static void main(String[] args) {
int[] array = {0, 1, 2, 3};
LinkedListNode head = AssortedMethods.createLinkedListFromArray(array);
for (int i = 0; i <= array.length + 1; i++) {
LinkedListNode node = nthToLast(head, i);
String nodeValue = node == null ? "null" : "" + node.data;
System.out.println(i + ": " + nodeValue);
}
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_02_Return_Kth_To_Last/Tester.java
================================================
package Q2_02_Return_Kth_To_Last;
import CtCILibrary.AssortedMethods;
public class Tester {
public static void main(String[] args) {
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_03_Delete_Middle_Node/Question.java
================================================
package Q2_03_Delete_Middle_Node;
import CtCILibrary.AssortedMethods;
import CtCILibrary.LinkedListNode;
public class Question {
public static boolean deleteNode(LinkedListNode n) {
if (n == null || n.next == null) {
return false; // Failure
}
LinkedListNode next = n.next;
n.data = next.data;
n.next = next.next;
return true;
}
public static void main(String[] args) {
LinkedListNode head = AssortedMethods.randomLinkedList(10, 0, 10);
System.out.println(head.printForward());
deleteNode(head.next.next.next.next); // delete node 4
System.out.println(head.printForward());
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_04_Partition/Question.java
================================================
package Q2_04_Partition;
import CtCILibrary.LinkedListNode;
public class Question {
public static LinkedListNode partition(LinkedListNode node, int x) {
LinkedListNode beforeStart = null;
LinkedListNode beforeEnd = null;
LinkedListNode afterStart = null;
LinkedListNode afterEnd = null;
/* Partition list */
while (node != null) {
LinkedListNode next = node.next;
node.next = null;
if (node.data < x) {
if (beforeStart == null) {
beforeStart = node;
beforeEnd = beforeStart;
} else {
beforeEnd.next = node;
beforeEnd = node;
}
} else {
if (afterStart == null) {
afterStart = node;
afterEnd = afterStart;
} else {
afterEnd.next = node;
afterEnd = node;
}
}
node = next;
}
/* Merge before list and after list */
if (beforeStart == null) {
return afterStart;
}
beforeEnd.next = afterStart;
return beforeStart;
}
public static void main(String[] args) {
/* Create linked list */
int[] vals = {33,9,2,3,10,10389,838,874578,5};
LinkedListNode head = new LinkedListNode(vals[0], null, null);
LinkedListNode current = head;
for (int i = 1; i < vals.length; i++) {
current = new LinkedListNode(vals[i], null, current);
}
System.out.println(head.printForward());
/* Partition */
LinkedListNode h = partition(head, 3);
/* Print Result */
System.out.println(h.printForward());
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_04_Partition/QuestionB.java
================================================
package Q2_04_Partition;
import CtCILibrary.LinkedListNode;
public class QuestionB {
public static LinkedListNode partition(LinkedListNode node, int x) {
LinkedListNode beforeStart = null;
LinkedListNode afterStart = null;
/* Partition list */
while (node != null) {
LinkedListNode next = node.next;
if (node.data < x) {
/* Insert node into start of before list */
node.next = beforeStart;
beforeStart = node;
} else {
/* Insert node into front of after list */
node.next = afterStart;
afterStart = node;
}
node = next;
}
/* Merge before list and after list */
if (beforeStart == null) {
return afterStart;
}
LinkedListNode head = beforeStart;
while (beforeStart.next != null) {
beforeStart = beforeStart.next;
}
beforeStart.next = afterStart;
return head;
}
public static void main(String[] args) {
int length = 20;
LinkedListNode[] nodes = new LinkedListNode[length];
for (int i = 0; i < length; i++) {
nodes[i] = new LinkedListNode(i >= length / 2 ? length - i - 1 : i, null, null);
}
for (int i = 0; i < length; i++) {
if (i < length - 1) {
nodes[i].setNext(nodes[i + 1]);
}
if (i > 0) {
nodes[i].setPrevious(nodes[i - 1]);
}
}
LinkedListNode head = nodes[0];
System.out.println(head.printForward());
LinkedListNode h = partition(head, 7);
System.out.println(h.printForward());
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_04_Partition/QuestionC.java
================================================
package Q2_04_Partition;
import CtCILibrary.LinkedListNode;
public class QuestionC {
public static LinkedListNode partition(LinkedListNode node, int x) {
LinkedListNode head = node;
LinkedListNode tail = node;
/* Partition list */
while (node != null) {
LinkedListNode next = node.next;
if (node.data < x) {
/* Insert node at head. */
node.next = head;
head = node;
} else {
/* Insert node at tail. */
tail.next = node;
tail = node;
}
node = next;
}
tail.next = null;
return head;
}
public static void main(String[] args) {
int length = 20;
LinkedListNode[] nodes = new LinkedListNode[length];
for (int i = 0; i < length; i++) {
nodes[i] = new LinkedListNode(i >= length / 2 ? length - i - 1 : i, null, null);
}
for (int i = 0; i < length; i++) {
if (i < length - 1) {
nodes[i].setNext(nodes[i + 1]);
}
if (i > 0) {
nodes[i].setPrevious(nodes[i - 1]);
}
}
LinkedListNode head = nodes[0];
System.out.println(head.printForward());
LinkedListNode h = partition(head, 8);
System.out.println(h.printForward());
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_04_Partition/Tester.java
================================================
package Q2_04_Partition;
import CtCILibrary.LinkedListNode;
public class Tester {
public static LinkedListNode createLinkedList() {
/* Create linked list */
int[] vals = {3, 5, 8, 5, 10, 2, 1};
LinkedListNode head = new LinkedListNode(vals[0], null, null);
LinkedListNode current = head;
for (int i = 1; i < vals.length; i++) {
current = new LinkedListNode(vals[i], null, current);
}
return head;
}
public static void main(String[] args) {
System.out.println(createLinkedList().printForward());
/* Partition */
LinkedListNode hA = Question.partition(createLinkedList(), 5);
LinkedListNode hB = QuestionB.partition(createLinkedList(), 5);
LinkedListNode hC = QuestionC.partition(createLinkedList(), 5);
/* Print Result */
System.out.println(hA.printForward());
System.out.println(hB.printForward());
System.out.println(hC.printForward());
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_05_Sum_Lists/PartialSum.java
================================================
package Q2_05_Sum_Lists;
import CtCILibrary.LinkedListNode;
public class PartialSum {
public LinkedListNode sum = null;
public int carry = 0;
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_05_Sum_Lists/QuestionA.java
================================================
package Q2_05_Sum_Lists;
import CtCILibrary.LinkedListNode;
public class QuestionA {
private static LinkedListNode addLists(LinkedListNode l1, LinkedListNode l2) {
return addLists(l1, l2, 0);
}
private static LinkedListNode addLists(LinkedListNode l1, LinkedListNode l2, int carry) {
if (l1 == null && l2 == null && carry == 0) {
return null;
}
LinkedListNode result = new LinkedListNode();
int value = carry;
if (l1 != null) {
value += l1.data;
}
if (l2 != null) {
value += l2.data;
}
result.data = value % 10;
if (l1 != null || l2 != null) {
LinkedListNode more = addLists(l1 == null ? null : l1.next,
l2 == null ? null : l2.next,
value >= 10 ? 1 : 0);
result.setNext(more);
}
return result;
}
public static int linkedListToInt(LinkedListNode node) {
int value = 0;
if (node.next != null) {
value = 10 * linkedListToInt(node.next);
}
return value + node.data;
}
public static void main(String[] args) {
LinkedListNode lA1 = new LinkedListNode(9, null, null);
LinkedListNode lA2 = new LinkedListNode(9, null, lA1);
LinkedListNode lA3 = new LinkedListNode(9, null, lA2);
LinkedListNode lB1 = new LinkedListNode(1, null, null);
LinkedListNode lB2 = new LinkedListNode(0, null, lB1);
LinkedListNode lB3 = new LinkedListNode(0, null, lB2);
LinkedListNode list3 = addLists(lA1, lB1);
System.out.println(" " + lA1.printForward());
System.out.println("+ " + lB1.printForward());
System.out.println("= " + list3.printForward());
int l1 = linkedListToInt(lA1);
int l2 = linkedListToInt(lB1);
int l3 = linkedListToInt(list3);
System.out.print(l1 + " + " + l2 + " = " + l3 + "\n");
System.out.print(l1 + " + " + l2 + " = " + (l1 + l2));
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_05_Sum_Lists/QuestionB.java
================================================
package Q2_05_Sum_Lists;
import CtCILibrary.LinkedListNode;
public class QuestionB {
private static int length(LinkedListNode l) {
if (l == null) {
return 0;
} else {
return 1 + length(l.next);
}
}
private static PartialSum addListsHelper(LinkedListNode l1, LinkedListNode l2) {
if (l1 == null && l2 == null) {
PartialSum sum = new PartialSum();
return sum;
}
PartialSum sum = addListsHelper(l1.next, l2.next);
int val = sum.carry + l1.data + l2.data;
LinkedListNode full_result = insertBefore(sum.sum, val % 10);
sum.sum = full_result;
sum.carry = val / 10;
return sum;
}
private static LinkedListNode addLists(LinkedListNode l1, LinkedListNode l2) {
int len1 = length(l1);
int len2 = length(l2);
if (len1 < len2) {
l1 = padList(l1, len2 - len1);
} else {
l2 = padList(l2, len1 - len2);
}
PartialSum sum = addListsHelper(l1, l2);
if (sum.carry == 0) {
return sum.sum;
} else {
LinkedListNode result = insertBefore(sum.sum, sum.carry);
return result;
}
}
private static LinkedListNode padList(LinkedListNode l, int padding) {
LinkedListNode head = l;
for (int i = 0; i < padding; i++) {
head = insertBefore(head, 0);
}
return head;
}
private static LinkedListNode insertBefore(LinkedListNode list, int data) {
LinkedListNode node = new LinkedListNode(data);
if (list != null) {
node.next = list;
}
return node;
}
public static int linkedListToInt(LinkedListNode node) {
int value = 0;
while (node != null) {
value = value * 10 + node.data;
node = node.next;
}
return value;
}
public static void main(String[] args) {
LinkedListNode lA1 = new LinkedListNode(3, null, null);
LinkedListNode lA2 = new LinkedListNode(1, null, lA1);
LinkedListNode lB1 = new LinkedListNode(5, null, null);
LinkedListNode lB2 = new LinkedListNode(9, null, lB1);
LinkedListNode lB3 = new LinkedListNode(1, null, lB2);
LinkedListNode list3 = addLists(lA1, lB1);
System.out.println(" " + lA1.printForward());
System.out.println("+ " + lB1.printForward());
System.out.println("= " + list3.printForward());
int l1 = linkedListToInt(lA1);
int l2 = linkedListToInt(lB1);
int l3 = linkedListToInt(list3);
System.out.print(l1 + " + " + l2 + " = " + l3 + "\n");
System.out.print(l1 + " + " + l2 + " = " + (l1 + l2));
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_06_Palindrome/QuestionA.java
================================================
package Q2_06_Palindrome;
import CtCILibrary.LinkedListNode;
public class QuestionA {
public static boolean isPalindrome(LinkedListNode head) {
LinkedListNode reversed = reverseAndClone(head);
return isEqual(head, reversed);
}
public static LinkedListNode reverseAndClone(LinkedListNode node) {
LinkedListNode head = null;
while (node != null) {
LinkedListNode n = new LinkedListNode(node.data); // Clone
n.next = head;
head = n;
node = node.next;
}
return head;
}
public static boolean isEqual(LinkedListNode one, LinkedListNode two) {
while (one != null && two != null) {
if (one.data != two.data) {
return false;
}
one = one.next;
two = two.next;
}
return one == null && two == null;
}
public static void main(String[] args) {
int length = 9;
LinkedListNode[] nodes = new LinkedListNode[length];
for (int i = 0; i < length; i++) {
nodes[i] = new LinkedListNode(i >= length / 2 ? length - i - 1 : i, null, null);
}
for (int i = 0; i < length; i++) {
if (i < length - 1) {
nodes[i].setNext(nodes[i + 1]);
}
if (i > 0) {
nodes[i].setPrevious(nodes[i - 1]);
}
}
// nodes[length - 2].data = 9; // Uncomment to ruin palindrome
LinkedListNode head = nodes[0];
System.out.println(head.printForward());
System.out.println(isPalindrome(head));
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_06_Palindrome/QuestionB.java
================================================
package Q2_06_Palindrome;
import CtCILibrary.LinkedListNode;
import java.util.Stack;
public class QuestionB {
public static boolean isPalindrome(LinkedListNode head) {
LinkedListNode fast = head;
LinkedListNode slow = head;
Stack stack = new Stack();
while (fast != null && fast.next != null) {
stack.push(slow.data);
slow = slow.next;
fast = fast.next.next;
}
/* Has odd number of elements, so skip the middle */
if (fast != null) {
slow = slow.next;
}
while (slow != null) {
int top = stack.pop().intValue();
if (top != slow.data) {
return false;
}
slow = slow.next;
}
return true;
}
public static void main(String[] args) {
int length = 9;
LinkedListNode[] nodes = new LinkedListNode[length];
for (int i = 0; i < length; i++) {
nodes[i] = new LinkedListNode(i >= length / 2 ? length - i - 1 : i, null, null);
}
for (int i = 0; i < length; i++) {
if (i < length - 1) {
nodes[i].setNext(nodes[i + 1]);
}
if (i > 0) {
nodes[i].setPrevious(nodes[i - 1]);
}
}
//nodes[length - 2].data = 9; // Uncomment to ruin palindrome
LinkedListNode head = nodes[0];
System.out.println(head.printForward());
System.out.println(isPalindrome(head));
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_06_Palindrome/QuestionC.java
================================================
package Q2_06_Palindrome;
import CtCILibrary.LinkedListNode;
public class QuestionC {
public static class Result {
public LinkedListNode node;
public boolean result;
public Result(LinkedListNode n, boolean res) {
node = n;
result = res;
}
}
public static Result isPalindromeRecurse(LinkedListNode head, int length) {
if (head == null || length <= 0) { // Even number of nodes
return new Result(head, true);
} else if (length == 1) { // Odd number of nodes
return new Result(head.next, true);
}
/* Recurse on sublist. */
Result res = isPalindromeRecurse(head.next, length - 2);
/* If child calls are not a palindrome, pass back up
* a failure. */
if (!res.result || res.node == null) {
return res;
}
/* Check if matches corresponding node on other side. */
res.result = (head.data == res.node.data);
/* Return corresponding node. */
res.node = res.node.next;
return res;
}
public static int lengthOfList(LinkedListNode n) {
int size = 0;
while (n != null) {
size++;
n = n.next;
}
return size;
}
public static boolean isPalindrome(LinkedListNode head) {
int length = lengthOfList(head);
Result p = isPalindromeRecurse(head, length);
return p.result;
}
public static void main(String[] args) {
int length = 9;
LinkedListNode[] nodes = new LinkedListNode[length];
for (int i = 0; i < length; i++) {
nodes[i] = new LinkedListNode(i >= length / 2 ? length - i - 1 : i, null, null);
}
for (int i = 0; i < length; i++) {
if (i < length - 1) {
nodes[i].setNext(nodes[i + 1]);
}
if (i > 0) {
nodes[i].setPrevious(nodes[i - 1]);
}
}
//nodes[length - 2].data = 9; // Uncomment to ruin palindrome
LinkedListNode head = nodes[0];
System.out.println(head.printForward());
System.out.println(isPalindrome(head));
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_06_Palindrome/Tester.java
================================================
package Q2_06_Palindrome;
import CtCILibrary.LinkedListNode;
public class Tester {
public static void main(String[] args) {
int max = 11;
for (int length = 1; length < max; length++) {
LinkedListNode[] nodes = new LinkedListNode[length];
for (int i = 0; i < length; i++) {
nodes[i] = new LinkedListNode(i >= length / 2 ? length - i - 1 : i, null, null);
}
for (int i = 0; i < length; i++) {
if (i < length - 1) {
nodes[i].setNext(nodes[i + 1]);
}
if (i > 0) {
nodes[i].setPrevious(nodes[i - 1]);
}
}
for (int i = -1; i < length; i++) {
if (i >= 0) {
nodes[i].data++; // Ruin palindrome
}
LinkedListNode head = nodes[0];
System.out.println(head.printForward());
boolean resultA = QuestionA.isPalindrome(head);
boolean resultB = QuestionB.isPalindrome(head);
boolean resultC = QuestionC.isPalindrome(head);
System.out.println("A: " + resultA);
System.out.println("B: " + resultB);
System.out.println("C: " + resultC);
if (resultA != resultB || resultB != resultC) {
System.out.println("ERROR");
length = max;
break;
}
if (i >= 0) {
nodes[i].data--;
}
}
}
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_07_Intersection/Question.java
================================================
package Q2_07_Intersection;
import CtCILibrary.AssortedMethods;
import CtCILibrary.LinkedListNode;
public class Question {
public static class Result {
public LinkedListNode tail;
public int size;
public Result(LinkedListNode tail, int size) {
this.tail = tail;
this.size = size;
}
}
public static Result getTailAndSize(LinkedListNode list) {
if (list == null) return null;
int size = 1;
LinkedListNode current = list;
while (current.next != null) {
size++;
current = current.next;
}
return new Result(current, size);
}
public static LinkedListNode getKthNode(LinkedListNode head, int k) {
LinkedListNode current = head;
while (k > 0 && current != null) {
current = current.next;
k--;
}
return current;
}
public static LinkedListNode findIntersection(LinkedListNode list1, LinkedListNode list2) {
if (list1 == null || list2 == null) return null;
/* Get tail and sizes. */
Result result1 = getTailAndSize(list1);
Result result2 = getTailAndSize(list2);
/* If different tail nodes, then there's no intersection. */
if (result1.tail != result2.tail) {
return null;
}
/* Set pointers to the start of each linked list. */
LinkedListNode shorter = result1.size < result2.size ? list1 : list2;
LinkedListNode longer = result1.size < result2.size ? list2 : list1;
/* Advance the pointer for the longer linked list by the difference in lengths. */
longer = getKthNode(longer, Math.abs(result1.size - result2.size));
/* Move both pointers until you have a collision. */
while (shorter != longer) {
shorter = shorter.next;
longer = longer.next;
}
/* Return either one. */
return longer;
}
public static void main(String[] args) {
/* Create linked list */
int[] vals = {-1, -2, 0, 1, 2, 3, 4, 5, 6, 7, 8};
LinkedListNode list1 = AssortedMethods.createLinkedListFromArray(vals);
int[] vals2 = {12, 14, 15};
LinkedListNode list2 = AssortedMethods.createLinkedListFromArray(vals2);
list2.next.next = list1.next.next.next.next;
System.out.println(list1.printForward());
System.out.println(list2.printForward());
LinkedListNode intersection = findIntersection(list1, list2);
System.out.println(intersection.printForward());
}
}
================================================
FILE: Java/Ch 02. Linked Lists/Q2_08_Loop_Detection/Question.java
================================================
package Q2_08_Loop_Detection;
import CtCILibrary.LinkedListNode;
public class Question {
public static LinkedListNode FindBeginning(LinkedListNode head) {
LinkedListNode slow = head;
LinkedListNode fast = head;
// Find meeting point
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
break;
}
}
// Error check - there is no meeting point, and therefore no loop
if (fast == null || fast.next == null) {
return null;
}
/* Move slow to Head. Keep fast at Meeting Point. Each are k steps
/* from the Loop Start. If they move at the same pace, they must
* meet at Loop Start. */
slow = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
// Both now point to the start of the loop.
return fast;
}
public static void main(String[] args) {
int list_length = 100;
int k = 10;
// Create linked list
LinkedListNode[] nodes = new LinkedListNode[list_length];
for (int i = 0; i < list_length; i++) {
nodes[i] = new LinkedListNode(i, null, i > 0 ? nodes[i - 1] : null);
}
// Create loop;
nodes[list_length - 1].next = nodes[list_length - k];
LinkedListNode loop = FindBeginning(nodes[0]);
if (loop == null) {
System.out.println("No Cycle.");
} else {
System.out.println(loop.data);
}
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Introduction/MyQueue.java
================================================
package Introduction;
import java.util.NoSuchElementException;
public class MyQueue {
private static class QueueNode {
private T data;
private QueueNode next;
public QueueNode(T data) {
this.data = data;
}
}
private QueueNode first;
private QueueNode last;
public void add(T item) {
QueueNode t = new QueueNode(item);
if (last != null) {
last.next = t;
}
last = t;
if (first == null) {
first = last;
}
}
public T remove() {
if (first == null) throw new NoSuchElementException();
T data = first.data;
first = first.next;
if (first == null) {
last = null;
}
return data;
}
public T peek() {
if (first == null) throw new NoSuchElementException();
return first.data;
}
public boolean isEmpty() {
return first == null;
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Introduction/MyStack.java
================================================
package Introduction;
import java.util.EmptyStackException;
public class MyStack {
private static class StackNode {
private T data;
private StackNode next;
public StackNode(T data) {
this.data = data;
}
public T getData() {
return data;
}
}
private StackNode top;
public T pop() {
if (top == null) throw new EmptyStackException();
T item = top.getData();
top = top.next;
return item;
}
public void push(T item) {
StackNode t = new StackNode(item);
t.next = top;
top = t;
}
public T peek() {
if (top == null) throw new EmptyStackException();
return top.data;
}
public boolean isEmpty() {
return top == null;
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Introduction/QueueTester.java
================================================
package Introduction;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Queue;
import CtCILibrary.AssortedMethods;
public class QueueTester {
public static void main(String[] args) {
int[] array = AssortedMethods.randomArray(100, -100, 100);
MyQueue queue1 = new MyQueue();
Queue queue2 = new LinkedList();
for (int a : array) {
if (a < 0) {
int top1, top2;
try {
top1 = queue1.remove();
} catch (NoSuchElementException ex) {
top1 = Integer.MIN_VALUE;
}
try {
top2 = queue2.remove();
} catch (NoSuchElementException ex) {
top2 = Integer.MIN_VALUE;
}
if (top1 != top2) {
System.out.println("ERROR: mismatching tails");
} else {
System.out.println("SUCCESS: matching tails: " + top1);
}
} else {
queue1.add(a);
queue2.add(a);
}
}
while (!queue1.isEmpty() || !queue2.isEmpty()) {
int top1, top2;
try {
top1 = queue1.remove();
} catch (NoSuchElementException ex) {
top1 = Integer.MIN_VALUE;
}
try {
top2 = queue2.remove();
} catch (NoSuchElementException ex) {
top2 = Integer.MIN_VALUE;
}
if (top1 != top2) {
System.out.println("ERROR: mismatching tails");
} else {
System.out.println("SUCCESS: matching tails: " + top1);
}
}
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Introduction/StackTester.java
================================================
package Introduction;
import java.util.EmptyStackException;
import java.util.Stack;
import CtCILibrary.AssortedMethods;
public class StackTester {
public static void main(String[] args) {
int[] array = AssortedMethods.randomArray(100, -100, 100);
MyStack stack1 = new MyStack();
Stack stack2 = new Stack();
for (int a : array) {
if (a < 0) {
int top1, top2;
try {
top1 = stack1.pop();
} catch (EmptyStackException ex) {
top1 = Integer.MIN_VALUE;
}
try {
top2 = stack2.pop();
} catch (EmptyStackException ex) {
top2 = Integer.MIN_VALUE;
}
if (top1 != top2) {
System.out.println("ERROR: mismatching tops");
} else {
System.out.println("SUCCESS: matching tops: " + top1);
}
} else {
stack1.push(a);
stack2.push(a);
}
}
while (!stack1.isEmpty() || !stack2.isEmpty()) {
int top1, top2;
try {
top1 = stack1.pop();
} catch (EmptyStackException ex) {
top1 = Integer.MIN_VALUE;
}
try {
top2 = stack2.pop();
} catch (EmptyStackException ex) {
top2 = Integer.MIN_VALUE;
}
if (top1 != top2) {
System.out.println("ERROR: mismatching tops");
} else {
System.out.println("SUCCESS: matching tops: " + top1);
}
}
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_01_Three_in_One/FixedMultiStack.java
================================================
package Q3_01_Three_in_One;
import java.util.EmptyStackException;
import CtCILibrary.AssortedMethods;
public class FixedMultiStack {
private int numberOfStacks = 3;
private int stackCapacity;
private int[] values;
private int[] sizes;
public FixedMultiStack(int stackSize) {
stackCapacity = stackSize;
values = new int[stackSize * numberOfStacks];
sizes = new int[numberOfStacks];
}
/* Push value onto stack. */
public void push(int stackNum, int value) throws FullStackException {
/* Check that we have space for the next element */
if (isFull(stackNum)) {
throw new FullStackException();
}
/* Increment stack pointer and then update top value. */
sizes[stackNum]++;
values[indexOfTop(stackNum)] = value;
}
/* Pop item from top stack. */
public int pop(int stackNum) {
if (isEmpty(stackNum)) {
throw new EmptyStackException();
}
int topIndex = indexOfTop(stackNum);
int value = values[topIndex]; // Get top
values[topIndex] = 0; // Clear
sizes[stackNum]--; // Shrink
return value;
}
/* Return top element. */
public int peek(int stackNum) {
if (isEmpty(stackNum)) {
throw new EmptyStackException();
}
return values[indexOfTop(stackNum)];
}
/* Return if stack is empty. */
public boolean isEmpty(int stackNum) {
return sizes[stackNum] == 0;
}
/* Return if stack is full. */
public boolean isFull(int stackNum) {
return sizes[stackNum] == stackCapacity;
}
/* Returns index of the top of the stack. */
private int indexOfTop(int stackNum) {
int offset = stackNum * stackCapacity;
int size = sizes[stackNum];
return offset + size - 1;
}
public int[] getValues() {
return values;
}
public int[] getStackValues(int stackNum) {
int[] items = new int[sizes[stackNum]];
for (int i = 0; i < items.length; i++) {
items[i] = values[stackNum * stackCapacity + i];
}
return items;
}
public String stackToString(int stackNum) {
int[] items = getStackValues(stackNum);
return stackNum + ": " + AssortedMethods.arrayToString(items);
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_01_Three_in_One/FullStackException.java
================================================
package Q3_01_Three_in_One;
public class FullStackException extends Exception {
private static final long serialVersionUID = 1L;
public FullStackException(){
super();
}
public FullStackException(String message){
super(message);
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_01_Three_in_One/MultiStack.java
================================================
package Q3_01_Three_in_One;
import java.util.EmptyStackException;
import CtCILibrary.AssortedMethods;
public class MultiStack {
/* StackInfo is a simple class that holds a set of data about
* each stack. It does not hold the actual items in the stack.
* We could have done this with just a bunch of individual
* variables, but that’s messy and doesn’t gain us much. */
private class StackInfo {
public int start, size, capacity;
public StackInfo(int start, int capacity) {
this.start = start;
this.capacity = capacity;
}
/* Check if an index on the full array is within the stack
* boundaries. The stack can wrap around to the start of
* the array. */
public boolean isWithinStackCapacity(int index) {
/* If outside of bounds of array, return false. */
if (index < 0 || index >= values.length) {
return false;
}
/* If index wraps around, adjust it. */
int contiguousIndex = index < start ? index + values.length : index;
int end = start + capacity;
return start <= contiguousIndex && contiguousIndex < end;
}
public int lastCapacityIndex() {
return adjustIndex(start + capacity - 1);
}
public int lastElementIndex() {
return adjustIndex(start + size - 1);
}
public boolean isFull() {
return size == capacity;
}
public boolean isEmpty() {
return size == 0;
}
}
private StackInfo[] info;
private int[] values;
public MultiStack(int numberOfStacks, int defaultSize) {
/* Create metadata for all the stacks. */
info = new StackInfo[numberOfStacks];
for (int i = 0; i < numberOfStacks; i++) {
info[i] = new StackInfo(defaultSize * i, defaultSize);
}
values = new int[numberOfStacks * defaultSize];
}
/* Returns the number of items actually present in stack. */
public int numberOfElements() {
int size = 0;
for (StackInfo sd : info) {
size += sd.size;
}
return size;
}
/* Returns true is all the stacks are full. */
public boolean allStacksAreFull() {
return numberOfElements() == values.length;
}
/* Adjust index to be within the range of 0 -> length - 1. */
private int adjustIndex(int index) {
/* Java's mod operator can return neg values. For example,
* (-11 % 5) will return -1, not 4. We actually want the
* value to be 4 (since we're wrapping around the index).
*/
int max = values.length;
return ((index % max) + max) % max;
}
/* Get index after this index, adjusted for wrap around. */
private int nextIndex(int index) {
return adjustIndex(index + 1);
}
/* Get index before this index, adjusted for wrap around. */
private int previousIndex(int index) {
return adjustIndex(index - 1);
}
/* Shift items in stack over by one element. If we have
* available capacity, then we'll end up shrinking the stack
* by one element. If we don't have available capacity, then
* we'll need to shift the next stack over too. */
private void shift(int stackNum) {
System.out.println("/// Shifting " + stackNum);
StackInfo stack = info[stackNum];
/* If this stack is at its full capacity, then you need
* to move the next stack over by one element. This stack
* can now claim the freed index. */
if (stack.size >= stack.capacity) {
int nextStack = (stackNum + 1) % info.length;
shift(nextStack);
stack.capacity++; // claim index that next stack lost
}
/* Shift all elements in stack over by one. */
int index = stack.lastCapacityIndex();
while (stack.isWithinStackCapacity(index)) {
values[index] = values[previousIndex(index)];
index = previousIndex(index);
}
/* Adjust stack data. */
values[stack.start] = 0; // Clear item
stack.start = nextIndex(stack.start); // move start
stack.capacity--; // Shrink capacity
}
/* Expand stack by shifting over other stacks */
private void expand(int stackNum) {
System.out.println("/// Expanding stack " + stackNum);
shift((stackNum + 1) % info.length);
info[stackNum].capacity++;
}
/* Push value onto stack num, shifting/expanding stacks as
* necessary. Throws exception if all stacks are full. */
public void push(int stackNum, int value) throws FullStackException {
System.out.println("/// Pushing stack " + stackNum + ": " + value);
if (allStacksAreFull()) {
throw new FullStackException();
}
/* If this stack is full, expand it. */
StackInfo stack = info[stackNum];
if (stack.isFull()) {
expand(stackNum);
}
/* Find the index of the top element in the array + 1,
* and increment the stack pointer */
stack.size++;
values[stack.lastElementIndex()] = value;
}
/* Remove value from stack. */
public int pop(int stackNum) throws Exception {
System.out.println("/// Popping stack " + stackNum);
StackInfo stack = info[stackNum];
if (stack.isEmpty()) {
throw new EmptyStackException();
}
/* Remove last element. */
int value = values[stack.lastElementIndex()];
values[stack.lastElementIndex()] = 0; // Clear item
stack.size--; // Shrink size
return value;
}
/* Get top element of stack.*/
public int peek(int stackNum) {
StackInfo stack = info[stackNum];
return values[stack.lastElementIndex()];
}
public int[] getValues() {
return values;
}
public int[] getStackValues(int stackNum) {
StackInfo stack = info[stackNum];
int[] items = new int[stack.size];
for (int i = 0; i < items.length; i++) {
items[i] = values[adjustIndex(stack.start + i)];
}
return items;
}
public String stackToString(int stackNum) {
int[] items = getStackValues(stackNum);
return stackNum + ": " + AssortedMethods.arrayToString(items);
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_01_Three_in_One/QuestionA.java
================================================
package Q3_01_Three_in_One;
import CtCILibrary.AssortedMethods;
public class QuestionA {
public static void printStacks(FixedMultiStack stacks) {
System.out.println(AssortedMethods.arrayToString(stacks.getValues()));
}
public static void main(String [] args) throws Exception {
FixedMultiStack stacks = new FixedMultiStack(4);
printStacks(stacks);
stacks.push(0, 10);
printStacks(stacks);
stacks.push(1, 20);
printStacks(stacks);
stacks.push(2, 30);
printStacks(stacks);
stacks.push(1, 21);
printStacks(stacks);
stacks.push(0, 11);
printStacks(stacks);
stacks.push(0, 12);
printStacks(stacks);
stacks.pop(0);
printStacks(stacks);
stacks.push(2, 31);
printStacks(stacks);
stacks.push(0, 13);
printStacks(stacks);
stacks.push(1, 22);
printStacks(stacks);
stacks.push(2, 31);
printStacks(stacks);
stacks.push(2, 32);
printStacks(stacks);
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_01_Three_in_One/QuestionB.java
================================================
package Q3_01_Three_in_One;
import CtCILibrary.AssortedMethods;
public class QuestionB {
public static void printStacks(MultiStack stacks) {
//System.out.println(stacks.stackToString(0));
//System.out.println(stacks.stackToString(1));
//System.out.println(stacks.stackToString(2));
System.out.println(AssortedMethods.arrayToString(stacks.getValues()));
}
public static void main(String [] args) throws Exception {
MultiStack stacks = new MultiStack(3, 4);
printStacks(stacks);
stacks.push(0, 10);
printStacks(stacks);
stacks.push(1, 20);
printStacks(stacks);
stacks.push(2, 30);
printStacks(stacks);
stacks.push(1, 21);
printStacks(stacks);
stacks.push(0, 11);
printStacks(stacks);
stacks.push(0, 12);
printStacks(stacks);
stacks.pop(0);
printStacks(stacks);
stacks.push(2, 31);
printStacks(stacks);
stacks.push(0, 13);
printStacks(stacks);
stacks.push(1, 22);
printStacks(stacks);
stacks.push(2, 31);
printStacks(stacks);
stacks.push(2, 32);
printStacks(stacks);
stacks.push(2, 33);
printStacks(stacks);
stacks.push(2, 34);
printStacks(stacks);
stacks.pop(1);
printStacks(stacks);
stacks.push(2, 35);
printStacks(stacks);
System.out.println("Final Stack: " + AssortedMethods.arrayToString(stacks.getValues()));
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_02_Stack_Min/NodeWithMin.java
================================================
package Q3_02_Stack_Min;
class NodeWithMin {
public int value;
public int min;
public NodeWithMin(int v, int min){
value = v;
this.min = min;
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_02_Stack_Min/Question.java
================================================
package Q3_02_Stack_Min;
public class Question {
public static void main(String[] args) {
StackWithMin stack = new StackWithMin();
StackWithMin2 stack2 = new StackWithMin2();
int[] array = {2, 1, 3, 1};
for (int value : array) {
stack.push(value);
stack2.push(value);
System.out.print(value + ", ");
}
System.out.println('\n');
for (int i = 0; i < array.length; i++) {
System.out.println("Popped " + stack.pop().value + ", " + stack2.pop());
System.out.println("New min is " + stack.min() + ", " + stack2.min());
}
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_02_Stack_Min/StackWithMin.java
================================================
package Q3_02_Stack_Min;
import java.util.Stack;
public class StackWithMin extends Stack {
public void push(int value) {
int newMin = Math.min(value, min());
super.push(new NodeWithMin(value, newMin));
}
public int min() {
if (this.isEmpty()) {
return Integer.MAX_VALUE;
} else {
return peek().min;
}
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_02_Stack_Min/StackWithMin2.java
================================================
package Q3_02_Stack_Min;
import java.util.Stack;
public class StackWithMin2 extends Stack {
Stack s2;
public StackWithMin2() {
s2 = new Stack();
}
public void push(int value){
if (value <= min()) {
s2.push(value);
}
super.push(value);
}
public Integer pop() {
int value = super.pop();
if (value == min()) {
s2.pop();
}
return value;
}
public int min() {
if (s2.isEmpty()) {
return Integer.MAX_VALUE;
} else {
return s2.peek();
}
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_03_Stack_of_Plates/Node.java
================================================
package Q3_03_Stack_of_Plates;
public class Node {
public Node above;
public Node below;
public int value;
public Node(int value) {
this.value = value;
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_03_Stack_of_Plates/Question.java
================================================
package Q3_03_Stack_of_Plates;
public class Question {
public static void main(String[] args) {
int capacity_per_substack = 5;
SetOfStacks set = new SetOfStacks(capacity_per_substack);
for (int i = 0; i < 34; i++) {
set.push(i);
}
for (int i = 0; i < 35; i++) {
System.out.println("Popped " + set.pop());
}
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_03_Stack_of_Plates/SetOfStacks.java
================================================
package Q3_03_Stack_of_Plates;
import java.util.ArrayList;
import java.util.EmptyStackException;
public class SetOfStacks {
ArrayList stacks = new ArrayList();
public int capacity;
public SetOfStacks(int capacity) {
this.capacity = capacity;
}
public Stack getLastStack() {
if (stacks.size() == 0) {
return null;
}
return stacks.get(stacks.size() - 1);
}
public void push(int v) {
Stack last = getLastStack();
if (last != null && !last.isFull()) { // add to last
last.push(v);
} else { // must create new stack
Stack stack = new Stack(capacity);
stack.push(v);
stacks.add(stack);
}
}
public int pop() {
Stack last = getLastStack();
if (last == null) throw new EmptyStackException();
int v = last.pop();
if (last.size == 0) {
stacks.remove(stacks.size() - 1);
}
return v;
}
public int popAt(int index) {
return leftShift(index, true);
}
public int leftShift(int index, boolean removeTop) {
Stack stack = stacks.get(index);
int removed_item;
if (removeTop) removed_item = stack.pop();
else removed_item = stack.removeBottom();
if (stack.isEmpty()) {
stacks.remove(index);
} else if (stacks.size() > index + 1) {
int v = leftShift(index + 1, false);
stack.push(v);
}
return removed_item;
}
public boolean isEmpty() {
Stack last = getLastStack();
return last == null || last.isEmpty();
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_03_Stack_of_Plates/Stack.java
================================================
package Q3_03_Stack_of_Plates;
import java.util.EmptyStackException;
public class Stack {
private int capacity;
public Node top;
public Node bottom;
public int size = 0;
public Stack(int capacity) {
this.capacity = capacity;
}
public boolean isFull() {
return capacity == size;
}
public void join(Node above, Node below) {
if (below != null) below.above = above;
if (above != null) above.below = below;
}
public boolean push(int v) {
if (size >= capacity) return false;
size++;
Node n = new Node(v);
if (size == 1) bottom = n;
join(n, top);
top = n;
return true;
}
public int pop() {
if (top == null) throw new EmptyStackException();
Node t = top;
top = top.below;
size--;
return t.value;
}
public boolean isEmpty() {
return size == 0;
}
public int removeBottom() {
Node b = bottom;
bottom = bottom.above;
if (bottom != null) bottom.below = null;
size--;
return b.value;
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_04_Queue_via_Stacks/MyQueue.java
================================================
package Q3_04_Queue_via_Stacks;
import java.util.Stack;
public class MyQueue {
Stack stackNewest, stackOldest;
public MyQueue() {
stackNewest = new Stack();
stackOldest = new Stack();
}
public int size() {
return stackNewest.size() + stackOldest.size();
}
public void add(T value) {
// Push onto stack1
stackNewest.push(value);
}
/* Move elements from stackNewest into stackOldest. This is usually done so that we can
* do operations on stackOldest.
*/
private void shiftStacks() {
if (stackOldest.isEmpty()) {
while (!stackNewest.isEmpty()) {
stackOldest.push(stackNewest.pop());
}
}
}
public T peek() {
shiftStacks();
return stackOldest.peek(); // retrieve the oldest item.
}
public T remove() {
shiftStacks();
return stackOldest.pop(); // pop the oldest item.
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_04_Queue_via_Stacks/Question.java
================================================
package Q3_04_Queue_via_Stacks;
import java.util.LinkedList;
import java.util.Queue;
import CtCILibrary.AssortedMethods;
public class Question {
public static void main(String[] args) {
MyQueue my_queue = new MyQueue();
// Let's test our code against a "real" queue
Queue test_queue = new LinkedList();
for (int i = 0; i < 100; i++) {
int choice = AssortedMethods.randomIntInRange(0, 10);
if (choice <= 5) { // enqueue
int element = AssortedMethods.randomIntInRange(1, 10);
test_queue.add(element);
my_queue.add(element);
System.out.println("Enqueued " + element);
} else if (test_queue.size() > 0) {
int top1 = test_queue.remove();
int top2 = my_queue.remove();
if (top1 != top2) { // Check for error
System.out.println("******* FAILURE - DIFFERENT TOPS: " + top1 + ", " + top2);
}
System.out.println("Dequeued " + top1);
}
if (test_queue.size() == my_queue.size()) {
if (test_queue.size() > 0 && test_queue.peek() != my_queue.peek()) {
System.out.println("******* FAILURE - DIFFERENT TOPS: " + test_queue.peek() + ", " + my_queue.peek() + " ******");
}
} else {
System.out.println("******* FAILURE - DIFFERENT SIZES ******");
}
}
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_05_Sort_Stack/Question.java
================================================
package Q3_05_Sort_Stack;
import java.util.Stack;
import CtCILibrary.AssortedMethods;
public class Question {
public static Stack mergesort(Stack inStack) {
if (inStack.size() <= 1) {
return inStack;
}
Stack left = new Stack();
Stack right = new Stack();
int count = 0;
while (inStack.size() != 0) {
count++;
if (count % 2 == 0) {
left.push(inStack.pop());
} else {
right.push(inStack.pop());
}
}
left = mergesort(left);
right = mergesort(right);
while (left.size() > 0 || right.size() > 0) {
if (left.size() == 0) {
inStack.push(right.pop());
} else if (right.size() == 0) {
inStack.push(left.pop());
} else if (right.peek().compareTo(left.peek()) <= 0) {
inStack.push(left.pop());
} else {
inStack.push(right.pop());
}
}
Stack reverseStack = new Stack();
while (inStack.size() > 0) {
reverseStack.push(inStack.pop());
}
return reverseStack;
}
public static void sort(Stack s) {
Stack r = new Stack();
while(!s.isEmpty()) {
/* Insert each element in s in sorted order into r. */
int tmp = s.pop();
while(!r.isEmpty() && r.peek() > tmp) {
s.push(r.pop());
}
r.push(tmp);
}
/* Copy the elements back. */
while (!r.isEmpty()) {
s.push(r.pop());
}
}
public static void main(String [] args) {
Stack s = new Stack();
for (int i = 0; i < 10; i++) {
int r = AssortedMethods.randomIntInRange(0, 1000);
s.push(r);
}
sort(s);
while(!s.isEmpty()) {
System.out.println(s.pop());
}
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_06_Animal_Shelter/Animal.java
================================================
package Q3_06_Animal_Shelter;
public abstract class Animal {
private int order;
protected String name;
public Animal(String n) {
name = n;
}
public abstract String name();
public void setOrder(int ord) {
order = ord;
}
public int getOrder() {
return order;
}
public boolean isOlderThan(Animal a) {
return this.order < a.getOrder();
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_06_Animal_Shelter/AnimalQueue.java
================================================
package Q3_06_Animal_Shelter;
import java.util.LinkedList;
public class AnimalQueue {
LinkedList dogs = new LinkedList();
LinkedList cats = new LinkedList();
private int order = 0;
public void enqueue(Animal a) {
a.setOrder(order);
order++;
if (a instanceof Dog) {
dogs.addLast((Dog) a);
} else if (a instanceof Cat) {
cats.addLast((Cat)a);
}
}
public Animal dequeueAny() {
if (dogs.size() == 0) {
return dequeueCats();
} else if (cats.size() == 0) {
return dequeueDogs();
}
Dog dog = dogs.peek();
Cat cat = cats.peek();
if (dog.isOlderThan(cat)) {
return dogs.poll();
} else {
return cats.poll();
}
}
public Animal peek() {
if (dogs.size() == 0) {
return cats.peek();
} else if (cats.size() == 0) {
return dogs.peek();
}
Dog dog = dogs.peek();
Cat cat = cats.peek();
if (dog.isOlderThan(cat)) {
return dog;
} else {
return cat;
}
}
public int size() {
return dogs.size() + cats.size();
}
public Dog dequeueDogs() {
return dogs.poll();
}
public Dog peekDogs() {
return dogs.peek();
}
public Cat dequeueCats() {
return cats.poll();
}
public Cat peekCats() {
return cats.peek();
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_06_Animal_Shelter/Cat.java
================================================
package Q3_06_Animal_Shelter;
public class Cat extends Animal {
public Cat(String n) {
super(n);
}
public String name() {
return "Cat: " + name;
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_06_Animal_Shelter/Dog.java
================================================
package Q3_06_Animal_Shelter;
public class Dog extends Animal {
public Dog(String n) {
super(n);
}
public String name() {
return "Dog: " + name;
}
}
================================================
FILE: Java/Ch 03. Stacks and Queues/Q3_06_Animal_Shelter/Question.java
================================================
package Q3_06_Animal_Shelter;
public class Question {
public static void main(String[] args) {
AnimalQueue animals = new AnimalQueue();
animals.enqueue(new Cat("Callie"));
animals.enqueue(new Cat("Kiki"));
animals.enqueue(new Dog("Fido"));
animals.enqueue(new Dog("Dora"));
animals.enqueue(new Cat("Kari"));
animals.enqueue(new Dog("Dexter"));
animals.enqueue(new Dog("Dobo"));
animals.enqueue(new Cat("Copa"));
System.out.println(animals.dequeueAny().name());
System.out.println(animals.dequeueAny().name());
System.out.println(animals.dequeueAny().name());
animals.enqueue(new Dog("Dapa"));
animals.enqueue(new Cat("Kilo"));
while (animals.size() != 0) {
System.out.println(animals.dequeueAny().name());
}
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Introduction/Traversals.java
================================================
package Introduction;
import CtCILibrary.TreeNode;
public class Traversals {
public static void visit(TreeNode node) {
if (node != null) {
System.out.println(node.data);
}
}
public static void inOrderTraversal(TreeNode node) {
if (node != null) {
inOrderTraversal(node.left);
visit(node);
inOrderTraversal(node.right);
}
}
public static void preOrderTraversal(TreeNode node) {
if (node != null) {
visit(node);
inOrderTraversal(node.left);
inOrderTraversal(node.right);
}
}
public static void postOrderTraversal(TreeNode node) {
if (node != null) {
inOrderTraversal(node.left);
inOrderTraversal(node.right);
visit(node);
}
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// We needed this code for other files, so check out the code in the library
TreeNode root = TreeNode.createMinimalBST(array);
inOrderTraversal(root);
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_01_Route_Between_Nodes/Graph.java
================================================
package Q4_01_Route_Between_Nodes;
public class Graph {
public static int MAX_VERTICES = 6;
private Node vertices[];
public int count;
public Graph() {
vertices = new Node[MAX_VERTICES];
count = 0;
}
public void addNode(Node x) {
if (count < vertices.length) {
vertices[count] = x;
count++;
} else {
System.out.print("Graph full");
}
}
public Node[] getNodes() {
return vertices;
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_01_Route_Between_Nodes/Node.java
================================================
package Q4_01_Route_Between_Nodes;
class Node {
private Node adjacent[];
public int adjacentCount;
private String vertex;
public Question.State state;
public Node(String vertex, int adjacentLength) {
this.vertex = vertex;
adjacentCount = 0;
adjacent = new Node[adjacentLength];
}
public void addAdjacent(Node x) {
if (adjacentCount < adjacent.length) {
this.adjacent[adjacentCount] = x;
adjacentCount++;
} else {
System.out.print("No more adjacent can be added");
}
}
public Node[] getAdjacent() {
return adjacent;
}
public String getVertex() {
return vertex;
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_01_Route_Between_Nodes/Question.java
================================================
package Q4_01_Route_Between_Nodes;
import java.util.LinkedList;
public class Question {
public enum State {
Unvisited, Visited, Visiting;
}
public static void main(String a[])
{
Graph g = createNewGraph();
Node[] n = g.getNodes();
Node start = n[3];
Node end = n[5];
System.out.println(search(g, start, end));
}
public static Graph createNewGraph()
{
Graph g = new Graph();
Node[] temp = new Node[6];
temp[0] = new Node("a", 3);
temp[1] = new Node("b", 0);
temp[2] = new Node("c", 0);
temp[3] = new Node("d", 1);
temp[4] = new Node("e", 1);
temp[5] = new Node("f", 0);
temp[0].addAdjacent(temp[1]);
temp[0].addAdjacent(temp[2]);
temp[0].addAdjacent(temp[3]);
temp[3].addAdjacent(temp[4]);
temp[4].addAdjacent(temp[5]);
for (int i = 0; i < 6; i++) {
g.addNode(temp[i]);
}
return g;
}
public static boolean search(Graph g,Node start,Node end) {
LinkedList q = new LinkedList();
for (Node u : g.getNodes()) {
u.state = State.Unvisited;
}
start.state = State.Visiting;
q.add(start);
Node u;
while(!q.isEmpty()) {
u = q.removeFirst();
if (u != null) {
for (Node v : u.getAdjacent()) {
if (v.state == State.Unvisited) {
if (v == end) {
return true;
} else {
v.state = State.Visiting;
q.add(v);
}
}
}
u.state = State.Visited;
}
}
return false;
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_02_Minimal_Tree/Question.java
================================================
package Q4_02_Minimal_Tree;
import CtCILibrary.TreeNode;
public class Question {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// We needed this code for other files, so check out the code in the library
TreeNode root = TreeNode.createMinimalBST(array);
System.out.println("Root? " + root.data);
System.out.println("Created BST? " + root.isBST());
System.out.println("Height: " + root.height());
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_03_List_of_Depths/QuestionBFS.java
================================================
package Q4_03_List_of_Depths;
import CtCILibrary.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
public class QuestionBFS {
public static ArrayList> createLevelLinkedList(TreeNode root) {
ArrayList> result = new ArrayList>();
/* "Visit" the root */
LinkedList current = new LinkedList();
if (root != null) {
current.add(root);
}
while (current.size() > 0) {
result.add(current); // Add previous level
LinkedList parents = current; // Go to next level
current = new LinkedList();
for (TreeNode parent : parents) {
/* Visit the children */
if (parent.left != null) {
current.add(parent.left);
}
if (parent.right != null) {
current.add(parent.right);
}
}
}
return result;
}
public static void printResult(ArrayList> result){
int depth = 0;
for(LinkedList entry : result) {
Iterator i = entry.listIterator();
System.out.print("Link list at depth " + depth + ":");
while(i.hasNext()){
System.out.print(" " + ((TreeNode)i.next()).data);
}
System.out.println();
depth++;
}
}
public static void main(String[] args) {
int[] nodes_flattened = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = AssortedMethods.createTreeFromArray(nodes_flattened);
ArrayList> list = createLevelLinkedList(root);
printResult(list);
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_03_List_of_Depths/QuestionDFS.java
================================================
package Q4_03_List_of_Depths;
import CtCILibrary.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
public class QuestionDFS {
public static void createLevelLinkedList(TreeNode root, ArrayList> lists, int level) {
if (root == null) return;
LinkedList list = null;
if (lists.size() == level) { // Level not contained in list
list = new LinkedList();
/* Levels are always traversed in order. So, if this is the first time we've visited level i,
* we must have seen levels 0 through i - 1. We can therefore safely add the level at the end. */
lists.add(list);
} else {
list = lists.get(level);
}
list.add(root);
createLevelLinkedList(root.left, lists, level + 1);
createLevelLinkedList(root.right, lists, level + 1);
}
public static ArrayList> createLevelLinkedList(TreeNode root) {
ArrayList> lists = new ArrayList>();
createLevelLinkedList(root, lists, 0);
return lists;
}
public static void printResult(ArrayList> result){
int depth = 0;
for(LinkedList entry : result) {
Iterator i = entry.listIterator();
System.out.print("Link list at depth " + depth + ":");
while(i.hasNext()){
System.out.print(" " + ((TreeNode)i.next()).data);
}
System.out.println();
depth++;
}
}
public static void main(String[] args) {
int[] nodes_flattened = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = AssortedMethods.createTreeFromArray(nodes_flattened);
ArrayList> list = createLevelLinkedList(root);
printResult(list);
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_04_Check_Balanced/QuestionBrute.java
================================================
package Q4_04_Check_Balanced;
import CtCILibrary.AssortedMethods;
import CtCILibrary.TreeNode;
public class QuestionBrute {
public static int getHeight(TreeNode root) {
if (root == null) {
return -1;
}
return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
}
public static boolean isBalanced(TreeNode root) {
if (root == null) {
return true;
}
int heightDiff = getHeight(root.left) - getHeight(root.right);
if (Math.abs(heightDiff) > 1) {
return false;
}
else {
return isBalanced(root.left) && isBalanced(root.right);
}
}
public static void main(String[] args) {
// Create balanced tree
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = TreeNode.createMinimalBST(array);
System.out.println("Root? " + root.data);
System.out.println("Is balanced? " + isBalanced(root));
// Could be balanced, actually, but it's very unlikely...
TreeNode unbalanced = new TreeNode(10);
for (int i = 0; i < 10; i++) {
unbalanced.insertInOrder(AssortedMethods.randomIntInRange(0, 100));
}
System.out.println("Root? " + unbalanced.data);
System.out.println("Is balanced? " + isBalanced(unbalanced));
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_04_Check_Balanced/QuestionImproved.java
================================================
package Q4_04_Check_Balanced;
import CtCILibrary.TreeNode;
public class QuestionImproved {
public static int checkHeight(TreeNode root) {
if (root == null) {
return -1;
}
int leftHeight = checkHeight(root.left);
if (leftHeight == Integer.MIN_VALUE) return Integer.MIN_VALUE; // Propagate error up
int rightHeight = checkHeight(root.right);
if (rightHeight == Integer.MIN_VALUE) return Integer.MIN_VALUE; // Propagate error up
int heightDiff = leftHeight - rightHeight;
if (Math.abs(heightDiff) > 1) {
return Integer.MIN_VALUE; // Found error -> pass it back
} else {
return Math.max(leftHeight, rightHeight) + 1;
}
}
public static boolean isBalanced(TreeNode root) {
return checkHeight(root) != Integer.MIN_VALUE;
}
public static void main(String[] args) {
// Create balanced tree
int[] array = {0, 1, 2, 3, 5, 6, 7, 8, 9, 10};
TreeNode root = TreeNode.createMinimalBST(array);
System.out.println("Is balanced? " + isBalanced(root));
root.insertInOrder(4); // Add 4 to make it unbalanced
System.out.println("Is balanced? " + isBalanced(root));
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_05_Validate_BST/IntWrapper.java
================================================
package Q4_05_Validate_BST;
public class IntWrapper {
public IntWrapper(int m) {
data = m;
}
public int data;
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_05_Validate_BST/Question.java
================================================
package Q4_05_Validate_BST;
import CtCILibrary.TreeNode;
public class Question {
public static Integer lastPrinted = null;
public static boolean checkBST(TreeNode node) {
return checkBST(node, true);
}
// Allow "equal" value only for left child. This validates the BST property.
public static boolean checkBST(TreeNode n, boolean isLeft) {
if (n == null) {
return true;
}
// Check / recurse left
if (!checkBST(n.left, true)) {
return false;
}
// Check current
if (lastPrinted != null) {
if (isLeft) {
// left child "is allowed" be equal to parent.
if (n.data < lastPrinted) {
return false;
}
} else {
// Right child "is not allowed" be equal to parent.
if (n.data <= lastPrinted) {
return false;
}
}
}
lastPrinted = n.data;
// Check / recurse right
if (!checkBST(n.right, false)) {
return false;
}
return true;
}
public static void main(String[] args) {
int[] array = {Integer.MIN_VALUE, Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1, Integer.MAX_VALUE};
TreeNode node = TreeNode.createMinimalBST(array);
//node.left.data = 5;
//node.left.right.data = 3;
System.out.println(checkBST(node));
test();
}
public static void test() {
TreeNode node;
boolean condition;
System.out.println("test cases for equals condition.");
/* Expect true: for left child: node.data <= last_printed.
2
/ \
/ \
2 3
\
4
*/
int[] array2 = {1, 2, 3, 4};
node = TreeNode.createMinimalBST(array2);
node.left.data = 2;
node.print();
lastPrinted = null;
condition = checkBST(node);
System.out.println("should be true: " + condition);
/* Expect false: for right child: node.data <= last_printed.
2
/ \
/ \
1 2
\
4
*/
int[] array3 = {1, 2, 3, 4};
node = TreeNode.createMinimalBST(array3);
node.right.data = 2;
node.print();
lastPrinted = null;
condition = checkBST(node);
System.out.println("should be false: " + condition);
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_05_Validate_BST/QuestionB.java
================================================
package Q4_05_Validate_BST;
import CtCILibrary.AssortedMethods;
import CtCILibrary.TreeNode;
public class QuestionB {
public static boolean checkBST(TreeNode n, Integer min, Integer max) {
if (n == null) {
return true;
}
if ((min != null && n.data <= min) || (max != null && n.data > max)) {
return false;
}
if (!checkBST(n.left, min, n.data) ||
!checkBST(n.right, n.data, max)) {
return false;
}
return true;
}
public static boolean checkBST(TreeNode n) {
return checkBST(n, null, null);
}
public static boolean checkBSTAlternate(TreeNode n) {
return checkBSTAlternate(n, new IntWrapper(0), new IntWrapper(0));
}
public static boolean checkBSTAlternate(TreeNode n, IntWrapper min, IntWrapper max) {
/* An alternate, less clean approach. This is not provided in the book, but is used to test the other method. */
if (n.left == null) {
min.data = n.data;
} else {
IntWrapper leftMin = new IntWrapper(0);
IntWrapper leftMax = new IntWrapper(0);
if (!checkBSTAlternate(n.left, leftMin, leftMax)) {
return false;
}
if (leftMax.data > n.data) {
return false;
}
min.data = leftMin.data;
}
if (n.right == null) {
max.data = n.data;
} else {
IntWrapper rightMin = new IntWrapper(0);
IntWrapper rightMax = new IntWrapper(0);
if (!checkBSTAlternate(n.right, rightMin, rightMax)) {
return false;
}
if (rightMin.data <= n.data) {
return false;
}
max.data = rightMax.data;
}
return true;
}
/* Create a tree that may or may not be a BST */
public static TreeNode createTestTree() {
/* Create a random BST */
TreeNode head = AssortedMethods.randomBST(10, -10, 10);
/* Insert an element into the BST and potentially ruin the BST property */
TreeNode node = head;
do {
int n = AssortedMethods.randomIntInRange(-10, 10);
int rand = AssortedMethods.randomIntInRange(0, 5);
if (rand == 0) {
node.data = n;
} else if (rand == 1) {
node = node.left;
} else if (rand == 2) {
node = node.right;
} else if (rand == 3 || rand == 4) {
break;
}
} while (node != null);
return head;
}
public static void main(String[] args) {
/* Simple test -- create one */
int[] array = {Integer.MIN_VALUE, 3, 5, 6, 10, 13, 15, Integer.MAX_VALUE};
TreeNode node = TreeNode.createMinimalBST(array);
//node.left.data = 6; // "ruin" the BST property by changing one of the elements
node.print();
boolean isBst = checkBST(node);
System.out.println(isBst);
/* More elaborate test -- creates 100 trees (some BST, some not) and compares the outputs of various methods. */
/*for (int i = 0; i < 100; i++) {
TreeNode head = createTestTree();
// Compare results
boolean isBst1 = checkBST(head);
boolean isBst2 = checkBSTAlternate(head);
if (isBst1 != isBst2) {
System.out.println("*********************** ERROR *******************");
head.print();
break;
} else {
System.out.println(isBst1 + " | " + isBst2);
head.print();
}
}*/
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_06_Successor/Question.java
================================================
package Q4_06_Successor;
import CtCILibrary.TreeNode;
public class Question {
public static TreeNode inorderSucc(TreeNode n) {
if (n == null) return null;
// Found right children -> return left most node of right subtree
if (n.parent == null || n.right != null) {
return leftMostChild(n.right);
} else {
TreeNode q = n;
TreeNode x = q.parent;
// Go up until we're on left instead of right
while (x != null && x.left != q) {
q = x;
x = x.parent;
}
return x;
}
}
public static TreeNode leftMostChild(TreeNode n) {
if (n == null) {
return null;
}
while (n.left != null) {
n = n.left;
}
return n;
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = TreeNode.createMinimalBST(array);
for (int i = 0; i < array.length; i++) {
TreeNode node = root.find(array[i]);
TreeNode next = inorderSucc(node);
if (next != null) {
System.out.println(node.data + "->" + next.data);
} else {
System.out.println(node.data + "->" + null);
}
}
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/DFS/Graph.java
================================================
package Q4_07_Build_Order.DFS;
import java.util.ArrayList;
import java.util.HashMap;
public class Graph {
private ArrayList nodes = new ArrayList();
private HashMap map = new HashMap();
public Project getOrCreateNode(String name) {
if (!map.containsKey(name)) {
Project node = new Project(name);
nodes.add(node);
map.put(name, node);
}
return map.get(name);
}
public void addEdge(String startName, String endName) {
Project start = getOrCreateNode(startName);
Project end = getOrCreateNode(endName);
start.addNeighbor(end);
}
public ArrayList getNodes() {
return nodes;
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/DFS/Project.java
================================================
package Q4_07_Build_Order.DFS;
import java.util.ArrayList;
import java.util.HashMap;
public class Project {
public enum State {COMPLETE, PARTIAL, BLANK};
private ArrayList children = new ArrayList();
private HashMap map = new HashMap();
private String name;
private State state = State.BLANK;
public Project(String n) {
name = n;
}
public String getName() {
return name;
}
public void addNeighbor(Project node) {
if (!map.containsKey(node.getName())) {
children.add(node);
map.put(node.getName(), node);
}
}
public State getState() {
return state;
}
public void setState(State st) {
state = st;
}
public ArrayList getChildren() {
return children;
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/DFS/Question.java
================================================
package Q4_07_Build_Order.DFS;
import java.util.ArrayList;
import java.util.Stack;
public class Question {
/* Build the graph, adding the edge (a, b) if b is dependent on a.
* Assumes a pair is listed in “build order” (which is the reverse
* of dependency order). The pair (a, b) in dependencies indicates
* that b depends on a and a must be built before a. */
public static Graph buildGraph(String[] projects, String[][] dependencies) {
Graph graph = new Graph();
for (String[] dependency : dependencies) {
String first = dependency[0];
String second = dependency[1];
graph.addEdge(first, second);
}
return graph;
}
public static boolean doDFS(Project project, Stack stack) {
if (project.getState() == Project.State.PARTIAL) {
return false; // Cycle
}
if (project.getState() == Project.State.BLANK) {
project.setState(Project.State.PARTIAL);
ArrayList children = project.getChildren();
for (Project child : children) {
if (!doDFS(child, stack)) {
return false;
}
}
project.setState(Project.State.COMPLETE);
stack.push(project);
}
return true;
}
public static Stack orderProjects(ArrayList projects) {
Stack stack = new Stack();
for (Project project : projects) {
if (project.getState() == Project.State.BLANK) {
if (!doDFS(project, stack)) {
return null;
}
}
}
return stack;
}
public static String[] convertToStringList(Stack projects) {
String[] buildOrder = new String[projects.size()];
for (int i = 0; i < buildOrder.length; i++) {
buildOrder[i] = projects.pop().getName();
}
return buildOrder;
}
public static Stack findBuildOrder(String[] projects, String[][] dependencies) {
Graph graph = buildGraph(projects, dependencies);
return orderProjects(graph.getNodes());
}
public static String[] buildOrderWrapper(String[] projects, String[][] dependencies) {
Stack buildOrder = findBuildOrder(projects, dependencies);
if (buildOrder == null) return null;
String[] buildOrderString = convertToStringList(buildOrder);
return buildOrderString;
}
public static void main(String[] args) {
String[] projects = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"};
String[][] dependencies = {
{"a", "b"},
{"b", "c"},
{"a", "c"},
{"d", "e"},
{"b", "d"},
{"e", "f"},
{"a", "f"},
{"h", "i"},
{"h", "j"},
{"i", "j"},
{"g", "j"}};
String[] buildOrder = buildOrderWrapper(projects, dependencies);
if (buildOrder == null) {
System.out.println("Circular Dependency.");
} else {
for (String s : buildOrder) {
System.out.println(s);
}
}
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/EdgeRemoval/Graph.java
================================================
package Q4_07_Build_Order.EdgeRemoval;
import java.util.ArrayList;
import java.util.HashMap;
public class Graph {
private ArrayList nodes = new ArrayList();
private HashMap map = new HashMap();
public Project getOrCreateNode(String name) {
if (!map.containsKey(name)) {
Project node = new Project(name);
nodes.add(node);
map.put(name, node);
}
return map.get(name);
}
public void addEdge(String startName, String endName) {
Project start = getOrCreateNode(startName);
Project end = getOrCreateNode(endName);
start.addNeighbor(end);
}
public ArrayList getNodes() {
return nodes;
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/EdgeRemoval/Project.java
================================================
package Q4_07_Build_Order.EdgeRemoval;
import java.util.ArrayList;
import java.util.HashMap;
public class Project {
private ArrayList children = new ArrayList();
private HashMap map = new HashMap();
private String name;
private int dependencies = 0;
public Project(String n) {
name = n;
}
public String getName() {
return name;
}
public void addNeighbor(Project node) {
if (!map.containsKey(node.getName())) {
children.add(node);
map.put(node.getName(), node);
node.incrementDependencies();
}
}
public void incrementDependencies() {
dependencies++;
}
public ArrayList getChildren() {
return children;
}
public void decrementDependencies() {
dependencies--;
}
public int getNumberDependencies() {
return dependencies;
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/EdgeRemoval/Question.java
================================================
package Q4_07_Build_Order.EdgeRemoval;
import java.util.ArrayList;
public class Question {
/* Build the graph, adding the edge (a, b) if b is dependent on a.
* Assumes a pair is listed in “build order”. The pair (a, b) in
* dependencies indicates that b depends on a and a must be built
* before b. */
public static Graph buildGraph(String[] projects, String[][] dependencies) {
Graph graph = new Graph();
for (String project : projects) {
graph.getOrCreateNode(project);
}
for (String[] dependency : dependencies) {
String first = dependency[0];
String second = dependency[1];
graph.addEdge(first, second);
}
return graph;
}
/* A helper function to insert projects with zero dependencies
* into the order array, starting at index offset. */
public static int addNonDependent(Project[] order, ArrayList projects, int offset) {
for (Project project : projects) {
if (project.getNumberDependencies() == 0) {
order[offset] = project;
offset++;
}
}
return offset;
}
public static Project[] orderProjects(ArrayList projects) {
Project[] order = new Project[projects.size()];
/* Add “roots” to the build order first.*/
int endOfList = addNonDependent(order, projects, 0);
int toBeProcessed = 0;
while (toBeProcessed < order.length) {
Project current = order[toBeProcessed];
/* We have a circular dependency since there are no remaining
* projects with zero dependencies. */
if (current == null) {
return null;
}
/* Remove myself as a dependency. */
ArrayList children = current.getChildren();
for (Project child : children) {
child.decrementDependencies();
}
/* Add children that have no one depending on them. */
endOfList = addNonDependent(order, children, endOfList);
toBeProcessed++;
}
return order;
}
public static String[] convertToStringList(Project[] projects) {
String[] buildOrder = new String[projects.length];
for (int i = 0; i < projects.length; i++) {
buildOrder[i] = projects[i].getName();
}
return buildOrder;
}
public static Project[] findBuildOrder(String[] projects, String[][] dependencies) {
Graph graph = buildGraph(projects, dependencies);
return orderProjects(graph.getNodes());
}
public static String[] buildOrderWrapper(String[] projects, String[][] dependencies) {
Project[] buildOrder = findBuildOrder(projects, dependencies);
if (buildOrder == null) return null;
String[] buildOrderString = convertToStringList(buildOrder);
return buildOrderString;
}
public static void main(String[] args) {
String[] projects = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"};
String[][] dependencies = {
{"a", "b"},
{"b", "c"},
{"a", "c"},
{"a", "c"},
{"d", "e"},
{"b", "d"},
{"e", "f"},
{"a", "f"},
{"h", "i"},
{"h", "j"},
{"i", "j"},
{"g", "j"}};
String[] buildOrder = buildOrderWrapper(projects, dependencies);
if (buildOrder == null) {
System.out.println("Circular Dependency.");
} else {
for (String s : buildOrder) {
System.out.println(s);
}
}
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_08_First_Common_Ancestor/Question.java
================================================
package Q4_08_First_Common_Ancestor;
import CtCILibrary.TreeNode;
public class Question {
static int TWO_NODES_FOUND = 2;
static int ONE_NODE_FOUND = 1;
static int NO_NODES_FOUND = 0;
// Checks how many 'special' nodes are located under this root
public static int covers(TreeNode root, TreeNode p, TreeNode q) {
int ret = NO_NODES_FOUND;
if (root == null) return ret;
if (root == p || root == q) ret += 1;
ret += covers(root.left, p, q);
if(ret == TWO_NODES_FOUND) // Found p and q
return ret;
return ret + covers(root.right, p, q);
}
public static TreeNode commonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (q == p && (root.left == q || root.right == q)) return root;
int nodesFromLeft = covers(root.left, p, q); // Check left side
if (nodesFromLeft == TWO_NODES_FOUND) {
if(root.left == p || root.left == q) return root.left;
else return commonAncestor(root.left, p, q);
} else if (nodesFromLeft == ONE_NODE_FOUND) {
if (root == p) return p;
else if (root == q) return q;
}
int nodesFromRight = covers(root.right, p, q); // Check right side
if(nodesFromRight == TWO_NODES_FOUND) {
if(root.right == p || root.right == q) return root.right;
else return commonAncestor(root.right, p, q);
} else if (nodesFromRight == ONE_NODE_FOUND) {
if (root == p) return p;
else if (root == q) return q;
}
if (nodesFromLeft == ONE_NODE_FOUND &&
nodesFromRight == ONE_NODE_FOUND) return root;
else return null;
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = TreeNode.createMinimalBST(array);
TreeNode n3 = root.find(1);
TreeNode n7 = root.find(7);
TreeNode ancestor = commonAncestor(root, n3, n7);
System.out.println(ancestor.data);
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_08_First_Common_Ancestor/QuestionA.java
================================================
package Q4_08_First_Common_Ancestor;
import CtCILibrary.TreeNode;
public class QuestionA {
public static TreeNode commonAncestor(TreeNode p, TreeNode q) {
if (p == q) return p;
TreeNode ancestor = p;
while (ancestor != null) {
if (isOnPath(ancestor, q)) {
return ancestor;
}
ancestor = ancestor.parent;
}
return null;
}
public static boolean isOnPath(TreeNode ancestor, TreeNode node) {
while (node != ancestor && node != null) {
node = node.parent;
}
return node == ancestor;
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = TreeNode.createMinimalBST(array);
TreeNode n3 = root.find(8);
TreeNode n7 = root.find(8);
TreeNode ancestor = commonAncestor(n3, n7);
System.out.println(ancestor.data);
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_08_First_Common_Ancestor/QuestionB.java
================================================
package Q4_08_First_Common_Ancestor;
import CtCILibrary.TreeNode;
public class QuestionB {
public static TreeNode commonAncestor(TreeNode p, TreeNode q) {
int delta = depth(p) - depth(q); // get difference in depths
TreeNode first = delta > 0 ? q : p; // get shallower node
TreeNode second = delta > 0 ? p : q; // get deeper node
second = goUpBy(second, Math.abs(delta)); // move shallower node to depth of deeper
while (first != second && first != null && second != null) {
first = first.parent;
second = second.parent;
}
return first == null || second == null ? null : first;
}
public static TreeNode goUpBy(TreeNode node, int delta) {
while (delta > 0 && node != null) {
node = node.parent;
delta--;
}
return node;
}
public static int depth(TreeNode node) {
int depth = 0;
while (node != null) {
node = node.parent;
depth++;
}
return depth;
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = TreeNode.createMinimalBST(array);
TreeNode n3 = root.find(3);
TreeNode n7 = root.find(7);
TreeNode ancestor = commonAncestor(n3, n7);
System.out.println(ancestor.data);
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_08_First_Common_Ancestor/QuestionC.java
================================================
package Q4_08_First_Common_Ancestor;
import CtCILibrary.TreeNode;
public class QuestionC {
public static TreeNode commonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (!covers(root, p) || !covers(root, q)) {
return null;
} else if (covers(p, q)) {
return p;
} else if (covers(q, p)) {
return q;
}
TreeNode sibling = getSibling(p);
TreeNode parent = p.parent;
while (!covers(sibling, q)) {
sibling = getSibling(parent);
parent = parent.parent;
}
return parent;
}
public static boolean covers(TreeNode root, TreeNode p) {
if (root == null) return false;
if (root == p) return true;
return covers(root.left, p) || covers(root.right, p);
}
public static TreeNode getSibling(TreeNode node) {
if (node == null || node.parent == null) {
return null;
}
TreeNode parent = node.parent;
return parent.left == node ? parent.right : parent.left;
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = TreeNode.createMinimalBST(array);
TreeNode n3 = root.find(1);
TreeNode n7 = root.find(7);
TreeNode ancestor = commonAncestor(root, n3, n7);
System.out.println(ancestor.data);
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_08_First_Common_Ancestor/QuestionD.java
================================================
package Q4_08_First_Common_Ancestor;
import CtCILibrary.TreeNode;
public class QuestionD {
public static TreeNode commonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (!covers(root, p) || !covers(root, q)) { // Error check - one node is not in tree
return null;
}
return ancestorHelper(root, p, q);
}
public static TreeNode ancestorHelper(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) {
return root;
}
boolean pIsOnLeft = covers(root.left, p);
boolean qIsOnLeft = covers(root.left, q);
if (pIsOnLeft != qIsOnLeft) { // Nodes are on different side
return root;
}
TreeNode childSide = pIsOnLeft ? root.left : root.right;
return ancestorHelper(childSide, p, q);
}
public static boolean covers(TreeNode root, TreeNode p) {
if (root == null) return false;
if (root == p) return true;
return covers(root.left, p) || covers(root.right, p);
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = TreeNode.createMinimalBST(array);
TreeNode n3 = root.find(1);
TreeNode n7 = root.find(7);
TreeNode ancestor = commonAncestor(root, n3, n7);
System.out.println(ancestor.data);
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_08_First_Common_Ancestor/QuestionE.java
================================================
package Q4_08_First_Common_Ancestor;
import CtCILibrary.TreeNode;
public class QuestionE {
public static class Result {
public TreeNode node;
public boolean isAncestor;
public Result(TreeNode n, boolean isAnc) {
node = n;
isAncestor = isAnc;
}
}
public static Result commonAncestorHelper(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return new Result(null, false);
}
if (root == p && root == q) {
return new Result(root, true);
}
Result rx = commonAncestorHelper(root.left, p, q);
if (rx.isAncestor) { // Found common ancestor
return rx;
}
Result ry = commonAncestorHelper(root.right, p, q);
if (ry.isAncestor) { // Found common ancestor
return ry;
}
if (rx.node != null && ry.node != null) {
return new Result(root, true); // This is the common ancestor
} else if (root == p || root == q) {
/* If we�re currently at p or q, and we also found one of those
* nodes in a subtree, then this is truly an ancestor and the
* flag should be true. */
boolean isAncestor = rx.node != null || ry.node != null;
return new Result(root, isAncestor);
} else {
return new Result(rx.node != null ? rx.node : ry.node, false);
}
}
public static TreeNode commonAncestor(TreeNode root, TreeNode p, TreeNode q) {
Result r = commonAncestorHelper(root, p, q);
if (r.isAncestor) {
return r.node;
}
return null;
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = TreeNode.createMinimalBST(array);
TreeNode n3 = root.find(10);
TreeNode n7 = root.find(6);
TreeNode ancestor = commonAncestor(root, n3, n7);
if (ancestor != null) {
System.out.println(ancestor.data);
} else {
System.out.println("null");
}
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_08_First_Common_Ancestor/QuestionEBad.java
================================================
package Q4_08_First_Common_Ancestor;
import CtCILibrary.TreeNode;
public class QuestionEBad {
public static TreeNode commonAncestorBad(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}
if (root == p && root == q) {
return root;
}
TreeNode x = commonAncestorBad(root.left, p, q);
if (x != null && x != p && x != q) { // Found common ancestor
return x;
}
TreeNode y = commonAncestorBad(root.right, p, q);
if (y != null && y != p && y != q) {
return y;
}
if (x != null && y != null) {
return root; // This is the common ancestor
} else if (root == p || root == q) {
return root;
} else {
return x == null ? y : x;
}
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = TreeNode.createMinimalBST(array);
TreeNode n3 = root.find(9);
TreeNode n7 = new TreeNode(6);//root.find(10);
TreeNode ancestor = commonAncestorBad(root, n3, n7);
if (ancestor != null) {
System.out.println(ancestor.data);
} else {
System.out.println("null");
}
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_08_First_Common_Ancestor/QuestionF.java
================================================
package Q4_08_First_Common_Ancestor;
import CtCILibrary.TreeNode;
public class QuestionF {
public static TreeNode commonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if ((p == null) || (q == null)) {
return null;
}
TreeNode ap = p.parent;
while (ap != null) {
TreeNode aq = q.parent;
while (aq != null) {
if (aq == ap) {
return aq;
}
aq = aq.parent;
}
ap = ap.parent;
}
return null;
}
public static void main(String[] args) {
int[] array = {5, 3, 6, 1, 9, 11};
TreeNode root = new TreeNode(20);
for (int a : array) {
root.insertInOrder(a);
}
TreeNode n1 = root.find(1);
TreeNode n9 = root.find(9);
TreeNode ancestor = commonAncestor(root, n1, n9);
System.out.println(ancestor.data);
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_08_First_Common_Ancestor/Tester.java
================================================
package Q4_08_First_Common_Ancestor;
import java.util.ArrayList;
import CtCILibrary.TreeNode;
public class Tester {
public static String resultToString(String s, TreeNode x, TreeNode y, TreeNode anc) {
s += ": ";
s += (x == null ? "null" : x.data);
s += " & ";
s += (y == null ? "null" : y.data);
s += " -> ";
s += (anc == null ? "null" : anc.data);
return s;
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = TreeNode.createMinimalBST(array);
ArrayList nodes = new ArrayList();
for (int a : array) {
nodes.add(root.find(a));
}
nodes.add(new TreeNode(11));
for (TreeNode x : nodes) {
for (TreeNode y : nodes) {
TreeNode r1 = QuestionA.commonAncestor(x, y);
TreeNode r2 = QuestionB.commonAncestor(x, y);
TreeNode r3 = QuestionC.commonAncestor(root, x, y);
TreeNode r4 = QuestionD.commonAncestor(root, x, y);
TreeNode r5 = QuestionE.commonAncestor(root, x, y);
String s1 = resultToString("A", x, y, r1);
String s2 = resultToString("B", x, y, r2);
String s3 = resultToString("C", x, y, r3);
String s4 = resultToString("D", x, y, r4);
String s5 = resultToString("D", x, y, r5);
if (r1 == r2 && r2 == r3 && r3 == r4 && r4 == r5) {
System.out.println("SUCCESS: " + s1);
} else {
System.out.println("ERROR");
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
System.out.println(s5);
}
}
}
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_09_BST_Sequences/Question.java
================================================
package Q4_09_BST_Sequences;
import java.util.ArrayList;
import java.util.LinkedList;
import CtCILibrary.TreeNode;
public class Question {
public static void weaveLists(LinkedList first, LinkedList second, ArrayList> results, LinkedList prefix) {
/* One list is empty. Add the remainder to [a cloned] prefix and
* store result. */
if (first.size() == 0 || second.size() == 0) {
LinkedList result = (LinkedList) prefix.clone();
result.addAll(first);
result.addAll(second);
results.add(result);
return;
}
/* Recurse with head of first added to the prefix. Removing the
* head will damage first, so we’ll need to put it back where we
* found it afterwards. */
int headFirst = first.removeFirst();
prefix.addLast(headFirst);
weaveLists(first, second, results, prefix);
prefix.removeLast();
first.addFirst(headFirst);
/* Do the same thing with second, damaging and then restoring
* the list.*/
int headSecond = second.removeFirst();
prefix.addLast(headSecond);
weaveLists(first, second, results, prefix);
prefix.removeLast();
second.addFirst(headSecond);
}
public static ArrayList> allSequences(TreeNode node) {
ArrayList> result = new ArrayList>();
if (node == null) {
result.add(new LinkedList());
return result;
}
LinkedList prefix = new LinkedList();
prefix.add(node.data);
/* Recurse on left and right subtrees. */
ArrayList> leftSeq = allSequences(node.left);
ArrayList> rightSeq = allSequences(node.right);
/* Weave together each list from the left and right sides. */
for (LinkedList left : leftSeq) {
for (LinkedList right : rightSeq) {
ArrayList> weaved = new ArrayList>();
weaveLists(left, right, weaved, prefix);
result.addAll(weaved);
}
}
return result;
}
public static void main(String[] args) {
TreeNode node = new TreeNode(100);
int[] array = {100, 50, 20, 75, 150, 120, 170};
for (int a : array) {
node.insertInOrder(a);
}
ArrayList> allSeq = allSequences(node);
for (LinkedList list : allSeq) {
System.out.println(list);
}
System.out.println(allSeq.size());
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_10_Check_Subtree/QuestionA.java
================================================
package Q4_10_Check_Subtree;
import CtCILibrary.AssortedMethods;
import CtCILibrary.TreeNode;
public class QuestionA {
public static boolean containsTree(TreeNode t1, TreeNode t2) {
StringBuilder string1 = new StringBuilder();
StringBuilder string2 = new StringBuilder();
getOrderString(t1, string1);
getOrderString(t2, string2);
return string1.indexOf(string2.toString()) != -1;
}
public static void getOrderString(TreeNode node, StringBuilder sb) {
if (node == null) {
sb.append("X"); // Add null indicator
return;
}
sb.append(node.data); // Add root
getOrderString(node.left, sb); // Add left
getOrderString(node.right, sb); // Add right
}
public static void main(String[] args) {
// t2 is a subtree of t1
int[] array1 = {1, 2, 1, 3, 1, 1, 5};
int[] array2 = {2, 3, 1};
TreeNode t1 = AssortedMethods.createTreeFromArray(array1);
TreeNode t2 = AssortedMethods.createTreeFromArray(array2);
if (containsTree(t1, t2)) {
System.out.println("t2 is a subtree of t1");
} else {
System.out.println("t2 is not a subtree of t1");
}
// t4 is not a subtree of t3
int[] array3 = {1, 2, 3};
TreeNode t3 = AssortedMethods.createTreeFromArray(array1);
TreeNode t4 = AssortedMethods.createTreeFromArray(array3);
if (containsTree(t3, t4)) {
System.out.println("t4 is a subtree of t3");
} else {
System.out.println("t4 is not a subtree of t3");
}
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_10_Check_Subtree/QuestionB.java
================================================
package Q4_10_Check_Subtree;
import CtCILibrary.AssortedMethods;
import CtCILibrary.TreeNode;
public class QuestionB {
public static boolean containsTree(TreeNode t1, TreeNode t2) {
if (t2 == null) {
return true; // The empty tree is a subtree of every tree.
}
return subTree(t1, t2);
}
/* Checks if the binary tree rooted at r1 contains the binary tree
* rooted at r2 as a subtree somewhere within it.
*/
public static boolean subTree(TreeNode r1, TreeNode r2) {
if (r1 == null) {
return false; // big tree empty & subtree still not found.
} else if (r1.data == r2.data && matchTree(r1,r2)) {
return true;
}
return subTree(r1.left, r2) || subTree(r1.right, r2);
}
/* Checks if the binary tree rooted at r1 contains the
* binary tree rooted at r2 as a subtree starting at r1.
*/
public static boolean matchTree(TreeNode r1, TreeNode r2) {
if (r1 == null && r2 == null) {
return true; // nothing left in the subtree
} else if (r1 == null || r2 == null) {
return false; // exactly one tree is empty, therefore trees don't match
} else if (r1.data != r2.data) {
return false; // data doesn't match
} else {
return matchTree(r1.left, r2.left) && matchTree(r1.right, r2.right);
}
}
public static void main(String[] args) {
// t2 is a subtree of t1
int[] array1 = {1, 2, 1, 3, 1, 1, 5};
int[] array2 = {2, 3, 1};
TreeNode t1 = AssortedMethods.createTreeFromArray(array1);
TreeNode t2 = AssortedMethods.createTreeFromArray(array2);
if (containsTree(t1, t2)) {
System.out.println("t2 is a subtree of t1");
} else {
System.out.println("t2 is not a subtree of t1");
}
// t4 is not a subtree of t3
int[] array3 = {1, 2, 3};
TreeNode t3 = AssortedMethods.createTreeFromArray(array1);
TreeNode t4 = AssortedMethods.createTreeFromArray(array3);
if (containsTree(t3, t4)) {
System.out.println("t4 is a subtree of t3");
} else {
System.out.println("t4 is not a subtree of t3");
}
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_11_Random_Node/Question.java
================================================
package Q4_11_Random_Node;
public class Question {
public static void main(String[] args) {
int[] counts = new int[10];
for (int i = 0; i < 1000000; i++) {
Tree tree = new Tree();
int[] array = {1, 0, 6, 2, 3, 9, 4, 5, 8, 7};
for (int x : array) {
tree.insertInOrder(x);
}
int d = tree.getRandomNode().data;
counts[d]++;
}
for (int i = 0; i < counts.length; i++) {
System.out.println(i + ": " + counts[i]);
}
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_11_Random_Node/Tree.java
================================================
package Q4_11_Random_Node;
import java.util.Random;
public class Tree {
TreeNode root = null;
public void insertInOrder(int value) {
if (root == null) {
root = new TreeNode(value);
} else {
root.insertInOrder(value);
}
}
public int size() {
return root == null ? 0 : root.size();
}
public TreeNode getRandomNode() {
if (root == null) return null;
Random random = new Random();
int i = random.nextInt(size());
return root.getIthNode(i);
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_11_Random_Node/TreeNode.java
================================================
package Q4_11_Random_Node;
import java.util.Random;
/* One node of a binary tree. The data element stored is a single
* character.
*/
public class TreeNode {
public int data;
public TreeNode left;
public TreeNode right;
private int size = 0;
public TreeNode(int d) {
data = d;
size = 1;
}
public void insertInOrder(int d) {
if (d <= data) {
if (left == null) {
left = new TreeNode(d);
} else {
left.insertInOrder(d);
}
} else {
if (right == null) {
right = new TreeNode(d);
} else {
right.insertInOrder(d);
}
}
size++;
}
public int size() {
return size;
}
public TreeNode find(int d) {
if (d == data) {
return this;
} else if (d <= data) {
return left != null ? left.find(d) : null;
} else if (d > data) {
return right != null ? right.find(d) : null;
}
return null;
}
public TreeNode getRandomNode() {
int leftSize = left == null ? 0 : left.size();
Random random = new Random();
int index = random.nextInt(size);
if (index < leftSize) {
return left.getRandomNode();
} else if (index == leftSize) {
return this;
} else {
return right.getRandomNode();
}
}
public TreeNode getIthNode(int i) {
int leftSize = left == null ? 0 : left.size();
if (i < leftSize) {
return left.getIthNode(i);
} else if (i == leftSize) {
return this;
} else {
return right.getIthNode(i - (leftSize + 1));
}
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_12_Paths_with_Sum/QuestionA.java
================================================
package Q4_12_Paths_with_Sum;
import CtCILibrary.TreeNode;
public class QuestionA {
public static int countPathsWithSum(TreeNode root, int targetSum) {
if (root == null) return 0;
/* Count paths with sum starting from the root. */
int pathsFromRoot = countPathsWithSumFromNode(root, targetSum, 0);
/* Try the nodes on the left and right. */
int pathsOnLeft = countPathsWithSum(root.left, targetSum);
int pathsOnRight = countPathsWithSum(root.right, targetSum);
return pathsFromRoot + pathsOnLeft + pathsOnRight;
}
/* Returns the number of paths with this sum starting from this node. */
public static int countPathsWithSumFromNode(TreeNode node, int targetSum, int currentSum) {
if (node == null) return 0;
currentSum += node.data;
int totalPaths = 0;
if (currentSum == targetSum) { // Found a path from the root
totalPaths++;
}
totalPaths += countPathsWithSumFromNode(node.left, targetSum, currentSum); // Go left
totalPaths += countPathsWithSumFromNode(node.right, targetSum, currentSum); // Go right
return totalPaths;
}
public static void main(String [] args) {
/*
TreeNode root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(1);
root.left.left = new TreeNode(-8);
root.left.right = new TreeNode(8);
root.right.left = new TreeNode(2);
root.right.right = new TreeNode(6);
System.out.println(countPathsWithSum(root, 0));*/
/*TreeNode root = new TreeNode(-7);
root.left = new TreeNode(-7);
root.left.right = new TreeNode(1);
root.left.right.left = new TreeNode(2);
root.right = new TreeNode(7);
root.right.left = new TreeNode(3);
root.right.right = new TreeNode(20);
root.right.right.left = new TreeNode(0);
root.right.right.left.left = new TreeNode(-3);
root.right.right.left.left.right = new TreeNode(2);
root.right.right.left.left.right.left = new TreeNode(1);
System.out.println(countPathsWithSum(root, -14));*/
TreeNode root = new TreeNode(0);
root.left = new TreeNode(0);
root.right = new TreeNode(0);
root.right.left = new TreeNode(0);
root.right.left.right = new TreeNode(0);
root.right.right = new TreeNode(0);
System.out.println(countPathsWithSum(root, 0));
System.out.println(countPathsWithSum(root, 4));
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_12_Paths_with_Sum/QuestionB.java
================================================
package Q4_12_Paths_with_Sum;
import java.util.HashMap;
import CtCILibrary.TreeNode;
public class QuestionB {
public static int countPathsWithSum(TreeNode root, int targetSum) {
return countPathsWithSum(root, targetSum, 0, new HashMap());
}
public static int countPathsWithSum(TreeNode node, int targetSum, int runningSum, HashMap pathCount) {
if (node == null) return 0; // Base case
runningSum += node.data;
/* Count paths with sum ending at the current node. */
int sum = runningSum - targetSum;
int totalPaths = pathCount.getOrDefault(sum, 0);
/* If runningSum equals targetSum, then one additional path starts at root. Add in this path.*/
if (runningSum == targetSum) {
totalPaths++;
}
/* Add runningSum to pathCounts. */
incrementHashTable(pathCount, runningSum, 1);
/* Count paths with sum on the left and right. */
totalPaths += countPathsWithSum(node.left, targetSum, runningSum, pathCount);
totalPaths += countPathsWithSum(node.right, targetSum, runningSum, pathCount);
incrementHashTable(pathCount, runningSum, -1); // Remove runningSum
return totalPaths;
}
public static void incrementHashTable(HashMap hashTable, int key, int delta) {
int newCount = hashTable.getOrDefault(key, 0) + delta;
if (newCount == 0) { // Remove when zero to reduce space usage
hashTable.remove(key);
} else {
hashTable.put(key, newCount);
}
}
public static void main(String [] args) {
/*
TreeNode root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(1);
root.left.left = new TreeNode(-8);
root.left.right = new TreeNode(8);
root.right.left = new TreeNode(2);
root.right.right = new TreeNode(6);
root.right.left.left = new TreeNode(0);
System.out.println(countPathsWithSum(root, 0));
*/
/*TreeNode root = new TreeNode(-7);
root.left = new TreeNode(-7);
root.left.right = new TreeNode(1);
root.left.right.left = new TreeNode(2);
root.right = new TreeNode(7);
root.right.left = new TreeNode(3);
root.right.right = new TreeNode(20);
root.right.right.left = new TreeNode(0);
root.right.right.left.left = new TreeNode(-3);
root.right.right.left.left.right = new TreeNode(2);
root.right.right.left.left.right.left = new TreeNode(1);
System.out.println(countPathsWithSum(root, 0));*/
TreeNode root = new TreeNode(0);
root.left = new TreeNode(0);
root.right = new TreeNode(0);
root.right.left = new TreeNode(0);
root.right.left.right = new TreeNode(0);
root.right.right = new TreeNode(0);
System.out.println(countPathsWithSum(root, 0));
System.out.println(countPathsWithSum(root, 4));
}
}
================================================
FILE: Java/Ch 04. Trees and Graphs/Q4_12_Paths_with_Sum/Tester.java
================================================
package Q4_12_Paths_with_Sum;
import CtCILibrary.AssortedMethods;
import CtCILibrary.TreeNode;
public class Tester {
public static void main(String[] args) {
boolean isWorking = true;
while (isWorking) {
int min = -20;
int max = 20;
int size = 20;
TreeNode root = AssortedMethods.randomBST(size, min, max);
for (int targetSum = Math.min(-1, min * size - 10); targetSum <= Math.max(100, max * size + 10); targetSum++) {
int answerA = QuestionA.countPathsWithSum(root, targetSum);
int answerB = QuestionB.countPathsWithSum(root, targetSum);
if (answerA > 0 || answerB > 0) {
System.out.println(targetSum + ": " + answerA + ", " + answerB + " | " + (answerA == answerB));
}
if (answerA != answerB) {
isWorking = false;
break;
}
}
}
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_01_Insertion/Question.java
================================================
package Q5_01_Insertion;
import CtCILibrary.AssortedMethods;
public class Question {
public static int updateBits(int n, int m, int i, int j) {
// Validation
if (i > j || i < 0 || j >= 32) {
return 0;
}
/* Create a mask to clear bits i through j in n
/* EXAMPLE: i = 2, j = 4. Result should be 11100011.
* (Using 8 bits for this example. This is obviously not actually 8 bits.)
*/
int allOnes = ~0; // allOnes = 11111111
int left = j < 31 ? (allOnes << (j + 1)) : 0; // 1s until position j, then 0s. left = 11100000
int right = ((1 << i) - 1); // 1s after position i. right = 00000011
int mask = left | right; // All 1s, except for 0s between i and j. mask = 11100011
/* Clear i through j, then put m in there */
int n_cleared = n & mask; // Clear bits j through i.
int m_shifted = m << i; // Move m into correct position.
/* OR them, and we're done! */
return n_cleared | m_shifted;
}
public static void main(String[] args) {
int a = ~23423;
System.out.println(AssortedMethods.toFullBinaryString(a));
int b = 5;
System.out.println(AssortedMethods.toFullBinaryString(b));
int c = updateBits(a, b, 29, 31);
System.out.println(AssortedMethods.toFullBinaryString(c));
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_02_Binary_to_String/Question.java
================================================
package Q5_02_Binary_to_String;
public class Question {
public static String printBinary(double num) {
if (num >= 1 || num <= 0) {
return "ERROR";
}
StringBuilder binary = new StringBuilder();
binary.append(".");
while (num > 0) {
/* Setting a limit on length: 32 characters */
if (binary.length() > 32) {
return "ERROR";
}
double r = num * 2;
if (r >= 1) {
binary.append(1);
num = r - 1;
} else {
binary.append(0);
num = r;
}
}
return binary.toString();
}
public static String printBinary2(double num) {
if (num >= 1 || num <= 0) {
return "ERROR";
}
StringBuilder binary = new StringBuilder();
double frac = 0.5;
binary.append(".");
while (num > 0) {
/* Setting a limit on length: 32 characters */
if (binary.length() >= 32) {
return "ERROR";
}
if (num >= frac) {
binary.append(1);
num -= frac;
} else {
binary.append(0);
}
frac /= 2;
}
return binary.toString();
}
public static void main(String[] args) {
String bs = printBinary(.125);
System.out.println(bs);
for (int i = 0; i < 1000; i++) {
double num = i / 1000.0;
String binary = printBinary(num);
String binary2 = printBinary2(num);
if (!binary.equals("ERROR") || !binary2.equals("ERROR")) {
System.out.println(num + " : " + binary + " " + binary2);
}
}
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_03_Flip_Bit_to_Win/QuestionA.java
================================================
package Q5_03_Flip_Bit_to_Win;
public class QuestionA {
public static int SEQUENCE_LENGTH = 32;
public static boolean getBit(int num, int i) {
return ((num & (1 << i)) != 0);
}
public static int longestSequence(int n) {
int maxSeq = 0;
for (int i = 0; i < SEQUENCE_LENGTH; i++) {
maxSeq = Math.max(maxSeq, longestSequenceOf1s(n, i));
}
return maxSeq;
}
public static int longestSequenceOf1s(int n, int indexToIgnore) {
int max = 0;
int counter = 0;
for (int i = 0; i < SEQUENCE_LENGTH; i++) {
if (i == indexToIgnore || getBit(n, i)) {
counter++;
max = Math.max(counter, max);
} else {
counter = 0;
}
}
return max;
}
public static void main(String[] args) {
int original_number = Integer.MAX_VALUE;
int new_number = longestSequence(original_number);
System.out.println(Integer.toBinaryString(original_number));
System.out.println(new_number);
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_03_Flip_Bit_to_Win/QuestionB.java
================================================
package Q5_03_Flip_Bit_to_Win;
import java.util.ArrayList;
public class QuestionB {
public static int longestSequence(int n) {
if (n == -1) return Integer.BYTES * 8;
ArrayList sequences = getAlternatingSequences(n);
return findLongestSequence(sequences);
}
/* Return a list of the sizes of the sequences. The sequence starts
* off with the number of 0s (which might be 0) and then alternates
* with the counts of each value.*/
public static ArrayList getAlternatingSequences(int n) {
ArrayList sequences = new ArrayList();
int searchingFor = 0;
int counter = 0;
for (int i = 0; i < Integer.BYTES * 8; i++) {
if ((n & 1) != searchingFor) {
sequences.add(counter);
searchingFor = n & 1; // Flip 1 to 0 or 0 to 1
counter = 0;
}
counter++;
n >>>= 1;
}
sequences.add(counter);
return sequences;
}
public static int findLongestSequence(ArrayList seq) {
int maxSeq = 1;
for (int i = 0; i < seq.size(); i += 2) {
int zerosSeq = seq.get(i);
int onesSeqPrev = i - 1 >= 0 ? seq.get(i - 1) : 0;
int onesSeqNext = i + 1 < seq.size() ? seq.get(i + 1) : 0;
int thisSeq = 0;
if (zerosSeq == 1) { // Can merge
thisSeq = onesSeqNext + 1 + onesSeqPrev;
} else if (zerosSeq > 1) { // Just add a one to either side
thisSeq = 1 + Math.max(onesSeqPrev, onesSeqNext);
} else if (zerosSeq == 0) { // No zero, but take either side
thisSeq = Math.max(onesSeqPrev, onesSeqNext);
}
maxSeq = Math.max(thisSeq, maxSeq);
}
return maxSeq;
}
public static void main(String[] args) {
int original_number = 1775;
int new_number = longestSequence(original_number);
System.out.println(Integer.toBinaryString(original_number));
System.out.println(new_number);
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_03_Flip_Bit_to_Win/QuestionC.java
================================================
package Q5_03_Flip_Bit_to_Win;
public class QuestionC {
public static int SEQUENCE_LENGTH = 32;
/* Given set of three sequences ordered as {0s, then 1s, then 0s},
* find max sequence that can be formed. */
public static int getMaxSequence(int[] sequences) { /* 1s, then 0s, then [old] ones */
if (sequences[1] == 1) { // a single 0 -> merge sequences
return sequences[0] + sequences[2] + 1;
} else if (sequences[1] == 0) { // no 0s -> take one side
return Math.max(sequences[0], sequences[2]);
} else { // many 0s -> take side, add 1 (flip a bit)
return Math.max(sequences[0], sequences[2]) + 1;
}
}
public static void shift(int[] sequences) {
sequences[2] = sequences[1];
sequences[1] = sequences[0];
sequences[0] = 0;
}
public static int longestSequence(int n) {
int searchingFor = 0;
int[] sequences = {0, 0, 0}; // Counts of last 3 sequences
int maxSequence = 1;
for (int i = 0; i < SEQUENCE_LENGTH; i++) {
if ((n & 1) != searchingFor) {
if (searchingFor == 1) { // End of 1s + 0s + 1s sequence
maxSequence = Math.max(maxSequence, getMaxSequence(sequences));
}
searchingFor = n & 1; // Flip 1 to 0 or 0 to 1
shift(sequences); // Shift sequences
}
sequences[0]++;
n >>>= 1;
}
/* Check final set of sequences */
if (searchingFor == 0) {
shift(sequences);
}
int finalSequence = getMaxSequence(sequences);
maxSequence = Math.max(finalSequence, maxSequence);
return maxSequence;
}
public static void main(String[] args) {
int original_number = Integer.MAX_VALUE;
int new_number = longestSequence(original_number);
System.out.println(Integer.toBinaryString(original_number));
System.out.println(new_number);
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_03_Flip_Bit_to_Win/QuestionD.java
================================================
package Q5_03_Flip_Bit_to_Win;
public class QuestionD {
public static int flipBit(int a) {
/* If all 1s, this is already the longest sequence. */
if (~a == 0) return Integer.BYTES * 8;
int currentLength = 0;
int previousLength = 0;
int maxLength = 1; // We can always have a sequence of at least one 1
while (a != 0) {
if ((a & 1) == 1) {
currentLength++;
} else if ((a & 1) == 0) {
/* Update to 0 (if next bit is 0) or currentLength (if next bit is 1). */
previousLength = (a & 2) == 0 ? 0 : currentLength;
currentLength = 0;
}
maxLength = Math.max(previousLength + currentLength + 1, maxLength);
a >>>= 1;
}
return maxLength;
}
public static void main(String[] args) {
int[][] cases = {{-1, 32}, {Integer.MAX_VALUE, 32}, {-10, 31}, {0, 1},
{1, 2}, {15, 5}, {1775, 8}};
for (int[] c : cases) {
int x = flipBit(c[0]);
boolean r = (c[1] == x);
System.out.println(c[0] + ": " + x + ", " + c[1] + " " + r);
}
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_03_Flip_Bit_to_Win/Tester.java
================================================
package Q5_03_Flip_Bit_to_Win;
public class Tester {
public static boolean checkRange(int start, int range) {
for (int i = 0; i < range; i++) {
int value = start + i;
int seqA = QuestionA.longestSequence(value);
int seqB = QuestionB.longestSequence(value);
int seqC = QuestionC.longestSequence(value);
int seqD = QuestionC.longestSequence(value);
if (seqA != seqB || seqB != seqC || seqC != seqD) {
System.out.println("FAILURE on value " + value);
String xs = Integer.toBinaryString(value);
System.out.println(xs);
System.out.println("A: " + seqA);
System.out.println("B: " + seqB);
System.out.println("C: " + seqC);
System.out.println("D: " + seqD);
return false;
}
}
return true;
}
public static void main(String[] args) {
int[][] ranges = {{Integer.MIN_VALUE, 1000}, {Integer.MAX_VALUE - 2333, 5333},
{-10000, 20000}};
for (int[] range : ranges) {
if (!checkRange(range[0], range[1])) {
System.out.println("ERROR");
} else {
int end = range[0] + range[1];
System.out.println("SUCCESS: " + range[0] + " -> " + end);
}
}
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_04_Next_Number/QuestionA.java
================================================
package Q5_04_Next_Number;
public class QuestionA {
public static int countOnes(int i) {
int count = 0;
while (i > 0) {
if ((i & 1) == 1) {
count++;
}
i = i >> 1;
}
return count;
}
public static int countZeros(int i) {
return 32 - countOnes(i);
}
public static boolean hasValidNext(int i) {
if (i == 0) {
return false;
}
int count = 0;
while ((i & 1) == 0) {
i >>= 1;
count++;
}
while ((i & 1) == 1) {
i >>= 1;
count++;
}
if (count == 31) {
return false;
}
return true;
}
public static boolean hasValidPrev(int i) {
while ((i & 1) == 1) {
i >>= 1;
}
if (i == 0) {
return false;
}
return true;
}
public static int getNextSlow(int i) {
if (!hasValidNext(i)) {
return -1;
}
int num_ones = countOnes(i);
i++;
while (countOnes(i) != num_ones) {
i++;
}
return i;
}
public static int getPrevSlow(int i) {
if (!hasValidPrev(i)) {
return -1;
}
int num_ones = countOnes(i);
i--;
while (countOnes(i) != num_ones) {
i--;
}
return i;
}
public static void main(String[] args) {
int i = 13948;
int p1 = getPrevSlow(i);
int n1 = getNextSlow(i);
Tester.binPrint(p1);
Tester.binPrint(n1);
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_04_Next_Number/QuestionB.java
================================================
package Q5_04_Next_Number;
public class QuestionB {
public static int getNext(int n) {
int c = n;
int c0 = 0;
int c1 = 0;
while (((c & 1) == 0) && (c != 0)) {
c0++;
c >>= 1;
}
while ((c & 1) == 1) {
c1++;
c >>= 1;
}
/* If c is 0, then n is a sequence of 1s followed by a sequence of 0s. This is already the biggest
* number with c1 ones. Return error.
*/
if (c0 + c1 == 31 || c0 + c1 == 0) {
return -1;
}
int pos = c0 + c1; // position of right-most non-trailing zero (where the right most bit is bit 0)
/* Flip the right-most non-trailing zero (which will be at position pos) */
n |= (1 << pos); // Flip right-most non-trailing zero
/* Clear all bits to the right of pos.
* Example with pos = 5
* (1) Shift 1 over by 5 to create 0..0100000 [ mask = 1 << pos ]
* (2) Subtract 1 to get 0..0011111 [ mask = mask - 1 ]
* (3) Flip all the bits by using '~' to get 1..1100000 [ mask = ~mask ]
* (4) AND with n
*/
n &= ~((1 << pos) - 1); // Clear all bits to the right of pos
/* Put (ones-1) 1s on the right by doing the following:
* (1) Shift 1 over by (ones-1) spots. If ones = 3, this gets you 0..0100
* (2) Subtract one from that to get 0..0011
* (3) OR with n
*/
n |= (1 << (c1 - 1)) - 1;
return n;
}
public static int getPrev(int n) {
int temp = n;
int c0 = 0;
int c1 = 0;
while ((temp & 1) == 1) {
c1++;
temp >>= 1;
}
/* If temp is 0, then the number is a sequence of 0s followed by a sequence of 1s. This is already
* the smallest number with c1 ones. Return -1 for an error.
*/
if (temp == 0) {
return -1;
}
while (((temp & 1) == 0) && (temp != 0)) {
c0++;
temp >>= 1;
}
int p = c0 + c1; // position of right-most non-trailing one (where the right most bit is bit 0)
/* Flip right-most non-trailing one.
* Example: n = 00011100011.
* c1 = 2
* c0 = 3
* pos = 5
*
* Build up a mask as follows:
* (1) ~0 will be a sequence of 1s
* (2) shifting left by p + 1 will give you 11.111000000 (six 0s)
* (3) ANDing with n will clear the last 6 bits
* n is now 00011000000
*/
n &= ((~0) << (p + 1)); // clears from bit p onwards (to the right)
/* Create a sequence of (c1+1) 1s as follows
* (1) Shift 1 to the left (c1+1) times. If c1 is 2, this will give you 0..001000
* (2) Subtract one from that. This will give you 0..00111
*/
int mask = (1 << (c1 + 1)) - 1; // Sequence of (c1+1) ones
/* Move the ones to be right up next to bit p
* Since this is a sequence of (c1+1) ones, and p = c1 + c0, we just need to
* shift this over by (c0-1) spots.
* If c0 = 3 and c1 = 2, then this will look like 00...0011100
*
* Then, finally, we OR this with n.
*/
n |= mask << (c0 - 1);
return n;
}
public static void binPrint(int i) {
System.out.println(i + ": " + Integer.toBinaryString(i));
}
public static void main(String[] args) {
int i = 13948;
int p1 = getPrev(i);
int n1 = getNext(i);
Tester.binPrint(p1);
Tester.binPrint(n1);
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_04_Next_Number/QuestionC.java
================================================
package Q5_04_Next_Number;
public class QuestionC {
public static int getNextArith(int n) {
int c = n;
int c0 = 0;
int c1 = 0;
while (((c & 1) == 0) && (c != 0)) {
c0++;
c >>= 1;
}
while ((c & 1) == 1) {
c1++;
c >>= 1;
}
/* If c is 0, then n is a sequence of 1s followed by a sequence of 0s. This is already the biggest
* number with c1 ones. Return error.
*/
if (c0 + c1 == 31 || c0 + c1 == 0) {
return -1;
}
/* Arithmetically:
* 2^c0 = 1 << c0
* 2^(c1-1) = 1 << (c0 - 1)
* next = n + 2^c0 + 2^(c1-1) - 1;
*/
return n + (1 << c0) + (1 << (c1 - 1)) - 1;
}
public static int getPrevArith(int n) {
int temp = n;
int c0 = 0;
int c1 = 0;
while (((temp & 1) == 1) && (temp != 0)) {
c1++;
temp >>= 1;
}
/* If temp is 0, then the number is a sequence of 0s followed by a sequence of 1s. This is already
* the smallest number with c1 ones. Return -1 for an error.
*/
if (temp == 0) {
return -1;
}
while ((temp & 1) == 0 && (temp != 0)) {
c0++;
temp >>= 1;
}
/* Arithmetic:
* 2^c1 = 1 << c1
* 2^(c0 - 1) = 1 << (c0 - 1)
*/
return n - (1 << c1) - (1 << (c0 - 1)) + 1;
}
public static void binPrint(int i) {
System.out.println(i + ": " + Integer.toBinaryString(i));
}
public static void main(String[] args) {
int i = 13948;
int p1 = getPrevArith(i);
int n1 = getNextArith(i);
Tester.binPrint(p1);
Tester.binPrint(n1);
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_04_Next_Number/Tester.java
================================================
package Q5_04_Next_Number;
public class Tester {
public static void binPrint(int i) {
System.out.println(i + ": " + Integer.toBinaryString(i));
}
public static void main(String[] args) {
for (int i = 0; i < 200; i++) {
int p1 = QuestionA.getPrevSlow(i);
int p2 = QuestionB.getPrev(i);
int p3 = QuestionC.getPrevArith(i);
int n1 = QuestionA.getNextSlow(i);
int n2 = QuestionB.getNext(i);
int n3 = QuestionC.getNextArith(i);
if (p1 != p2 || p2 != p3 || n1 != n2 || n2 != n3) {
binPrint(i);
binPrint(p1);
binPrint(p2);
binPrint(p3);
binPrint(n1);
binPrint(n2);
binPrint(n3);
System.out.println("");
break;
}
}
System.out.println("Done!");
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_06_Conversion/QuestionA.java
================================================
package Q5_06_Conversion;
import CtCILibrary.AssortedMethods;
public class QuestionA {
public static int bitSwapRequired(int a, int b) {
int count = 0;
int c = a ^ b;
while (c != 0) {
count += c & 1; // Increment count if c ends with a 1
c >>>= 1; // Shift right by 1
}
return count;
}
public static void main(String[] args) {
int a = -23432;
int b = 512132;
System.out.println(a + ": " + AssortedMethods.toFullBinaryString(a));
System.out.println(b + ": " + AssortedMethods.toFullBinaryString(b));
System.out.println("Required number of bits: " + bitSwapRequired(a, b));
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_06_Conversion/QuestionB.java
================================================
package Q5_06_Conversion;
import CtCILibrary.AssortedMethods;
public class QuestionB {
public static int bitSwapRequired(int a, int b){
int count = 0;
int c = a ^ b;
System.out.println("****");
System.out.println(c + ": " + AssortedMethods.toFullBinaryString(c));
while (c != 0) {
System.out.println("c - 1: " + c + ": " + AssortedMethods.toFullBinaryString(c - 1));
c = c & (c-1);
System.out.println("c: " + c + ": " + AssortedMethods.toFullBinaryString(c));
count++;
System.out.println("****");
}
return count;
}
public static void main(String[] args) {
int a = -23432;
int b = 512132;
System.out.println(a + ": " + AssortedMethods.toFullBinaryString(a));
System.out.println(b + ": " + AssortedMethods.toFullBinaryString(b));
System.out.println("Required number of bits: " + bitSwapRequired(a, b));
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_06_Conversion/Tester.java
================================================
package Q5_06_Conversion;
import CtCILibrary.AssortedMethods;
public class Tester {
public static int bitSwapRequired(int a, int b) {
int count = 0;
for (int c = a ^ b; c != 0; c = c >>> 1) {
count += c & 1;
}
return count;
}
public static int bitSwapRequired2(int a, int b){
int count = 0;
for (int c = a ^ b; c != 0; c = c & (c-1)) {
count++;
}
return count;
}
public static void main(String[] args) {
int a = -23432;
int b = 512132;
System.out.println(a + ": " + AssortedMethods.toFullBinaryString(a));
System.out.println(b + ": " + AssortedMethods.toFullBinaryString(b));
int nbits = QuestionA.bitSwapRequired(a, b);
int nbits2 = QuestionB.bitSwapRequired(a, b);
System.out.println("Required number of bits: " + nbits + " " + nbits2);
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_07_Pairwise_Swap/Question.java
================================================
package Q5_07_Pairwise_Swap;
import CtCILibrary.AssortedMethods;
public class Question {
public static int swapOddEvenBits(int x) {
return ( ((x & 0xaaaaaaaa) >>> 1) | ((x & 0x55555555) << 1) );
}
public static void main(String[] args) {
int a = 234321;
System.out.println(a + ": " + AssortedMethods.toFullBinaryString(a));
int b = swapOddEvenBits(a);
System.out.println(b + ": " + AssortedMethods.toFullBinaryString(b));
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Q5_08_Draw_Line/Question.java
================================================
package Q5_08_Draw_Line;
public class Question {
public static int computeByteNum(int width, int x, int y) {
return (width * y + x) / 8;
}
public static void drawLine(byte[] screen, int width, int x1, int x2, int y) {
int start_offset = x1 % 8;
int first_full_byte = x1 / 8;
if (start_offset != 0) {
first_full_byte++;
}
int end_offset = x2 % 8;
int last_full_byte = x2 / 8;
if (end_offset != 7) {
last_full_byte--;
}
// Set full bytes
for (int b = first_full_byte; b <= last_full_byte; b++) {
screen[(width / 8) * y + b] = (byte) 0xFF;
}
byte start_mask = (byte) (0xFF >> start_offset);
byte end_mask = (byte) ~(0xFF >> (end_offset + 1));
// Set start and end of line
if ((x1 / 8) == (x2 / 8)) { // If x1 and x2 are in the same byte
byte mask = (byte) (start_mask & end_mask);
screen[(width / 8) * y + (x1 / 8)] |= mask;
} else {
if (start_offset != 0) {
int byte_number = (width / 8) * y + first_full_byte - 1;
screen[byte_number] |= start_mask;
}
if (end_offset != 7) {
int byte_number = (width / 8) * y + last_full_byte + 1;
screen[byte_number] |= end_mask;
}
}
}
public static void printByte(byte b) {
for (int i = 7; i >= 0; i--) {
char c = ((b >> i) & 1) == 1 ? '1' : '_';
System.out.print(c);
}
}
public static void printScreen(byte[] screen, int width) {
int height = screen.length * 8 / width;
for (int r = 0; r < height; r++) {
for (int c = 0; c < width; c+=8) {
byte b = screen[computeByteNum(width, c, r)];
printByte(b);
}
System.out.println("");
}
}
public static void main(String[] args) {
int width = 8 * 1;
int height = 1;
for (int r = 0; r < height; r++) {
for (int c1 = 0; c1 < width; c1++) {
for (int c2 = c1; c2 < width; c2++) {
byte[] screen = new byte[width * height / 8];
System.out.println("row: " + r + ": " + c1 + " -> " + c2);
drawLine(screen, width, c1, c2, r);
printScreen(screen, width);
System.out.println("\n\n");
}
}
}
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Sample_Code/RightShifts.java
================================================
package Sample_Code;
import CtCILibrary.AssortedMethods;
public class RightShifts {
public static int repeatedArithmeticShift(int x, int count) {
for (int i = 0; i < count; i++) {
x >>= 1; // Arithmetic shift by 1
}
return x;
}
public static int repeatedLogicalShift(int x, int count) {
for (int i = 0; i < count; i++) {
x >>>= 1; // Logical shift by 1
}
return x;
}
public static void main(String[] args) {
for (int i = 8; i >= -8; i--) {
System.out.println(AssortedMethods.toFullBinaryString(i) + ": " + i);
}
int x = -93242;
int resultArithmetic = repeatedArithmeticShift(x, 40);
int resultLogical = repeatedLogicalShift(x, 40);
System.out.println(AssortedMethods.toFullBinaryString(resultArithmetic) + ": " + resultArithmetic);
System.out.println(AssortedMethods.toFullBinaryString(resultLogical) + ": " + resultLogical);
}
}
================================================
FILE: Java/Ch 05. Bit Manipulation/Sample_Code/Sample_Code.java
================================================
package Sample_Code;
import CtCILibrary.AssortedMethods;
public class Sample_Code {
public static boolean getBit(int num, int i) {
return ((num & (1 << i)) != 0);
}
public static int setBit(int num, int i) {
return num | (1 << i);
}
public static int clearBit(int num, int i) {
int mask = ~(1 << i);
return num & mask;
}
public static int updateBit(int num, int i, boolean bitIs1) {
int value = bitIs1 ? 1 : 0;
int mask = ~(1 << i);
return (num & mask) | (value << i);
}
public static int clearBitsMSBthroughI(int num, int i) {
int mask = (1 << i) - 1;
return num & mask;
}
public static int clearBitsIthrough0(int num, int i) {
int mask = (-1 << (i+1));
return num & mask;
}
public static void main(String[] args) {
int number = 59;
System.out.println("Testing with number: " + number);
// Get Bit
System.out.println("Get Bit");
System.out.println(AssortedMethods.toFullBinaryString(number));
for (int i = 31; i >= 0; i--) {
int res = getBit(number, i) ? 1 : 0;
System.out.print(res);
}
// Update Bit
System.out.println("\n\nUpdate Bit");
int num1 = 1578; // arbitrary number
for (int i = 31; i >= 0; i--) {
num1 = updateBit(num1, i, getBit(number, i));
}
System.out.println(num1);
// Set and Clear Bit
System.out.println("\nSet and Clear Bit");
int num2 = 1578; // arbitrary number
for (int i = 31; i >= 0; i--) {
if (getBit(number, i)) {
num2 = setBit(num2, i);
} else {
num2 = clearBit(num2, i);
}
}
System.out.println(num2);
// Clear Bits MSB through i
number = 13242352;
int clearMSBThrough = 4;
System.out.println("\nClear bits MSB through " + clearMSBThrough);
System.out.println(AssortedMethods.toFullBinaryString(number));
int num3 = clearBitsMSBthroughI(number, clearMSBThrough);
System.out.println(AssortedMethods.toFullBinaryString(num3));
// Clear Bits i through 0
int clearToLSB = 2;
System.out.println("\nClear bits " + clearToLSB + " through 0");
number = -1;
System.out.println(AssortedMethods.toFullBinaryString(number));
int num4 = clearBitsIthrough0(number, clearToLSB);
System.out.println(AssortedMethods.toFullBinaryString(num4));
}
}
================================================
FILE: Java/Ch 06. Math and Logic Puzzles/Introduction/PrimeNumbers.java
================================================
package Introduction;
public class PrimeNumbers {
public static boolean primeNaive(int n) {
for (int i = 2; i < n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
public static boolean primeSlightlyBetter(int n) {
int sqrt = (int) Math.sqrt(n);
for (int i = 2; i <= sqrt; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
for (int i = 2; i < 100; i++) {
if (primeSlightlyBetter(i)) {
System.out.println(i);
}
}
}
}
================================================
FILE: Java/Ch 06. Math and Logic Puzzles/Introduction/SieveOfEratosthenes.java
================================================
package Introduction;
public class SieveOfEratosthenes {
public static void crossOff(boolean[] flags, int prime) {
/* Cross off remaining multiples of prime. We can start with
* (prime*prime), because if we have a k * prime, where k < prime,
* this value would have already been crossed off in a prior
* iteration. */
for (int i = prime * prime; i < flags.length; i += prime) {
flags[i] = false;
}
}
public static int getNextPrime(boolean[] flags, int prime) {
int next = prime + 1;
while (next < flags.length && !flags[next]) {
next++;
}
return next;
}
public static void init(boolean[] flags) {
flags[0] = false;
flags[1] = false;
for (int i = 2; i < flags.length; i++) {
flags[i] = true;
}
}
public static int[] prune(boolean[] flags, int count) {
int[] primes = new int[count];
int index = 0;
for (int i = 0; i < flags.length; i++) {
if (flags[i]) {
primes[index] = i;
index++;
}
}
return primes;
}
public static boolean[] sieveOfEratosthenes(int max) {
boolean[] flags = new boolean[max + 1];
init(flags);
int prime = 2;
while (prime <= Math.sqrt(max)) {
/* Cross off remaining multiples of prime */
crossOff(flags, prime);
/* Find next value which is true */
prime = getNextPrime(flags, prime);
}
return flags; //prune(flags, count);
}
public static void main(String[] args) {
boolean[] primes = sieveOfEratosthenes(4);
for (int i = 0; i < primes.length; i++) {
if (primes[i]) {
System.out.println(i);
}
}
}
}
================================================
FILE: Java/Ch 06. Math and Logic Puzzles/Q6_05_Egg_Drop/Question.java
================================================
package Q6_05_Egg_Drop;
public class Question {
public static int breakingPoint = 89;
public static int countDrops = 0;
public static boolean willBreak(int floor) {
countDrops++;
return floor >= breakingPoint;
}
public static int findBreakingPoint(int floors) {
int interval = 14;
int previousFloor = 0;
int egg1 = interval;
/* Drop egg1 at decreasing intervals. */
while (!willBreak(egg1) && egg1 <= floors) {
interval -= 1;
previousFloor = egg1;
egg1 += interval;
}
/* Drop egg2 at 1 unit increments. */
int egg2 = previousFloor + 1;
while (egg2 < egg1 && egg2 <= floors && !willBreak(egg2)) {
egg2 += 1;
}
/* If it didn’t break, return -1. */
return egg2 > floors ? -1 : egg2;
}
public static void main(String[] args) {
int max = 0;
for (int i = 1; i <= 100; i++) {
countDrops = 0;
breakingPoint = i;
int bp = findBreakingPoint(100);
if (bp == breakingPoint) {
System.out.println("SUCCESS: " + i + " -> " + bp + " -> " + countDrops);
} else {
System.out.println("ERROR: " + i + " -> " + bp + " vs " + breakingPoint);
break;
}
max = countDrops > max ? countDrops : max;
}
System.out.println(max);
}
}
================================================
FILE: Java/Ch 06. Math and Logic Puzzles/Q6_07_The_Apocalypse/Question.java
================================================
package Q6_07_The_Apocalypse;
import java.util.Random;
public class Question {
public static int[] runOneFamily() {
Random random = new Random();
int boys = 0;
int girls = 0;
while (girls == 0) { // until we have a girl
if (random.nextBoolean()) { // girl
girls += 1;
} else { // boy
boys += 1;
}
}
int[] genders = {girls, boys};
return genders;
}
public static double runNFamilies(int n) {
int boys = 0;
int girls = 0;
for (int i = 0; i < n; i++) {
int[] genders = runOneFamily();
girls += genders[0];
boys += genders[1];
}
return girls / (double) (boys + girls);
}
public static void main(String[] args) {
double ratio = runNFamilies(10000000);
System.out.println(ratio);
}
}
================================================
FILE: Java/Ch 06. Math and Logic Puzzles/Q6_10_Test_Strips/Bottle.java
================================================
package Q6_10_Test_Strips;
public class Bottle {
private boolean poisoned = false;
private int id;
public Bottle(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setAsPoisoned() {
poisoned = true;
}
public boolean isPoisoned() {
return poisoned;
}
}
================================================
FILE: Java/Ch 06. Math and Logic Puzzles/Q6_10_Test_Strips/QuestionA.java
================================================
package Q6_10_Test_Strips;
import java.util.ArrayList;
import java.util.Random;
public class QuestionA {
public static int findPoisonedBottle(ArrayList bottles, ArrayList strips) {
int today = 0;
while (bottles.size() > 1 && strips.size() > 0) {
/* Run tests. */
runTestSet(bottles, strips, today);
/* Wait for results. */
today += TestStrip.DAYS_FOR_RESULT;
/* Check results. */
for (TestStrip strip : strips) {
if (strip.isPositiveOnDay(today)) {
bottles = strip.getLastWeeksBottles(today);
strips.remove(strip);
break;
}
}
}
if (bottles.size() == 1) {
System.out.println("Suspected bottle is " + bottles.get(0).getId() + " on day " + today);
return bottles.get(0).getId();
}
return -1;
}
public static void runTestSet(ArrayList bottles, ArrayList strips, int day) {
int index = 0;
for (Bottle bottle : bottles) {
TestStrip strip = strips.get(index);
strip.addDropOnDay(day, bottle);
index = (index + 1) % strips.size();
}
}
public static ArrayList createBottles(int nBottles, int poisoned) {
ArrayList bottles = new ArrayList();
for (int i = 0; i < nBottles; i++) {
bottles.add(new Bottle(i));
}
if (poisoned == -1) {
Random random = new Random();
poisoned = random.nextInt(nBottles);
}
bottles.get(poisoned).setAsPoisoned();
System.out.println("Added poison to bottle " + poisoned);
return bottles;
}
public static ArrayList createTestStrips(int nTestStrips) {
ArrayList testStrips = new ArrayList();
for (int i = 0; i < nTestStrips; i++) {
testStrips.add(new TestStrip(i));
}
return testStrips;
}
public static void main(String[] args) {
int nBottles = 1000;
int nTestStrips = 10;
for (int poisoned = 0; poisoned < nBottles; poisoned++) {
ArrayList bottles = createBottles(nBottles, poisoned);
ArrayList testStrips = createTestStrips(nTestStrips);
int poisonedId = findPoisonedBottle(bottles, testStrips);
System.out.println("Suspected Bottle: " + poisonedId);
if (poisonedId != poisoned) {
System.out.println("ERROR");
break;
}
}
}
}
================================================
FILE: Java/Ch 06. Math and Logic Puzzles/Q6_10_Test_Strips/QuestionB.java
================================================
package Q6_10_Test_Strips;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Random;
public class QuestionB {
public static ArrayList createBottles(int nBottles, int poisoned) {
ArrayList bottles = new ArrayList();
for (int i = 0; i < nBottles; i++) {
bottles.add(new Bottle(i));
}
if (poisoned == -1) {
Random random = new Random();
poisoned = random.nextInt(nBottles);
}
bottles.get(poisoned).setAsPoisoned();
System.out.println("Added poison to bottle " + poisoned);
return bottles;
}
public static int findPoisonedBottle(ArrayList bottles, ArrayList strips) {
if (bottles.size() > 1000 || strips.size() < 10) return -1;
int tests = 4; // three digits, plus one extra
int nTestStrips = strips.size();
/* Run tests. */
for (int day = 0; day < tests; day++) {
runTestSet(bottles, strips, day);
}
/* Get results. */
HashSet previousResults = new HashSet();
int[] digits = new int[tests];
for (int day = 0; day < tests; day++) {
int resultDay = day + TestStrip.DAYS_FOR_RESULT;
digits[day] = getPositiveOnDay(strips, resultDay, previousResults);
previousResults.add(digits[day]);
}
/* If day 1's results matched day 0's, update the digit. */
if (digits[1] == -1) {
digits[1] = digits[0];
}
/* If day 2 matched day 0 or day 1, check day 3. Day 3 is
* the same as day 2, but incremented by 1. */
if (digits[2] == -1) {
if (digits[3] == -1) { /* Day 3 didn't give new result */
/* Digit 2 equals digit 0 or digit 1. But, digit 2, when incremented also matches
* digit 0 or digit 1. This means that digit 0 incremented matches digit 1, or the
* other way around. */
digits[2] = ((digits[0] + 1) % nTestStrips) == digits[1] ? digits[0] : digits[1];
} else {
digits[2] = (digits[3] - 1 + nTestStrips) % nTestStrips;
}
}
return digits[0] * 100 + digits[1] * 10 + digits[2];
}
/* Run set of tests for this day. */
public static void runTestSet(ArrayList bottles, ArrayList strips, int day) {
if (day > 3) return; // only works for 3 days (digits) + one extra
for (Bottle bottle : bottles) {
int index = getTestStripIndexForDay(bottle, day, strips.size());
TestStrip testStrip = strips.get(index);
testStrip.addDropOnDay(day, bottle);
}
}
/* Get test strip index that should be used on this bottle on this day. */
public static int getTestStripIndexForDay(Bottle bottle, int day, int nTestStrips) {
int id = bottle.getId();
switch (day) {
case 0: return id /100;
case 1: return (id % 100) / 10;
case 2: return id % 10;
case 3: return (id % 10 + 1) % nTestStrips;
default: return -1;
}
}
/* Get results that are positive for a particular day, excluding prior results. */
public static int getPositiveOnDay(ArrayList testStrips, int day, HashSet previousResults) {
for (TestStrip testStrip : testStrips) {
int id = testStrip.getId();
if (testStrip.isPositiveOnDay(day) && !previousResults.contains(id)) {
return testStrip.getId();
}
}
return -1;
}
public static ArrayList createTestStrips(int nTestStrips) {
ArrayList testStrips = new ArrayList();
for (int i = 0; i < nTestStrips; i++) {
testStrips.add(new TestStrip(i));
}
return testStrips;
}
public static void main(String[] args) {
int nBottles = 1000;
int nTestStrips = 10;
for (int poisoned = 0; poisoned < nBottles; poisoned++) {
ArrayList bottles = createBottles(nBottles, poisoned);
ArrayList testStrips = createTestStrips(nTestStrips);
int poisonedId = findPoisonedBottle(bottles, testStrips);
System.out.println("Suspected Bottle: " + poisonedId);
if (poisonedId != poisoned) {
System.out.println("ERROR");
break;
}
}
}
}
================================================
FILE: Java/Ch 06. Math and Logic Puzzles/Q6_10_Test_Strips/QuestionC.java
================================================
package Q6_10_Test_Strips;
import java.util.ArrayList;
import java.util.Random;
public class QuestionC {
public static ArrayList createBottles(int nBottles, int poisoned) {
ArrayList bottles = new ArrayList();
for (int i = 0; i < nBottles; i++) {
bottles.add(new Bottle(i));
}
if (poisoned == -1) {
Random random = new Random();
poisoned = random.nextInt(nBottles);
}
bottles.get(poisoned).setAsPoisoned();
System.out.println("Added poison to bottle " + poisoned);
return bottles;
}
public static int findPoisonedBottle(ArrayList bottles, ArrayList strips) {
runTests(bottles, strips);
ArrayList positive = getPositiveOnDay(strips, 7);
return setBits(positive);
}
/* Add bottles to test strips */
public static void runTests(ArrayList bottles, ArrayList testStrips) {
for (Bottle bottle : bottles) {
int id = bottle.getId();
int bitIndex = 0;
while (id > 0) {
if ((id & 1) == 1) {
testStrips.get(bitIndex).addDropOnDay(0, bottle);
}
bitIndex++;
id >>= 1;
}
}
}
/* Get test strips that are positive on a particular day. */
public static ArrayList getPositiveOnDay(ArrayList testStrips, int day) {
ArrayList positive = new ArrayList();
for (TestStrip testStrip : testStrips) {
int id = testStrip.getId();
if (testStrip.isPositiveOnDay(day)) {
positive.add(id);
}
}
return positive;
}
/* Create number by setting bits with indices specified in positive. */
public static int setBits(ArrayList positive) {
int id = 0;
for (Integer bitIndex : positive) {
id |= 1 << bitIndex;
}
return id;
}
public static ArrayList createTestStrips(int nTestStrips) {
ArrayList testStrips = new ArrayList();
for (int i = 0; i < nTestStrips; i++) {
testStrips.add(new TestStrip(i));
}
return testStrips;
}
public static void main(String[] args) {
int nBottles = 1000;
int nTestStrips = 10;
for (int poisoned = 0; poisoned < nBottles; poisoned++) {
ArrayList bottles = createBottles(nBottles, poisoned);
ArrayList testStrips = createTestStrips(nTestStrips);
int poisonedId = findPoisonedBottle(bottles, testStrips);
System.out.println("Suspected Bottle: " + poisonedId);
if (poisonedId != poisoned) {
System.out.println("ERROR");
break;
}
}
}
}
================================================
FILE: Java/Ch 06. Math and Logic Puzzles/Q6_10_Test_Strips/TestStrip.java
================================================
package Q6_10_Test_Strips;
import java.util.ArrayList;
public class TestStrip {
public static int DAYS_FOR_RESULT = 7;
private ArrayList> dropsByDay = new ArrayList>();
private int id;
public TestStrip(int id) {
this.id = id;
}
public int getId() {
return id;
}
/* Resize list of days/drops to be large enough. */
private void sizeDropsForDay(int day) {
while (dropsByDay.size() <= day) {
dropsByDay.add(new ArrayList());
}
}
/* Add drop from bottle on specific day. */
public void addDropOnDay(int day, Bottle bottle) {
sizeDropsForDay(day);
ArrayList drops = dropsByDay.get(day);
drops.add(bottle);
}
/* Checks if any of the bottles in the set are poisoned. */
private boolean hasPoison(ArrayList bottles) {
for (Bottle b : bottles) {
if (b.isPoisoned()) {
return true;
}
}
return false;
}
/* Gets bottles that were used in the test DAYS_FOR_RESULT days ago. */
public ArrayList getLastWeeksBottles(int day) {
if (day < DAYS_FOR_RESULT) {
return null;
}
return dropsByDay.get(day - DAYS_FOR_RESULT);
}
/* Checks if the test strip has had any poisoned bottles since before DAYS_FOR_RESULT */
public boolean isPositiveOnDay(int day) {
int testDay = day - DAYS_FOR_RESULT;
if (testDay < 0 || testDay >= dropsByDay.size()) {
return false;
}
for (int d = 0; d <= testDay; d++) {
ArrayList bottles = dropsByDay.get(d);
if (hasPoison(bottles)) {
return true;
}
}
return false;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_01_Deck_of_Cards/BlackJackCard.java
================================================
package Q7_01_Deck_of_Cards;
public class BlackJackCard extends Card {
public BlackJackCard(int c, Suit s) {
super(c, s);
}
public int value() {
if (isAce()) { // Ace
return 1;
} else if (isFaceCard()) { // Face card
return 10;
} else { // Number card
return faceValue;
}
}
public int minValue() {
if (isAce()) { // Ace
return 1;
} else {
return value();
}
}
public int maxValue() {
if (isAce()) { // Ace
return 11;
} else {
return value();
}
}
public boolean isAce() {
return faceValue == 1;
}
public boolean isFaceCard() {
return faceValue >= 11 && faceValue <= 13;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_01_Deck_of_Cards/BlackJackGameAutomator.java
================================================
package Q7_01_Deck_of_Cards;
import java.util.ArrayList;
public class BlackJackGameAutomator {
private Deck deck;
private BlackJackHand[] hands;
private static final int HIT_UNTIL = 16;
public BlackJackGameAutomator(int numPlayers) {
hands = new BlackJackHand[numPlayers];
for (int i = 0; i < numPlayers; i++) {
hands[i] = new BlackJackHand();
}
}
public boolean dealInitial() {
for (BlackJackHand hand : hands) {
BlackJackCard card1 = deck.dealCard();
BlackJackCard card2 = deck.dealCard();
if (card1 == null || card2 == null) {
return false;
}
hand.addCard(card1);
hand.addCard(card2);
}
return true;
}
public ArrayList getBlackJacks() {
ArrayList winners = new ArrayList();
for (int i = 0; i < hands.length; i++) {
if (hands[i].isBlackJack()) {
winners.add(i);
}
}
return winners;
}
public boolean playHand(int i) {
BlackJackHand hand = hands[i];
return playHand(hand);
}
public boolean playHand(BlackJackHand hand) {
while (hand.score() < HIT_UNTIL) {
BlackJackCard card = deck.dealCard();
if (card == null) {
return false;
}
hand.addCard(card);
}
return true;
}
public boolean playAllHands() {
for (BlackJackHand hand : hands) {
if (!playHand(hand)) {
return false;
}
}
return true;
}
public ArrayList getWinners() {
ArrayList winners = new ArrayList();
int winningScore = 0;
for (int i = 0; i < hands.length; i++) {
BlackJackHand hand = hands[i];
if (!hand.busted()) {
if (hand.score() > winningScore) {
winningScore = hand.score();
winners.clear();
winners.add(i);
} else if (hand.score() == winningScore) {
winners.add(i);
}
}
}
return winners;
}
public void initializeDeck() {
ArrayList cards = new ArrayList();
for (int i = 1; i <= 13; i++) {
for (int j = 0; j <= 3; j++) {
Suit suit = Suit.getSuitFromValue(j);
BlackJackCard card = new BlackJackCard(i, suit);
cards.add(card);
}
}
deck = new Deck();
deck.setDeckOfCards(cards);
deck.shuffle();
}
public void printHandsAndScore() {
for (int i = 0; i < hands.length; i++) {
System.out.print("Hand " + i + " (" + hands[i].score() + "): ");
hands[i].print();
System.out.println("");
}
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_01_Deck_of_Cards/BlackJackHand.java
================================================
package Q7_01_Deck_of_Cards;
import java.util.ArrayList;
public class BlackJackHand extends Hand {
public BlackJackHand() {
}
public int score() {
ArrayList scores = possibleScores();
int maxUnder = Integer.MIN_VALUE;
int minOver = Integer.MAX_VALUE;
for (int score : scores) {
if (score > 21 && score < minOver) {
minOver = score;
} else if (score <= 21 && score > maxUnder) {
maxUnder = score;
}
}
return maxUnder == Integer.MIN_VALUE ? minOver : maxUnder;
}
private ArrayList possibleScores() {
ArrayList scores = new ArrayList();
if (cards.size() == 0) {
return scores;
}
for (BlackJackCard card : cards) {
addCardToScoreList(card, scores);
}
return scores;
}
private void addCardToScoreList(BlackJackCard card, ArrayList scores) {
if (scores.size() == 0) {
scores.add(0);
}
int length = scores.size();
for (int i = 0; i < length; i++) {
int score = scores.get(i);
scores.set(i, score + card.minValue());
if (card.minValue() != card.maxValue()) {
scores.add(score + card.maxValue());
}
}
}
public boolean busted() {
return score() > 21;
}
public boolean is21() {
return score() == 21;
}
public boolean isBlackJack() {
if (cards.size() != 2) {
return false;
}
BlackJackCard first = cards.get(0);
BlackJackCard second = cards.get(1);
return (first.isAce() && second.isFaceCard()) || (second.isAce() && first.isFaceCard());
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_01_Deck_of_Cards/Card.java
================================================
package Q7_01_Deck_of_Cards;
public abstract class Card {
private boolean available = true;
/* number or face that's on card - a number 2 through 10,
* or 11 for Jack, 12 for Queen, 13 for King, or 1 for Ace
*/
protected int faceValue;
protected Suit suit;
public Card(int c, Suit s) {
faceValue = c;
suit = s;
}
public abstract int value();
public Suit suit() {
return suit;
}
/* returns whether or not the card is available to be given out to someone */
public boolean isAvailable() {
return available;
}
public void markUnavailable() {
available = false;
}
public void markAvailable() {
available = true;
}
public void print() {
String[] faceValues = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
System.out.print(faceValues[faceValue - 1]);
switch (suit) {
case Club:
System.out.print("c");
break;
case Heart:
System.out.print("h");
break;
case Diamond:
System.out.print("d");
break;
case Spade:
System.out.print("s");
break;
}
System.out.print(" ");
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_01_Deck_of_Cards/Deck.java
================================================
package Q7_01_Deck_of_Cards;
import java.util.ArrayList;
import CtCILibrary.AssortedMethods;
public class Deck {
private ArrayList cards;
private int dealtIndex = 0; // marks first undealt card
public Deck() {
}
public void setDeckOfCards(ArrayList deckOfCards) {
cards = deckOfCards;
}
public void shuffle() {
for (int i = 0; i < cards.size(); i++) {
int j = AssortedMethods.randomIntInRange(i, cards.size() - i - 1);
T card1 = cards.get(i);
T card2 = cards.get(j);
cards.set(i, card2);
cards.set(j, card1);
}
}
public int remainingCards() {
return cards.size() - dealtIndex;
}
public T[] dealHand(int number) {
if (remainingCards() < number) {
return null;
}
T[] hand = (T[]) new Card[number];
int count = 0;
while (count < number) {
T card = dealCard();
if (card != null) {
hand[count] = card;
count++;
}
}
return hand;
}
public T dealCard() {
if (remainingCards() == 0) {
return null;
}
T card = cards.get(dealtIndex);
card.markUnavailable();
dealtIndex++;
return card;
}
public void print() {
for (Card card : cards) {
card.print();
}
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_01_Deck_of_Cards/Hand.java
================================================
package Q7_01_Deck_of_Cards;
import java.util.ArrayList;
public class Hand {
protected ArrayList cards = new ArrayList();
public int score() {
int score = 0;
for (T card : cards) {
score += card.value();
}
return score;
}
public void addCard(T card) {
cards.add(card);
}
public void print() {
for (Card card : cards) {
card.print();
}
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_01_Deck_of_Cards/Question.java
================================================
package Q7_01_Deck_of_Cards;
import java.util.ArrayList;
public class Question {
public static void main(String[] args) {
int numHands = 5;
BlackJackGameAutomator automator = new BlackJackGameAutomator(numHands);
automator.initializeDeck();
boolean success = automator.dealInitial();
if (!success) {
System.out.println("Error. Out of cards.");
} else {
System.out.println("-- Initial --");
automator.printHandsAndScore();
ArrayList blackjacks = automator.getBlackJacks();
if (blackjacks.size() > 0) {
System.out.print("Blackjack at ");
for (int i : blackjacks) {
System.out.print(i + ", ");
}
System.out.println("");
} else {
success = automator.playAllHands();
if (!success) {
System.out.println("Error. Out of cards.");
} else {
System.out.println("\n-- Completed Game --");
automator.printHandsAndScore();
ArrayList winners = automator.getWinners();
if (winners.size() > 0) {
System.out.print("Winners: ");
for (int i : winners) {
System.out.print(i + ", ");
}
System.out.println("");
} else {
System.out.println("Draw. All players have busted.");
}
}
}
}
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_01_Deck_of_Cards/Suit.java
================================================
package Q7_01_Deck_of_Cards;
public enum Suit {
Club (0),
Diamond (1),
Heart (2),
Spade (3);
private int value;
private Suit(int v) {
value = v;
}
public int getValue() {
return value;
}
public static Suit getSuitFromValue(int value) {
switch (value) {
case 0:
return Suit.Club;
case 1:
return Suit.Diamond;
case 2:
return Suit.Heart;
case 3:
return Suit.Spade;
default:
return null;
}
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_02_Call_Center/Call.java
================================================
package Q7_02_Call_Center;
/* Represents a call from a user. Calls have a minimum rank and are assigned to the
* first employee who can handle that call.
*/
public class Call {
/* Minimal rank of employee who can handle this call. */
private Rank rank;
/* Person who is calling. */
private Caller caller;
/* Employee who is handling call. */
private Employee handler;
public Call(Caller c) {
rank = Rank.Responder;
caller = c;
}
/* Set employee who is handling call. */
public void setHandler(Employee e) {
handler = e;
}
/* Play recorded message to the customer. */
public void reply(String message) {
System.out.println(message);
}
public Rank getRank() {
return rank;
}
public void setRank(Rank r) {
rank = r;
}
public Rank incrementRank() {
if (rank == Rank.Responder) {
rank = Rank.Manager;
} else if (rank == Rank.Manager) {
rank = Rank.Director;
}
return rank;
}
/* Disconnect call. */
public void disconnect() {
reply("Thank you for calling");
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_02_Call_Center/CallHandler.java
================================================
package Q7_02_Call_Center;
import java.util.ArrayList;
import java.util.List;
/* CallHandler represents the body of the program,
* and all calls are funneled first through it.
*/
public class CallHandler {
/* We have 3 levels of employees: respondents, managers, directors. */
private final int LEVELS = 3;
/* Initialize with 10 respondents, 4 managers, and 2 directors. */
private final int NUM_RESPONDENTS = 10;
private final int NUM_MANAGERS = 4;
private final int NUM_DIRECTORS = 2;
/* List of employees, by level.
* employeeLevels[0] = respondents
* employeeLevels[1] = managers
* employeeLevels[2] = directors
*/
List> employeeLevels;
/* queues for each call�s rank */
List> callQueues;
public CallHandler() {
employeeLevels = new ArrayList>(LEVELS);
callQueues = new ArrayList>(LEVELS);
// Create respondents.
ArrayList respondents = new ArrayList(NUM_RESPONDENTS);
for (int k = 0; k < NUM_RESPONDENTS - 1; k++) {
respondents.add(new Respondent(this));
}
employeeLevels.add(respondents);
// Create managers.
ArrayList managers = new ArrayList(NUM_MANAGERS);
managers.add(new Manager(this));
employeeLevels.add(managers);
// Create directors.
ArrayList directors = new ArrayList(NUM_DIRECTORS);
directors.add(new Director(this));
employeeLevels.add(directors);
}
/* Gets the first available employee who can handle this call. */
public Employee getHandlerForCall(Call call) {
for (int level = call.getRank().getValue(); level < LEVELS - 1; level++) {
List employeeLevel = employeeLevels.get(level);
for (Employee emp : employeeLevel) {
if (emp.isFree()) {
return emp;
}
}
}
return null;
}
/* Routes the call to an available employee, or saves in a queue if no employee available. */
public void dispatchCall(Caller caller) {
Call call = new Call(caller);
dispatchCall(call);
}
/* Routes the call to an available employee, or saves in a queue if no employee available. */
public void dispatchCall(Call call) {
/* Try to route the call to an employee with minimal rank. */
Employee emp = getHandlerForCall(call);
if (emp != null) {
emp.receiveCall(call);
call.setHandler(emp);
} else {
/* Place the call into corresponding call queue according to its rank. */
call.reply("Please wait for free employee to reply");
callQueues.get(call.getRank().getValue()).add(call);
}
}
/* An employee got free. Look for a waiting call that he/she can serve. Return true
* if we were able to assign a call, false otherwise. */
public boolean assignCall(Employee emp) {
/* Check the queues, starting from the highest rank this employee can serve. */
for (int rank = emp.getRank().getValue(); rank >= 0; rank--) {
List que = callQueues.get(rank);
/* Remove the first call, if any */
if (que.size() > 0) {
Call call = que.remove(0);
if (call != null) {
emp.receiveCall(call);
return true;
}
}
}
return false;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_02_Call_Center/Caller.java
================================================
package Q7_02_Call_Center;
public class Caller {
private String name;
private int userId;
public Caller(int id, String nm) {
name = nm;
userId = id;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_02_Call_Center/Director.java
================================================
package Q7_02_Call_Center;
class Director extends Employee {
public Director(CallHandler callHandler) {
super(callHandler);
rank = Rank.Director;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_02_Call_Center/Employee.java
================================================
package Q7_02_Call_Center;
/* Employee is a super class for the Director, Manager, and Respondent classes. It is implemented as an
* abstract class, since there should be no reason to instantiated an Employee type directly.
*/
abstract class Employee {
private Call currentCall = null;
protected Rank rank;
private CallHandler callHandler;
public Employee(CallHandler handler) {
callHandler = handler;
}
/* Start the conversation */
public void receiveCall(Call call) {
currentCall = call;
}
/* the issue is resolved, finish the call */
public void callCompleted() {
if (currentCall != null) {
/* Disconnect the call. */
currentCall.disconnect();
/* Free the employee */
currentCall = null;
}
/* Check if there is a call waiting in queue */
assignNewCall();
}
/*
* The issue has not been resolved. Escalate the call, and assign a new call
* to the employee.
*/
public void escalateAndReassign() {
if (currentCall != null) {
/* escalate call */
currentCall.incrementRank();
callHandler.dispatchCall(currentCall);
/* free the employee */
currentCall = null;
}
/* assign a new call */
assignNewCall();
}
/* Assign a new call to an employee, if the employee is free. */
public boolean assignNewCall() {
if (!isFree()) {
return false;
}
return callHandler.assignCall(this);
}
/* Returns whether or not the employee is free. */
public boolean isFree() {
return currentCall == null;
}
public Rank getRank() {
return rank;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_02_Call_Center/Manager.java
================================================
package Q7_02_Call_Center;
class Manager extends Employee {
public Manager(CallHandler callHandler) {
super(callHandler);
rank = Rank.Manager;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_02_Call_Center/Rank.java
================================================
package Q7_02_Call_Center;
public enum Rank {
Responder (0),
Manager (1),
Director (2);
private int value;
private Rank(int v) {
value = v;
}
public int getValue() {
return value;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_02_Call_Center/Respondent.java
================================================
package Q7_02_Call_Center;
class Respondent extends Employee {
public Respondent(CallHandler callHandler) {
super(callHandler);
rank = Rank.Responder;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_02_Call_Center/Test.java
================================================
package Q7_02_Call_Center;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
CallHandler ch = new CallHandler();
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_03_Jukebox/CD.java
================================================
package Q7_03_Jukebox;
public class CD {
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_03_Jukebox/CDPlayer.java
================================================
package Q7_03_Jukebox;
public class CDPlayer {
private Playlist p;
private CD c;
public Playlist getPlaylist() { return p; }
public void setPlaylist(Playlist p) { this.p = p; }
public CD getCD() { return c; }
public void setCD(CD c) { this.c = c; }
public CDPlayer(Playlist p) { this.p = p; }
public CDPlayer(CD c, Playlist p) {
this.p = p;
this.c = c;
}
public CDPlayer(CD c){ this.c = c; }
public void playSong(Song s) { }
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_03_Jukebox/JukeBox.java
================================================
package Q7_03_Jukebox;
import java.util.Set;
public class JukeBox {
private CDPlayer cdPlayer;
private User user;
private Set cdCollection;
private SongSelector ts;
public JukeBox(CDPlayer cdPlayer, User user, Set cdCollection,
SongSelector ts) {
super();
this.cdPlayer = cdPlayer;
this.user = user;
this.cdCollection = cdCollection;
this.ts = ts;
}
public Song getCurrentSong() { return ts.getCurrentSong(); }
public void setUser(User u) { this.user = u; }
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_03_Jukebox/Playlist.java
================================================
package Q7_03_Jukebox;
import java.util.Queue;
public class Playlist {
private Song song;
private Queue queue;
public Playlist(Song song, Queue queue) {
super();
this.song = song;
this.queue = queue;
}
public Song getNextSongToPlay(){ return queue.peek(); }
public void queueUpSong(Song s){ queue.add(s); }
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_03_Jukebox/Song.java
================================================
package Q7_03_Jukebox;
public class Song {
private String songName;
public String toString() { return songName; }
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_03_Jukebox/SongSelector.java
================================================
package Q7_03_Jukebox;
public class SongSelector {
private Song currentSong;
public SongSelector(Song s) { currentSong=s; }
public void setSong(Song s) { currentSong = s; }
public Song getCurrentSong() { return currentSong; }
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_03_Jukebox/User.java
================================================
package Q7_03_Jukebox;
public class User {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public long getID() { return ID; }
public void setID(long iD) { ID = iD; }
private long ID;
public User(String name, long iD) {
this.name = name;
ID = iD;
}
public User getUser() { return this; }
public static User addUser(String name, long iD){
return new User(name, iD);
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_04_Parking_Lot/Bus.java
================================================
package Q7_04_Parking_Lot;
public class Bus extends Vehicle {
public Bus() {
spotsNeeded = 5;
size = VehicleSize.Large;
}
public boolean canFitInSpot(ParkingSpot spot) {
return spot.getSize() == VehicleSize.Large;
}
public void print() {
System.out.print("B");
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_04_Parking_Lot/Car.java
================================================
package Q7_04_Parking_Lot;
public class Car extends Vehicle {
public Car() {
spotsNeeded = 1;
size = VehicleSize.Compact;
}
public boolean canFitInSpot(ParkingSpot spot) {
return spot.getSize() == VehicleSize.Large || spot.getSize() == VehicleSize.Compact;
}
public void print() {
System.out.print("C");
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_04_Parking_Lot/Level.java
================================================
package Q7_04_Parking_Lot;
/* Represents a level in a parking garage */
public class Level {
private int floor;
private ParkingSpot[] spots;
private int availableSpots = 0; // number of free spots
private static final int SPOTS_PER_ROW = 10;
public Level(int flr, int numberSpots) {
floor = flr;
spots = new ParkingSpot[numberSpots];
int largeSpots = numberSpots / 4;
int bikeSpots = numberSpots / 4;
int compactSpots = numberSpots - largeSpots - bikeSpots;
for (int i = 0; i < numberSpots; i++) {
VehicleSize sz = VehicleSize.Motorcycle;
if (i < largeSpots) {
sz = VehicleSize.Large;
} else if (i < largeSpots + compactSpots) {
sz = VehicleSize.Compact;
}
int row = i / SPOTS_PER_ROW;
spots[i] = new ParkingSpot(this, row, i, sz);
}
availableSpots = numberSpots;
}
public int availableSpots() {
return availableSpots;
}
/* Try to find a place to park this vehicle. Return false if failed. */
public boolean parkVehicle(Vehicle vehicle) {
if (availableSpots() < vehicle.getSpotsNeeded()) {
return false;
}
int spotNumber = findAvailableSpots(vehicle);
if (spotNumber < 0) {
return false;
}
return parkStartingAtSpot(spotNumber, vehicle);
}
/* Park a vehicle starting at the spot spotNumber, and continuing until vehicle.spotsNeeded. */
private boolean parkStartingAtSpot(int spotNumber, Vehicle vehicle) {
vehicle.clearSpots();
boolean success = true;
for (int i = spotNumber; i < spotNumber + vehicle.spotsNeeded; i++) {
success &= spots[i].park(vehicle);
}
availableSpots -= vehicle.spotsNeeded;
return success;
}
/* find a spot to park this vehicle. Return index of spot, or -1 on failure. */
private int findAvailableSpots(Vehicle vehicle) {
int spotsNeeded = vehicle.getSpotsNeeded();
int lastRow = -1;
int spotsFound = 0;
for (int i = 0; i < spots.length; i++) {
ParkingSpot spot = spots[i];
if (lastRow != spot.getRow()) {
spotsFound = 0;
lastRow = spot.getRow();
}
if (spot.canFitVehicle(vehicle)) {
spotsFound++;
} else {
spotsFound = 0;
}
if (spotsFound == spotsNeeded) {
return i - (spotsNeeded - 1);
}
}
return -1;
}
public void print() {
int lastRow = -1;
for (int i = 0; i < spots.length; i++) {
ParkingSpot spot = spots[i];
if (spot.getRow() != lastRow) {
System.out.print(" ");
lastRow = spot.getRow();
}
spot.print();
}
}
/* When a car was removed from the spot, increment availableSpots */
public void spotFreed() {
availableSpots++;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_04_Parking_Lot/Motorcycle.java
================================================
package Q7_04_Parking_Lot;
public class Motorcycle extends Vehicle {
public Motorcycle() {
spotsNeeded = 1;
size = VehicleSize.Motorcycle;
}
public boolean canFitInSpot(ParkingSpot spot) {
return true;
}
public void print() {
System.out.print("M");
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_04_Parking_Lot/ParkingLot.java
================================================
package Q7_04_Parking_Lot;
public class ParkingLot {
private Level[] levels;
private final int NUM_LEVELS = 5;
public ParkingLot() {
levels = new Level[NUM_LEVELS];
for (int i = 0; i < NUM_LEVELS; i++) {
levels[i] = new Level(i, 30);
}
}
/* Park the vehicle in a spot (or multiple spots). Return false if failed. */
public boolean parkVehicle(Vehicle vehicle) {
for (int i = 0; i < levels.length; i++) {
if (levels[i].parkVehicle(vehicle)) {
return true;
}
}
return false;
}
public void print() {
for (int i = 0; i < levels.length; i++) {
System.out.print("Level" + i + ": ");
levels[i].print();
System.out.println("");
}
System.out.println("");
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_04_Parking_Lot/ParkingSpot.java
================================================
package Q7_04_Parking_Lot;
public class ParkingSpot {
private Vehicle vehicle;
private VehicleSize spotSize;
private int row;
private int spotNumber;
private Level level;
public ParkingSpot(Level lvl, int r, int n, VehicleSize sz) {
level = lvl;
row = r;
spotNumber = n;
spotSize = sz;
}
public boolean isAvailable() {
return vehicle == null;
}
/* Checks if the spot is big enough for the vehicle (and is available). This compares
* the SIZE only. It does not check if it has enough spots. */
public boolean canFitVehicle(Vehicle vehicle) {
return isAvailable() && vehicle.canFitInSpot(this);
}
/* Park vehicle in this spot. */
public boolean park(Vehicle v) {
if (!canFitVehicle(v)) {
return false;
}
vehicle = v;
vehicle.parkInSpot(this);
return true;
}
public int getRow() {
return row;
}
public int getSpotNumber() {
return spotNumber;
}
public VehicleSize getSize() {
return spotSize;
}
/* Remove vehicle from spot, and notify level that a new spot is available */
public void removeVehicle() {
level.spotFreed();
vehicle = null;
}
public void print() {
if (vehicle == null) {
if (spotSize == VehicleSize.Compact) {
System.out.print("c");
} else if (spotSize == VehicleSize.Large) {
System.out.print("l");
} else if (spotSize == VehicleSize.Motorcycle) {
System.out.print("m");
}
} else {
vehicle.print();
}
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_04_Parking_Lot/Question.java
================================================
package Q7_04_Parking_Lot;
import CtCILibrary.AssortedMethods;
public class Question {
/**
* @param args
*/
public static void main(String[] args) {
ParkingLot lot = new ParkingLot();
Vehicle v = null;
while (v == null || lot.parkVehicle(v)) {
lot.print();
int r = AssortedMethods.randomIntInRange(0, 10);
if (r < 2) {
v = new Bus();
} else if (r < 4) {
v = new Motorcycle();
} else {
v = new Car();
}
System.out.print("\nParking a ");
v.print();
System.out.println("");
}
System.out.println("Parking Failed. Final state: ");
lot.print();
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_04_Parking_Lot/Vehicle.java
================================================
package Q7_04_Parking_Lot;
import java.util.ArrayList;
public abstract class Vehicle {
protected ArrayList parkingSpots = new ArrayList();
protected String licensePlate;
protected int spotsNeeded;
protected VehicleSize size;
public int getSpotsNeeded() {
return spotsNeeded;
}
public VehicleSize getSize() {
return size;
}
/* Park vehicle in this spot (among others, potentially) */
public void parkInSpot(ParkingSpot spot) {
parkingSpots.add(spot);
}
/* Remove car from spot, and notify spot that it's gone */
public void clearSpots() {
for (int i = 0; i < parkingSpots.size(); i++) {
parkingSpots.get(i).removeVehicle();
}
parkingSpots.clear();
}
public abstract boolean canFitInSpot(ParkingSpot spot);
public abstract void print();
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_04_Parking_Lot/VehicleSize.java
================================================
package Q7_04_Parking_Lot;
public enum VehicleSize {
Motorcycle,
Compact,
Large,
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_05_Online_Book_Reader/Book.java
================================================
package Q7_05_Online_Book_Reader;
public class Book {
private int bookId;
private String details;
public Book(int id, String det) {
bookId = id;
details = det;
}
public void update() { }
public int getID() {
return bookId;
}
public void setID(int id) {
bookId = id;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_05_Online_Book_Reader/Display.java
================================================
package Q7_05_Online_Book_Reader;
public class Display {
private Book activeBook;
private User activeUser;
private int pageNumber = 0;
public void displayUser(User user) {
activeUser = user;
refreshUsername();
}
public void displayBook(Book book) {
pageNumber = 0;
activeBook = book;
refreshTitle();
refreshDetails();
refreshPage();
}
public void refreshUsername() {
/* updates username display */
}
public void refreshTitle() {
/* updates title display */
}
public void refreshDetails() {
/* updates details display */
}
public void refreshPage() {
/* updated page display */
}
public void turnPageForward() {
pageNumber++;
refreshPage();
}
public void turnPageBackward() {
pageNumber--;
refreshPage();
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_05_Online_Book_Reader/Library.java
================================================
package Q7_05_Online_Book_Reader;
import java.util.HashMap;
public class Library {
private HashMap books;
public Book addBook(int id, String details) {
if (books.containsKey(id)) {
return null;
}
Book book = new Book(id, details);
books.put(id, book);
return book;
}
public boolean remove(Book b){
return remove(b.getID());
}
public boolean remove(int id) {
if (!books.containsKey(id)) {
return false;
}
books.remove(id);
return true;
}
public Book find(int id){
return books.get(id);
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_05_Online_Book_Reader/OnlineReaderSystem.java
================================================
package Q7_05_Online_Book_Reader;
public class OnlineReaderSystem {
private Library library;
private UserManager userManager;
private Display display;
private Book activeBook;
private User activeUser;
public OnlineReaderSystem() {
userManager = new UserManager();
library = new Library();
display = new Display();
}
public Library getLibrary() {
return library;
}
public UserManager getUserManager() {
return userManager;
}
public Display getDisplay() {
return display;
}
public Book getActiveBook() {
return activeBook;
}
public void setActiveBook(Book book) {
display.displayBook(book);
activeBook = book;
}
public User getActiveUser() {
return activeUser;
}
public void setActiveUser(User user) {
activeUser = user;
display.displayUser(user);
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_05_Online_Book_Reader/User.java
================================================
package Q7_05_Online_Book_Reader;
public class User {
private int userId;
private String details;
private int accountType;
public void renewMembership() { }
public User(int id, String details, int accountType) {
userId = id;
this.details = details;
this.accountType = accountType;
}
/* getters and setters */
public int getID() { return userId; }
public void setID(int id) { userId = id; }
public String getDetails() { return details; }
public void setDetails(String details) { this.details = details; }
public int getAccountType() { return accountType; }
public void setAccountType(int accountType) {
this.accountType = accountType;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_05_Online_Book_Reader/UserManager.java
================================================
package Q7_05_Online_Book_Reader;
import java.util.HashMap;
public class UserManager {
private HashMap users;
public User addUser(int id, String details, int accountType) {
if (users.containsKey(id)) {
return null;
}
User user = new User(id, details, accountType);
users.put(id, user);
return user;
}
public boolean remove(User u) {
return remove(u.getID());
}
public boolean remove(int id) {
if (!users.containsKey(id)) {
return false;
}
users.remove(id);
return true;
}
public User find(int id){
return users.get(id);
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_06_Jigsaw/Edge.java
================================================
package Q7_06_Jigsaw;
public class Edge {
private Shape shape;
private String code; // used to mock how pieces would fit together.
private Piece parentPiece;
public Edge(Shape shape, String code) {
this.shape = shape;
this.code = code;
}
private String getCode() {
return code;
}
public Edge _createMatchingEdge() {
if (shape == Shape.FLAT) return null;
return new Edge(shape.getOpposite(), getCode());
}
/* Check if this edge fits into the other one. */
public boolean fitsWith(Edge edge) {
return edge.getCode().equals(getCode());
}
/* Set parent piece. */
public void setParentPiece(Piece parentPiece) {
this.parentPiece = parentPiece;
}
/* Get the parent piece. */
public Piece getParentPiece() {
return parentPiece;
}
/* Return the shape of the edge. */
public Shape getShape() {
return shape;
}
public String toString() {
return code;
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_06_Jigsaw/Orientation.java
================================================
package Q7_06_Jigsaw;
public enum Orientation {
LEFT, TOP, RIGHT, BOTTOM; // Should stay in this order
public Orientation getOpposite() {
switch (this) {
case LEFT: return RIGHT;
case RIGHT: return LEFT;
case TOP: return BOTTOM;
case BOTTOM: return TOP;
default: return null;
}
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_06_Jigsaw/Piece.java
================================================
package Q7_06_Jigsaw;
import java.util.HashMap;
import java.util.Map.Entry;
public class Piece {
private final static int NUMBER_OF_EDGES = 4;
private HashMap edges = new HashMap();
public Piece(Edge[] edgeList) {
Orientation[] orientations = Orientation.values();
for (int i = 0; i < edgeList.length; i++) {
Edge edge = edgeList[i];
edge.setParentPiece(this);
edges.put(orientations[i], edge);
}
}
/* Set this edge in the appropriate orientation, rotating the piece as necessary. */
public void setEdgeAsOrientation(Edge edge, Orientation orientation) {
Orientation currentOrientation = getOrientation(edge);
rotateEdgesBy(orientation.ordinal() - currentOrientation.ordinal());
}
/* Return the current orientation of the edge. */
private Orientation getOrientation(Edge edge) {
for (Entry entry : edges.entrySet()) {
if (entry.getValue() == edge) {
return entry.getKey();
}
}
return null;
}
/* Rotate edges by "numberRotations". */
public void rotateEdgesBy(int numberRotations) {
Orientation[] orientations = Orientation.values();
HashMap rotated = new HashMap();
numberRotations = numberRotations % NUMBER_OF_EDGES;
if (numberRotations < 0) numberRotations += NUMBER_OF_EDGES;
for (int i = 0; i < orientations.length; i++) {
Orientation oldOrientation = orientations[(i - numberRotations + NUMBER_OF_EDGES) % NUMBER_OF_EDGES];
Orientation newOrientation = orientations[i];
rotated.put(newOrientation, edges.get(oldOrientation));
}
edges = rotated;
}
/* Check if this piece is a corner piece. */
public boolean isCorner() {
Orientation[] orientations = Orientation.values();
for (int i = 0; i < orientations.length; i++) {
Shape current = edges.get(orientations[i]).getShape();
Shape next = edges.get(orientations[(i + 1) % NUMBER_OF_EDGES]).getShape();
if (current == Shape.FLAT && next == Shape.FLAT) {
return true;
}
}
return false;
}
/* Check if this piece has a border edge. */
public boolean isBorder() {
Orientation[] orientations = Orientation.values();
for (int i = 0; i < orientations.length; i++) {
if (edges.get(orientations[i]).getShape() == Shape.FLAT) {
return true;
}
}
return false;
}
/* Get edge at this orientation. */
public Edge getEdgeWithOrientation(Orientation orientation) {
return edges.get(orientation);
}
/* Return the edge that matches targetEdge. Returns null if there is no match. */
public Edge getMatchingEdge(Edge targetEdge) {
for (Edge e : edges.values()) {
if (targetEdge.fitsWith(e)) {
return e;
}
}
return null;
}
public String toString() {
StringBuilder sb = new StringBuilder();
Orientation[] orientations = Orientation.values();
for (Orientation o : orientations) {
sb.append(edges.get(o).toString() + ",");
}
return "[" + sb.toString() + "]";
}
}
================================================
FILE: Java/Ch 07. Object-Oriented Design/Q7_06_Jigsaw/Puzzle.java
================================================
package Q7_06_Jigsaw;
import java.util.LinkedList;
public class Puzzle {
private LinkedList pieces; /* Remaining pieces left to put away. */
private Piece[][] solution;
private int size;
public Puzzle(int size, LinkedList pieces) {
this.pieces = pieces;
this.size = size;
}
/* Group pieces into border pieces (including corners) and inside pieces. */
public void groupPieces(LinkedList cornerPieces, LinkedList borderPieces, LinkedList insidePieces) {
for (Piece p : pieces) {
if (p.isCorner()) {
cornerPieces.add(p);
} else if (p.isBorder()) {
borderPieces.add(p);
} else {
insidePieces.add(p);
}
}
}
/* Orient this corner piece so that its flat edges are on the top and left. */
public void orientTopLeftCorner(Piece piece) {
if (!piece.isCorner()) return;
Orientation[] orientations = Orientation.values();
for (int i = 0; i < orientations.length; i++) {
Edge current = piece.getEdgeWithOrientation(orientations[i]);
Edge next = piece.getEdgeWithOrientation(orientations[(i + 1) % orientations.length]);
if (current.getShape() == Shape.FLAT && next.getShape() == Shape.FLAT) {
piece.setEdgeAsOrientation(current, Orientation.LEFT);
return;
}
}
}
/* Bounds check. Check if this index is on a border (0 or size - 1) */
public boolean isBorderIndex(int location) {
return location == 0 || location == size - 1;
}
/* Given a list of pieces, check if any have an edge that matches this piece. Return the edge*/
private Edge getMatchingEdge(Edge targetEdge, LinkedList pieces) {
for (Piece piece : pieces) {
Edge matchingEdge = piece.getMatchingEdge(targetEdge);
if (matchingEdge != null) {
return matchingEdge;
}
}
return null;
}
/* Put the edge/piece into the solution, turn it appropriately, and remove from list. */
private void setEdgeInSolution(LinkedList pieces, Edge edge, int row, int column, Orientation orientation) {
Piece piece = edge.getParentPiece();
piece.setEdgeAsOrientation(edge, orientation);
pieces.remove(piece);
solution[row][column] = piece;
}
/* Return the list where a piece with this index would be found. */
private LinkedList getPieceListToSearch(LinkedList cornerPieces, LinkedList borderPieces, LinkedList