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 insidePieces, int row, int column) { if (isBorderIndex(row) && isBorderIndex(column)) { return cornerPieces; } else if (isBorderIndex(row) || isBorderIndex(column)) { return borderPieces; } else { return insidePieces; } } /* Find the matching piece within piecesToSearch and insert it at row, column. */ private boolean fitNextEdge(LinkedList piecesToSearch, int row, int column) { if (row == 0 && column == 0) { Piece p = piecesToSearch.remove(); orientTopLeftCorner(p); solution[0][0] = p; } else { /* Get the right edge and list to match. */ Piece pieceToMatch = column == 0 ? solution[row - 1][0] : solution[row][column - 1]; Orientation orientationToMatch = column == 0 ? Orientation.BOTTOM : Orientation.RIGHT; Edge edgeToMatch = pieceToMatch.getEdgeWithOrientation(orientationToMatch); /* Get matching edge. */ Edge edge = getMatchingEdge(edgeToMatch, piecesToSearch); if (edge == null) return false; // Can't solve Orientation orientation = orientationToMatch.getOpposite(); setEdgeInSolution(piecesToSearch, edge, row, column, orientation); } return true; } public boolean solve() { /* Group pieces. */ LinkedList cornerPieces = new LinkedList(); LinkedList borderPieces = new LinkedList(); LinkedList insidePieces = new LinkedList(); groupPieces(cornerPieces, borderPieces, insidePieces); /* Walk through puzzle, finding the piece that joins the previous one. */ solution = new Piece[size][size]; for (int row = 0; row < size; row++) { for (int column = 0; column < size; column++) { LinkedList piecesToSearch = getPieceListToSearch(cornerPieces, borderPieces, insidePieces, row, column); if (!fitNextEdge(piecesToSearch, row, column)) { return false; } } } return true; } public Piece[][] getCurrentSolution() { return solution; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_06_Jigsaw/Question.java ================================================ package Q7_06_Jigsaw; import java.util.LinkedList; import java.util.Random; public class Question { public static Edge createRandomEdge(String code) { Random random = new Random(); Shape type = Shape.INNER; if (random.nextBoolean()) { type = Shape.OUTER; } return new Edge(type, code); } public static Edge[] createEdges(Piece[][] puzzle, int column, int row) { String key = column + ":" + row + ":"; /* Get left edge */ Edge left = column == 0 ? new Edge(Shape.FLAT, key + "h|e") : puzzle[row][column - 1].getEdgeWithOrientation(Orientation.RIGHT)._createMatchingEdge(); /* Get top edge */ Edge top = row == 0 ? new Edge(Shape.FLAT, key + "v|e") : puzzle[row - 1][column].getEdgeWithOrientation(Orientation.BOTTOM)._createMatchingEdge(); /* Get right edge */ Edge right = column == puzzle[row].length - 1 ? new Edge(Shape.FLAT, key + "h|e") : createRandomEdge(key + "h"); /* Get bottom edge */ Edge bottom = row == puzzle.length - 1 ? new Edge(Shape.FLAT, key + "v|e") : createRandomEdge(key + "v"); Edge[] edges = {left, top, right, bottom}; return edges; } public static LinkedList initializePuzzle(int size) { /* Create completed puzzle. */ Piece[][] puzzle = new Piece[size][size]; for (int row = 0; row < size; row++) { for (int column = 0; column < size; column++) { Edge[] edges = createEdges(puzzle, column, row); puzzle[row][column] = new Piece(edges); } } /* Shuffle and rotate pieces. */ LinkedList pieces = new LinkedList(); Random r = new Random(); for (int row = 0; row < size; row++) { for (int column = 0; column < size; column++) { int rotations = r.nextInt(4); Piece piece = puzzle[row][column]; piece.rotateEdgesBy(rotations); int index = pieces.size() == 0 ? 0 : r.nextInt(pieces.size()); pieces.add(index, piece); } } return pieces; } public static String solutionToString(Piece[][] solution) { StringBuilder sb = new StringBuilder(); for (int h = 0; h < solution.length; h++) { for (int w = 0; w < solution[h].length; w++) { Piece p = solution[h][w]; if (p == null) { sb.append("null"); } else { sb.append(p.toString()); } } sb.append("\n"); } return sb.toString(); } /* Used for testing. Check if puzzle is solved. */ public static boolean validate(Piece[][] solution) { if (solution == null) return false; for (int r = 0; r < solution.length; r++) { for (int c = 0; c < solution[r].length; c++) { Piece piece = solution[r][c]; if (piece == null) return false; if (c > 0) { /* match left */ Piece left = solution[r][c-1]; if (!left.getEdgeWithOrientation(Orientation.RIGHT).fitsWith(piece.getEdgeWithOrientation(Orientation.LEFT))) { return false; } } if (c < solution[r].length - 1) { /* match right */ Piece right = solution[r][c+1]; if (!right.getEdgeWithOrientation(Orientation.LEFT).fitsWith(piece.getEdgeWithOrientation(Orientation.RIGHT))) { return false; } } if (r > 0) { /* match top */ Piece top = solution[r-1][c]; if (!top.getEdgeWithOrientation(Orientation.BOTTOM).fitsWith(piece.getEdgeWithOrientation(Orientation.TOP))) { return false; } } if (r < solution.length - 1) { /* match bottom */ Piece bottom = solution[r+1][c]; if (!bottom.getEdgeWithOrientation(Orientation.TOP).fitsWith(piece.getEdgeWithOrientation(Orientation.BOTTOM))) { return false; } } } } return true; } public static boolean testSize(int size) { LinkedList pieces = initializePuzzle(size); Puzzle puzzle = new Puzzle(size, pieces); puzzle.solve(); Piece[][] solution = puzzle.getCurrentSolution(); System.out.println(solutionToString(solution)); boolean result = validate(solution); System.out.println(result); return result; } public static void main(String[] args) { for (int size = 1; size < 10; size++) { if (!testSize(size)) { System.out.println("ERROR: " + size); } } } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_06_Jigsaw/Shape.java ================================================ package Q7_06_Jigsaw; public enum Shape { INNER, OUTER, FLAT; public Shape getOpposite() { switch (this) { case INNER: return OUTER; case OUTER: return INNER; default: return null; } } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_07_Chat_Server/AddRequest.java ================================================ package Q7_07_Chat_Server; import java.util.Date; public class AddRequest { private User fromUser; private User toUser; private Date date; RequestStatus status; public AddRequest(User from, User to, Date date) { fromUser = from; toUser = to; this.date = date; status = RequestStatus.Unread; } public RequestStatus getStatus() { return status; } public User getFromUser() { return fromUser; } public User getToUser() { return toUser; } public Date getDate() { return date; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_07_Chat_Server/Conversation.java ================================================ package Q7_07_Chat_Server; import java.util.ArrayList; public abstract class Conversation { protected ArrayList participants = new ArrayList(); protected int id; protected ArrayList messages = new ArrayList(); public ArrayList getMessages() { return messages; } public boolean addMessage(Message m) { messages.add(m); return true; } public int getId() { return id; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_07_Chat_Server/GroupChat.java ================================================ package Q7_07_Chat_Server; public class GroupChat extends Conversation { public void removeParticipant(User user) { participants.remove(user); } public void addParticipant(User user) { participants.add(user); } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_07_Chat_Server/Message.java ================================================ package Q7_07_Chat_Server; import java.util.Date; public class Message { private String content; private Date date; public Message(String content, Date date) { this.content = content; this.date = date; } public String getContent() { return content; } public Date getDate() { return date; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_07_Chat_Server/PrivateChat.java ================================================ package Q7_07_Chat_Server; public class PrivateChat extends Conversation { public PrivateChat(User user1, User user2) { participants.add(user1); participants.add(user2); } public User getOtherParticipant(User primary) { if (participants.get(0) == primary) { return participants.get(1); } else if (participants.get(1) == primary) { return participants.get(0); } return null; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_07_Chat_Server/RequestStatus.java ================================================ package Q7_07_Chat_Server; public enum RequestStatus { Unread, Read, Accepted, Rejected } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_07_Chat_Server/System.java ================================================ package Q7_07_Chat_Server; public class System { } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_07_Chat_Server/User.java ================================================ package Q7_07_Chat_Server; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; public class User { private int id; private UserStatus status = null; private HashMap privateChats = new HashMap(); private ArrayList groupChats = new ArrayList(); private HashMap receivedAddRequests = new HashMap(); private HashMap sentAddRequests = new HashMap(); private HashMap contacts = new HashMap(); private String accountName; private String fullName; public User(int id, String accountName, String fullName) { this.accountName = accountName; this.fullName = fullName; this.id = id; } public boolean sendMessageToUser(User toUser, String content) { PrivateChat chat = privateChats.get(toUser.getId()); if (chat == null) { chat = new PrivateChat(this, toUser); privateChats.put(toUser.getId(), chat); } Message message = new Message(content, new Date()); return chat.addMessage(message); } public boolean sendMessageToGroupChat(int groupId, String content) { GroupChat chat = groupChats.get(groupId); if (chat != null) { Message message = new Message(content, new Date()); return chat.addMessage(message); } return false; } public void setStatus(UserStatus status) { this.status = status; } public UserStatus getStatus() { return status; } public boolean addContact(User user) { if (contacts.containsKey(user.getId())) { return false; } else { contacts.put(user.getId(), user); return true; } } public void receivedAddRequest(AddRequest req) { int senderId = req.getFromUser().getId(); if (!receivedAddRequests.containsKey(senderId)) { receivedAddRequests.put(senderId, req); } } public void sentAddRequest(AddRequest req) { int receiverId = req.getFromUser().getId(); if (!sentAddRequests.containsKey(receiverId)) { sentAddRequests.put(receiverId, req); } } public void removeAddRequest(AddRequest req) { if (req.getToUser() == this) { receivedAddRequests.remove(req); } else if (req.getFromUser() == this) { sentAddRequests.remove(req); } } public void requestAddUser(String accountName) { UserManager.getInstance().addUser(this, accountName); } public void addConversation(PrivateChat conversation) { User otherUser = conversation.getOtherParticipant(this); privateChats.put(otherUser.getId(), conversation); } public void addConversation(GroupChat conversation) { groupChats.add(conversation); } public int getId() { return id; } public String getAccountName() { return accountName; } public String getFullName() { return fullName; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_07_Chat_Server/UserManager.java ================================================ package Q7_07_Chat_Server; import java.util.Date; import java.util.HashMap; /* UserManager serves as the central place for the core user actions. */ public class UserManager { private static UserManager instance; private HashMap usersById = new HashMap(); private HashMap usersByAccountName = new HashMap(); private HashMap onlineUsers = new HashMap(); public static UserManager getInstance() { if (instance == null) { instance = new UserManager(); } return instance; } public void addUser(User fromUser, String toAccountName) { User toUser = usersByAccountName.get(toAccountName); AddRequest req = new AddRequest(fromUser, toUser, new Date()); toUser.receivedAddRequest(req); fromUser.sentAddRequest(req); } public void approveAddRequest(AddRequest req) { req.status = RequestStatus.Accepted; User from = req.getFromUser(); User to = req.getToUser(); from.addContact(to); to.addContact(from); } public void rejectAddRequest(AddRequest req) { req.status = RequestStatus.Rejected; User from = req.getFromUser(); User to = req.getToUser(); from.removeAddRequest(req); to.removeAddRequest(req); } public void userSignedOn(String accountName) { User user = usersByAccountName.get(accountName); if (user != null) { user.setStatus(new UserStatus(UserStatusType.Available, "")); onlineUsers.put(user.getId(), user); } } public void userSignedOff(String accountName) { User user = usersByAccountName.get(accountName); if (user != null) { user.setStatus(new UserStatus(UserStatusType.Offline, "")); onlineUsers.remove(user.getId()); } } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_07_Chat_Server/UserStatus.java ================================================ package Q7_07_Chat_Server; public class UserStatus { private String message; private UserStatusType type; public UserStatus(UserStatusType type, String message) { this.type = type; this.message = message; } public UserStatusType getStatusType() { return type; } public String getMessage() { return message; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_07_Chat_Server/UserStatusType.java ================================================ package Q7_07_Chat_Server; public enum UserStatusType { Offline, Away, Idle, Available, Busy } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_08_Othello/Automator.java ================================================ package Q7_08_Othello; import java.util.ArrayList; import CtCILibrary.AssortedMethods; /* A helper class to automate this game. This is just used for testing purposes. */ public class Automator { private Player[] players; private Player lastPlayer = null; public ArrayList remainingMoves = new ArrayList(); private static Automator instance; private Automator() { for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { Location loc = new Location(i, j); remainingMoves.add(loc); } } } public static Automator getInstance() { if (instance == null) { instance = new Automator(); } return instance; } public void initialize(Player[] ps) { players = ps; lastPlayer = players[1]; } public void shuffle() { for (int i = 0; i < remainingMoves.size(); i++) { int t = AssortedMethods.randomIntInRange(i, remainingMoves.size() - 1); Location other = remainingMoves.get(t); Location current = remainingMoves.get(i); remainingMoves.set(t, current); remainingMoves.set(i, other); } } public void removeLocation(int r, int c) { for (int i = 0; i < remainingMoves.size(); i++) { Location loc = remainingMoves.get(i); if (loc.isSameAs(r, c)) { remainingMoves.remove(i); } } } public Location getLocation(int index) { return remainingMoves.get(index); } public boolean playRandom() { Board board = Game.getInstance().getBoard(); shuffle(); lastPlayer = lastPlayer == players[0] ? players[1] : players[0]; String color = lastPlayer.getColor().toString(); for (int i = 0; i < remainingMoves.size(); i++) { Location loc = remainingMoves.get(i); boolean success = lastPlayer.playPiece(loc.getRow(), loc.getColumn()); if (success) { System.out.println("Success: " + color + " move at (" + loc.getRow() + ", " + loc.getColumn() + ")"); board.printBoard(); printScores(); return true; } } System.out.println("Game over. No moves found for " + color); return false; } public boolean isOver() { if (players[0].getScore() == 0 || players[1].getScore() == 0) { return true; } return false; } public void printScores() { System.out.println("Score: " + players[0].getColor().toString() + ": " + players[0].getScore() + ", " + players[1].getColor().toString() + ": " + players[1].getScore()); } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_08_Othello/Board.java ================================================ package Q7_08_Othello; public class Board { private int blackCount = 0; private int whiteCount = 0; private Piece[][] board; public Board(int rows, int columns) { board = new Piece[rows][columns]; } public void initialize() { /* initial board has a grid like the following in the center: * WB * BW */ int middleRow = board.length / 2; int middleColumn = board[middleRow].length / 2; board[middleRow][middleColumn] = new Piece(Color.White); board[middleRow + 1][middleColumn] = new Piece(Color.Black); board[middleRow + 1][middleColumn + 1] = new Piece(Color.White); board[middleRow][middleColumn + 1] = new Piece(Color.Black); blackCount = 2; whiteCount = 2; } public boolean placeColor(int row, int column, Color color) { if (board[row][column] != null) { return false; } /* attempt to flip each of the four directions */ int[] results = new int[4]; results[0] = flipSection(row - 1, column, color, Direction.up); results[1] = flipSection(row + 1, column, color, Direction.down); results[2] = flipSection(row, column + 1, color, Direction.right); results[3] = flipSection(row, column - 1, color, Direction.left); /* compute how many pieces were flipped */ int flipped = 0; for (int result : results) { if (result > 0) { flipped += result; } } /* if nothing was flipped, then it's an invalid move */ if (flipped < 0) { return false; } /* flip the piece, and update the score */ board[row][column] = new Piece(color); updateScore(color, flipped + 1); return true; } private int flipSection(int row, int column, Color color, Direction d) { /* Compute the delta for the row and the column. At all times, only the row or the column * will have a delta, since we're only moving in one direction at a time. */ int r = 0; int c = 0; switch (d) { case up: r = -1; break; case down: r = 1; break; case left: c = -1; break; case right: c = 1; break; } /* If out of bounds, or nothing to flip, return an error (-1) */ if (row < 0 || row >= board.length || column < 0 || column >= board[row].length || board[row][column] == null) { return -1; } /* Found same color - return nothing flipped */ if (board[row][column].getColor() == color) { return 0; } /* Recursively flip the remainder of the row. If -1 is returned, then we know we hit the boundary * of the row (or a null piece) before we found our own color, so there's nothing to flip. Return * the error code. */ int flipped = flipSection(row + r, column + c, color, d); if (flipped < 0) { return -1; } /* flip our own color */ board[row][column].flip(); return flipped + 1; } public int getScoreForColor(Color c) { if (c == Color.Black) { return blackCount; } else { return whiteCount; } } public void updateScore(Color newColor, int newPieces) { /* If we added x pieces of a color, then we actually removed x - 1 pieces of the other * color. The -1 is because one of the new pieces was the just-placed one. */ if (newColor == Color.Black) { whiteCount -= newPieces - 1; blackCount += newPieces; } else { blackCount -= newPieces - 1; whiteCount += newPieces; } } public void printBoard() { for (int r = 0; r < board.length; r++) { for (int c = 0; c < board[r].length; c++) { if (board[r][c] == null) { System.out.print("_"); } else if (board[r][c].getColor() == Color.White) { System.out.print("W"); } else { System.out.print("B"); } } System.out.println(); } } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_08_Othello/Color.java ================================================ package Q7_08_Othello; public enum Color { White, Black } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_08_Othello/Direction.java ================================================ package Q7_08_Othello; public enum Direction { left, right, up, down } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_08_Othello/Game.java ================================================ package Q7_08_Othello; public class Game { private Player[] players; private static Game instance; private Board board; private final int ROWS = 10; private final int COLUMNS = 10; private Game() { board = new Board(ROWS, COLUMNS); players = new Player[2]; players[0] = new Player(Color.Black); players[1] = new Player(Color.White); Automator.getInstance().initialize(players); // used for testing } public static Game getInstance() { if (instance == null) { instance = new Game(); } return instance; } public Board getBoard() { return board; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_08_Othello/Location.java ================================================ package Q7_08_Othello; public class Location { private int row; private int column; public Location(int r, int c) { row = r; column = c; } public boolean isSameAs(int r, int c) { return row == r && column == c; } public int getRow() { return row; } public int getColumn() { return column; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_08_Othello/Piece.java ================================================ package Q7_08_Othello; public class Piece { private Color color; public Piece(Color c) { color = c; } public void flip() { if (color == Color.Black) { color = Color.White; } else { color = Color.Black; } } public Color getColor() { return color; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_08_Othello/Player.java ================================================ package Q7_08_Othello; public class Player { private Color color; public Player(Color c) { color = c; } public int getScore() { return Game.getInstance().getBoard().getScoreForColor(color); } public boolean playPiece(int row, int column) { return Game.getInstance().getBoard().placeColor(row, column, color); } public Color getColor() { return color; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_08_Othello/Question.java ================================================ package Q7_08_Othello; public class Question { public static void main(String[] args) { Game game = Game.getInstance(); game.getBoard().initialize(); game.getBoard().printBoard(); Automator automator = Automator.getInstance(); while (!automator.isOver() && automator.playRandom()) { } automator.printScores(); } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_09_Circular_Array/CircularArray.java ================================================ package Q7_09_Circular_Array; import java.util.Iterator; public class CircularArray implements Iterable { private T[] items; private int head = 0; public CircularArray(int size) { items = (T[]) new Object[size]; } private int convert(int index) { if (index < 0) { index += items.length; } return (head + index) % items.length; } public void rotate(int shiftRight) { head = convert(shiftRight); } public T get(int i) { if (i < 0 || i >= items.length) { throw new java.lang.IndexOutOfBoundsException("Index " + i + " is out of bounds"); } return items[convert(i)]; } public void set(int i, T item) { items[convert(i)] = item; } public Iterator iterator() { return new CircularArrayIterator(); } private class CircularArrayIterator implements Iterator { private int _current = -1; public CircularArrayIterator() { } @Override public boolean hasNext() { return _current < items.length - 1; } @Override public T next() { _current++; return (T) items[convert(_current)]; } @Override public void remove() { throw new UnsupportedOperationException("Remove is not supported by CircularArray"); } } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_09_Circular_Array/Question.java ================================================ package Q7_09_Circular_Array; public class Question { /** * @param args */ public static void main(String[] args) { int size = 10; CircularArray array = new CircularArray(size); for (int i = 0; i < size; i++) { array.set(i, String.valueOf(i)); } array.rotate(3); for (int i = 0; i < size; i++) { System.out.println(array.get(i)); } System.out.println(""); array.rotate(2); for (String s : array) { System.out.println(s); } } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_10_Minesweeper/Board.java ================================================ package Q7_10_Minesweeper; import java.util.LinkedList; import java.util.Queue; import java.util.Random; import Q7_10_Minesweeper.Game.GameState; public class Board { private int nRows; private int nColumns; private int nBombs = 0; private Cell[][] cells; private Cell[] bombs; private int numUnexposedRemaining; public Board(int r, int c, int b) { nRows = r; nColumns = c; nBombs = b; initializeBoard(); shuffleBoard(); setNumberedCells(); numUnexposedRemaining = nRows * nColumns - nBombs; } private void initializeBoard() { cells = new Cell[nRows][nColumns]; bombs = new Cell[nBombs]; for (int r = 0; r < nRows; r++) { for (int c = 0; c < nColumns; c++) { cells[r][c] = new Cell(r, c); } } for (int i = 0; i < nBombs; i++) { int r = i / nColumns; int c = (i - r * nColumns) % nColumns; bombs[i] = cells[r][c]; bombs[i].setBomb(true); } } private void shuffleBoard() { int nCells = nRows * nColumns; Random random = new Random(); for (int index1 = 0; index1 < nCells; index1++) { int index2 = index1 + random.nextInt(nCells - index1); if (index1 != index2) { /* Get cell at index1. */ int row1 = index1 / nColumns; int column1 = (index1 - row1 * nColumns) % nColumns; Cell cell1 = cells[row1][column1]; /* Get cell at index2. */ int row2 = index2 / nColumns; int column2 = (index2 - row2 * nColumns) % nColumns; Cell cell2 = cells[row2][column2]; /* Swap. */ cells[row1][column1] = cell2; cell2.setRowAndColumn(row1, column1); cells[row2][column2] = cell1; cell1.setRowAndColumn(row2, column2); } } } private boolean inBounds(int row, int column) { return row >= 0 && row < nRows && column >= 0 && column < nColumns; } /* Set the cells around the bombs to the right number. Although * the bombs have been shuffled, the reference in the bombs array * is still to same object. */ private void setNumberedCells() { int[][] deltas = { // Offsets of 8 surrounding cells {-1, -1}, {-1, 0}, {-1, 1}, { 0, -1}, { 0, 1}, { 1, -1}, { 1, 0}, { 1, 1} }; for (Cell bomb : bombs) { int row = bomb.getRow(); int col = bomb.getColumn(); for (int[] delta : deltas) { int r = row + delta[0]; int c = col + delta[1]; if (inBounds(r, c)) { cells[r][c].incrementNumber(); } } } } public void printBoard(boolean showUnderside) { System.out.println(); System.out.print(" "); for (int i = 0; i < nColumns; i++) { System.out.print(i + " "); } System.out.println(); for (int i = 0; i < nColumns; i++) { System.out.print("--"); } System.out.println(); for (int r = 0; r < nRows; r++) { System.out.print(r + "| "); for (int c = 0; c < nColumns; c++) { if (showUnderside) { System.out.print(cells[r][c].getUndersideState()); } else { System.out.print(cells[r][c].getSurfaceState()); } } System.out.println(); } } private boolean flipCell(Cell cell) { if (!cell.isExposed() && !cell.isGuess()) { cell.flip(); numUnexposedRemaining--; return true; } return false; } public void expandBlank(Cell cell) { int[][] deltas = { {-1, -1}, {-1, 0}, {-1, 1}, { 0, -1}, { 0, 1}, { 1, -1}, { 1, 0}, { 1, 1} }; Queue toExplore = new LinkedList(); toExplore.add(cell); while (!toExplore.isEmpty()) { Cell current = toExplore.remove(); for (int[] delta : deltas) { int r = current.getRow() + delta[0]; int c = current.getColumn() + delta[1]; if (inBounds(r, c)) { Cell neighbor = cells[r][c]; if (flipCell(neighbor) && neighbor.isBlank()) { toExplore.add(neighbor); } } } } } public UserPlayResult playFlip(UserPlay play) { Cell cell = getCellAtLocation(play); if (cell == null) { return new UserPlayResult(false, GameState.RUNNING); } if (play.isGuess()) { boolean guessResult = cell.toggleGuess(); return new UserPlayResult(guessResult, GameState.RUNNING); } boolean result = flipCell(cell); if (cell.isBomb()) { return new UserPlayResult(result, GameState.LOST); } if (cell.isBlank()) { expandBlank(cell); } if (numUnexposedRemaining == 0) { return new UserPlayResult(result, GameState.WON); } return new UserPlayResult(result, GameState.RUNNING); } public Cell getCellAtLocation(UserPlay play) { int row = play.getRow(); int col = play.getColumn(); if (!inBounds(row, col)) { return null; } return cells[row][col]; } public int getNumRemaining() { return numUnexposedRemaining; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_10_Minesweeper/Cell.java ================================================ package Q7_10_Minesweeper; public class Cell { private int row; private int column; private boolean isBomb; private int number; private boolean isExposed = false; private boolean isGuess = false; public Cell(int r, int c) { isBomb = false; number = 0; row = r; column = c; } public void setRowAndColumn(int r, int c) { row = r; column = c; } public void setBomb(boolean bomb) { isBomb = bomb; number = -1; } public void incrementNumber() { number++; } public int getRow() { return row; } public int getColumn() { return column; } public boolean isBomb() { return isBomb; } public boolean isBlank() { return number == 0; } public boolean isExposed() { return isExposed; } public boolean flip() { isExposed = true; return !isBomb; } public boolean toggleGuess() { if (!isExposed) { isGuess = !isGuess; } return isGuess; } public boolean isGuess() { return isGuess; } @Override public String toString() { return getUndersideState(); } public String getSurfaceState() { if (isExposed) { return getUndersideState(); } else if (isGuess) { return "B "; } else { return "? "; } } public String getUndersideState() { if (isBomb) { return "* "; } else if (number > 0) { return Integer.toString(number) + " "; } else { return " "; } } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_10_Minesweeper/Game.java ================================================ package Q7_10_Minesweeper; import java.util.Scanner; public class Game { public enum GameState { WON, LOST, RUNNING } private Board board; private int rows; private int columns; private int bombs; private GameState state; public Game(int r, int c, int b) { rows = r; columns = c; bombs = b; state = GameState.RUNNING; } public boolean initialize() { if (board == null) { board = new Board(rows, columns, bombs); board.printBoard(true); return true; } else { System.out.println("Game has already been initialized."); return false; } } public boolean start() { if (board == null) { initialize(); } return playGame(); } public void printGameState() { if (state == GameState.LOST) { board.printBoard(true); System.out.println("FAIL"); } else if (state == GameState.WON) { board.printBoard(true); System.out.println("WIN"); } else { System.out.println("Number remaining: " + board.getNumRemaining()); board.printBoard(false); } } private boolean playGame() { Scanner scanner = new Scanner(System.in); printGameState(); while (state == GameState.RUNNING) { String input = scanner.nextLine(); if (input.equals("exit")) { scanner.close(); return false; } UserPlay play = UserPlay.fromString(input); if (play == null) { continue; } UserPlayResult result = board.playFlip(play); if (result.successfulMove()) { state = result.getResultingState(); } else { System.out.println("Could not flip cell (" + play.getRow() + "," + play.getColumn() + ")."); } printGameState(); } scanner.close(); return true; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_10_Minesweeper/Question.java ================================================ package Q7_10_Minesweeper; public class Question { public static void main(String[] args) { Game game = new Game(7, 7, 3); game.initialize(); game.start(); } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_10_Minesweeper/UserPlay.java ================================================ package Q7_10_Minesweeper; public class UserPlay { private int row; private int column; private boolean isGuess; private UserPlay(int r, int c, boolean guess) { setRow(r); setColumn(c); isGuess = guess; } public static UserPlay fromString(String input) { boolean isGuess = false; if (input.length() > 0 && input.charAt(0) == 'B') { isGuess = true; input = input.substring(1); } if (!input.matches("\\d* \\d+")) { return null; } String[] parts = input.split(" "); try { int r = Integer.parseInt(parts[0]); int c = Integer.parseInt(parts[1]); return new UserPlay(r, c, isGuess); } catch (NumberFormatException e) { return null; } } public boolean isGuess() { return isGuess; } public boolean isMove() { return !isMove(); } public int getColumn() { return column; } public void setColumn(int column) { this.column = column; } public int getRow() { return row; } public void setRow(int row) { this.row = row; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_10_Minesweeper/UserPlayResult.java ================================================ package Q7_10_Minesweeper; public class UserPlayResult { private boolean successful; private Game.GameState resultingState; public UserPlayResult(boolean success, Game.GameState state) { successful = success; resultingState = state; } public boolean successfulMove() { return successful; } public Game.GameState getResultingState() { return resultingState; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_11_File_System/Directory.java ================================================ package Q7_11_File_System; import java.util.ArrayList; public class Directory extends Entry { protected ArrayList contents; public Directory(String n, Directory p) { super(n, p); contents = new ArrayList(); } protected ArrayList getContents() { return contents; } public int size() { int size = 0; for (Entry e : contents) { size += e.size(); } return size; } public int numberOfFiles() { int count = 0; for (Entry e : contents) { if (e instanceof Directory) { count++; // Directory counts as a file Directory d = (Directory) e; count += d.numberOfFiles(); } else if (e instanceof File) { count++; } } return count; } public boolean deleteEntry(Entry entry) { return contents.remove(entry); } public void addEntry(Entry entry) { contents.add(entry); } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_11_File_System/Entry.java ================================================ package Q7_11_File_System; public abstract class Entry { protected Directory parent; protected long created; protected long lastUpdated; protected long lastAccessed; protected String name; public Entry(String n, Directory p) { name = n; parent = p; created = System.currentTimeMillis(); } public boolean delete() { if (parent == null) { return false; } return parent.deleteEntry(this); } public abstract int size(); public String getFullPath() { if (parent == null) { return name; } else { return parent.getFullPath() + "/" + name; } } public long getCreationTime() { return created; } public long getLastUpdatedTime() { return lastUpdated; } public long getLastAccessedTime() { return lastAccessed; } public void changeName(String n) { name = n; } public String getName() { return name; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_11_File_System/File.java ================================================ package Q7_11_File_System; public class File extends Entry { private String content; private int size; public File(String n, Directory p, int sz) { super(n, p); size = sz; } public int size() { return size; } public String getContents() { return content; } public void setContents(String c) { content = c; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_11_File_System/Question.java ================================================ package Q7_11_File_System; public class Question { public static void main(String[] args) { Directory root = new Directory("Food", null); File taco = new File("Taco", root, 4); File hamburger = new File("Hamburger", root, 9); root.addEntry(taco); root.addEntry(hamburger); Directory healthy = new Directory("Healthy", root); Directory fruits = new Directory("Fruits", healthy); File apple = new File("Apple", fruits, 5); File banana = new File("Banana", fruits, 6); fruits.addEntry(apple); fruits.addEntry(banana); healthy.addEntry(fruits); Directory veggies = new Directory("Veggies", healthy); File carrot = new File("Carrot", veggies, 6); File lettuce = new File("Lettuce", veggies, 7); File peas = new File("Peas", veggies, 4); veggies.addEntry(carrot); veggies.addEntry(lettuce); veggies.addEntry(peas); healthy.addEntry(veggies); root.addEntry(healthy); System.out.println(root.numberOfFiles()); System.out.println(veggies.getFullPath()); } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_12_Hash_Table/Dummy.java ================================================ package Q7_12_Hash_Table; public class Dummy { private String name; private int age; public Dummy(String n, int a) { name = n; age = a; } @Override public String toString() { return "(" + name + ", " + age + ")"; } public int getAge() { return age; } public String getName() { return name; } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_12_Hash_Table/Hasher.java ================================================ package Q7_12_Hash_Table; import java.util.ArrayList; public class Hasher { private static class LinkedListNode { public LinkedListNode next; public LinkedListNode prev; public K key; public V value; public LinkedListNode(K k, V v) { key = k; value = v; } public String printForward() { String data = "(" + key + "," + value + ")"; if (next != null) { return data + "->" + next.printForward(); } else { return data; } } } private ArrayList> arr; public Hasher(int capacity) { /* Create list of linked lists. */ arr = new ArrayList>(); arr.ensureCapacity(capacity); for (int i = 0; i < capacity; i++) { arr.add(null); } } /* Insert key and value into hash table. */ public V put(K key, V value) { LinkedListNode node = getNodeForKey(key); if (node != null) { V oldValue = node.value; node.value = value; // just update the value. return oldValue; } node = new LinkedListNode(key, value); int index = getIndexForKey(key); if (arr.get(index) != null) { node.next = arr.get(index); node.next.prev = node; } arr.set(index, node); return null; } /* Remove node for key. */ public V remove(K key) { LinkedListNode node = getNodeForKey(key); if (node == null) { return null; } if (node.prev != null) { node.prev.next = node.next; } else { /* Removing head - update. */ int hashKey = getIndexForKey(key); arr.set(hashKey, node.next); } if (node.next != null) { node.next.prev = node.prev; } return node.value; } /* Get value for key. */ public V get(K key) { if (key == null) return null; LinkedListNode node = getNodeForKey(key); return node == null ? null : node.value; } /* Get linked list node associated with a given key. */ private LinkedListNode getNodeForKey(K key) { int index = getIndexForKey(key); LinkedListNode current = arr.get(index); while (current != null) { if (current.key == key) { return current; } current = current.next; } return null; } /* Really stupid function to map a key to an index. */ public int getIndexForKey(K key) { return Math.abs(key.hashCode() % arr.size()); } public void printTable() { for (int i = 0; i < arr.size(); i++) { String s = arr.get(i) == null ? "" : arr.get(i).printForward(); System.out.println(i + ": " + s); } } } ================================================ FILE: Java/Ch 07. Object-Oriented Design/Q7_12_Hash_Table/Question.java ================================================ package Q7_12_Hash_Table; public class Question { /** * @param args */ public static void main(String[] args) { Dummy bob = new Dummy("Bob", 20); Dummy jim = new Dummy("Jim", 25); Dummy alex = new Dummy("Alex", 30); Dummy tim = new Dummy("Tim", 35); Dummy maxwell = new Dummy("Maxwell", 40); Dummy john = new Dummy("John", 45); Dummy julie = new Dummy("Julie", 50); Dummy christy = new Dummy("Christy", 55); Dummy tim2 = new Dummy("Tim", 100); // This should replace the first "tim" Dummy[] dummies = {bob, jim, alex, tim, maxwell, john, julie, christy, tim2}; /* Test: Insert Elements. */ Hasher hash = new Hasher(3); for (Dummy d : dummies) { System.out.println(hash.put(d.getName(), d)); } hash.printTable(); /* Test: Recall */ for (Dummy d : dummies) { String name = d.getName(); Dummy dummy = hash.get(name); if (dummy == null) { System.out.println("Dummy named " + name + ": null"); } else { System.out.println("Dummy named " + name + ": " + dummy.toString()); } Dummy d2 = hash.remove(name); if (d2 == null) { System.out.println("Dummy removed named " + name + ": " + "null"); } else { System.out.println("Dummy removed named " + name + ": " + d2.toString()); } } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Introduction/FibonacciA.java ================================================ package Introduction; public class FibonacciA { public static int fibonacci(int i) { if (i == 0) { return 0; } if (i == 1) { return 1; } return fibonacci(i - 1) + fibonacci(i - 2); } /** * @param args */ public static void main(String[] args) { int max = 35; // WARNING: If you make this above 40ish, your computer may serious slow down. int trials = 10; // Run code multiple times to compute average time. double[] times = new double[max]; // Store times for (int j = 0; j < trials; j++) { // Run this 10 times to compute for (int i = 0; i < max; i++) { long start = System.currentTimeMillis(); fibonacci(i); long end = System.currentTimeMillis(); long time = end - start; times[i] += time; } } for (int j = 0; j < max; j++) { System.out.println(j + ": " + times[j] / trials + "ms"); } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Introduction/FibonacciB.java ================================================ package Introduction; public class FibonacciB { public static int fibonacci(int n) { return fibonacci(n, new int[n + 1]); } public static int fibonacci(int i, int[] memo) { if (i == 0) return 0; else if (i == 1) return 1; if (memo[i] == 0) { memo[i] = fibonacci(i - 1, memo) + fibonacci(i - 2, memo); } return memo[i]; } /** * @param args */ public static void main(String[] args) { int max = 100; // Make this as big as you want! (Though you'll exceed the bounds of a long around 46) int trials = 10; // Run code multiple times to compute average time. double[] times = new double[max]; // Store times for (int j = 0; j < trials; j++) { // Run this 10 times to compute for (int i = 0; i < max; i++) { long start = System.currentTimeMillis(); System.out.println(fibonacci(i)); long end = System.currentTimeMillis(); long time = end - start; times[i] += time; } } for (int j = 0; j < max; j++) { //System.out.println(j + ": " + times[j] / trials + "ms"); } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Introduction/FibonacciC.java ================================================ package Introduction; public class FibonacciC { public static int fibonacci(int n) { if (n == 0) return 0; else if (n == 1) return 1; int[] memo = new int[n]; memo[0] = 0; memo[1] = 1; for (int i = 2; i < n; i++) { memo[i] = memo[i - 1] + memo[i - 2]; } return memo[n - 1] + memo[n - 2]; } /** * @param args */ public static void main(String[] args) { int max = 100; // Make this as big as you want! (Though you'll exceed the bounds of a long around 46) int trials = 10; // Run code multiple times to compute average time. double[] times = new double[max]; // Store times for (int j = 0; j < trials; j++) { // Run this 10 times to compute for (int i = 0; i < max; i++) { long start = System.currentTimeMillis(); System.out.println(fibonacci(i)); long end = System.currentTimeMillis(); long time = end - start; times[i] += time; } } for (int j = 0; j < max; j++) { //System.out.println(j + ": " + times[j] / trials + "ms"); } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Introduction/FibonacciD.java ================================================ package Introduction; public class FibonacciD { public static int fibonacci(int n) { if (n == 0) return 0; int a = 0; int b = 1; for (int i = 2; i < n; i++) { int c = a + b; a = b; b = c; } return a + b; } /** * @param args */ public static void main(String[] args) { int max = 100; // Make this as big as you want! (Though you'll exceed the bounds of a long around 46) int trials = 10; // Run code multiple times to compute average time. double[] times = new double[max]; // Store times for (int j = 0; j < trials; j++) { // Run this 10 times to compute for (int i = 0; i < max; i++) { long start = System.currentTimeMillis(); System.out.println(fibonacci(i)); long end = System.currentTimeMillis(); long time = end - start; times[i] += time; } } for (int j = 0; j < max; j++) { //System.out.println(j + ": " + times[j] / trials + "ms"); } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_01_Triple_Step/QuestionA.java ================================================ package Q8_01_Triple_Step; public class QuestionA { public static int countWays(int n) { if (n < 0) { return 0; } else if (n == 0) { return 1; } else { return countWays(n - 1) + countWays(n - 2) + countWays(n - 3); } } public static void main(String[] args) { int n = 20; int ways = countWays(n); System.out.println(ways); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_01_Triple_Step/QuestionB.java ================================================ package Q8_01_Triple_Step; import java.util.Arrays; public class QuestionB { public static int countWays(int n) { int[] map = new int[n + 1]; Arrays.fill(map, -1); return countWays(n, map); } public static int countWays(int n, int[] memo) { if (n < 0) { return 0; } else if (n == 0) { return 1; } else if (memo[n] > -1) { return memo[n]; } else { memo[n] = countWays(n - 1, memo) + countWays(n - 2, memo) + countWays(n - 3, memo); return memo[n]; } } public static void main(String[] args) { int n = 50; int ways = countWays(n); System.out.println(ways); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_01_Triple_Step/Tester.java ================================================ package Q8_01_Triple_Step; public class Tester { public static void main(String[] args) { for (int i = 0; i < 30; i++) { int c1 = QuestionB.countWays(i); int c2 = QuestionA.countWays(i); System.out.println(i + ": " + c1 + " " + c2); } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_02_Robot_in_a_Grid/Point.java ================================================ package Q8_02_Robot_in_a_Grid; public class Point { public int row, column; public Point(int row, int column) { this.row = row; this.column = column; } @Override public String toString() { return "(" + row + ", " + column + ")"; } @Override public int hashCode() { return this.toString().hashCode(); } @Override public boolean equals(Object o) { if ((o instanceof Point) && (((Point) o).row == this.row) && (((Point) o).column == this.column)) { return true; } else { return false; } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_02_Robot_in_a_Grid/QuestionA.java ================================================ package Q8_02_Robot_in_a_Grid; import java.util.ArrayList; import CtCILibrary.AssortedMethods; public class QuestionA { public static ArrayList getPath(boolean[][] maze) { if (maze == null || maze.length == 0) return null; ArrayList path = new ArrayList(); if (getPath(maze, maze.length - 1, maze[0].length - 1, path)) { return path; } return null; } public static boolean getPath(boolean[][] maze, int row, int col, ArrayList path) { // If out of bounds or not available, return. if (col < 0 || row < 0 || !maze[row][col]) { return false; } boolean isAtOrigin = (row == 0) && (col == 0); // If there's a path from the start to my current location, add my location. if (isAtOrigin || getPath(maze, row, col - 1, path) || getPath(maze, row - 1, col, path)) { Point p = new Point(row, col); path.add(p); return true; } return false; } public static void main(String[] args) { int size = 5; boolean[][] maze = AssortedMethods.randomBooleanMatrix(size, size, 70); AssortedMethods.printMatrix(maze); ArrayList path = getPath(maze); if (path != null) { System.out.println(path.toString()); } else { System.out.println("No path found."); } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_02_Robot_in_a_Grid/QuestionB.java ================================================ package Q8_02_Robot_in_a_Grid; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import CtCILibrary.AssortedMethods; public class QuestionB { public static ArrayList getPath(boolean[][] maze) { if (maze == null || maze.length == 0) return null; ArrayList path = new ArrayList(); HashSet failedPoints = new HashSet(); if (getPath(maze, maze.length - 1, maze[0].length - 1, path, failedPoints)) { return path; } return null; } public static boolean getPath(boolean[][] maze, int row, int col, ArrayList path, HashSet failedPoints) { /* If out of bounds or not available, return.*/ if (col < 0 || row < 0 || !maze[row][col]) { return false; } Point p = new Point(row, col); /* If we've already visited this cell, return. */ if (failedPoints.contains(p)) { return false; } boolean isAtOrigin = (row == 0) && (col == 0); /* If there's a path from the start to my current location, add my location.*/ if (isAtOrigin || getPath(maze, row, col - 1, path, failedPoints) || getPath(maze, row - 1, col, path, failedPoints)) { path.add(p); return true; } failedPoints.add(p); // Cache result return false; } public static void main(String[] args) { int size = 20; boolean[][] maze = AssortedMethods.randomBooleanMatrix(size, size, 60); AssortedMethods.printMatrix(maze); ArrayList path = getPath(maze); if (path != null) { System.out.println(path.toString()); } else { System.out.println("No path found."); } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_02_Robot_in_a_Grid/Tester.java ================================================ package Q8_02_Robot_in_a_Grid; import java.util.ArrayList; import CtCILibrary.AssortedMethods; public class Tester { public static void main(String[] args) { int size = 5; boolean[][] maze = AssortedMethods.randomBooleanMatrix(size, size, 70); AssortedMethods.printMatrix(maze); ArrayList pathA = QuestionA.getPath(maze); ArrayList pathB = QuestionB.getPath(maze); if (pathA != null) { System.out.println(pathA.toString()); } else { System.out.println("No path found."); } if (pathB != null) { System.out.println(pathB.toString()); } else { System.out.println("No path found."); } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_03_Magic_Index/Question.java ================================================ package Q8_03_Magic_Index; import java.util.Arrays; import CtCILibrary.AssortedMethods; public class Question { public static int magicSlow(int[] array) { for (int i = 0; i < array.length; i++) { if (array[i] == i) { return i; } } return -1; } public static int magicFast(int[] array, int start, int end) { if (end < start) { return -1; } int mid = (start + end) / 2; if (array[mid] == mid) { return mid; } else if (array[mid] > mid){ return magicFast(array, start, mid - 1); } else { return magicFast(array, mid + 1, end); } } public static int magicFast(int[] array) { return magicFast(array, 0, array.length - 1); } /* Creates an array that is distinct and sorted */ public static int[] getDistinctSortedArray(int size) { int[] array = AssortedMethods.randomArray(size, -1 * size, size); Arrays.sort(array); for (int i = 1; i < array.length; i++) { if (array[i] == array[i-1]) { array[i]++; } else if (array[i] < array[i - 1]) { array[i] = array[i-1] + 1; } } return array; } public static void main(String[] args) { for (int i = 0; i < 1000; i++) { int size = AssortedMethods.randomIntInRange(5, 20); int[] array = getDistinctSortedArray(size); int v2 = magicFast(array); if (v2 == -1 && magicSlow(array) != -1) { int v1 = magicSlow(array); System.out.println("Incorrect value: index = -1, actual = " + v1 + " " + i); System.out.println(AssortedMethods.arrayToString(array)); break; } else if (v2 > -1 && array[v2] != v2) { System.out.println("Incorrect values: index= " + v2 + ", value " + array[v2]); System.out.println(AssortedMethods.arrayToString(array)); break; } } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_03_Magic_Index/QuestionB.java ================================================ package Q8_03_Magic_Index; import java.util.Arrays; import CtCILibrary.AssortedMethods; public class QuestionB { public static int magicSlow(int[] array) { for (int i = 0; i < array.length; i++) { if (array[i] == i) { return i; } } return -1; } public static int magicFast(int[] array, int start, int end) { if (end < start) { return -1; } int midIndex = (start + end) / 2; int midValue = array[midIndex]; if (midValue == midIndex) { return midIndex; } /* Search left */ int leftIndex = Math.min(midIndex - 1, midValue); int left = magicFast(array, start, leftIndex); if (left >= 0) { return left; } /* Search right */ int rightIndex = Math.max(midIndex + 1, midValue); int right = magicFast(array, rightIndex, end); return right; } public static int magicFast(int[] array) { return magicFast(array, 0, array.length - 1); } /* Creates an array that is sorted */ public static int[] getSortedArray(int size) { int[] array = AssortedMethods.randomArray(size, -1 * size, size); Arrays.sort(array); return array; } public static void main(String[] args) { for (int i = 0; i < 1000; i++) { int size = AssortedMethods.randomIntInRange(5, 20); int[] array = getSortedArray(size); int v2 = magicFast(array); if (v2 == -1 && magicSlow(array) != -1) { int v1 = magicSlow(array); System.out.println("Incorrect value: index = -1, actual = " + v1 + " " + i); System.out.println(AssortedMethods.arrayToString(array)); break; } else if (v2 > -1 && array[v2] != v2) { System.out.println("Incorrect values: index= " + v2 + ", value " + array[v2]); System.out.println(AssortedMethods.arrayToString(array)); break; } } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_04_Power_Set/QuestionA.java ================================================ package Q8_04_Power_Set; import java.util.*; public class QuestionA { public static ArrayList> getSubsets(ArrayList set, int index) { ArrayList> allsubsets; if (set.size() == index) { // Base case - add empty set allsubsets = new ArrayList>(); allsubsets.add(new ArrayList()); } else { allsubsets = getSubsets(set, index + 1); int item = set.get(index); ArrayList> moresubsets = new ArrayList>(); for (ArrayList subset : allsubsets) { ArrayList newsubset = new ArrayList(); newsubset.addAll(subset); newsubset.add(item); moresubsets.add(newsubset); } allsubsets.addAll(moresubsets); } return allsubsets; } public static void main(String[] args) { ArrayList list = new ArrayList(); for (int i = 0; i < 3; i++) { list.add(i); } ArrayList> subsets = getSubsets(list, 0); System.out.println(subsets.toString()); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_04_Power_Set/QuestionB.java ================================================ package Q8_04_Power_Set; import java.util.*; public class QuestionB { public static ArrayList convertIntToSet(int x, ArrayList set) { ArrayList subset = new ArrayList(); int index = 0; for (int k = x; k > 0; k >>= 1) { if ((k & 1) == 1) { subset.add(set.get(index)); } index++; } return subset; } public static ArrayList> getSubsets(ArrayList set) { ArrayList> allsubsets = new ArrayList>(); int max = 1 << set.size(); /* Compute 2^n */ for (int k = 0; k < max; k++) { ArrayList subset = convertIntToSet(k, set); allsubsets.add(subset); } return allsubsets; } public static void main(String[] args) { ArrayList list = new ArrayList(); for (int i = 0; i < 3; i++) { list.add(i); } ArrayList> subsets2 = getSubsets(list); System.out.println(subsets2.toString()); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_05_Recursive_Multiply/QuestionA.java ================================================ package Q8_05_Recursive_Multiply; public class QuestionA { public static int counter = 0; public static int sum(int x, int y) { counter++; return x + y; } public static int minProductHelper(int smaller, int bigger) { if (smaller == 0) { // 0 x bigger = 0 return 0; } else if (smaller == 1) { // 1 x bigger = bigger return bigger; } /* Compute half. If uneven, compute other half. If even, * double it. */ int s = smaller >> 1; // Divide by 2 int side1 = minProductHelper(s, bigger); int side2 = side1; if (smaller % 2 == 1) { counter++; side2 = minProductHelper(smaller - s, bigger); } counter++; return side1 + side2; } public static int minProduct(int a, int b) { int bigger = a < b ? b : a; int smaller = a < b ? a : b; return minProductHelper(smaller, bigger); } public static void main(String[] args) { int a = 13494; int b = 22323; int product = a * b; int minProduct = minProduct(a, b); if (product == minProduct) { System.out.println("Success: " + a + " * " + b + " = " + product); } else { System.out.println("Failure: " + a + " * " + b + " = " + product + " instead of " + minProduct); } System.out.println("Adds: " + counter); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_05_Recursive_Multiply/QuestionB.java ================================================ package Q8_05_Recursive_Multiply; public class QuestionB { public static int counter = 0; public static int sum(int x, int y) { counter += 1; return x + y; } public static int minProduct(int smaller, int bigger, int[] memo) { if (smaller == 0) { return 0; } else if (smaller == 1) { return bigger; } else if (memo[smaller] > 0) { return memo[smaller]; } /* Compute half. If uneven, compute other half. If even, * double it. */ int s = smaller >> 1; // Divide by 2 int side1 = minProduct(s, bigger, memo); // Compute half int side2 = side1; if (smaller % 2 == 1) { counter++; side2 = minProduct(smaller - s, bigger, memo); } /* Sum and cache.*/ counter++; memo[smaller] = side1 + side2; return memo[smaller]; } public static int minProduct(int a, int b) { int bigger = a < b ? b : a; int smaller = a < b ? a : b; int memo[] = new int[sum(smaller, 1)]; return minProduct(smaller, bigger, memo); } public static void main(String[] args) { int a = 13494; int b = 22323; int product = a * b; int minProduct = minProduct(a, b); if (product == minProduct) { System.out.println("Success: " + a + " * " + b + " = " + product); } else { System.out.println("Failure: " + a + " * " + b + " = " + product + " instead of " + minProduct); } System.out.println("Adds: " + counter); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_05_Recursive_Multiply/QuestionC.java ================================================ package Q8_05_Recursive_Multiply; public class QuestionC { public static int counter = 0; public static int minProductHelper(int smaller, int bigger) { if (smaller == 0) { return 0; } else if (smaller == 1) { return bigger; } int s = smaller >> 1; int halfProd = minProductHelper(s, bigger); if (smaller % 2 == 0) { counter++; return halfProd + halfProd; } else { counter+=2; return halfProd + halfProd + bigger; } } public static int minProduct(int a, int b) { int bigger = a < b ? b : a; int smaller = a < b ? a : b; return minProductHelper(smaller, bigger); } public static void main(String[] args) { int a = 13494; int b = 22323; int product = a * b; int minProduct = minProduct(a, b); if (product == minProduct) { System.out.println("Success: " + a + " * " + b + " = " + product); } else { System.out.println("Failure: " + a + " * " + b + " = " + product + " instead of " + minProduct); } System.out.println("Adds: " + counter); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_05_Recursive_Multiply/QuestionD.java ================================================ package Q8_05_Recursive_Multiply; public class QuestionD { public static int counter = 0; /* This is an algorithm called the peasant algorithm. * https://en.wikipedia.org/wiki/Multiplication_algorithm#Peasant_or_binary_multiplication */ public static int minProduct(int a, int b) { if (a < b) return minProduct(b, a); int value = 0; while (a > 0) { counter++; if ((a % 10) % 2 == 1) { value += b; } a >>= 1; b <<= 1; } return value; } public static void main(String[] args) { for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { int prod1 = minProduct(i, j); int prod2 = i * j; if (prod1 != prod2) { System.out.println("ERROR: " + i + " * " + j + " = " + prod2 + ", not " + prod1); } } } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_05_Recursive_Multiply/Tester.java ================================================ package Q8_05_Recursive_Multiply; public class Tester { /** * @param args */ public static void main(String[] args) { int max = 1000; int counterA = 0, counterB = 0, counterC = 0, counterD = 0; for (int a = 0; a < max; a++) { for (int b = 0; b < max; b++) { int prodA = QuestionA.minProduct(a, b); int prodB = QuestionB.minProduct(a, b); int prodC = QuestionC.minProduct(a, b); int prodD = QuestionD.minProduct(a, b); int product = a * b; counterA += QuestionA.counter; counterB += QuestionB.counter; counterC += QuestionC.counter; counterD += QuestionD.counter; QuestionA.counter = 0; QuestionB.counter = 0; QuestionC.counter = 0; QuestionD.counter = 0; if (prodA != product || prodB != product || prodC != product || prodD != product) { System.out.println("Failure: " + a + " * " + b + " = " + product + " instead of (" + prodA + ", " + prodB + ", " + prodC + ", " + prodD + ")"); break; } } } System.out.println(); System.out.println("A: " + counterA); System.out.println("B: " + counterB); System.out.println("C: " + counterC); System.out.println("D: " + counterD); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_06_Towers_of_Hanoi/Question.java ================================================ package Q8_06_Towers_of_Hanoi; public class Question { public static void main(String[] args) { Tower source = new Tower(); Tower destination = new Tower(); Tower buffer = new Tower(); source.name = "s"; destination.name = "d"; buffer.name = "b"; /* Load up tower */ int numberOfDisks = 5; for (int disk = numberOfDisks - 1; disk >= 0; disk--) { source.add(disk); } source.print(); source.moveDisks(numberOfDisks, destination, buffer); destination.print(); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_06_Towers_of_Hanoi/Tower.java ================================================ package Q8_06_Towers_of_Hanoi; import java.util.Stack; public class Tower { private Stack disks = new Stack(); public String name; public void add(int d) { if (!disks.isEmpty() && disks.peek() <= d) { System.out.println("Error placing disk " + d); } else { disks.push(d); } } public void moveTopTo(Tower t) { int top = disks.pop(); t.add(top); } public void print() { System.out.println("Contents of Tower " + name + ": " + disks.toString()); } public void moveDisks(int quantity, Tower destination, Tower buffer){ if (quantity <= 0) return; moveDisks(quantity - 1, buffer, destination); System.out.println("Move " + disks.peek() + " from " + this.name + " to " + destination.name); moveTopTo(destination); buffer.moveDisks(quantity - 1, destination, this); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_07_Permutations_Without_Dups/QuestionA.java ================================================ package Q8_07_Permutations_Without_Dups; import java.util.*; public class QuestionA { public static ArrayList getPerms(String str) { if (str == null) { return null; } ArrayList permutations = new ArrayList(); if (str.length() == 0) { // base case permutations.add(""); return permutations; } char first = str.charAt(0); // get the first character String remainder = str.substring(1); // remove the first character ArrayList words = getPerms(remainder); for (String word : words) { for (int j = 0; j <= word.length(); j++) { String s = insertCharAt(word, first, j); permutations.add(s); } } return permutations; } public static String insertCharAt(String word, char c, int i) { String start = word.substring(0, i); String end = word.substring(i); return start + c + end; } public static void main(String[] args) { ArrayList list = getPerms("abcde"); System.out.println("There are " + list.size() + " permutations."); for (String s : list) { System.out.println(s); } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_07_Permutations_Without_Dups/QuestionB.java ================================================ package Q8_07_Permutations_Without_Dups; import java.util.*; public class QuestionB { public static ArrayList getPerms(String remainder) { int len = remainder.length(); ArrayList result = new ArrayList(); /* Base case. */ if (len == 0) { result.add(""); // Be sure to return empty string! return result; } for (int i = 0; i < len; i++) { /* Remove char i and find permutations of remaining characters.*/ String before = remainder.substring(0, i); String after = remainder.substring(i + 1, len); ArrayList partials = getPerms(before + after); /* Prepend char i to each permutation.*/ for (String s : partials) { result.add(remainder.charAt(i) + s); } } return result; } public static void main(String[] args) { ArrayList list = getPerms("abc"); System.out.println("There are " + list.size() + " permutations."); for (String s : list) { System.out.println(s); } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_07_Permutations_Without_Dups/QuestionC.java ================================================ package Q8_07_Permutations_Without_Dups; import java.util.*; public class QuestionC { public static void getPerms(String prefix, String remainder, ArrayList result) { if (remainder.length() == 0) { result.add(prefix); } int len = remainder.length(); for (int i = 0; i < len; i++) { String before = remainder.substring(0, i); String after = remainder.substring(i + 1, len); char c = remainder.charAt(i); getPerms(prefix + c, before + after, result); } } public static ArrayList getPerms(String str) { ArrayList result = new ArrayList(); getPerms("", str, result); return result; } public static void main(String[] args) { ArrayList list = getPerms("abc"); System.out.println("There are " + list.size() + " permutations."); for (String s : list) { System.out.println(s); } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_08_Permutations_With_Dups/Question.java ================================================ package Q8_08_Permutations_With_Dups; import java.util.ArrayList; import java.util.HashMap; public class Question { public static HashMap buildFreqTable(String s) { HashMap map = new HashMap(); for (char c : s.toCharArray()) { if (!map.containsKey(c)) { map.put(c, 0); } map.put(c, map.get(c) + 1); } return map; } public static void printPerms(HashMap map, String prefix, int remaining, ArrayList result) { if (remaining == 0) { result.add(prefix); return; } for (Character c : map.keySet()) { int count = map.get(c); if (count > 0) { map.put(c, count - 1); printPerms(map, prefix + c, remaining - 1, result); map.put(c, count); } } } public static ArrayList printPerms(String s) { ArrayList result = new ArrayList(); HashMap map = buildFreqTable(s); printPerms(map, "", s.length(), result); return result; } public static void main(String[] args) { String s = "aabbccc"; ArrayList result = printPerms(s); System.out.println("Count: " + result.size()); for (String r : result) { System.out.println(r); } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_09_Parens/QuestionA.java ================================================ package Q8_09_Parens; import java.util.HashSet; import java.util.Set; public class QuestionA { public static String insertInside(String str, int leftIndex) { String left = str.substring(0, leftIndex + 1); String right = str.substring(leftIndex + 1, str.length()); return left + "()" + right; } public static Set generateParens(int remaining) { Set set = new HashSet(); if (remaining == 0) { set.add(""); } else { Set prev = generateParens(remaining - 1); for (String str : prev) { for (int i = 0; i < str.length(); i++) { if (str.charAt(i) == '(') { String s = insertInside(str, i); /* Add s to set if it is not already in there. Note: * HashSet automatically checks for duplicates before * adding, so an explicit check is not necessary. */ set.add(s); } } set.add("()" + str); } } return set; } public static void main(String[] args) { Set list = generateParens(4); for (String s : list) { System.out.println(s); } System.out.println(list.size()); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_09_Parens/QuestionB.java ================================================ package Q8_09_Parens; import java.util.ArrayList; public class QuestionB { public static void addParen(ArrayList list, int leftRem, int rightRem, char[] str, int index) { if (leftRem < 0 || rightRem < leftRem) return; // invalid state if (leftRem == 0 && rightRem == 0) { /* all out of left and right parentheses */ list.add(String.copyValueOf(str)); } else { str[index] = '('; // Add left and recurse addParen(list, leftRem - 1, rightRem, str, index + 1); str[index] = ')'; // Add right and recurse addParen(list, leftRem, rightRem - 1, str, index + 1); } } public static ArrayList generateParens(int count) { char[] str = new char[count*2]; ArrayList list = new ArrayList(); addParen(list, count, count, str, 0); return list; } public static void main(String[] args) { ArrayList list = generateParens(6); for (String s : list) { System.out.println(s); } System.out.println(list.size()); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_10_Paint_Fill/Question.java ================================================ package Q8_10_Paint_Fill; public class Question { public enum Color { Black, White, Red, Yellow, Green } public static String PrintColor(Color c) { switch(c) { case Black: return "B"; case White: return "W"; case Red: return "R"; case Yellow: return "Y"; case Green: return "G"; } return "X"; } public static void PrintScreen(Color[][] screen) { for (int r = 0; r < screen.length; r++) { for (int c = 0; c < screen[0].length; c++) { System.out.print(PrintColor(screen[r][c])); } System.out.println(); } } public static int randomInt(int n) { return (int) (Math.random() * n); } public static boolean PaintFill(Color[][] screen, int r, int c, Color ocolor, Color ncolor) { if (r < 0 || r >= screen.length || c < 0 || c >= screen[0].length) { return false; } if (screen[r][c] == ocolor) { screen[r][c] = ncolor; PaintFill(screen, r - 1, c, ocolor, ncolor); // up PaintFill(screen, r + 1, c, ocolor, ncolor); // down PaintFill(screen, r, c - 1, ocolor, ncolor); // left PaintFill(screen, r, c + 1, ocolor, ncolor); // right } return true; } public static boolean PaintFill(Color[][] screen, int r, int c, Color ncolor) { if (screen[r][c] == ncolor) return false; return PaintFill(screen, r, c, screen[r][c], ncolor); } public static void main(String[] args) { int N = 10; Color[][] screen = new Color[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { screen[i][j] = Color.Black; } } for (int i = 0; i < 100; i++) { screen[randomInt(N)][randomInt(N)] = Color.Green; } PrintScreen(screen); PaintFill(screen, 2, 2, Color.White); System.out.println(); PrintScreen(screen); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_11_Coins/Question.java ================================================ package Q8_11_Coins; public class Question { public static int makeChangeHelper(int total, int[] denoms, int index) { int coin = denoms[index]; if (index == denoms.length - 1) { // One denom left, either you can do it or not int remaining = total % coin; return remaining == 0 ? 1 : 0; } int ways = 0; /* Try 1 coin, then 2 coins, 3 three, ... (recursing each time on rest). */ for (int amount = 0; amount <= total; amount += coin) { ways += makeChangeHelper(total - amount, denoms, index + 1); // go to next denom } return ways; } public static int makeChange(int amount, int[] denoms) { return makeChangeHelper(amount, denoms, 0); } public static void main(String[] args) { int[] denoms = {25, 10, 5, 1}; int ways = makeChange(10, denoms); System.out.println(ways); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_11_Coins/QuestionB.java ================================================ package Q8_11_Coins; public class QuestionB { public static int makeChange(int n, int[] denoms) { int[][] map = new int[n + 1][denoms.length]; return makeChangeHelper(n, denoms, 0, map); } public static int makeChangeHelper(int total, int[] denoms, int index, int[][] map) { /* Check cache for prior result. */ if (map[total][index] > 0) { // retrieve value return map[total][index]; } int coin = denoms[index]; if (index == denoms.length - 1) { int remaining = total % coin; return remaining == 0 ? 1 : 0; } int numberOfWays = 0; /* Try 1 coin, then 2 coins, 3 three, ... (recursing each time on rest). */ for (int amount = 0; amount <= total; amount += coin) { numberOfWays += makeChangeHelper(total - amount, denoms, index + 1, map); // go to next denom } /* Update cache with current result. */ map[total][index] = numberOfWays; return numberOfWays; } public static void main(String[] args) { int[] denoms = {25, 10, 5, 1}; int ways = makeChange(10, denoms); System.out.println(ways); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_11_Coins/Tester.java ================================================ package Q8_11_Coins; public class Tester { public static void main(String[] args) { for (int i = 0; i < 200; i++) { int[] denoms = {25, 10, 5, 1}; int waysA = Question.makeChange(i, denoms); int waysB = QuestionB.makeChange(i, denoms); if (waysA != waysB) { System.out.println("Error: " + i + " : " + waysA + ", " + waysB); } } } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_12_Eight_Queens/Question.java ================================================ package Q8_12_Eight_Queens; import java.util.ArrayList; public class Question { public static int GRID_SIZE = 8; /* Check if (row1, column1) is a valid spot for a queen by checking if there * is a queen in the same column or diagonal. We don't need to check it for queens * in the same row because the calling placeQueen only attempts to place one queen at * a time. We know this row is empty. */ public static boolean checkValid(Integer[] columns, int row1, int column1) { for (int row2 = 0; row2 < row1; row2++) { int column2 = columns[row2]; /* Check if (row2, column2) invalidates (row1, column1) as a queen spot. */ /* Check if rows have a queen in the same column */ if (column1 == column2) { return false; } /* Check diagonals: if the distance between the columns equals the distance * between the rows, then they’re in the same diagonal. */ int columnDistance = Math.abs(column2 - column1); int rowDistance = row1 - row2; // row1 > row2, so no need to use absolute value if (columnDistance == rowDistance) { return false; } } return true; } public static void placeQueens(int row, Integer[] columns, ArrayList results) { if (row == GRID_SIZE) { // Found valid placement results.add(columns.clone()); } else { for (int col = 0; col < GRID_SIZE; col++) { if (checkValid(columns, row, col)) { columns[row] = col; // Place queen placeQueens(row + 1, columns, results); } } } } public static void clear(Integer[] columns) { for (int i = 0; i < GRID_SIZE; i++) { columns[i] = -1; } } public static void printBoard(Integer[] columns) { drawLine(); for(int i = 0; i < GRID_SIZE; i++){ System.out.print("|"); for (int j = 0; j < GRID_SIZE; j++){ if (columns[i] == j) { System.out.print("Q|"); } else { System.out.print(" |"); } } System.out.print("\n"); drawLine(); } System.out.println(""); } private static void drawLine() { StringBuilder line = new StringBuilder(); for (int i=0;i boards) { for (int i = 0; i < boards.size(); i++) { Integer[] board = boards.get(i); printBoard(board); } } public static void main(String[] args) { ArrayList results = new ArrayList(); Integer[] columns = new Integer[GRID_SIZE]; clear(columns); placeQueens(0, columns, results); printBoards(results); System.out.println(results.size()); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_13_Stack_of_Boxes/Box.java ================================================ package Q8_13_Stack_of_Boxes; public class Box { public int width; public int height; public int depth; public Box(int w, int h, int d) { width = w; height = h; depth = d; } public boolean canBeUnder(Box b) { if (width > b.width && height > b.height && depth > b.depth) { return true; } return false; } public boolean canBeAbove(Box b) { if (b == null) { return true; } if (width < b.width && height < b.height && depth < b.depth) { return true; } return false; } public String toString() { return "Box(" + width + "," + height + "," + depth + ")"; } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_13_Stack_of_Boxes/BoxComparator.java ================================================ package Q8_13_Stack_of_Boxes; import java.util.Comparator; public class BoxComparator implements Comparator { @Override public int compare(Box x, Box y){ return y.height - x.height; } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_13_Stack_of_Boxes/QuestionA.java ================================================ package Q8_13_Stack_of_Boxes; import java.util.ArrayList; import java.util.Collections; public class QuestionA { public static int createStack(ArrayList boxes) { Collections.sort(boxes, new BoxComparator()); int maxHeight = 0; for (int i = 0; i < boxes.size(); i++) { int height = createStack(boxes, i); maxHeight = Math.max(maxHeight, height); } return maxHeight; } public static int createStack(ArrayList boxes, int bottomIndex) { Box bottom = boxes.get(bottomIndex); int maxHeight = 0; for (int i = bottomIndex + 1; i < boxes.size(); i++) { if (boxes.get(i).canBeAbove(bottom)) { int height = createStack(boxes, i); maxHeight = Math.max(height, maxHeight); } } maxHeight += bottom.height; return maxHeight; } public static void main(String[] args) { Box[] boxList = { new Box(6, 4, 4), new Box(8, 6, 2), new Box(5, 3, 3), new Box(7, 8, 3), new Box(4, 2, 2), new Box(9, 7, 3)}; ArrayList boxes = new ArrayList(); for (Box b : boxList) { boxes.add(b); } int height = createStack(boxes); System.out.println(height); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_13_Stack_of_Boxes/QuestionB.java ================================================ package Q8_13_Stack_of_Boxes; import java.util.ArrayList; import java.util.Collections; public class QuestionB { public static int createStack(ArrayList boxes) { Collections.sort(boxes, new BoxComparator()); int maxHeight = 0; int[] stackMap = new int[boxes.size()]; for (int i = 0; i < boxes.size(); i++) { int height = createStack(boxes, i, stackMap); maxHeight = Math.max(maxHeight, height); } return maxHeight; } public static int createStack(ArrayList boxes, int bottomIndex, int[] stackMap) { if (bottomIndex < boxes.size() && stackMap[bottomIndex] > 0) { return stackMap[bottomIndex]; } Box bottom = boxes.get(bottomIndex); int maxHeight = 0; for (int i = bottomIndex + 1; i < boxes.size(); i++) { if (boxes.get(i).canBeAbove(bottom)) { int height = createStack(boxes, i, stackMap); maxHeight = Math.max(height, maxHeight); } } maxHeight += bottom.height; stackMap[bottomIndex] = maxHeight; return maxHeight; } public static void main(String[] args) { Box[] boxList = { new Box(6, 4, 4), new Box(8, 6, 2), new Box(5, 3, 3), new Box(7, 8, 3), new Box(4, 2, 2), new Box(9, 7, 3)}; ArrayList boxes = new ArrayList(); for (Box b : boxList) { boxes.add(b); } int height = createStack(boxes); System.out.println(height); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_13_Stack_of_Boxes/QuestionC.java ================================================ package Q8_13_Stack_of_Boxes; import java.util.ArrayList; import java.util.Collections; public class QuestionC { public static int createStack(ArrayList boxes) { Collections.sort(boxes, new BoxComparator()); int[] stackMap = new int[boxes.size()]; return createStack(boxes, null, 0, stackMap); } public static int createStack(ArrayList boxes, Box bottom, int offset, int[] stackMap) { if (offset >= boxes.size()) { return 0; } /* height with this bottom */ Box newBottom = boxes.get(offset); int heightWithBottom = 0; if (bottom == null || newBottom.canBeAbove(bottom)) { if (stackMap[offset] == 0) { stackMap[offset] = createStack(boxes, newBottom, offset + 1, stackMap); stackMap[offset] += newBottom.height; } heightWithBottom = stackMap[offset]; } /* without this bottom */ int heightWithoutBottom = createStack(boxes, bottom, offset + 1, stackMap); return Math.max(heightWithBottom, heightWithoutBottom); } public static void main(String[] args) { Box[] boxList = { new Box(6, 4, 4), new Box(8, 6, 2), new Box(5, 3, 3), new Box(7, 8, 3), new Box(4, 2, 2), new Box(9, 7, 3)}; ArrayList boxes = new ArrayList(); for (Box b : boxList) { boxes.add(b); } int height = createStack(boxes); System.out.println(height); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_13_Stack_of_Boxes/Tester.java ================================================ package Q8_13_Stack_of_Boxes; import java.util.ArrayList; import java.util.Random; public class Tester { public static Box createRandomBox() { Random r = new Random(); return new Box(r.nextInt(100), r.nextInt(100), r.nextInt(100)); } public static void main(String[] args) { ArrayList boxes1 = new ArrayList(); ArrayList boxes2 = new ArrayList(); ArrayList boxes3 = new ArrayList(); for (int i = 0; i < 200; i++) { Box b = createRandomBox(); boxes1.add(b); boxes2.add(b); boxes3.add(b); } int height1 = QuestionA.createStack(boxes1); int height2 = QuestionB.createStack(boxes2); int height3 = QuestionB.createStack(boxes3); System.out.println(height1 + ", " + height2 + ", " + height3); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_14_Boolean_Evaluation/Others.java ================================================ package Q8_14_Boolean_Evaluation; import java.util.HashMap; public class Others { public enum Term { True, False, And, Or, Xor, LeftParen, RightParen }; public static String reduce(String expression, int start, int end) { if (start == end) { if (expression.charAt(start) == '1') { return "1"; } else if (expression.charAt(start) == '0') { return "0"; } } int count = 0; int i = 0; String[] reduced = new String[3]; int index = 0; int left = start; int right = start; for (i = start; i <= end; i++) { if (expression.charAt(i) == '(') { if (count == 0) { left = i + 1; } count++; } else if (expression.charAt(i) == ')') { count--; if (count == 0) { right = i - 1; } } if (count == 0) { reduced[index] = reduce(expression, left, right); if (index == 0) { reduced[index + 1] = Character.toString(expression.charAt(i + 1)); i += 1; left = i + 1; right = i + 1; } index += 2; } } if (reduced[1].equals("&")) { if (reduced[0].equals("1") && reduced[2].equals("1")) { return "1"; } return "0"; } else if (reduced[1].equals("|")) { if (reduced[0].equals("1") || reduced[2].equals("1")) { return "1"; } return "0"; } else if (reduced[1].equals("^")) { if (reduced[0].equals("1") && reduced[2].equals("0")) { return "1"; } else if (reduced[0].equals("0") && reduced[2].equals("1")) { return "1"; } return "0"; } return "0"; } public static boolean evaluate(String expression, int start, int end) { String result = reduce(expression, start, end); if (result == "0") { return false; } else { return true; } } public static boolean isOperator(char c) { switch (c) { case '&': case '|': case '^': return true; default: return false; } } public static String insertParensAround(String expression, int ind) { int left = 0; int right = 0; int index = 0; int count = 0; for (int i = 0; i < expression.length(); i++) { if (isOperator(expression.charAt(i))) { if (count == ind) { index = i; } count++; } } count = 0; for (int i = index - 1; i >= 0; i--) { if (expression.charAt(i) == ')') { count++; } else if (expression.charAt(i) == '(') { count--; } if (count == 0) { left = i; break; } } count = 0; for (int i = index + 1; i <= expression.length(); i++) { if (expression.charAt(i) == '(') { count++; } else if (expression.charAt(i) == ')') { count--; } if (count == 0) { right = i; break; } } if (left == 0 && right == expression.length() - 1) { return expression; } String newexpression = expression.substring(0, left) + '(' + expression.substring(left, right + 1) + ')' + expression.substring(right + 1); return newexpression; } public static int bruteForce(String expression, HashMap completed, boolean result, boolean[] flags) { int count = 0; boolean isDone = true; if (completed.containsKey(expression)) { return 0; } for (int i = 0; i < flags.length; i++) { if (!flags[i]) { flags[i] = true; String newexpression = insertParensAround(expression, i); isDone = false; count += bruteForce(newexpression, completed, result, flags); flags[i] = false; } } if (isDone) { if (evaluate(expression, 0, expression.length() - 1) == result) { //System.out.println(expression + " = " + result); return 1; } else { //System.out.println(expression + " = " + !result); return 0; } } completed.put(expression, true); return count; } public static int countR(String exp, boolean result, int start, int end) { if (start == end) { if (exp.charAt(start) == '1' && result) { return 1; } else if (exp.charAt(start) == '0' && !result) { return 1; } return 0; } int c = 0; if (result) { for (int i = start + 1; i <= end; i += 2) { char op = exp.charAt(i); if (op == '&') { c += countR(exp, true, start, i - 1) * countR(exp, true, i + 1, end); } else if (op == '|') { c += countR(exp, true, start, i - 1) * countR(exp, false, i + 1, end); c += countR(exp, false, start, i - 1) * countR(exp, true, i + 1, end); c += countR(exp, true, start, i - 1) * countR(exp, true, i + 1, end); } else if (op == '^') { c += countR(exp, true, start, i - 1) * countR(exp, false, i + 1, end); c += countR(exp, false, start, i - 1) * countR(exp, true, i + 1, end); } } } else { for (int i = start + 1; i <= end; i += 2) { char op = exp.charAt(i); if (op == '&') { c += countR(exp, false, start, i - 1) * countR(exp, true, i + 1, end); c += countR(exp, true, start, i - 1) * countR(exp, false, i + 1, end); c += countR(exp, false, start, i - 1) * countR(exp, false, i + 1, end); } else if (op == '|') { c += countR(exp, false, start, i - 1) * countR(exp, false, i + 1, end); } else if (op == '^') { c += countR(exp, true, start, i - 1) * countR(exp, true, i + 1, end); c += countR(exp, false, start, i - 1) * countR(exp, false, i + 1, end); } } } return c; } public static int countDP(String exp, boolean result, int start, int end, HashMap cache) { String key = "" + result + start + end; if (cache.containsKey(key)) { return cache.get(key); } if (start == end) { if (exp.charAt(start) == '1' && result == true) { return 1; } else if (exp.charAt(start) == '0' && result == false) { return 1; } return 0; } int count = 0; if (result) { for (int i = start + 1; i <= end; i += 2) { char op = exp.charAt(i); if (op == '&') { count += countDP(exp, true, start, i - 1, cache) * countDP(exp, true, i + 1, end, cache); } else if (op == '|') { count += countDP(exp, true, start, i - 1, cache) * countDP(exp, false, i + 1, end, cache); count += countDP(exp, false, start, i - 1, cache) * countDP(exp, true, i + 1, end, cache); count += countDP(exp, true, start, i - 1, cache) * countDP(exp, true, i + 1, end, cache); } else if (op == '^') { count += countDP(exp, true, start, i - 1, cache) * countDP(exp, false, i + 1, end, cache); count += countDP(exp, false, start, i - 1, cache) * countDP(exp, true, i + 1, end, cache); } } } else { for (int i = start + 1; i <= end; i += 2) { char op = exp.charAt(i); if (op == '&') { count += countDP(exp, false, start, i - 1, cache) * countDP(exp, true, i + 1, end, cache); count += countDP(exp, true, start, i - 1, cache) * countDP(exp, false, i + 1, end, cache); count += countDP(exp, false, start, i - 1, cache) * countDP(exp, false, i + 1, end, cache); } else if (op == '|') { count += countDP(exp, false, start, i - 1, cache) * countDP(exp, false, i + 1, end, cache); } else if (op == '^') { count += countDP(exp, true, start, i - 1, cache) * countDP(exp, true, i + 1, end, cache); count += countDP(exp, false, start, i - 1, cache) * countDP(exp, false, i + 1, end, cache); } } } cache.put(key, count); return count; } public static int total(int n) { // Function to return (2n) ! / ((n+1)! * n!) // To keep the numbers small, we divide by i when possible to do evenly. If not, // we store up the remainder and divide when possible. long num = 1; long rem = 1; for (int i = 2; i <= n; i++) { num *= (n + i); rem *= i; if (num % rem == 0) { num /= rem; rem = 1; } } return (int)num; } public static int countDPEff(String exp, boolean result, int start, int end, HashMap cache) { String key = "" + start + end; int count = 0; if (!cache.containsKey(key)) { if (start == end) { if (exp.charAt(start) == '1') { count = 1; } else { count = 0; } } for (int i = start + 1; i <= end; i += 2) { char op = exp.charAt(i); if (op == '&') { count += countDPEff(exp, true, start, i - 1, cache) * countDPEff(exp, true, i + 1, end, cache); } else if (op == '|') { int left_ops = (i - 1 - start) / 2; // parens on left int right_ops = (end - i - 1) / 2; // parens on right int total_ways = total(left_ops) * total(right_ops); int total_false = countDPEff(exp, false, start, i - 1, cache) * countDPEff(exp, false, i + 1, end, cache); count += total_ways - total_false; } else if (op == '^') { count += countDPEff(exp, true, start, i - 1, cache) * countDPEff(exp, false, i + 1, end, cache); count += countDPEff(exp, false, start, i - 1, cache) * countDPEff(exp, true, i + 1, end, cache); } } cache.put(key, count); } else { count = cache.get(key); } if (result) { return count; } else { int num_ops = (end - start) / 2; return total(num_ops) - count; } } public static void main(String[] args) { String terms = "0^0|1&1^1|0|1"; boolean result = true; bruteForce(terms, new HashMap(), result, new boolean[(terms.length() - 1) / 2]); System.out.println(countR(terms, result, 0, terms.length() - 1)); System.out.println(countDP(terms, result, 0, terms.length() - 1, new HashMap())); System.out.println(countDPEff(terms, result, 0, terms.length() - 1, new HashMap())); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_14_Boolean_Evaluation/QuestionA.java ================================================ package Q8_14_Boolean_Evaluation; public class QuestionA { public static int count = 0; public static boolean stringToBool(String c) { return c.equals("1") ? true : false; } public static int countEval(String s, boolean result) { count++; if (s.length() == 0) return 0; if (s.length() == 1) return stringToBool(s) == result ? 1 : 0; int ways = 0; for (int i = 1; i < s.length(); i += 2) { char c = s.charAt(i); String left = s.substring(0, i); String right = s.substring(i + 1, s.length()); int leftTrue = countEval(left, true); int leftFalse = countEval(left, false); int rightTrue = countEval(right, true); int rightFalse = countEval(right, false); int total = (leftTrue + leftFalse) * (rightTrue + rightFalse); int totalTrue = 0; if (c == '^') { // required: one true and one false totalTrue = leftTrue * rightFalse + leftFalse * rightTrue; } else if (c == '&') { // required: both true totalTrue = leftTrue * rightTrue; } else if (c == '|') { // required: anything but both false totalTrue = leftTrue * rightTrue + leftFalse * rightTrue + leftTrue * rightFalse; } int subWays = result ? totalTrue : total - totalTrue; ways += subWays; } return ways; } public static void main(String[] args) { String expression = "0^0|1&1^1|0|1"; boolean result = true; System.out.println(countEval(expression, result)); System.out.println(count); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_14_Boolean_Evaluation/QuestionB.java ================================================ package Q8_14_Boolean_Evaluation; import java.util.HashMap; public class QuestionB { public static int count = 0; public static boolean stringToBool(String c) { return c.equals("1") ? true : false; } public static int countEval(String s, boolean result, HashMap memo) { count++; if (s.length() == 0) return 0; if (s.length() == 1) return stringToBool(s) == result ? 1 : 0; if (memo.containsKey(result + s)) return memo.get(result + s); int ways = 0; for (int i = 1; i < s.length(); i += 2) { char c = s.charAt(i); String left = s.substring(0, i); String right = s.substring(i + 1, s.length()); int leftTrue = countEval(left, true, memo); int leftFalse = countEval(left, false, memo); int rightTrue = countEval(right, true, memo); int rightFalse = countEval(right, false, memo); int total = (leftTrue + leftFalse) * (rightTrue + rightFalse); int totalTrue = 0; if (c == '^') { totalTrue = leftTrue * rightFalse + leftFalse * rightTrue; } else if (c == '&') { totalTrue = leftTrue * rightTrue; } else if (c == '|') { totalTrue = leftTrue * rightTrue + leftFalse * rightTrue + leftTrue * rightFalse; } int subWays = result ? totalTrue : total - totalTrue; ways += subWays; } memo.put(result + s, ways); return ways; } public static int countEval(String s, boolean result) { return countEval(s, result, new HashMap()); } public static void main(String[] args) { String expression = "0^0|1&1^1|0|1"; boolean result = true; System.out.println(countEval(expression, result)); System.out.println(count); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_14_Boolean_Evaluation/QuestionC.java ================================================ package Q8_14_Boolean_Evaluation; public class QuestionC { public static int count = 0; public static boolean stringToBool(String c) { return c.equals("1") ? true : false; } public static int countEval(String s, boolean result) { count++; if (s.length() == 0) return 0; if (s.length() == 1) return stringToBool(s) == result ? 1 : 0; int ways = 0; for (int i = 1; i < s.length(); i += 2) { char c = s.charAt(i); String left = s.substring(0, i); String right = s.substring(i + 1, s.length()); int subWays = 0; if (c == '^') { // required: one true and one false if (result) { int leftTrue = countEval(left, true); int leftFalse = countEval(left, false); int rightTrue = countEval(right, true); int rightFalse = countEval(right, false); subWays = leftTrue * rightFalse + leftFalse * rightTrue; } else { int leftTrue = countEval(left, true); int leftFalse = countEval(left, false); int rightTrue = countEval(right, true); int rightFalse = countEval(right, false); subWays = leftTrue * rightTrue + leftFalse * rightFalse; } } else if (c == '&') { // required: both true if (result) { int leftTrue = countEval(left, true); int rightTrue = countEval(right, true); subWays = leftTrue * rightTrue; } else { int leftTrue = countEval(left, true); int leftFalse = countEval(left, false); int rightTrue = countEval(right, true); int rightFalse = countEval(right, false); subWays = leftTrue * rightFalse + leftFalse * rightTrue + leftFalse * rightFalse; } } else if (c == '|') { // required: anything but both false if (result) { int leftTrue = countEval(left, true); int leftFalse = countEval(left, false); int rightTrue = countEval(right, true); int rightFalse = countEval(right, false); subWays = leftTrue * rightFalse + leftFalse * rightTrue + leftTrue * rightTrue; } else { int leftFalse = countEval(left, false); int rightFalse = countEval(right, false); subWays = leftFalse * rightFalse; } } ways += subWays; } return ways; } public static void main(String[] args) { String expression = "0&0&0&1^1|0"; boolean result = true; System.out.println(countEval(expression, result)); System.out.println(count); } } ================================================ FILE: Java/Ch 08. Recursion and Dynamic Programming/Q8_14_Boolean_Evaluation/Tester.java ================================================ package Q8_14_Boolean_Evaluation; import java.util.HashMap; import java.util.Map.Entry; import java.util.Random; public class Tester { public static boolean allEqual(HashMap map) { int val = 0; for (Entry e : map.entrySet()) { if (val != 0 && val != e.getValue()) { return false; } val = e.getValue(); } return true; } public static char getRandomOperator() { Random rand = new Random(); int r = rand.nextInt(3); char[] ops = {'^', '&', '|'}; return ops[r]; } public static String getRandomExpression() { Random rand = new Random(); int len = rand.nextInt(10) * 2 + 1; String s = ""; for (int i = 0; i < len; i++) { char next = '1'; if (i % 2 == 0) { next = rand.nextBoolean() ? '1' : '0'; } else { next = getRandomOperator(); } s += next; } return s; } public static void main(String[] args) { for (int i = 0; i < 50; i++) { //String terms = "0^0|1&1^1|0|1"; String terms = getRandomExpression(); boolean result = true; int oBF = Others.bruteForce(terms, new HashMap(), result, new boolean[(terms.length() - 1) / 2]); int oR = Others.countR(terms, result, 0, terms.length() - 1); int oDP = Others.countDP(terms, result, 0, terms.length() - 1, new HashMap()); int oDPEFF = Others.countDPEff(terms, result, 0, terms.length() - 1, new HashMap()); int a = QuestionA.countEval(terms, result); int b = QuestionB.countEval(terms, result); HashMap results = new HashMap(); results.put("oBF", oBF); results.put("oR", oR); results.put("oDP", oDP); results.put("oDPEFF", oDPEFF); results.put("a", a); results.put("b", b); if (allEqual(results)) { System.out.println("Success: " + terms + "->" + b); System.out.println(results.toString()); } else { System.out.println("Failure: " + terms); System.out.println(results.toString()); break; } } } } ================================================ FILE: Java/Ch 09. Scalability and Memory Limits/Q9_02_Social_Network/BFSData.java ================================================ package Q9_02_Social_Network; import java.util.HashMap; import java.util.LinkedList; import java.util.Queue; public class BFSData { public Queue toVisit = new LinkedList(); public HashMap visited = new HashMap(); public BFSData(Person root) { PathNode sourcePath = new PathNode(root, null); toVisit.add(sourcePath); visited.put(root.getID(), sourcePath); } public boolean isFinished() { return toVisit.isEmpty(); } } ================================================ FILE: Java/Ch 09. Scalability and Memory Limits/Q9_02_Social_Network/Machine.java ================================================ package Q9_02_Social_Network; import java.util.HashMap; public class Machine { public HashMap persons = new HashMap(); public int machineID; public Person getPersonWithID(int personID) { return persons.get(personID); } } ================================================ FILE: Java/Ch 09. Scalability and Memory Limits/Q9_02_Social_Network/PathNode.java ================================================ package Q9_02_Social_Network; import java.util.LinkedList; public class PathNode { private Person person = null; private PathNode previousNode = null; public PathNode(Person p, PathNode previous) { person = p; previousNode = previous; } public Person getPerson() { return person; } public LinkedList collapse(boolean startsWithRoot) { LinkedList path = new LinkedList(); PathNode node = this; while (node != null) { if (startsWithRoot) { path.addLast(node.person); } else { path.addFirst(node.person); } node = node.previousNode; } return path; } } ================================================ FILE: Java/Ch 09. Scalability and Memory Limits/Q9_02_Social_Network/Person.java ================================================ package Q9_02_Social_Network; import java.util.ArrayList; public class Person { private ArrayList friends = new ArrayList(); private int personID; private String info; public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } public ArrayList getFriends() { return friends; } public int getID() { return personID; } public void addFriend(int id) { friends.add(id); } public Person(int id) { this.personID = id; } } ================================================ FILE: Java/Ch 09. Scalability and Memory Limits/Q9_02_Social_Network/QuestionA.java ================================================ package Q9_02_Social_Network; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.Queue; public class QuestionA { public static LinkedList findPathBFS(HashMap people, int source, int destination) { Queue toVisit = new LinkedList(); HashSet visited = new HashSet(); toVisit.add(new PathNode(people.get(source), null)); visited.add(source); while (!toVisit.isEmpty()) { PathNode node = toVisit.poll(); Person person = node.getPerson(); if (person.getID() == destination) { return node.collapse(false); } /* Search friends. */ ArrayList friends = person.getFriends(); for (int friendId : friends) { if (!visited.contains(friendId)) { visited.add(friendId); Person friend = people.get(friendId); toVisit.add(new PathNode(friend, node)); } } } return null; } public static void main(String[] args) { int nPeople = 11; HashMap people = new HashMap(); for (int i = 0; i < nPeople; i++) { Person p = new Person(i); people.put(i, p); } int[][] edges = {{1, 4}, {1, 2}, {1, 3}, {3, 2}, {4, 6}, {3, 7}, {6, 9}, {9, 10}, {5, 10}, {2, 5}, {3, 7}}; for (int[] edge : edges) { Person source = people.get(edge[0]); source.addFriend(edge[1]); Person destination = people.get(edge[1]); destination.addFriend(edge[0]); } int i = 1; int j = 10; LinkedList path1 = findPathBFS(people, i, j); Tester.printPeople(path1); } } ================================================ FILE: Java/Ch 09. Scalability and Memory Limits/Q9_02_Social_Network/QuestionB.java ================================================ package Q9_02_Social_Network; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.Queue; public class QuestionB { public static LinkedList mergePaths(BFSData bfs1, BFSData bfs2, int connection) { PathNode end1 = bfs1.visited.get(connection); // end1 -> source PathNode end2 = bfs2.visited.get(connection); // end2 -> dest LinkedList pathOne = end1.collapse(false); // forward: source -> connection LinkedList pathTwo = end2.collapse(true); // reverse: connection -> dest pathTwo.removeFirst(); // remove connection pathOne.addAll(pathTwo); // add second path return pathOne; } /* Search one level and return collision, if any. */ public static Person searchLevel(HashMap people, BFSData primary, BFSData secondary) { /* We only want to search one level at a time. Count how many nodes are currently in the primary's * level and only do that many nodes. We'll continue to add nodes to the end. */ int count = primary.toVisit.size(); for (int i = 0; i < count; i++) { /* Pull out first node. */ PathNode pathNode = primary.toVisit.poll(); int personId = pathNode.getPerson().getID(); /* Check if it's already been visited. */ if (secondary.visited.containsKey(personId)) { return pathNode.getPerson(); } /* Add friends to queue. */ Person person = pathNode.getPerson(); ArrayList friends = person.getFriends(); for (int friendId : friends) { if (!primary.visited.containsKey(friendId)) { Person friend = people.get(friendId); PathNode next = new PathNode(friend, pathNode); primary.visited.put(friendId, next); primary.toVisit.add(next); } } } return null; } public static LinkedList findPathBiBFS(HashMap people, int source, int destination) { BFSData sourceData = new BFSData(people.get(source)); BFSData destData = new BFSData(people.get(destination)); while (!sourceData.isFinished() && !destData.isFinished()) { /* Search out from source. */ Person collision = searchLevel(people, sourceData, destData); if (collision != null) { return mergePaths(sourceData, destData, collision.getID()); } /* Search out from destination. */ collision = searchLevel(people, destData, sourceData); if (collision != null) { return mergePaths(sourceData, destData, collision.getID()); } } return null; } public static void main(String[] args) { int nPeople = 11; HashMap people = new HashMap(); for (int i = 0; i < nPeople; i++) { Person p = new Person(i); people.put(i, p); } int[][] edges = {{1, 4}, {1, 2}, {1, 3}, {3, 2}, {4, 6}, {3, 7}, {6, 9}, {9, 10}, {5, 10}, {2, 5}, {3, 7}}; for (int[] edge : edges) { Person source = people.get(edge[0]); source.addFriend(edge[1]); Person destination = people.get(edge[1]); destination.addFriend(edge[0]); } int i = 1; int j = 10; LinkedList path1 = findPathBiBFS(people, i, j); Tester.printPeople(path1); } } ================================================ FILE: Java/Ch 09. Scalability and Memory Limits/Q9_02_Social_Network/Server.java ================================================ package Q9_02_Social_Network; import java.util.HashMap; public class Server { HashMap machines = new HashMap(); HashMap personToMachineMap = new HashMap(); public Machine getMachineWithId(int machineID) { return machines.get(machineID); } public int getMachineIDForUser(int personID) { Integer machineID = personToMachineMap.get(personID); return machineID == null ? -1 : machineID; } public Person getPersonWithID(int personID) { Integer machineID = personToMachineMap.get(personID); if (machineID == null) { return null; } Machine machine = getMachineWithId(machineID); if (machine == null) { return null; } return machine.getPersonWithID(personID); } } ================================================ FILE: Java/Ch 09. Scalability and Memory Limits/Q9_02_Social_Network/Tester.java ================================================ package Q9_02_Social_Network; import java.util.HashMap; import java.util.LinkedList; public class Tester { public static void printPeople(LinkedList path) { if (path == null) { System.out.println("No path"); } else { for (Person p : path) { System.out.println(p.getID()); } } } public static boolean isEqual(LinkedList path1, LinkedList path2, boolean reverse) { if (path1 == null || path2 == null) { return path1 == null && path2 == null; } if (path1.size() != path2.size()) { return false; } for (int i = 0; i < path1.size(); i++) { int other = reverse ? path2.size() - i - 1 : i; if (path1.get(i) != path2.get(other)) { return false; } } return true; } public static boolean isEquivalent(LinkedList path1, LinkedList path2) { boolean f1 = isEqual(path1, path2, false); boolean f2 = isEqual(path1, path2, true); return f1 || f2; } public static void main(String[] args) { int nPeople = 11; HashMap people = new HashMap(); for (int i = 0; i < nPeople; i++) { Person p = new Person(i); people.put(i, p); } int[][] edges = {{1, 4}, {1, 2}, {1, 3}, {3, 2}, {4, 6}, {3, 7}, {6, 9}, {9, 10}, {5, 10}, {2, 5}, {3, 7}}; //int[][] edges = {{1, 4}, {1, 2}, {4, 6}, {6, 9}, {9, 10}, {5, 10}, {2, 5}}; //int[][] edges = {{1, 2}, {1, 4}, {2, 3}, {3, 4}, {4, 6}, {5, 6}, {4, 5}}; for (int[] edge : edges) { Person source = people.get(edge[0]); source.addFriend(edge[1]); Person destination = people.get(edge[1]); destination.addFriend(edge[0]); } /*int i = 1; int j = 10; LinkedList path1 = findPathBFS(people, i, j); LinkedList path2 = findPathBiBFS(people, i, j); System.out.println("Path 1"); printPeople(path1); System.out.println("Path 2"); printPeople(path2);*/ for (int i = 0; i < nPeople; i++) { for (int j = 0; j < nPeople; j++) { LinkedList path1 = QuestionA.findPathBFS(people, i, j); LinkedList path2 = QuestionB.findPathBiBFS(people, i, j); if (!isEquivalent(path1, path2)) { System.out.println("Not equal: " + i + " to " + j); System.out.println("Path 1"); printPeople(path1); System.out.println("Path 2"); printPeople(path2); break; } else { System.out.println("Is equal: " + i + " to " + j); } } } } } ================================================ FILE: Java/Ch 09. Scalability and Memory Limits/Q9_05_Cache/Cache.java ================================================ package Q9_05_Cache; import java.util.HashMap; public class Cache { public static int MAX_SIZE = 10; public Node head; public Node tail; public HashMap map; public int size = 0; public Cache() { map = new HashMap(); } public void moveToFront(Node node) { if (node == head) { return; } removeFromLinkedList(node); node.next = head; if (head != null) { head.prev = node; } head = node; size++; if (tail == null) { tail = node; } } public void moveToFront(String query) { Node node = map.get(query); moveToFront(node); } public void removeFromLinkedList(Node node) { if (node == null) { return; } if (node.next != null || node.prev != null) { size--; } Node prev = node.prev; if (prev != null) { prev.next = node.next; } Node next = node.next; if (next != null) { next.prev = prev; } if (node == head) { head = next; } if (node == tail) { tail = prev; } node.next = null; node.prev = null; } public String[] getResults(String query) { if (map.containsKey(query)) { Node node = map.get(query); moveToFront(node); return node.results; } return null; } public void insertResults(String query, String[] results) { if (map.containsKey(query)) { Node node = map.get(query); node.results = results; moveToFront(node); return; } Node node = new Node(query, results); moveToFront(node); map.put(query, node); if (size > MAX_SIZE) { map.remove(tail.query); removeFromLinkedList(tail); } } } ================================================ FILE: Java/Ch 09. Scalability and Memory Limits/Q9_05_Cache/Node.java ================================================ package Q9_05_Cache; public class Node { public Node prev; public Node next; public String[] results; public String query; public Node(String q, String[] res) { results = res; query = q; } } ================================================ FILE: Java/Ch 09. Scalability and Memory Limits/Q9_05_Cache/Question.java ================================================ package Q9_05_Cache; public class Question { public static String[] generateResults(int i) { String[] results = {"resultA" + i, "resultB" + i, "resultC" + i}; return results; } public static void main(String[] args) { Cache cache = new Cache(); for (int i = 0; i < 20; i++) { String query = "query" + i; cache.insertResults(query, generateResults(i)); if (i == 9 || i == 16 || i == 19) { cache.getResults("query" + 2); cache.getResults("query" + 6); cache.getResults("query" + 9); } } for (int i = 0; i < 30; i++) { String query = "query" + i; String[] results = cache.getResults(query); System.out.print(query + ": "); if (results == null) { System.out.print("null"); } else { for (String s : results) { System.out.print(s + ", "); } } System.out.println(""); } } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Introduction/BinarySearch.java ================================================ package Introduction; public class BinarySearch { public static int binarySearch(int[] a, int x) { int low = 0; int high = a.length - 1; int mid; while (low <= high) { mid = low + (high - low) / 2; if (a[mid] < x) { low = mid + 1; } else if (a[mid] > x) { high = mid - 1; } else { return mid; } } return -1; } public static int binarySearchRecursive(int[] a, int x, int low, int high) { if (low > high) return -1; // Error int mid = (low + high) / 2; if (a[mid] < x) { return binarySearchRecursive(a, x, mid + 1, high); } else if (a[mid] > x) { return binarySearchRecursive(a, x, low, mid - 1); } else { return mid; } } // Recursive algorithm to return the closest element public static int binarySearchRecursiveClosest(int[] a, int x, int low, int high) { if (low > high) { // high is on the left side now if (high < 0) return low; if (low >= a.length) return high; if (x - a[high] < a[low] - x) { return high; } return low; } int mid = (low + high) / 2; if (a[mid] < x) { return binarySearchRecursiveClosest(a, x, mid + 1, high); } else if (a[mid] > x) { return binarySearchRecursiveClosest(a, x, low, mid - 1); } else { return mid; } } public static void main(String[] args) { int[] array = {3, 6, 9, 12, 15, 18}; for (int i = 0; i < 20; i++) { int loc = binarySearch(array, i); int loc2 = binarySearchRecursive(array, i, 0, array.length - 1); int loc3 = binarySearchRecursiveClosest(array, i, 0, array.length - 1); System.out.println(i + ": " + loc + " " + loc2 + " " + loc3); } } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Introduction/MergeSort.java ================================================ package Introduction; import CtCILibrary.AssortedMethods; public class MergeSort { public static void mergesort(int[] array) { int[] helper = new int[array.length]; mergesort(array, helper, 0, array.length - 1); } public static void mergesort(int[] array, int[] helper, int low, int high) { if (low < high) { int middle = low + (high - low) / 2; mergesort(array, helper, low, middle); // Sort left half mergesort(array, helper, middle+1, high); // Sort right half merge(array, helper, low, middle, high); // Merge them } } public static void merge(int[] array, int[] helper, int low, int middle, int high) { /* Copy both halves into a helper array */ for (int i = low; i <= high; i++) { helper[i] = array[i]; } int helperLeft = low; int helperRight = middle + 1; int current = low; /* Iterate through helper array. Compare the left and right * half, copying back the smaller element from the two halves * into the original array. */ while (helperLeft <= middle && helperRight <= high) { if (helper[helperLeft] <= helper[helperRight]) { array[current] = helper[helperLeft]; helperLeft++; } else { // If right element is smaller than left element array[current] = helper[helperRight]; helperRight++; } current++; } /* Copy the rest of the left side of the array into the * target array */ int remaining = middle - helperLeft; for (int i = 0; i <= remaining; i++) { array[current + i] = helper[helperLeft + i]; } } public static void main(String[] args) { int size = 20; int[] array = AssortedMethods.randomArray(size, 0, size - 1); int[] validate = new int[size]; AssortedMethods.printIntArray(array); for (int i = 0; i < size; i++) { validate[array[i]]++; } mergesort(array); for (int i = 0; i < size; i++) { validate[array[i]]--; } AssortedMethods.printIntArray(array); for (int i = 0; i < size; i++) { if (validate[i] != 0 || (i < (size-1) && array[i] > array[i+1])) { System.out.println("ERROR"); } } } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Introduction/Quicksort.java ================================================ package Introduction; import CtCILibrary.AssortedMethods; public class Quicksort { public static void swap(int[] array, int i, int j) { int tmp = array[i]; array[i] = array[j]; array[j] = tmp; } public static int partition(int[] arr, int left, int right) { int pivot = arr[left + (right - left) / 2]; // Pick a pivot point. Can be an element while (left <= right) { // Until we've gone through the whole array // Find element on left that should be on right while (arr[left] < pivot) { left++; } // Find element on right that should be on left while (arr[right] > pivot) { right--; } // Swap elements, and move left and right indices if (left <= right) { swap(arr, left, right); left++; right--; } } return left; } public static void quickSort(int[] arr, int left, int right) { int index = partition(arr, left, right); if (left < index - 1) { // Sort left half quickSort(arr, left, index - 1); } if (index < right) { // Sort right half quickSort(arr, index, right); } } public static void main(String[] args) { int[] arr = AssortedMethods.randomArray(20, 0, 6); AssortedMethods.printIntArray(arr); quickSort(arr, 0, arr.length - 1); AssortedMethods.printIntArray(arr); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_01_Sorted_Merge/Question.java ================================================ package Q10_01_Sorted_Merge; import CtCILibrary.AssortedMethods; public class Question { /** Merges array * @param a first array * @param b second array * @param countA number of "real" elements in a * @param countB number of "real" elements in b */ public static void merge(int[] a, int[] b, int countA, int countB) { int indexMerged = countB + countA - 1; /* Index of last location of merged array */ int indexA = countA - 1; /* Index of last element in array b */ int indexB = countB - 1; /* Index of last element in array a */ /* Merge a and b, starting from the last element in each */ while (indexB >= 0) { if (indexA >= 0 && a[indexA] > b[indexB]) { /* end of A is bigger than end of B */ a[indexMerged] = a[indexA]; // copy element indexA--; } else { a[indexMerged] = b[indexB]; // copy element indexB--; } indexMerged--; // move indices } } public static void main(String[] args) { int[] a = {2, 3, 4, 5, 6, 8, 10, 100, 0, 0, 0, 0, 0, 0}; int[] b = {1, 4, 7, 6, 7, 7}; merge(a, b, 8, 6); System.out.println(AssortedMethods.arrayToString(a)); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_02_Group_Anagrams/AnagramComparator.java ================================================ package Q10_02_Group_Anagrams; import java.util.Arrays; import java.util.Comparator; public class AnagramComparator implements Comparator { private String sortChars(String s) { char[] content = s.toCharArray(); Arrays.sort(content); return new String(content); } public int compare(String s1, String s2) { return sortChars(s1).compareTo(sortChars(s2)); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_02_Group_Anagrams/Question.java ================================================ package Q10_02_Group_Anagrams; import java.util.Arrays; import CtCILibrary.AssortedMethods; public class Question { public static void main(String[] args) { String[] array = {"apple", "banana", "carrot", "ele", "duck", "papel", "tarroc", "cudk", "eel", "lee"}; System.out.println(AssortedMethods.stringArrayToString(array)); Arrays.sort(array, new AnagramComparator()); System.out.println(AssortedMethods.stringArrayToString(array)); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_02_Group_Anagrams/QuestionB.java ================================================ package Q10_02_Group_Anagrams; import java.util.ArrayList; import java.util.Arrays; import CtCILibrary.AssortedMethods; import CtCILibrary.HashMapList; public class QuestionB { public static void sort(String[] array) { HashMapList mapList = new HashMapList(); /* Group words by anagram */ for (String s : array) { String key = sortChars(s); mapList.put(key, s); } /* Convert hash table to array */ int index = 0; for (String key : mapList.keySet()) { ArrayList list = mapList.get(key); for (String t : list) { array[index] = t; index++; } } } public static String sortChars(String s) { char[] content = s.toCharArray(); Arrays.sort(content); return new String(content); } public static void main(String[] args) { String[] array = {"apple", "banana", "carrot", "ele", "duck", "papel", "tarroc", "cudk", "eel", "lee"}; sort(array); System.out.println(AssortedMethods.stringArrayToString(array)); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_03_Search_in_Rotated_Array/Question.java ================================================ package Q10_03_Search_in_Rotated_Array; public class Question { public static int search(int a[], int x) { return search(a, 0, a.length - 1, x); } public static int search(int a[], int left, int right, int x) { int mid = (left + right) / 2; if (x == a[mid]) { // Found element return mid; } if (right < left) { return -1; } /* While there may be an inflection point due to the rotation, either the left or * right half must be normally ordered. We can look at the normally ordered half * to make a determination as to which half we should search. */ if (a[left] < a[mid]) { // Left is normally ordered. if (x >= a[left] && x < a[mid]) { return search(a, left, mid - 1, x); } else { return search(a, mid + 1, right, x); } } else if (a[mid] < a[right]) { // Right is normally ordered. if (x > a[mid] && x <= a[right]) { return search(a, mid + 1, right, x); } else { return search(a, left, mid - 1, x); } } else if (a[left] == a[mid]) { // Left is either all repeats OR loops around (with the right half being all dups) if (a[mid] != a[right]) { // If right half is different, search there return search(a, mid + 1, right, x); } else { // Else, we have to search both halves int result = search(a, left, mid - 1, x); if (result == -1) { return search(a, mid + 1, right, x); } else { return result; } } } return -1; } public static void main(String[] args) { int[] a = { 2, 3, 1, 2, 2, 2, 2, 2 , 2 , 2 }; System.out.println(search(a, 2)); System.out.println(search(a, 3)); System.out.println(search(a, 4)); System.out.println(search(a, 1)); System.out.println(search(a, 8)); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_04_Sorted_Search_No_Size/Arrayish/Listy.java ================================================ package Q10_04_Sorted_Search_No_Size.Arrayish; public class Listy { int[] array; public Listy(int[] arr) { array = arr.clone(); } public int elementAt(int index) { if (index >= array.length) { return -1; } return array[index]; } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_04_Sorted_Search_No_Size/Arrayish/Question.java ================================================ package Q10_04_Sorted_Search_No_Size.Arrayish; public class Question { public static int binarySearch(Listy list, int value, int low, int high) { int mid; while (low <= high) { mid = (low + high) / 2; int middle = list.elementAt(mid); if (middle > value || middle == -1) { high = mid - 1; } else if (middle < value) { low = mid + 1; } else { return mid; } } return -1; } public static int search(Listy list, int value) { int index = 1; while (list.elementAt(index) != -1 && list.elementAt(index) < value) { index *= 2; } return binarySearch(list, value, index / 2, index); } public static void main(String[] args) { int[] array = {1, 2, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 16, 18}; Listy list = new Listy(array); for (int a : array) { System.out.println(search(list, a)); } System.out.println(search(list, 15)); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_05_Sparse_Search/QuestionA.java ================================================ package Q10_05_Sparse_Search; public class QuestionA { public static int search(String[] strings, String str, int first, int last) { if (first > last) { return -1; } /* Move mid to the middle */ int mid = (last + first) / 2; /* If mid is empty, find closest non-empty string. */ if (strings[mid].isEmpty()) { int left = mid - 1; int right = mid + 1; while (true) { if (left < first && right > last) { return -1; } else if (right <= last && !strings[right].isEmpty()) { mid = right; break; } else if (left >= first && !strings[left].isEmpty()) { mid = left; break; } right++; left--; } } /* Check for string, and recurse if necessary */ if (str.equals(strings[mid])) { // Found it! return mid; } else if (strings[mid].compareTo(str) < 0) { // Search right return search(strings, str, mid + 1, last); } else { // Search left return search(strings, str, first, mid - 1); } } public static int search(String[] strings, String str) { if (strings == null || str == null || str.isEmpty()) { return -1; } return search(strings, str, 0, strings.length - 1); } public static void main(String[] args) { String[] stringList = {"apple", "", "", "banana", "", "", "", "carrot", "duck", "", "", "eel", "", "flower"}; System.out.println(search(stringList, "ac")); //for (String s : stringList) { // String cloned = new String(s); // System.out.println("<" + cloned + "> " + " appears at location " + search(stringList, cloned)); //} } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_05_Sparse_Search/QuestionB.java ================================================ package Q10_05_Sparse_Search; public class QuestionB { public static int searchI(String[] strings, String str, int first, int last) { while (first <= last) { /* Move mid to the middle */ int mid = (last + first) / 2; /* If mid is empty, find closest non-empty string */ if (strings[mid].isEmpty()) { int left = mid - 1; int right = mid + 1; while (true) { if (left < first && right > last) { return -1; } else if (right <= last && !strings[right].isEmpty()) { mid = right; break; } else if (left >= first && !strings[left].isEmpty()) { mid = left; break; } right++; left--; } } int res = strings[mid].compareTo(str); if (res == 0) { // Found it! return mid; } else if (res < 0) { // Search right first = mid + 1; } else { // Search left last = mid - 1; } } return -1; } public static int searchR(String[] strings, String str, int first, int last) { if (first > last) { return -1; } /* Move mid to the middle */ int mid = (last + first) / 2; /* If mid is empty, find closest non-empty string. */ if (strings[mid].isEmpty()) { int left = mid - 1; int right = mid + 1; while (true) { if (left < first && right > last) { return -1; } else if (right <= last && !strings[right].isEmpty()) { mid = right; break; } else if (left >= first && !strings[left].isEmpty()) { mid = left; break; } right++; left--; } } /* Check for string, and recurse if necessary */ if (str.equals(strings[mid])) { // Found it! return mid; } else if (strings[mid].compareTo(str) < 0) { // Search right return searchR(strings, str, mid + 1, last); } else { // Search left return searchR(strings, str, first, mid - 1); } } public static int search(String[] strings, String str) { if (strings == null || str == null || str.isEmpty()) { return -1; } return searchR(strings, str, 0, strings.length - 1); } public static void main(String[] args) { String[] stringList = {"apple", "", "", "banana", "", "", "", "carrot", "duck", "", "", "eel", "", "flower"}; System.out.println(search(stringList, "ac")); //for (String s : stringList) { // String cloned = new String(s); // System.out.println("<" + cloned + "> " + " appears at location " + search(stringList, cloned)); //} } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_07_Missing_Int/QuestionA.java ================================================ package Q10_07_Missing_Int; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Scanner; public class QuestionA { public static long numberOfInts = ((long) Integer.MAX_VALUE) + 1; public static byte[] bitfield = new byte [(int) (numberOfInts / 8)]; public static void findOpenNumber() throws FileNotFoundException { Scanner in = new Scanner(new FileReader("Ch 10. Sorting and Searching/Q10_07_Missing_Int/input.txt")); while (in.hasNextInt()) { int n = in.nextInt (); /* Finds the corresponding number in the bitfield by using * the OR operator to set the nth bit of a byte * (e.g., 10 would correspond to bit 2 of index 1 in * the byte array). */ bitfield [n / 8] |= 1 << (n % 8); } for (int i = 0; i < bitfield.length; i++) { for (int j = 0; j < 8; j++) { /* Retrieves the individual bits of each byte. When 0 bit * is found, finds the corresponding value. */ if ((bitfield[i] & (1 << j)) == 0) { System.out.println (i * 8 + j); return; } } } } public static void main(String[] args) throws IOException { findOpenNumber(); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_07_Missing_Int/QuestionB.java ================================================ package Q10_07_Missing_Int; import java.io.*; import java.util.*; public class QuestionB { public static int findOpenNumber(String filename) throws FileNotFoundException { int rangeSize = (1 << 20); // 2^20 bits (2^17 bytes) /* Get count of number of values within each block. */ int[] blocks = getCountPerBlock(filename, rangeSize); /* Find a block with a missing value. */ int blockIndex = findBlockWithMissing(blocks, rangeSize); if (blockIndex < 0) return -1; /* Create bit vector for items within this range. */ byte[] bitVector = getBitVectorForRange(filename, blockIndex, rangeSize); /* Find a zero in the bit vector */ int offset = findZero(bitVector); if (offset < 0) return -1; /* Compute missing value. */ return blockIndex * rangeSize + offset; } /* Get count of items within each range. */ public static int[] getCountPerBlock(String filename, int rangeSize) throws FileNotFoundException { int arraySize = Integer.MAX_VALUE / rangeSize + 1; int[] blocks = new int[arraySize]; Scanner in = new Scanner (new FileReader(filename)); while (in.hasNextInt()) { int value = in.nextInt(); blocks[value / rangeSize]++; } in.close(); return blocks; } /* Find a block whose count is low. */ public static int findBlockWithMissing(int[] blocks, int rangeSize) { for (int i = 0; i < blocks.length; i++) { if (blocks[i] < rangeSize){ return i; } } return -1; } /* Create a bit vector for the values within a specific range. */ public static byte[] getBitVectorForRange(String filename, int blockIndex, int rangeSize) throws FileNotFoundException { int startRange = blockIndex * rangeSize; int endRange = startRange + rangeSize; byte[] bitVector = new byte[rangeSize/Byte.SIZE]; Scanner in = new Scanner(new FileReader(filename)); while (in.hasNextInt()) { int value = in.nextInt(); /* If the number is inside the block that's missing * numbers, we record it */ if (startRange <= value && value < endRange) { int offset = value - startRange; int mask = (1 << (offset % Byte.SIZE)); bitVector[offset / Byte.SIZE] |= mask; } } in.close(); return bitVector; } /* Find bit index that is 0 within byte. */ public static int findZero(byte b) { for (int i = 0; i < Byte.SIZE; i++) { int mask = 1 << i; if ((b & mask) == 0) { return i; } } return -1; } /* Find a zero within the bit vector and return the index. */ public static int findZero(byte[] bitVector) { for (int i = 0; i < bitVector.length; i++) { if (bitVector[i] != ~0) { // If not all 1s int bitIndex = findZero(bitVector[i]); return i * Byte.SIZE + bitIndex; } } return -1; } public static void generateFile(String filename, int max, int missing) throws FileNotFoundException { PrintWriter writer = new PrintWriter(filename); for (int i = 0; i < max && i >= 0; i++) { if (i != missing) { writer.println(i); } if (i % 10000 == 0) { System.out.println("Now at location: " + i); } } writer.flush(); writer.close(); } public static void main(String[] args) throws FileNotFoundException { String filename = "Ch 10. Scalability and Memory Limits/Q10_04_Missing_Int/input.txt"; int max = 10000000; int missing = 1234325; System.out.println("Generating file..."); generateFile(filename, max, missing); System.out.println("Generated file from 0 to " + max + " with " + missing + " missing."); System.out.println("Searching for missing number..."); System.out.println("Missing value: " + findOpenNumber(filename)); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_07_Missing_Int/input.txt ================================================ [File too large to display: 75.2 MB] ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_08_Find_Duplicates/BitSet.java ================================================ package Q10_08_Find_Duplicates; class BitSet { int[] bitset; public BitSet(int size) { bitset = new int[(size >> 5) + 1]; // divide by 32 } boolean get(int pos) { int wordNumber = (pos >> 5); // divide by 32 int bitNumber = (pos & 0x1F); // mod 32 return (bitset[wordNumber] & (1 << bitNumber)) != 0; } void set(int pos) { int wordNumber = (pos >> 5); // divide by 32 int bitNumber = (pos & 0x1F); // mod 32 bitset[wordNumber] |= 1 << bitNumber; } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_08_Find_Duplicates/Question.java ================================================ package Q10_08_Find_Duplicates; import CtCILibrary.AssortedMethods; public class Question { public static void checkDuplicates(int[] array) { BitSet bs = new BitSet(32000); for (int i = 0; i < array.length; i++) { int num = array[i]; int num0 = num - 1; // bitset starts at 0, numbers start at 1 if (bs.get(num0)) { System.out.println(num); } else { bs.set(num0); } } } public static void main(String[] args) { int[] array = AssortedMethods.randomArray(30, 1, 30); System.out.println(AssortedMethods.arrayToString(array)); checkDuplicates(array); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search/Coordinate.java ================================================ package Q10_09_Sorted_Matrix_Search; public class Coordinate implements Cloneable { public int row; public int column; public Coordinate(int r, int c) { row = r; column = c; } public boolean inbounds(int[][] matrix) { return row >= 0 && column >= 0 && row < matrix.length && column < matrix[0].length; } public boolean isBefore(Coordinate p) { return row <= p.row && column <= p.column; } public Object clone() { return new Coordinate(row, column); } public void moveDownRight() { row++; column++; } public void setToAverage(Coordinate min, Coordinate max) { row = (min.row + max.row) / 2; column = (min.column + max.column) / 2; } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search/QuestionA.java ================================================ package Q10_09_Sorted_Matrix_Search; import CtCILibrary.*; public class QuestionA { public static boolean findElement(int[][] matrix, int elem) { int row = 0; int col = matrix[0].length - 1; while (row < matrix.length && col >= 0) { if (matrix[row][col] == elem) { return true; } else if (matrix[row][col] > elem) { col--; } else { row++; } } return false; } public static void main(String[] args) { int M = 10; int N = 5; int[][] matrix = new int[M][N]; for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { matrix[i][j] = 10 * i + j; } } AssortedMethods.printMatrix(matrix); for (int i = 0; i < M; i++) { for (int j = 0; j < M; j++) { int v = 10 * i + j; System.out.println(v + ": " + findElement(matrix, v)); } } } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search/QuestionB.java ================================================ package Q10_09_Sorted_Matrix_Search; import CtCILibrary.*; public class QuestionB { public static Coordinate partitionAndSearch(int[][] matrix, Coordinate origin, Coordinate dest, Coordinate pivot, int x) { Coordinate lowerLeftOrigin = new Coordinate(pivot.row, origin.column); Coordinate lowerLeftDest = new Coordinate(dest.row, pivot.column - 1); Coordinate upperRightOrigin = new Coordinate(origin.row, pivot.column); Coordinate upperRightDest = new Coordinate(pivot.row - 1, dest.column); Coordinate lowerLeft = findElement(matrix, lowerLeftOrigin, lowerLeftDest, x); if (lowerLeft == null) { return findElement(matrix, upperRightOrigin, upperRightDest, x); } return lowerLeft; } public static Coordinate findElement(int[][] matrix, Coordinate origin, Coordinate dest, int x) { if (!origin.inbounds(matrix) || !dest.inbounds(matrix)) { return null; } if (matrix[origin.row][origin.column] == x) { return origin; } else if (!origin.isBefore(dest)) { return null; } /* Set start to start of diagonal and end to the end of the diagonal. Since * the grid may not be square, the end of the diagonal may not equal dest. */ Coordinate start = (Coordinate) origin.clone(); int diagDist = Math.min(dest.row - origin.row, dest.column - origin.column); Coordinate end = new Coordinate(start.row + diagDist, start.column + diagDist); Coordinate p = new Coordinate(0, 0); /* Do binary search on the diagonal, looking for the first element greater than x */ while (start.isBefore(end)) { p.setToAverage(start, end); if (x > matrix[p.row][p.column]) { start.row = p.row + 1; start.column = p.column + 1; } else { end.row = p.row - 1; end.column = p.column - 1; } } /* Split the grid into quadrants. Search the bottom left and the top right. */ return partitionAndSearch(matrix, origin, dest, start, x); } public static Coordinate findElement(int[][] matrix, int x) { Coordinate origin = new Coordinate(0, 0); Coordinate dest = new Coordinate(matrix.length - 1, matrix[0].length - 1); return findElement(matrix, origin, dest, x); } public static void main(String[] args) { int[][] matrix = {{15, 30, 50, 70, 73}, {35, 40, 100, 102, 120}, {36, 42, 105, 110, 125}, {46, 51, 106, 111, 130}, {48, 55, 109, 140, 150}}; AssortedMethods.printMatrix(matrix); int m = matrix.length; int n = matrix[0].length; int count = 0; int littleOverTheMax = matrix[m - 1][n - 1] + 10; for (int i = 0; i < littleOverTheMax; i++) { Coordinate c = findElement(matrix, i); if (c != null) { System.out.println(i + ": (" + c.row + ", " + c.column + ")"); count++; } } System.out.println("Found " + count + " unique elements."); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_10_Rank_from_Stream/IntComparable.java ================================================ package Q10_10_Rank_from_Stream; import java.util.Comparator; public class IntComparable implements Comparator{ @Override public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_10_Rank_from_Stream/Question.java ================================================ package Q10_10_Rank_from_Stream; import CtCILibrary.AssortedMethods; public class Question { private static RankNode root = null; public static void track(int number) { if (root == null) { root = new RankNode(number); } else { root.insert(number); } } public static int getRankOfNumber(int number) { return root.getRank(number); } public static void main(String[] args) { int size = 100; int[] list = AssortedMethods.randomArray(size, -100, 100); for (int i = 0; i < list.length; i++) { track(list[i]); } int[] tracker = new int[size]; for (int i = 0; i < list.length; i++) { int v = list[i]; int rank1 = root.getRank(list[i]); tracker[rank1] = v; } for (int i = 0; i < tracker.length - 1; i++) { if (tracker[i] != 0 && tracker[i + 1] != 0) { if (tracker[i] > tracker[i + 1]) { System.out.println("ERROR at " + i); } } } System.out.println("Array: " + AssortedMethods.arrayToString(list)); System.out.println("Ranks: " + AssortedMethods.arrayToString(tracker)); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_10_Rank_from_Stream/RankNode.java ================================================ package Q10_10_Rank_from_Stream; public class RankNode { public int left_size = 0; public RankNode left; public RankNode right; public int data = 0; public RankNode(int d) { data = d; } public void insert(int d) { if (d <= data) { if (left != null) { left.insert(d); } else { left = new RankNode(d); } left_size++; } else { if (right != null) { right.insert(d); } else { right = new RankNode(d); } } } public int getRank(int d) { if (d == data) { return left_size; } else if (d < data) { if (left == null) { return -1; } else { return left.getRank(d); } } else { int right_rank = right == null ? -1 : right.getRank(d); if (right_rank == -1) { return -1; } else { return left_size + 1 + right_rank; } } } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_11_Peaks_and_Valleys/QuestionA.java ================================================ package Q10_11_Peaks_and_Valleys; import java.util.Arrays; import CtCILibrary.AssortedMethods; public class QuestionA { public static void sortValleyPeak(int[] array) { Arrays.sort(array); for (int i = 1; i < array.length; i += 2) { swap(array, i - 1, i); } } public static void swap(int[] array, int left, int right) { int temp = array[left]; array[left] = array[right]; array[right] = temp; } public static void main(String[] args) { int[] array = {48, 40, 31, 62, 28, 21, 64, 40, 23, 17}; System.out.println(AssortedMethods.arrayToString(array)); sortValleyPeak(array); System.out.println(AssortedMethods.arrayToString(array)); System.out.println(Tester.confirmValleyPeak(array)); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_11_Peaks_and_Valleys/QuestionB.java ================================================ package Q10_11_Peaks_and_Valleys; import CtCILibrary.AssortedMethods; public class QuestionB { public static void swap(int[] array, int left, int right) { int temp = array[left]; array[left] = array[right]; array[right] = temp; } public static void sortValleyPeak(int[] array) { for (int i = 1; i < array.length; i += 2) { int biggestIndex = maxIndex(array, i - 1, i, i + 1); if (i != biggestIndex) { swap(array, i, biggestIndex); } } } public static int maxIndex(int[] array, int a, int b, int c) { int len = array.length; int aValue = a >= 0 && a < len ? array[a] : Integer.MIN_VALUE; int bValue = b >= 0 && b < len ? array[b] : Integer.MIN_VALUE; int cValue = c >= 0 && c < len ? array[c] : Integer.MIN_VALUE; int max = Math.max(aValue, Math.max(bValue, cValue)); if (aValue == max) { return a; } else if (bValue == max) { return b; } else { return c; } } public static void main(String[] args) { int[] array = {48, 40, 31, 62, 28, 21, 64, 40, 23, 17}; System.out.println(AssortedMethods.arrayToString(array)); sortValleyPeak(array); System.out.println(AssortedMethods.arrayToString(array)); System.out.println(Tester.confirmValleyPeak(array)); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_11_Peaks_and_Valleys/QuestionC.java ================================================ package Q10_11_Peaks_and_Valleys; import CtCILibrary.AssortedMethods; public class QuestionC { public static void swap(int[] array, int left, int right) { int temp = array[left]; array[left] = array[right]; array[right] = temp; } public static void sortValleyPeak(int[] array) { for (int i = 1; i < array.length; i += 2) { if (array[i - 1] < array[i]) { swap(array, i - 1, i); } if (i + 1 < array.length && array[i + 1] < array[i]) { swap(array, i + 1, i); } } } public static void main(String[] args) { int[] array = {5, 3, 1, 2, 3}; System.out.println(AssortedMethods.arrayToString(array)); sortValleyPeak(array); System.out.println(AssortedMethods.arrayToString(array)); System.out.println(Tester.confirmValleyPeak(array)); } } ================================================ FILE: Java/Ch 10. Sorting and Searching/Q10_11_Peaks_and_Valleys/Tester.java ================================================ package Q10_11_Peaks_and_Valleys; import CtCILibrary.AssortedMethods; public class Tester { public static boolean confirmValleyPeak(int[] array) { for (int i = 1; i < array.length - 1; i++) { int prev = array[i - 1]; int curr = array[i]; int next = array[i + 1]; if (prev <= curr && curr >= next) { continue; } else if (prev >= curr && curr <= next) { continue; } else { return false; } } return true; } public static void main(String[] args) { for (int i = 0; i < 100; i++) { int[] originalArray = AssortedMethods.randomArray(10, 0, 100); int[] arrayA = originalArray.clone(); int[] arrayB = originalArray.clone(); int[] arrayC = originalArray.clone(); //System.out.println(AssortedMethods.arrayToString(array)); QuestionA.sortValleyPeak(arrayA); QuestionB.sortValleyPeak(arrayB); QuestionC.sortValleyPeak(arrayC); if (!confirmValleyPeak(arrayA) || !confirmValleyPeak(arrayB) || !confirmValleyPeak(arrayC)) { System.out.println(AssortedMethods.arrayToString(originalArray)); System.out.println(AssortedMethods.arrayToString(arrayA)); System.out.println(AssortedMethods.arrayToString(arrayB)); System.out.println(AssortedMethods.arrayToString(arrayC)); System.out.println(confirmValleyPeak(arrayA)); System.out.println(confirmValleyPeak(arrayB)); System.out.println(confirmValleyPeak(arrayC)); break; } } } } ================================================ FILE: Java/Ch 13. Java/Introduction/Ambiguous.java ================================================ package Introduction; public class Ambiguous extends Shape { private double area = 10; public double computeArea() { return area; } } ================================================ FILE: Java/Ch 13. Java/Introduction/Circle.java ================================================ package Introduction; public class Circle extends Shape { private double rad = 5; public void printMe() { System.out.println("I am a circle."); } public double computeArea() { return rad * rad * 3.15; } } ================================================ FILE: Java/Ch 13. Java/Introduction/Introduction.java ================================================ package Introduction; public class Introduction { public static String lem() { System.out.println("lem"); return "return from lem"; } public static String foo() { int x = 0; int y = 5; try { System.out.println("start try"); int b = y / x; System.out.println("end try"); return "returned from try"; } catch (Exception ex) { System.out.println("catch"); return lem() + " | returned from catch"; } finally { System.out.println("finally"); } } public static void bar() { System.out.println("start bar"); String v = foo(); System.out.println(v); System.out.println("end bar"); } public static void main(String[] args) { bar(); } } ================================================ FILE: Java/Ch 13. Java/Introduction/IntroductionCollections.java ================================================ package Introduction; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.Vector; public class IntroductionCollections { public static void main(String[] args) { // ArrayList ArrayList myArr = new ArrayList(); myArr.add("one"); myArr.add("two"); System.out.println(myArr.get(0)); // Vector Vector myVect = new Vector(); myVect.add("one"); myVect.add("two"); System.out.println(myVect.get(0)); // Linked List LinkedList myLinkedList = new LinkedList(); myLinkedList.add("two"); myLinkedList.addFirst("one"); Iterator iter = myLinkedList.iterator(); while (iter.hasNext()) { System.out.println(iter.next()); } // Hash Map HashMap map = new HashMap(); map.put("one", "uno"); map.put("two", "dos"); System.out.println(map.get("one")); } } ================================================ FILE: Java/Ch 13. Java/Introduction/IntroductionOverriding.java ================================================ package Introduction; public class IntroductionOverriding { public static void printArea(Circle c) { System.out.println("The circle is " + c.computeArea()); } public static void printArea(Square s) { System.out.println("The square is " + s.computeArea()); } public static void printArea(Ambiguous s) { System.out.println("The ambiguous is undefined"); } public static void main(String[] args) { Shape[] shapes = new Shape[2]; Circle circle = new Circle(); Ambiguous ambiguous = new Ambiguous(); shapes[0] = circle; shapes[1] = ambiguous; for (Shape s : shapes) { s.printMe(); System.out.println(s.computeArea()); } } } ================================================ FILE: Java/Ch 13. Java/Introduction/Shape.java ================================================ package Introduction; public abstract class Shape { public void printMe() { System.out.println("I am a shape."); } public abstract double computeArea(); } ================================================ FILE: Java/Ch 13. Java/Introduction/Square.java ================================================ package Introduction; public class Square extends Shape { private double len = 5; public void printMe() { System.out.println("I am a square."); } public double computeArea() { return len * len; } } ================================================ FILE: Java/Ch 13. Java/Q13_01_Private_Constructor/Question.java ================================================ package Q13_01_Private_Constructor; public class Question { private Question() { System.out.println("Q"); } static class A { private A() { } } static class B extends A { public B() { } } public static void main(String[] args) { new B(); } } ================================================ FILE: Java/Ch 13. Java/Q13_05_TreeMap_HashMap_LinkedHashMap/Question.java ================================================ package Q13_05_TreeMap_HashMap_LinkedHashMap; import java.util.AbstractMap; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.TreeMap; public class Question { public static void insertAndPrint(AbstractMap map) { int[] array = {1, -1, 0}; for (int x : array) { map.put(x, Integer.toString(x)); } for (int k : map.keySet()) { System.out.print(k + ", "); } } public static void main(String[] args) { TreeMap treeMap = new TreeMap(); HashMap hashMap = new HashMap(); LinkedHashMap linkedHashMap = new LinkedHashMap(); System.out.println("\nHashMap - Arbitrary Order:"); insertAndPrint(hashMap); System.out.println("\nLinkedHashMap - Insertion Order:"); insertAndPrint(linkedHashMap); System.out.println("\nTreeMap - Natural Order:"); insertAndPrint(treeMap); } } ================================================ FILE: Java/Ch 13. Java/Q13_06_Object_Reflection/Question.java ================================================ package Q13_06_Object_Reflection; import java.lang.reflect.*; public class Question { public static void main(String args[]) { try { /* Parameters */ Object[] doubleArgs = new Object[] { 4.2, 3.9 }; /* Get class */ Class rectangleDefinition = Class.forName("Question14_5.Rectangle"); /* Equivalent: Rectangle rectangle = new Rectangle(4.2, 3.9); */ Class[] doubleArgsClass = new Class[] {double.class, double.class}; Constructor doubleArgsConstructor = rectangleDefinition.getConstructor(doubleArgsClass); Rectangle rectangle = (Rectangle) doubleArgsConstructor.newInstance(doubleArgs); /* Equivalent: Double area = rectangle.area(); */ Method m = rectangleDefinition.getDeclaredMethod("area"); Double area = (Double) m.invoke(rectangle); System.out.println(area); } catch (ClassNotFoundException e) { System.out.println(e); } catch (NoSuchMethodException e) { System.out.println(e); } catch (IllegalArgumentException e) { System.out.println(e); } catch (IllegalAccessException e) { System.out.println(e); } catch (InvocationTargetException e) { System.out.println(e); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ================================================ FILE: Java/Ch 13. Java/Q13_06_Object_Reflection/Rectangle.java ================================================ package Q13_06_Object_Reflection; public class Rectangle { private double width; private double height; public Rectangle(double w, double h) { width = w; height = h; } public double area() { return width * height; } } ================================================ FILE: Java/Ch 13. Java/Q13_07_Lambda_Expressions/Country.java ================================================ package Q13_07_Lambda_Expressions; public class Country { private String name; private int size; private String continent; public Country(String n, String c, int sz) { name = n; size = sz; continent = c; } public String getName() { return name; } public String getContinent() { return continent; } public int getPopulation() { return size; } } ================================================ FILE: Java/Ch 13. Java/Q13_07_Lambda_Expressions/QuestionA.java ================================================ package Q13_07_Lambda_Expressions; import java.util.ArrayList; import java.util.List; public class QuestionA { public static int getPopulation(List countries, String continent) { int sum = 0; for (Country c : countries) { if (c.getContinent().equals(continent)) { sum += c.getPopulation(); } } return sum; } public static void main(String... args) { ArrayList countries = new ArrayList(); countries.add(new Country("United States", "North America", 1)); countries.add(new Country("Canada", "North America", 5)); countries.add(new Country("India", "Asia", 9)); System.out.println(getPopulation(countries, "Asia")); } } ================================================ FILE: Java/Ch 13. Java/Q13_07_Lambda_Expressions/QuestionB.java ================================================ package Q13_07_Lambda_Expressions; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; public class QuestionB { public static int getPopulation(List countries, String continent) { Stream sublist = countries.stream().filter( country -> { return country.getContinent().equals(continent); }); Stream populations = sublist.map(c -> c.getPopulation()); int population = populations.reduce(0, (a, b) -> a + b); return population; } public static void main(String... args) { ArrayList countries = new ArrayList(); countries.add(new Country("United States", "North America", 5)); countries.add(new Country("Canada", "North America", 10)); countries.add(new Country("India", "Asia", 30)); System.out.println(getPopulation(countries, "North America")); } } ================================================ FILE: Java/Ch 13. Java/Q13_07_Lambda_Expressions/QuestionC.java ================================================ package Q13_07_Lambda_Expressions; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; public class QuestionC { public static int getPopulation(List countries, String continent) { Stream populations = countries.stream().map(c -> c.getContinent().equals(continent) ? c.getPopulation() : 0); return populations.reduce(0, (a, b) -> a + b); } public static void main(String... args) { ArrayList countries = new ArrayList(); countries.add(new Country("United States", "North America", 5)); countries.add(new Country("Canada", "North America", 10)); countries.add(new Country("India", "Asia", 30)); System.out.println(getPopulation(countries, "North America")); } } ================================================ FILE: Java/Ch 13. Java/Q13_07_Lambda_Expressions/Tester.java ================================================ package Q13_07_Lambda_Expressions; import java.util.ArrayList; public class Tester { public static void main(String[] args) { ArrayList countries = new ArrayList(); countries.add(new Country("United States", "North America", 5)); countries.add(new Country("Canada", "North America", 10)); countries.add(new Country("India", "Asia", 30)); String continent = "North America"; int popA = QuestionA.getPopulation(countries, continent); int popB = QuestionB.getPopulation(countries, continent); int popC = QuestionC.getPopulation(countries, continent); if (popA == popB && popB == popC) { System.out.println("Population: " + popA); } else { System.out.println("Mismatch: " + popA + ", " + popB + ", " + popC); } } } ================================================ FILE: Java/Ch 13. Java/Q13_08_Lambda_Random/QuestionA.java ================================================ package Q13_08_Lambda_Random; import java.util.ArrayList; import java.util.List; import java.util.Random; public class QuestionA { public static List getRandomSubset(List list) { List subset = new ArrayList(); Random random = new Random(); for (int item : list) { if (random.nextBoolean()) { subset.add(item); } } return subset; } public static void main(String... args) { List list = new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); List subset = getRandomSubset(list); System.out.println(subset.toString()); } } ================================================ FILE: Java/Ch 13. Java/Q13_08_Lambda_Random/QuestionB.java ================================================ package Q13_08_Lambda_Random; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.stream.Collectors; public class QuestionB { public static List getRandomSubset(List list) { Random random = new Random(); List subset = list.stream().filter( k -> { return random.nextBoolean(); /* Flip coin. */ }).collect(Collectors.toList()); return subset; } public static void main(String... args) { List list = new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); List subset = getRandomSubset(list); System.out.println(subset.toString()); } } ================================================ FILE: Java/Ch 13. Java/Q13_08_Lambda_Random/QuestionC.java ================================================ package Q13_08_Lambda_Random; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.function.Predicate; import java.util.stream.Collectors; public class QuestionC { public static Random random = new Random(); public static Predicate flipCoin = o -> { return random.nextBoolean(); }; public static List getRandomSubset(List list) { List subset = list.stream().filter(flipCoin). collect(Collectors.toList()); return subset; } public static void main(String... args) { List list = new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); List subset = getRandomSubset(list); System.out.println(subset.toString()); } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionA/ExampleA.java ================================================ package IntroductionA; public class ExampleA { public static void main(String[] args) { RunnableThreadExample instance = new RunnableThreadExample(); Thread thread = new Thread(instance); thread.start(); /* waits until earlier thread counts to 5 (slowly) */ while (instance.count != 5) { try { Thread.sleep(250); } catch (InterruptedException exc) { exc.printStackTrace(); } } System.out.println("Program Terminating."); } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionA/RunnableThreadExample.java ================================================ package IntroductionA; public class RunnableThreadExample implements Runnable { public int count = 0; public void run() { System.out.println("RunnableThread starting."); try { while (count < 5) { Thread.sleep(500); System.out.println("RunnableThread count: " + count); count++; } } catch (InterruptedException exc) { System.out.println("RunnableThread interrupted."); } System.out.println("RunnableThread terminating."); } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionB/ExampleB.java ================================================ package IntroductionB; public class ExampleB { public static void main(String args[]) { ThreadExample instance = new ThreadExample(); instance.start(); while (instance.count != 5) { try { Thread.sleep(250); } catch (InterruptedException exc) { exc.printStackTrace(); } } } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionB/ThreadExample.java ================================================ package IntroductionB; public class ThreadExample extends Thread { int count = 0; public void run() { System.out.println("Thread starting."); try { while (count < 5) { Thread.sleep(500); System.out.println("In Thread, count is " + count); count++; } } catch (InterruptedException exc) { System.out.println("Thread interrupted."); } System.out.println("Thread terminating."); } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionLocks/Intro.java ================================================ package IntroductionLocks; public class Intro { public static void main(String[] args) { NoLockATM noLockATM = new NoLockATM(); LockedATM lockedATM = new LockedATM(); MyClass thread1 = new MyClass(noLockATM, lockedATM); MyClass thread2 = new MyClass(noLockATM, lockedATM); thread1.start(); thread2.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } thread1.waitUntilDone(); thread2.waitUntilDone(); System.out.println("NoLock ATM: " + noLockATM.getBalance()); System.out.println("Locked ATM: " + lockedATM.getBalance()); int v = thread1.delta + thread2.delta + 100; System.out.println("Should Be: " + v); System.out.println("Program terminating."); } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionLocks/LockedATM.java ================================================ package IntroductionLocks; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockedATM { private Lock lock; private int balance = 100; public LockedATM() { lock = new ReentrantLock(); } public int withdraw(int value) { lock.lock(); int temp = balance; try { Thread.sleep(100); temp = temp - value; Thread.sleep(100); balance = temp; } catch (InterruptedException e) { } lock.unlock(); return temp; } public int deposit(int value) { lock.lock(); int temp = balance; try { Thread.sleep(100); temp = temp + value; Thread.sleep(100); balance = temp; } catch (InterruptedException e) { } lock.unlock(); return temp; } public int getBalance() { return balance; } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionLocks/MyClass.java ================================================ package IntroductionLocks; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import CtCILibrary.AssortedMethods; public class MyClass extends Thread { private NoLockATM noLockATM; private LockedATM lockedATM; public int delta = 0; private Lock completionLock; public MyClass(NoLockATM atm1, LockedATM atm2) { noLockATM = atm1; lockedATM = atm2; completionLock = new ReentrantLock(); } public void run() { completionLock.lock(); int[] operations = AssortedMethods.randomArray(20, -50, 50); for (int op : operations) { delta += op; if (op < 0) { int val = op * -1; noLockATM.withdraw(val); lockedATM.withdraw(val); } else { noLockATM.deposit(op); lockedATM.deposit(op); } } completionLock.unlock(); } public void waitUntilDone() { completionLock.lock(); completionLock.unlock(); } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionLocks/NoLockATM.java ================================================ package IntroductionLocks; public class NoLockATM { private int balance = 100; public NoLockATM() { } public int withdraw(int value) { int temp = balance; try { Thread.sleep(300); temp = temp - value; Thread.sleep(300); balance = temp; } catch (InterruptedException e) { } return temp; } public int deposit(int value) { int temp = balance; try { Thread.sleep(300); temp = temp + value; Thread.sleep(300); balance = temp; } catch (InterruptedException e) { } return temp; } public int getBalance() { return balance; } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionSynchronization/Intro.java ================================================ package IntroductionSynchronization; public class Intro { public static void main(String[] args) { try { MyObject obj1 = new MyObject(); MyObject obj2 = new MyObject(); MyClass thread1 = new MyClass(obj1, "1"); MyClass thread2 = new MyClass(obj2, "2"); thread1.start(); thread2.start(); Thread.sleep(3000 * 3); } catch (InterruptedException exc) { System.out.println("Program Interrupted."); } System.out.println("Program terminating."); } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionSynchronization/MyClass.java ================================================ package IntroductionSynchronization; public class MyClass extends Thread { private String name; private MyObject myObj; public MyClass(MyObject obj, String n) { name = n; myObj = obj; } public void run() { if (name.equals("1")) { MyObject.foo(name); } else if (name.equals("2")) { MyObject.bar(name); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionSynchronization/MyObject.java ================================================ package IntroductionSynchronization; public class MyObject { public static synchronized void foo(String name) { try { System.out.println("Thread " + name + ".foo(): starting"); Thread.sleep(3000); System.out.println("Thread " + name + ".foo(): ending"); } catch (InterruptedException exc) { System.out.println("Thread " + name + ": interrupted."); } } public static synchronized void bar(String name) { try { System.out.println("Thread " + name + ".bar(): starting"); Thread.sleep(3000); System.out.println("Thread " + name + ".bar(): ending"); } catch (InterruptedException exc) { System.out.println("Thread " + name + ": interrupted."); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionSynchronizedBlocks/Intro.java ================================================ package IntroductionSynchronizedBlocks; public class Intro { public static void main(String[] args) { try { MyObject obj1 = new MyObject(); MyObject obj2 = new MyObject(); MyClass thread1 = new MyClass(obj1, "1"); MyClass thread2 = new MyClass(obj1, "2"); thread1.start(); thread2.start(); Thread.sleep(3000 * 3); } catch (InterruptedException exc) { System.out.println("Program Interrupted."); } System.out.println("Program terminating."); } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionSynchronizedBlocks/MyClass.java ================================================ package IntroductionSynchronizedBlocks; public class MyClass extends Thread { private String name; private MyObject myObj; public MyClass(MyObject obj, String n) { name = n; myObj = obj; } public void run() { myObj.foo(name); } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionSynchronizedBlocks/MyObject.java ================================================ package IntroductionSynchronizedBlocks; public class MyObject { public void foo(String name) { synchronized(this) { try { System.out.println("Thread " + name + ".foo(): starting"); Thread.sleep(3000); System.out.println("Thread " + name + ".foo(): ending"); } catch (InterruptedException exc) { System.out.println("Thread " + name + ": interrupted."); } } } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionWaitNotify/Intro.java ================================================ package IntroductionWaitNotify; public class Intro { public static void main(String[] args) { try { MyObject obj1 = new MyObject(); MyObject obj2 = new MyObject(); MyClass thread1 = new MyClass(obj1, "1"); MyClass thread2 = new MyClass(obj1, "2"); thread1.start(); thread2.start(); Thread.sleep(3000 * 3); } catch (InterruptedException exc) { System.out.println("Program Interrupted."); } System.out.println("Program terminating."); } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionWaitNotify/MyClass.java ================================================ package IntroductionWaitNotify; public class MyClass extends Thread { private String name; private MyObject myObj; public MyClass(MyObject obj, String n) { name = n; myObj = obj; } public void run() { try { myObj.wait(1000); myObj.foo(name); myObj.notify(); } catch (InterruptedException e) { e.printStackTrace(); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/IntroductionWaitNotify/MyObject.java ================================================ package IntroductionWaitNotify; public class MyObject { public void foo(String name) { try { System.out.println("Thread " + name + ".foo(): starting"); Thread.sleep(3000); System.out.println("Thread " + name + ".foo(): ending"); } catch (InterruptedException exc) { System.out.println("Thread " + name + ": interrupted."); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_03_Dining_Philosophers/QuestionA/Chopstick.java ================================================ package Q15_03_Dining_Philosophers.QuestionA; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Chopstick { private Lock lock; public Chopstick() { lock = new ReentrantLock(); } public boolean pickUp() { return lock.tryLock(); } public void putDown() { lock.unlock(); } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_03_Dining_Philosophers/QuestionA/Philosopher.java ================================================ package Q15_03_Dining_Philosophers.QuestionA; import CtCILibrary.AssortedMethods; public class Philosopher extends Thread { private final int maxPause = 100; private int bites = 10; private Chopstick left; private Chopstick right; private int index; public Philosopher(int i, Chopstick left, Chopstick right) { index = i; this.left = left; this.right = right; } public void eat() { System.out.println("Philosopher " + index + ": start eating"); if (pickUp()) { chew(); putDown(); System.out.println("Philosopher " + index + ": done eating"); } else { System.out.println("Philosopher " + index + ": gave up on eating"); } } public boolean pickUp() { pause(); if (!left.pickUp()) { return false; } pause(); if (!right.pickUp()) { left.putDown(); return false; } pause(); return true; } public void chew() { System.out.println("Philosopher " + index + ": eating"); pause(); } public void pause() { try { int pause = AssortedMethods.randomIntInRange(0, maxPause); Thread.sleep(pause); } catch (InterruptedException e) { e.printStackTrace(); } } public void putDown() { right.putDown(); left.putDown(); } public void run() { for (int i = 0; i < bites; i++) { eat(); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_03_Dining_Philosophers/QuestionA/Question.java ================================================ package Q15_03_Dining_Philosophers.QuestionA; public class Question { public static int size = 3; public static int leftOf(int i) { return i; } public static int rightOf(int i) { return (i + 1) % size; } public static void main(String[] args) { Chopstick[] chopsticks = new Chopstick[size + 1]; for (int i = 0; i < size + 1; i++) { chopsticks[i] = new Chopstick(); } Philosopher[] philosophers = new Philosopher[size]; for (int i = 0; i < size; i++) { Chopstick left = chopsticks[leftOf(i)]; Chopstick right = chopsticks[rightOf(i)]; philosophers[i] = new Philosopher(i, left, right); } for (int i = 0; i < size; i++) { philosophers[i].start(); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_03_Dining_Philosophers/QuestionB/Chopstick.java ================================================ package Q15_03_Dining_Philosophers.QuestionB; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Chopstick { private Lock lock; private int number; public Chopstick(int n) { lock = new ReentrantLock(); this.number = n; } public void pickUp() { lock.lock(); } public void putDown() { lock.unlock(); } public int getNumber() { return number; } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_03_Dining_Philosophers/QuestionB/Philosopher.java ================================================ package Q15_03_Dining_Philosophers.QuestionB; import CtCILibrary.AssortedMethods; public class Philosopher extends Thread { private final int maxPause = 100; private int bites = 10; private Chopstick lower; private Chopstick higher; private int index; public Philosopher(int i, Chopstick left, Chopstick right) { index = i; if (left.getNumber() < right.getNumber()) { this.lower = left; this.higher = right; } else { this.lower = right; this.higher = left; } } public void eat() { System.out.println("Philosopher " + index + ": start eating"); pickUp(); chew(); putDown(); System.out.println("Philosopher " + index + ": done eating"); } public void pickUp() { pause(); lower.pickUp(); pause(); higher.pickUp(); pause(); } public void chew() { System.out.println("Philosopher " + index + ": eating"); pause(); } public void pause() { try { int pause = AssortedMethods.randomIntInRange(0, maxPause); Thread.sleep(pause); } catch (InterruptedException e) { e.printStackTrace(); } } public void putDown() { higher.putDown(); lower.putDown(); } public void run() { for (int i = 0; i < bites; i++) { eat(); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_03_Dining_Philosophers/QuestionB/Question.java ================================================ package Q15_03_Dining_Philosophers.QuestionB; public class Question { public static int size = 3; public static int leftOf(int i) { return i; } public static int rightOf(int i) { return (i + 1) % size; } public static void main(String[] args) { Chopstick[] chopsticks = new Chopstick[size + 1]; for (int i = 0; i < size + 1; i++) { chopsticks[i] = new Chopstick(i); } Philosopher[] philosophers = new Philosopher[size]; for (int i = 0; i < size; i++) { Chopstick left = chopsticks[leftOf(i)]; Chopstick right = chopsticks[rightOf(i)]; philosophers[i] = new Philosopher(i, left, right); } for (int i = 0; i < size; i++) { philosophers[i].start(); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_04_Deadlock_Free_Class/LockFactory.java ================================================ package Q15_04_Deadlock_Free_Class; import java.util.HashMap; import java.util.LinkedList; import java.util.concurrent.locks.Lock; public class LockFactory { private static LockFactory instance; private int numberOfLocks = 5; /* default */ private LockNode[] locks; /* Maps from a process or owner to the order that the owner claimed it would call the locks in */ private HashMap> lockOrder; private LockFactory(int count) { numberOfLocks = count; locks = new LockNode[numberOfLocks]; lockOrder = new HashMap>(); for (int i = 0; i < numberOfLocks; i++) { locks[i] = new LockNode(i, count); } } public static LockFactory getInstance() { return instance; } public static LockFactory initialize(int count) { if (instance == null) { instance = new LockFactory(count); } return instance; } public boolean hasCycle(HashMap touchedNodes, int[] resourcesInOrder) { /* check for a cycle */ for (int resource : resourcesInOrder) { if (touchedNodes.get(resource) == false) { LockNode n = locks[resource]; if (n.hasCycle(touchedNodes)) { return true; } } } return false; } /* To prevent deadlocks, force the processes to declare upfront what order they will * need the locks in. Verify that this order does not create a deadlock (a cycle in a directed graph) */ public boolean declare(int ownerId, int[] resourcesInOrder) { HashMap touchedNodes = new HashMap(); /* add nodes to graph */ int index = 1; touchedNodes.put(resourcesInOrder[0], false); for (index = 1; index < resourcesInOrder.length; index++) { LockNode prev = locks[resourcesInOrder[index - 1]]; LockNode curr = locks[resourcesInOrder[index]]; prev.joinTo(curr); touchedNodes.put(resourcesInOrder[index], false); } /* if we created a cycle, destroy this resource list and return false */ if (hasCycle(touchedNodes, resourcesInOrder)) { for (int j = 1; j < resourcesInOrder.length; j++) { LockNode p = locks[resourcesInOrder[j - 1]]; LockNode c = locks[resourcesInOrder[j]]; p.remove(c); } return false; } /* No cycles detected. Save the order that was declared, so that we can verify that the * process is really calling the locks in the order it said it would. */ LinkedList list = new LinkedList(); for (int i = 0; i < resourcesInOrder.length; i++) { LockNode resource = locks[resourcesInOrder[i]]; list.add(resource); } lockOrder.put(ownerId, list); return true; } /* Get the lock, verifying first that the process is really calling the locks in the order * it said it would. */ public Lock getLock(int ownerId, int resourceID) { LinkedList list = lockOrder.get(ownerId); if (list == null) { return null; } LockNode head = list.getFirst(); if (head.getId() == resourceID) { list.removeFirst(); return head.getLock(); } return null; } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_04_Deadlock_Free_Class/LockNode.java ================================================ package Q15_04_Deadlock_Free_Class; import java.util.ArrayList; import java.util.HashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockNode { public enum VisitState { FRESH, VISITING, VISITED }; private ArrayList children; private int lockId; private Lock lock; private int maxLocks; public LockNode(int id, int max) { lockId = id; children = new ArrayList(); maxLocks = max; } /* Join "this" to "node", checking to make sure that it doesn't create a cycle */ public void joinTo(LockNode node) { children.add(node); } public void remove(LockNode node) { children.remove(node); } /* Check for a cycle by doing a depth-first-search. */ public boolean hasCycle(HashMap touchedNodes) { VisitState[] visited = new VisitState[maxLocks]; for (int i = 0; i < maxLocks; i++) { visited[i] = VisitState.FRESH; } return hasCycle(visited, touchedNodes); } private boolean hasCycle(VisitState[] visited, HashMap touchedNodes) { if (touchedNodes.containsKey(lockId)) { touchedNodes.put(lockId, true); } if (visited[lockId] == VisitState.VISITING) { return true; } else if (visited[lockId] == VisitState.FRESH) { visited[lockId] = VisitState.VISITING; for (LockNode n : children) { if (n.hasCycle(visited, touchedNodes)) { return true; } } visited[lockId] = VisitState.VISITED; } return false; } public Lock getLock() { if (lock == null) { lock = new ReentrantLock(); } return lock; } public int getId() { return lockId; } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_04_Deadlock_Free_Class/Question.java ================================================ package Q15_04_Deadlock_Free_Class; public class Question { public static void main(String[] args) { int[] res1 = {1, 2, 3, 4}; int[] res2 = {1, 5, 4, 1}; int[] res3 = {1, 4, 5}; LockFactory.initialize(10); LockFactory lf = LockFactory.getInstance(); System.out.println(lf.declare(1, res1)); System.out.println(lf.declare(2, res2)); System.out.println(lf.declare(3, res3)); System.out.println(lf.getLock(1, 1)); System.out.println(lf.getLock(1, 2)); System.out.println(lf.getLock(2, 4)); } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_05_Call_In_Order/Foo.java ================================================ package Q15_05_Call_In_Order; import java.util.concurrent.Semaphore; public class Foo { public int pauseTime = 1000; public Semaphore sem1; public Semaphore sem2; public Foo() { try { sem1 = new Semaphore(1); sem2 = new Semaphore(1); sem1.acquire(); sem2.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } } public void first() { try { System.out.println("Started Executing 1"); Thread.sleep(pauseTime); System.out.println("Finished Executing 1"); sem1.release(); } catch (Exception ex) { ex.printStackTrace(); } } public void second() { try { sem1.acquire(); sem1.release(); System.out.println("Started Executing 2"); Thread.sleep(pauseTime); System.out.println("Finished Executing 2"); sem2.release(); } catch (Exception ex) { ex.printStackTrace(); } } public void third() { try { sem2.acquire(); sem2.release(); System.out.println("Started Executing 3"); Thread.sleep(pauseTime); System.out.println("Finished Executing 3"); } catch (Exception ex) { ex.printStackTrace(); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_05_Call_In_Order/FooBad.java ================================================ package Q15_05_Call_In_Order; import java.util.concurrent.locks.ReentrantLock; public class FooBad { public int pauseTime = 1000; public ReentrantLock lock1; public ReentrantLock lock2; public FooBad() { try { lock1 = new ReentrantLock(); lock2 = new ReentrantLock(); lock1.lock(); lock2.lock(); } catch (Exception ex) { ex.printStackTrace(); } } public void first() { try { System.out.println("Started Executing 1"); Thread.sleep(pauseTime); System.out.println("Finished Executing 1"); lock1.unlock(); } catch (Exception ex) { ex.printStackTrace(); } } public void second() { try { lock1.lock(); lock1.unlock(); System.out.println("Started Executing 2"); Thread.sleep(pauseTime); System.out.println("Finished Executing 2"); lock2.unlock(); } catch (Exception ex) { ex.printStackTrace(); } } public void third() { try { lock2.lock(); lock2.unlock(); System.out.println("Started Executing 3"); Thread.sleep(pauseTime); System.out.println("Finished Executing 3"); } catch (Exception ex) { ex.printStackTrace(); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_05_Call_In_Order/MyThread.java ================================================ package Q15_05_Call_In_Order; public class MyThread extends Thread { private String method; private FooBad foo; public MyThread(FooBad foo, String method) { this.method = method; this.foo = foo; } public void run() { if (method == "first") { foo.first(); } else if (method == "second") { foo.second(); } else if (method == "third") { foo.third(); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_05_Call_In_Order/Question.java ================================================ package Q15_05_Call_In_Order; public class Question { public static void main(String[] args) { FooBad foo = new FooBad(); MyThread thread1 = new MyThread(foo, "first"); MyThread thread2 = new MyThread(foo, "second"); MyThread thread3 = new MyThread(foo, "third"); thread3.start(); thread2.start(); thread1.start(); } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_06_Synchronized_Methods/Foo.java ================================================ package Q15_06_Synchronized_Methods; public class Foo { private String name; public Foo(String nm) { name = nm; } public String getName() { return name; } public void pause() { try { Thread.sleep(1000 * 3); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void methodA(String threadName) { System.out.println("thread " + threadName + " starting: " + name + ".methodA()"); pause(); System.out.println("thread " + threadName + " ending: " + name + ".methodA()"); } public void methodB(String threadName) { System.out.println("thread " + threadName + " starting: " + name + ".methodB()"); pause(); System.out.println("thread " + threadName + " ending: " + name + ".methodB()"); } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_06_Synchronized_Methods/MyThread.java ================================================ package Q15_06_Synchronized_Methods; public class MyThread extends Thread { private Foo foo; public String name; public String firstMethod; public MyThread(Foo f, String nm, String fM) { foo = f; name = nm; firstMethod = fM; } public void run() { if (firstMethod.equals("A")) { foo.methodA(name); } else { foo.methodB(name); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_06_Synchronized_Methods/Question.java ================================================ package Q15_06_Synchronized_Methods; public class Question { /** * @param args */ public static void main(String[] args) { /* Part 1 Demo -- same instance */ System.out.println("Part 1 Demo with same instance."); Foo fooA = new Foo("ObjectOne"); MyThread thread1a = new MyThread(fooA, "Dog", "A"); MyThread thread2a = new MyThread(fooA, "Cat", "A"); thread1a.start(); thread2a.start(); while (thread1a.isAlive() || thread2a.isAlive()) { }; System.out.println("\n\n"); /* Part 1 Demo -- difference instances */ System.out.println("Part 1 Demo with different instances."); Foo fooB1 = new Foo("ObjectOne"); Foo fooB2 = new Foo("ObjectTwo"); MyThread thread1b = new MyThread(fooB1, "Dog", "A"); MyThread thread2b = new MyThread(fooB2, "Cat", "A"); thread1b.start(); thread2b.start(); while (thread1b.isAlive() || thread2b.isAlive()) { }; System.out.println("\n\n"); /* Part 2 Demo */ System.out.println("Part 2 Demo."); Foo fooC = new Foo("ObjectOne"); MyThread thread1c = new MyThread(fooC, "Dog", "A"); MyThread thread2c = new MyThread(fooC, "Cat", "B"); thread1c.start(); thread2c.start(); } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_07_FizzBuzz/FBThread.java ================================================ package Q15_07_FizzBuzz; import java.util.function.Function; import java.util.function.Predicate; public class FBThread extends Thread { private static Object lock = new Object(); protected static int current = 1; private int max; private Predicate validate; private Function printer; int x = 1; public FBThread(Predicate validate, Function printer, int max) { this.validate = validate; this.printer = printer; this.max = max; } public void run() { while (true) { synchronized (lock) { if (current > max) { return; } if (validate.test(current)) { System.out.println(printer.apply(current)); current++; } } } } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_07_FizzBuzz/FizzBuzzThread.java ================================================ package Q15_07_FizzBuzz; public class FizzBuzzThread extends Thread { private static Object lock = new Object(); protected static int current = 1; private int max; private boolean div3, div5; private String toPrint; public FizzBuzzThread(boolean div3, boolean div5, int max, String toPrint) { this.div3 = div3; this.div5 = div5; this.max = max; this.toPrint = toPrint; } public void print() { System.out.println(toPrint); } public void run() { while (true) { synchronized (lock) { if (current > max) { return; } if ((current % 3 == 0) == div3 && (current % 5 == 0) == div5) { print(); current++; } } } } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_07_FizzBuzz/NumberThread.java ================================================ package Q15_07_FizzBuzz; public class NumberThread extends FizzBuzzThread { public NumberThread(boolean div3, boolean div5, int max) { super(div3, div5, max, null); } public void print() { System.out.println(current); } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_07_FizzBuzz/QuestionA.java ================================================ package Q15_07_FizzBuzz; public class QuestionA { public static void fizzbuzz(int n) { for (int i = 1; i <= n; i++) { if (i % 3 == 0 && i % 5 == 0) { System.out.println("FizzBuzz"); } else if (i % 3 == 0) { System.out.println("Fizz"); } else if (i % 5 == 0) { System.out.println("Buzz"); } else { System.out.println(i); } } } public static void main(String[] args) { fizzbuzz(100); } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_07_FizzBuzz/QuestionB.java ================================================ package Q15_07_FizzBuzz; public class QuestionB { public static void main(String[] args) { int n = 100; Thread[] threads = {new FizzBuzzThread(true, true, n, "FizzBuzz"), new FizzBuzzThread(true, false, n, "Fizz"), new FizzBuzzThread(false, true, n, "Buzz"), new NumberThread(false, false, n)}; for (Thread thread : threads) { thread.start(); } } } ================================================ FILE: Java/Ch 15. Threads and Locks/Q15_07_FizzBuzz/QuestionC.java ================================================ package Q15_07_FizzBuzz; public class QuestionC { public static void main(String[] args) { int n = 100; Thread[] threads = {new FBThread(i -> i % 3 == 0 && i % 5 == 0, i -> "FizzBuzz", n), new FBThread(i -> i % 3 == 0 && i % 5 != 0, i -> "Fizz", n), new FBThread(i -> i % 3 != 0 && i % 5 == 0, i -> "Buzz", n), new FBThread(i -> i % 3 != 0 && i % 5 != 0, i -> Integer.toString(i), n)}; for (Thread thread : threads) { thread.start(); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_01_Number_Swapper/Question.java ================================================ package Q16_01_Number_Swapper; public class Question { public static void swap(int a, int b) { // Example for a = 9, b = 4 a = a - b; // a = 9 - 4 = 5 b = a + b; // b = 5 + 4 = 9 a = b - a; // a = 9 - 5 System.out.println("a: " + a); System.out.println("b: " + b); } public static void swap_opt(int a, int b) { a = a^b; b = a^b; a = a^b; System.out.println("a: " + a); System.out.println("b: " + b); } public static void main(String[] args) { int a = 1672; int b = 9332; System.out.println("a: " + a); System.out.println("b: " + b); swap(a, b); swap_opt(a, b); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_02_Word_Frequencies/QuestionA.java ================================================ package Q16_02_Word_Frequencies; import CtCILibrary.AssortedMethods; public class QuestionA { public static int getFrequency(String[] book, String word) { word = word.trim().toLowerCase(); int count = 0; for (String w : book) { if (w.trim().toLowerCase().equals(word)) { count++; } } return count; } public static void main(String[] args) { String[] wordlist = AssortedMethods.getLongTextBlobAsStringList(); String[] words = {"the", "Lara", "and", "outcropping", "career", "it"}; for (String word : words) { System.out.println(word + ": " + getFrequency(wordlist, word)); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_02_Word_Frequencies/QuestionB.java ================================================ package Q16_02_Word_Frequencies; import java.util.*; import CtCILibrary.AssortedMethods; public class QuestionB { public static HashMap setupDictionary(String[] book) { HashMap table = new HashMap(); for (String word : book) { word = word.toLowerCase(); if (word.trim() != "") { if (!table.containsKey(word)) { table.put(word, 0); } table.put(word, table.get(word) + 1); } } return table; } public static int getFrequency(HashMap table, String word) { if (table == null || word == null) { return -1; } word = word.toLowerCase(); if (table.containsKey(word)) { return table.get(word); } return 0; } public static void main(String[] args) { String[] wordlist = AssortedMethods.getLongTextBlobAsStringList(); HashMap dictionary = setupDictionary(wordlist); String[] words = {"the", "Lara", "and", "outcropping", "career", "it"}; for (String word : words) { System.out.println(word + ": " + getFrequency(dictionary, word)); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_03_Intersection/Line.java ================================================ package Q16_03_Intersection; public class Line { public double slope, yintercept; public Point start, end; public Line(Point start, Point end) { this.start = start; this.end = end; if (start.x == end.x) { slope = Double.POSITIVE_INFINITY; yintercept = Double.POSITIVE_INFINITY; } else { slope = (end.y - start.y) / (end.x - start.x); yintercept = end.y - slope * end.x; } } public boolean isVertical() { return slope == Double.POSITIVE_INFINITY; } @Override public String toString() { return "Line [slope=" + slope + ", yintercept=" + yintercept + ", start=" + start + ", end=" + end + "]"; } public double getYFromX(double x) { if (isVertical()) { return Double.POSITIVE_INFINITY; } return slope * x + yintercept; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_03_Intersection/Point.java ================================================ package Q16_03_Intersection; public class Point { public double x, y; public Point(double x, double y) { this.x = x; this.y = y; } @Override public String toString() { return "Point [x=" + x + ", y=" + y + "]"; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_03_Intersection/Question.java ================================================ package Q16_03_Intersection; public class Question { /* Checks if middle is between start and end. */ public static boolean isBetween(double start, double middle, double end) { if (start > end) { return end <= middle && middle <= start; } else { return start <= middle && middle <= end; } } /* Checks if middle is between start and end. */ public static boolean isBetween(Point start, Point middle, Point end) { return isBetween(start.x, middle.x, end.x) && isBetween(start.y, middle.y, end.y); } public static Point intersection(Point start1, Point end1, Point start2, Point end2) { /* Compute lines (including slope and y-intercept). */ Line line1 = new Line(start1, end1); Line line2 = new Line(start2, end2); /* If the lines are parallel, then their extended lines must have same y-intercept. * If so, check that the start or end of one point is on the other line. */ if (line1.slope == line2.slope) { if (line1.yintercept != line2.yintercept) { return null; } /* Check if the start or end of one line is in the other. If so, return that point*/ if (isBetween(start1, start2, end1)) return start2; else if (isBetween(start1, end2, end1)) return end2; else if (isBetween(start2, start1, end2)) return start1; else if (isBetween(start2, end1, end2)) return end1; else return null; } /* Compute the intersection of the infinite lines, and then check if this falls within the * boundary of the line segments. Note that at most one line is vertical. */ /* Get intersection's x coordinate. If one is vertical, always use its x coordinate. * Otherwise, compute the intersection's x coordinate based on setting each line's y = mx + b equation * equal and solving for x. */ double x; if (line1.isVertical() || line2.isVertical()) { /* If a line is vertical, use its x coordinate. */ x = line1.isVertical() ? line1.start.x : line2.start.x; } else { /* Set y = mx + b equations equal and solve for x */ x = (line2.yintercept - line1.yintercept) / (line1.slope - line2.slope); } /* Get insection's y coordinate using a non-vertical line. Note that if line1 is vertical * then line 2 is not vertical (else it would have been caught earlier). */ double y = line1.isVertical() ? line2.getYFromX(x) : line1.getYFromX(x); /* We now have the intersection of the infinite lines. Check if it's within the boundaries * of each line segment. */ Point intersection = new Point(x, y); if (isBetween(start1, intersection, end1) && isBetween(start2, intersection, end2)) { return intersection; } return null; } public static void main(String[] args) { Point s1 = new Point(2147000000, 1); Point e1 = new Point(-2147000000, -1); Point s2 = new Point(-10, 0); Point e2 = new Point(0, 0); Point intersection = intersection(s1, e1, s2, e2); System.out.println("Line Segment 1: " + s1 + " to " + e1); System.out.println("Line Segment 2: " + s2 + " to " + e2); System.out.println("Intersection: " + (intersection == null ? "None" : intersection)); if (intersection != null) { System.out.println("Intersection is on segment1: " + Tester.checkIfPointOnLineSegments(s1, intersection, e1)); System.out.println("Intersection is on segment1: " + Tester.checkIfPointOnLineSegments(s2, intersection, e2)); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_03_Intersection/Tester.java ================================================ package Q16_03_Intersection; import java.util.ArrayList; public class Tester { public static boolean equalish(double a, double b) { return Math.abs(a - b) < .001; } public static boolean checkIfPointOnLineSegments(Point start, Point middle, Point end) { if (equalish(start.x, middle.x) && equalish(start.y, middle.y)) { return true; } if (equalish(middle.x, end.x) && equalish(middle.y, end.y)) { return true; } if (start.x == end.x) { // Vertical if (equalish(start.x, middle.x)) { return Question.isBetween(start, middle, end); } return false; } Line line = new Line(start, end); double x = middle.x; double y = line.slope * x + line.yintercept; if (equalish(y, middle.y)) { return true; } return false; } public static ArrayList getPoints(int size) { ArrayList points = new ArrayList(); for (int x1 = size * -1; x1 < size; x1+=3) { for (int y1 = size * -1 + 1; y1 < size - 1; y1+=3) { points.add(new Point(x1, y1)); } } return points; } public static boolean runTest(Point start1, Point end1, Point start2, Point end2) { Point intersection = Question.intersection(start1, end1, start2, end2); boolean validate1 = true; boolean validate2 = true; if (intersection == null) { System.out.println("No intersection."); } else { validate1 = checkIfPointOnLineSegments(start1, intersection, end1); validate2 = checkIfPointOnLineSegments(start2, intersection, end2); if (validate1 && validate2) { System.out.println("has intersection"); } if (!validate1 || !validate2) { System.out.println("ERROR -- " + validate1 + ", " + validate2); } } System.out.println(" Start1: " + start1.x + ", " + start1.y); System.out.println(" End1: " + end1.x + ", " + end1.y); System.out.println(" Start2: " + start2.x + ", " + start2.y); System.out.println(" End2: " + end2.x + ", " + end2.y); if (intersection != null) { System.out.println(" Intersection: " + intersection.x + ", " + intersection.y); } if (!validate1 || !validate2) { return false; } return true; } public static void main(String[] args) { ArrayList points = getPoints(10); for (Point start1 : points) { for (Point end1 : points) { for (Point start2 : points) { for (Point end2 : points) { boolean success = runTest(start1, end1, start2, end2); if (!success) { return; } } } } } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_04_Tic_Tac_Win/Piece.java ================================================ package Q16_04_Tic_Tac_Win; enum Piece { Empty, Red, Blue }; ================================================ FILE: Java/Ch 16. Moderate/Q16_04_Tic_Tac_Win/Position.java ================================================ package Q16_04_Tic_Tac_Win; public class Position { public int row, column; public Position(int row, int column) { this.row = row; this.column = column; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_04_Tic_Tac_Win/PositionIterator.java ================================================ package Q16_04_Tic_Tac_Win; import java.util.Iterator; public class PositionIterator implements Iterator { private int rowIncrement, colIncrement, size; private Position current; public PositionIterator(Position p, int rowIncrement, int colIncrement, int size) { this.rowIncrement = rowIncrement; this.colIncrement = colIncrement; this.size = size; current = new Position(p.row - rowIncrement, p.column - colIncrement); } @Override public boolean hasNext() { return current.row + rowIncrement < size && current.column + colIncrement < size; } @Override public Position next() { current = new Position(current.row + rowIncrement, current.column + colIncrement); return current; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_04_Tic_Tac_Win/QuestionA.java ================================================ package Q16_04_Tic_Tac_Win; public class QuestionA { public static int convertBoardToInt(Piece[][] board) { int sum = 0; for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[i].length; j++) { int value = board[i][j].ordinal(); sum = sum * 3 + value; } } return sum; } public static void main(String[] args) { Piece[][] board = { {Piece.Empty, Piece.Empty, Piece.Empty}, {Piece.Empty, Piece.Empty, Piece.Empty}, {Piece.Blue, Piece.Blue, Piece.Blue}}; int v = convertBoardToInt(board); System.out.println(v); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_04_Tic_Tac_Win/QuestionB.java ================================================ package Q16_04_Tic_Tac_Win; import CtCILibrary.AssortedMethods; public class QuestionB { public static Piece hasWon(Piece[][] board, int row, int column) { if (board.length != board[0].length) return Piece.Empty; Piece piece = board[row][column]; if (piece == Piece.Empty) return Piece.Empty; if (hasWonRow(board, row) || hasWonColumn(board, column)) { return piece; } if (row == column && hasWonDiagonal(board, 1)) { return piece; } if (row == (board.length - column - 1) && hasWonDiagonal(board, -1)) { return piece; } return Piece.Empty; } public static boolean hasWonRow(Piece[][] board, int row) { for (int c = 1; c < board[row].length; c++) { if (board[row][c] != board[row][0]) { return false; } } return true; } public static boolean hasWonColumn(Piece[][] board, int column) { for (int r = 1; r < board.length; r++) { if (board[r][column] != board[0][column]) { return false; } } return true; } public static boolean hasWonDiagonal(Piece[][] board, int direction) { int row = 0; int column = direction == 1 ? 0 : board.length - 1; Piece first = board[0][column]; for (int i = 0; i < board.length; i++) { if (board[row][column] != first) { return false; } row += 1; column += direction; } return true; } public static void main(String[] args) { int N = 3; int[][] board_t = AssortedMethods.randomMatrix(N, N, 0, 2); board_t[1][1] = board_t[0][2]; board_t[2][0] = board_t[0][2]; Piece[][] board = new Piece[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int x = board_t[i][j]; board[i][j] = Tester.convertIntToPiece(x); } } Piece p1 = hasWon(board, 0, 2); System.out.println(p1); AssortedMethods.printMatrix(board_t); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_04_Tic_Tac_Win/QuestionC.java ================================================ package Q16_04_Tic_Tac_Win; import CtCILibrary.AssortedMethods; public class QuestionC { public static boolean hasWinner(Piece p1, Piece p2, Piece p3) { if (p1 == Piece.Empty) { return false; } return p1 == p2 && p2 == p3; } public static Piece hasWon(Piece[][] board) { for (int i = 0; i < board.length; i++) { /* Check Rows */ if (hasWinner(board[i][0], board[i][1], board[i][2])) { return board[i][0]; } /* Check Columns */ if (hasWinner(board[0][i], board[1][i], board[2][i])) { return board[0][i]; } } /* Check Diagonal */ if (hasWinner(board[0][0], board[1][1], board[2][2])) { return board[0][0]; } if (hasWinner(board[0][2], board[1][1], board[2][0])) { return board[0][2]; } return Piece.Empty; } public static void main(String[] args) { int N = 3; int[][] board_t = AssortedMethods.randomMatrix(N, N, 0, 2); Piece[][] board = new Piece[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int x = board_t[i][j]; board[i][j] = Tester.convertIntToPiece(x); } } Piece p1 = hasWon(board); System.out.println(p1); AssortedMethods.printMatrix(board_t); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_04_Tic_Tac_Win/QuestionD.java ================================================ package Q16_04_Tic_Tac_Win; import CtCILibrary.AssortedMethods; public class QuestionD { public static boolean hasWinner(Piece p1, Piece p2, Piece p3) { if (p1 == Piece.Empty) { return false; } return p1 == p2 && p2 == p3; } public static Piece hasWon(Piece[][] board) { if (board[0][0] != Piece.Empty && (hasWinner(board[0][0], board[0][1], board[0][2]) || hasWinner(board[0][0], board[1][0], board[2][0]))) { return board[0][0]; } if (board[2][2] != Piece.Empty && (hasWinner(board[2][0], board[2][1], board[2][2]) || hasWinner(board[0][2], board[1][2], board[2][2]))) { return board[2][2]; } if (board[1][1] != Piece.Empty && (hasWinner(board[0][0], board[1][1], board[2][2]) || hasWinner(board[0][2], board[1][1], board[2][0]) || hasWinner(board[1][0], board[1][1], board[1][2]) || hasWinner(board[0][1], board[1][1], board[2][1]))) { return board[1][1]; } return Piece.Empty; } public static void main(String[] args) { int N = 3; int[][] board_t = AssortedMethods.randomMatrix(N, N, 0, 2); Piece[][] board = new Piece[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int x = board_t[i][j]; board[i][j] = Tester.convertIntToPiece(x); } } Piece p1 = hasWon(board); System.out.println(p1); AssortedMethods.printMatrix(board_t); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_04_Tic_Tac_Win/QuestionE.java ================================================ package Q16_04_Tic_Tac_Win; import CtCILibrary.AssortedMethods; public class QuestionE { public static Piece hasWon(Piece[][] board) { int size = board.length; if (board[0].length != size) return Piece.Empty; Piece first; /* Check rows. */ for (int i = 0; i < size; i++) { first = board[i][0]; if (first == Piece.Empty) continue; for (int j = 1; j < size; j++) { if (board[i][j] != first) { break; } else if (j == size - 1) { return first; } } } /* Check columns. */ for (int i = 0; i < size; i++) { first = board[0][i]; if (first == Piece.Empty) continue; for (int j = 1; j < size; j++) { if (board[j][i] != first) { break; } else if (j == size - 1) { return first; } } } /* Check diagonals. */ first = board[0][0]; if (first != Piece.Empty) { for (int i = 1; i < size; i++) { if (board[i][i] != first) { break; } else if (i == size - 1) { return first; } } } first = board[0][size - 1]; if (first != Piece.Empty) { for (int i = 1; i < size; i++) { if (board[i][size - i - 1] != first) { break; } else if (i == size - 1) { return first; } } } return Piece.Empty; } public static void main(String[] args) { int N = 3; int[][] board_t = AssortedMethods.randomMatrix(N, N, 0, 2); Piece[][] board = new Piece[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int x = board_t[i][j]; board[i][j] = Tester.convertIntToPiece(x); } } Piece p1 = hasWon(board); System.out.println(p1); AssortedMethods.printMatrix(board_t); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_04_Tic_Tac_Win/QuestionF.java ================================================ package Q16_04_Tic_Tac_Win; import CtCILibrary.AssortedMethods; public class QuestionF { public static Piece hasWon(Piece[][] board) { Piece winner = Piece.Empty; /* Check rows. */ for (int i = 0; i < board.length; i++) { winner = hasWon(board, i, 0, 0, 1); if (winner != Piece.Empty) { return winner; } } /* Check columns. */ for (int i = 0; i < board[0].length; i++) { winner = hasWon(board, 0, i, 1, 0); if (winner != Piece.Empty) { return winner; } } /* Check top/left -> bottom/right diagonal. */ winner = hasWon(board, 0, 0, 1, 1); if (winner != Piece.Empty) { return winner; } /* Check top/right -> bottom/left diagonal. */ return hasWon(board, 0, board[0].length - 1, 1, -1); } public static Piece hasWon(Piece[][] board, int row, int col, int incrementRow, int incrementCol) { Piece first = board[row][col]; while (row < board.length && col < board[row].length) { if (board[row][col] != first) { return Piece.Empty; } row += incrementRow; col += incrementCol; } return first; } public static void main(String[] args) { int N = 3; int[][] board_t = AssortedMethods.randomMatrix(N, N, 0, 2); Piece[][] board = new Piece[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int x = board_t[i][j]; board[i][j] = Tester.convertIntToPiece(x); } } Piece p1 = hasWon(board); System.out.println(p1); AssortedMethods.printMatrix(board_t); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_04_Tic_Tac_Win/QuestionG.java ================================================ package Q16_04_Tic_Tac_Win; import java.util.ArrayList; import CtCILibrary.AssortedMethods; public class QuestionG { public static class Check { public int row, column; private int rowIncrement, columnIncrement; public Check(int row, int column, int rowI, int colI) { this.row = row; this.column = column; this.rowIncrement = rowI; this.columnIncrement = colI; } public void increment() { row += rowIncrement; column += columnIncrement; } public boolean inBounds(int size) { return row >= 0 && column >= 0 && row < size && column < size; } } public static Piece hasWon(Piece[][] board) { if (board.length != board[0].length) return Piece.Empty; int size = board.length; /* Create list of things to check. */ ArrayList instructions = new ArrayList(); for (int i = 0; i < board.length; i++) { instructions.add(new Check(0, i, 1, 0)); instructions.add(new Check(i, 0, 0, 1)); } instructions.add(new Check(0, 0, 1, 1)); instructions.add(new Check(0, size - 1, 1, -1)); /* Check them. */ for (Check instr : instructions) { Piece winner = hasWon(board, instr); if (winner != Piece.Empty) { return winner; } } return Piece.Empty; } public static Piece hasWon(Piece[][] board, Check instr) { Piece first = board[instr.row][instr.column]; while (instr.inBounds(board.length)) { if (board[instr.row][instr.column] != first) { return Piece.Empty; } instr.increment(); } return first; } public static void main(String[] args) { int N = 3; int[][] board_t = AssortedMethods.randomMatrix(N, N, 0, 2); Piece[][] board = new Piece[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int x = board_t[i][j]; board[i][j] = Tester.convertIntToPiece(x); } } Piece p1 = hasWon(board); System.out.println(p1); AssortedMethods.printMatrix(board_t); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_04_Tic_Tac_Win/QuestionH.java ================================================ package Q16_04_Tic_Tac_Win; import java.util.ArrayList; import CtCILibrary.AssortedMethods; public class QuestionH { public static Piece hasWon(Piece[][] board) { if (board.length != board[0].length) return Piece.Empty; int size = board.length; ArrayList instructions = new ArrayList(); for (int i = 0; i < board.length; i++) { instructions.add(new PositionIterator(new Position(0, i), 1, 0, size)); instructions.add(new PositionIterator(new Position(i, 0), 0, 1, size)); } instructions.add(new PositionIterator(new Position(0, 0), 1, 1, size)); instructions.add(new PositionIterator(new Position(0, size - 1), 1, -1, size)); for (PositionIterator iterator : instructions) { Piece winner = hasWon(board, iterator); if (winner != Piece.Empty) { return winner; } } return Piece.Empty; } public static Piece hasWon(Piece[][] board, PositionIterator iterator) { Position firstPosition = iterator.next(); Piece first = board[firstPosition.row][firstPosition.column]; while (iterator.hasNext()) { Position position = iterator.next(); if (board[position.row][position.column] != first) { return Piece.Empty; } } return first; } public static void main(String[] args) { int N = 3; int[][] board_t = AssortedMethods.randomMatrix(N, N, 0, 2); Piece[][] board = new Piece[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int x = board_t[i][j]; board[i][j] = Tester.convertIntToPiece(x); } } Piece p1 = hasWon(board); System.out.println(p1); AssortedMethods.printMatrix(board_t); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_04_Tic_Tac_Win/Tester.java ================================================ package Q16_04_Tic_Tac_Win; import CtCILibrary.AssortedMethods; public class Tester { public static Piece convertIntToPiece(int i) { if (i == 1) { return Piece.Blue; } else if (i == 2) { return Piece.Red; } else { return Piece.Empty; } } public static Piece hasWonB(Piece[][] board) { for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[0].length; j++) { Piece winner =QuestionB.hasWon(board, i, j); if (winner != Piece.Empty) { return winner; } } } return Piece.Empty; } public static void main(String[] args) { for (int k = 0; k < 100; k++) { int N = 3; int[][] board_t = AssortedMethods.randomMatrix(N, N, 0, 2); Piece[][] board = new Piece[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int x = board_t[i][j]; board[i][j] = convertIntToPiece(x); } } //AssortedMethods.printMatrix(board_t); Piece p1 = hasWonB(board); Piece p2 = QuestionC.hasWon(board); Piece p3 = QuestionD.hasWon(board); Piece p4 = QuestionE.hasWon(board); Piece p5 = QuestionF.hasWon(board); Piece p6 = QuestionG.hasWon(board); Piece p7 = QuestionH.hasWon(board); //System.out.println(p + " " + p2); if (p1 != p2 || p2 != p3 || p3 != p4 || p4 != p5 || p5 != p6 || p6 != p7) { System.out.println(p1 + " " + p2 + " " + p3 + " " + p4 + " " + p5 + " " + p6 + " " + p7); AssortedMethods.printMatrix(board_t); } } for (int k = 0; k < 100; k++) { int N = 4; int[][] board_t = AssortedMethods.randomMatrix(N, N, 0, 2); Piece[][] board = new Piece[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int x = board_t[i][j]; board[i][j] = convertIntToPiece(x); } } //AssortedMethods.printMatrix(board_t); Piece p3 = hasWonB(board); Piece p4 = QuestionE.hasWon(board); Piece p5 = QuestionF.hasWon(board); Piece p6 = QuestionG.hasWon(board); Piece p7 = QuestionH.hasWon(board); //System.out.println(p + " " + p2); if (p3 != p4 || p4 != p5 || p5 != p6 || p6 != p7) { System.out.println(p3 + " " + p4 + " " + p5 + " " + p6 + " " + p7); AssortedMethods.printMatrix(board_t); } } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_05_Factorial_Zeros/QuestionA.java ================================================ package Q16_05_Factorial_Zeros; public class QuestionA { public static int factorsOf5(int i) { int count = 0; while (i % 5 == 0) { count++; i /= 5; } return count; } public static int countFactZeros(int num) { int count = 0; for (int i = 2; i <= num; i++) { count += factorsOf5(i); } return count; } public static int factorial(int num) { if (num == 1) { return 1; } else if (num > 1) { return num * factorial(num - 1); } else { return -1; // Error } } public static void main(String[] args) { for (int i = 1; i < 12; i++) { System.out.println(i + "! (or " + factorial(i) + ") has " + countFactZeros(i) + " zeros"); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_05_Factorial_Zeros/QuestionB.java ================================================ package Q16_05_Factorial_Zeros; public class QuestionB { public static int countFactZeros(int num) { int count = 0; if (num < 0) { System.out.println("Factorial is not defined for negative numbers"); return 0; } for (int i = 5; num / i > 0; i *= 5) { count += num / i; } return count; } public static int factorial(int num) { if (num == 1) { return 1; } else if (num > 1) { return num * factorial(num - 1); } else { return -1; // Error } } public static void main(String[] args) { for (int i = 1; i < 12; i++) { System.out.println(i + "! (or " + factorial(i) + ") has " + countFactZeros(i) + " zeros"); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_06_Smallest_Difference/QuestionA.java ================================================ package Q16_06_Smallest_Difference; public class QuestionA { public static int findSmallestDifference(int[] arrayA, int[] arrayB) { if (arrayA.length == 0 || arrayB.length == 0) return -1; int smallestDifference = Integer.MAX_VALUE; for (int a : arrayA) { for (int b : arrayB) { smallestDifference = Math.min(smallestDifference, Math.abs(a - b)); } } return smallestDifference; } public static void main(String[] args) { int[] array1 = {1, 3, 15, 11, 2}; int[] array2 = {23, 127, 234, 19, 8}; int difference = findSmallestDifference(array1, array2); System.out.println(difference); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_06_Smallest_Difference/QuestionB.java ================================================ package Q16_06_Smallest_Difference; import java.util.Arrays; public class QuestionB { public static int findSmallestDifference(int[] arrayA, int[] arrayB) { if (arrayA.length == 0 || arrayB.length == 0) return -1; Arrays.sort(arrayA); Arrays.sort(arrayB); int indexA = 0; int indexB = 0; int smallestDifference = Integer.MAX_VALUE; while (indexA < arrayA.length && indexB < arrayB.length) { int difference = Math.abs(arrayA[indexA] - arrayB[indexB]); smallestDifference = Math.min(smallestDifference, difference); if (arrayA[indexA] < arrayB[indexB]) { indexA++; } else { indexB++; } } return smallestDifference; } public static void main(String[] args) { int[] array1 = {1, 3, 15, 11, 2}; int[] array2 = {23, 127, 234, 19, 8}; int difference = findSmallestDifference(array1, array2); System.out.println(difference); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_06_Smallest_Difference/QuestionC.java ================================================ package Q16_06_Smallest_Difference; import java.util.Arrays; public class QuestionC { public static int getClosestValue(int[] array, int target) { int low = 0; int high = array.length - 1; int mid; while (low <= high) { mid = low + (high - low) / 2; if (array[mid] < target) { low = mid + 1; } else if (array[mid] > target) { high = mid - 1; } else { return array[mid]; } } int valueA = low < 0 || low >= array.length ? Integer.MAX_VALUE : array[low]; int valueB = high < 0 || high >= array.length ? Integer.MAX_VALUE : array[high]; return Math.abs(valueA - target) < Math.abs(valueB - target) ? valueA : valueB; // return closest value } public static int findSmallestDifference(int[] shorter, int[] longer) { if (shorter.length == 0 || longer.length == 0) return -1; if (shorter.length > longer.length) return findSmallestDifference(longer, shorter); Arrays.sort(shorter); int smallestDifference = Integer.MAX_VALUE; for (int target : longer) { int closest = getClosestValue(shorter, target); smallestDifference = Math.min(smallestDifference, Math.abs(closest - target)); } return smallestDifference; } public static void main(String[] args) { int[] array1 = {1, 3, 15, 11, 2}; int[] array2 = {23, 127, 234, 19, 8}; int difference = findSmallestDifference(array1, array2); System.out.println(difference); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_06_Smallest_Difference/Tester.java ================================================ package Q16_06_Smallest_Difference; import CtCILibrary.AssortedMethods; public class Tester { public static void main(String[] args) { for (int i = 0; i < 100; i++) { int size = (int) (Math.random() * 100.0); int[] array1 = AssortedMethods.randomArray(size, i * -1, i); int[] array2 = AssortedMethods.randomArray(size, i * -1, i); int diffA = QuestionA.findSmallestDifference(array1, array2); int diffB = QuestionB.findSmallestDifference(array1, array2); int diffC = QuestionC.findSmallestDifference(array1, array2); if (diffA != diffB || diffB != diffC) { diffA = QuestionA.findSmallestDifference(array1, array2); diffB = QuestionB.findSmallestDifference(array1, array2); diffC = QuestionC.findSmallestDifference(array1, array2); System.out.println(diffA); System.out.println(diffB); System.out.println(diffC); System.out.println(); } } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_07_Number_Max/Question.java ================================================ package Q16_07_Number_Max; public class Question { /* Flips a 1 to a 0 and a 0 to a 1 */ public static int flip(int bit) { return 1 ^ bit; } /* Returns 1 if a is positive, and 0 if a is negative */ public static int sign(int a) { return flip((a >> 31) & 0x1); } public static int getMaxNaive(int a, int b) { int k = sign(a - b); int q = flip(k); return a * k + b * q; } public static int getMax(int a, int b) { int c = a - b; int sa = sign(a); // if a >= 0, then 1 else 0 int sb = sign(b); // if b >= 0, then 1 else 0 int sc = sign(c); // depends on whether or not a - b overflows /* We want to define a value k which is 1 if a > b and 0 if a < b. * (if a = b, it doesn't matter what value k is) */ int use_sign_of_a = sa ^ sb; // If a and b have different signs, then k = sign(a) int use_sign_of_c = flip(sa ^ sb); // If a and b have the same sign, then k = sign(a - b) /* We can't use a comparison operator, but we can multiply values by 1 or 0 */ int k = use_sign_of_a * sa + use_sign_of_c * sc; int q = flip(k); // opposite of k return a * k + b * q; } public static void main(String[] args) { int a = 26; int b = -15; System.out.println("max_naive(" + a + ", " + b + ") = " + getMaxNaive(a, b)); System.out.println("max(" + a + ", " + b + ") = " + getMax(a, b)); a = -15; b = 2147483647; System.out.println("max_naive(" + a + ", " + b + ") = " + getMaxNaive(a, b)); System.out.println("max(" + a + ", " + b + ") = " + getMax(a, b)); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_08_English_Int/Question.java ================================================ package Q16_08_English_Int; import java.util.LinkedList; import CtCILibrary.AssortedMethods; public class Question { public static String[] smalls = {"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}; public static String[] tens = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}; public static String[] bigs = {"", "Thousand", "Million", "Billion"}; public static String hundred = "Hundred"; public static String negative = "Negative"; public static String convert(int num) { if (num == 0) { return smalls[0]; } else if (num < 0) { return negative + " " + convert(-1 * num); } LinkedList parts = new LinkedList(); int chunkCount = 0; while (num > 0) { if (num % 1000 != 0) { String chunk = convertChunk(num % 1000) + " " + bigs[chunkCount]; parts.addFirst(chunk); } num /= 1000; // shift chunk chunkCount++; } return listToString(parts); } /* Convert a linked list of strings to a string, dividing it up with spaces. */ public static String listToString(LinkedList parts) { StringBuilder sb = new StringBuilder(); while (parts.size() > 1) { sb.append(parts.pop()); sb.append(" "); } sb.append(parts.pop()); return sb.toString(); } public static String convertChunk(int number) { LinkedList parts = new LinkedList(); /* Convert hundreds place */ if (number >= 100) { parts.addLast(smalls[number / 100]); parts.addLast(hundred); number %= 100; } /* Convert tens place */ if (number >= 10 && number <= 19) { parts.addLast(smalls[number]); } else if (number >= 20) { parts.addLast(tens[number / 10]); number %= 10; } /* Convert ones place */ if (number >= 1 && number <= 9) { parts.addLast(smalls[number]); } return listToString(parts); } public static void main(String[] args) { /* numbers between 100000 and 1000000 */ for (int i = 0; i < 8; i++) { int value = (int) (-1 * Math.pow(10, i)); String s = convert(value); System.out.println(value + ": " + s); } /* numbers between 0 and 100 */ for (int i = 0; i < 10; i++) { int value = AssortedMethods.randomIntInRange(0, 100); String s = convert(value); System.out.println(value + ": " + s); } /* numbers between 100 and 1000 */ for (int i = 0; i < 10; i++) { int value = AssortedMethods.randomIntInRange(100, 1000); String s = convert(value); System.out.println(value + ": " + s); } /* numbers between 1000 and 100000 */ for (int i = 0; i < 10; i++) { int value = AssortedMethods.randomIntInRange(1000, 100000); String s = convert(value); System.out.println(value + ": " + s); } /* numbers between 100000 and 100000000 */ for (int i = 0; i < 10; i++) { int value = AssortedMethods.randomIntInRange(100000, 100000000); String s = convert(value); System.out.println(value + ": " + s); } /* numbers between 100000000 and 1000000000 */ for (int i = 0; i < 10; i++) { int value = AssortedMethods.randomIntInRange(100000000, 1000000000); String s = convert(value); System.out.println(value + ": " + s); } /* numbers between 1000000000 and Integer.MAX_VALUE */ for (int i = 0; i < 10; i++) { int value = AssortedMethods.randomIntInRange(1000000000, Integer.MAX_VALUE); String s = convert(value); System.out.println(value + ": " + s); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_09_Operations/Question.java ================================================ package Q16_09_Operations; import java.util.Random; import CtCILibrary.AssortedMethods; public class Question { /* Flip a positive sign to negative, or a negative sign to pos */ public static int negate(int a) { int neg = 0; int newSign = a < 0 ? 1 : -1; while (a != 0) { neg += newSign; a += newSign; } return neg; } /* Flip a positive sign to negative, or a negative sign to pos */ public static int negateOptimized(int a) { int neg = 0; int newSign = a < 0 ? 1 : -1; int delta = newSign; while (a != 0) { boolean differentSigns = (a + delta > 0) != (a > 0); if (a + delta != 0 && differentSigns) { // If delta is too big, reset it. delta = newSign; } neg += delta; a += delta; delta += delta; // Double the delta } return neg; } /* Subtract two numbers by negating b and adding them */ public static int minus(int a, int b) { return a + negate(b); } /* Return absolute value */ public static int abs(int a) { if (a < 0) { return negateOptimized(a); } else return a; } /* Multiply a by b by adding a to itself b times */ public static int multiply(int a, int b) { if (a < b) { return multiply(b, a); // algo is faster if b < a } int sum = 0; for (int i = abs(b); i > 0; i = minus(i, 1)) { sum += a; } if (b < 0) { sum = negateOptimized(sum); } return sum; } /* Divide a by b by literally counting how many times b can go into * a. That is, count how many times you can add b to itself until you reach a. */ public static int divide(int a, int b) throws java.lang.ArithmeticException { if (b == 0) { throw new java.lang.ArithmeticException("ERROR: Divide by zero."); } int absa = abs(a); int absb = abs(b); int product = 0; int x = 0; while (product + absb <= absa) { /* don't go past a */ product += absb; x++; } if ((a < 0 && b < 0) || (a > 0 && b > 0)) { return x; } else { return negateOptimized(x); } } public static void main(String[] args) { int minRange = -100; int maxRange = 100; int cycles = 100; for (int i = 0; i < cycles; i++) { int a = AssortedMethods.randomIntInRange(minRange, maxRange); int b = AssortedMethods.randomIntInRange(minRange, maxRange); int ans = minus(a, b); if (ans != a - b) { System.out.println("ERROR"); } System.out.println(a + " - " + b + " = " + ans); } for (int i = 0; i < cycles; i++) { int a = AssortedMethods.randomIntInRange(minRange, maxRange); int b = AssortedMethods.randomIntInRange(minRange, maxRange); int ans = multiply(a, b); if (ans != a * b) { System.out.println("ERROR"); } System.out.println(a + " * " + b + " = " + ans); } for (int i = 0; i < cycles; i++) { int a = AssortedMethods.randomIntInRange(minRange, maxRange); int b = AssortedMethods.randomIntInRange(minRange, maxRange); System.out.print(a + " / " + b + " = "); int ans = divide(a, b); if (ans != a / b) { System.out.println("ERROR"); } System.out.println(ans); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_10_Living_People/Person.java ================================================ package Q16_10_Living_People; public class Person { public int birth; public int death; public Person(int birthYear, int deathYear) { birth = birthYear; death = deathYear; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_10_Living_People/QuestionA.java ================================================ package Q16_10_Living_People; import java.util.Random; public class QuestionA { public static int maxAliveYear(Person[] people, int min, int max) { int maxAlive = 0; int maxAliveYear = min; for (int year = min; year <= max; year++) { int alive = 0; for (Person person : people) { if (person.birth <= year && year <= person.death) { alive++; } } if (alive > maxAlive) { maxAlive = alive; maxAliveYear = year; } } return maxAliveYear; } public static void main(String[] args) { int n = 10000; int first = 0; int last = 200000; Random random = new Random(); Person[] people = new Person[n]; for (int i = 0; i < n; i++) { int birth = first + random.nextInt(last - first); int death = birth + random.nextInt(last - birth); people[i] = new Person(birth, death); //System.out.println(birth + ", " + death); } System.out.println(n); for (int i = 0; i < n; i++) { //int birth = first + random.nextInt(last - first); //int death = birth + random.nextInt(last - birth); //people[i] = new Person(birth, death); System.out.println(people[i].birth); } System.out.println(n); for (int i = 0; i < n; i++) { //int birth = first + random.nextInt(last - first); //int death = birth + random.nextInt(last - birth); //people[i] = new Person(birth, death); System.out.println(people[i].death); } int year = maxAliveYear(people, first, last); System.out.println(year); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_10_Living_People/QuestionB.java ================================================ package Q16_10_Living_People; import java.util.Random; public class QuestionB { public static int maxAliveYear(Person[] people, int min, int max) { int[] years = createYearMap(people, min, max); int best = getMaxIndex(years); return best + min; } /* Add each person's years to a year map. */ public static int[] createYearMap(Person[] people, int min, int max) { int[] years = new int[max - min + 1]; for (Person person : people) { int left = person.birth - min; int right = person.death - min; incrementRange(years, left, right); } return years; } /* Increment array for each value between left and right. */ public static void incrementRange(int[] values, int left, int right) { for (int i = left; i <= right; i++) { values[i]++; } } /* Get index of largest element in array. */ public static int getMaxIndex(int[] values) { int max = 0; for (int i = 1; i < values.length; i++) { if (values[i] > values[max]) { max = i; } } return max; } public static void main(String[] args) { int n = 3; int first = 1900; int last = 2000; Random random = new Random(); Person[] people = new Person[n]; for (int i = 0; i < n; i++) { int birth = first + random.nextInt(last - first); int death = birth + random.nextInt(last - birth); people[i] = new Person(birth, death); System.out.println(birth + ", " + death); } int year = maxAliveYear(people, first, last); System.out.println(year); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_10_Living_People/QuestionC.java ================================================ package Q16_10_Living_People; import java.util.Arrays; import java.util.Random; public class QuestionC { public static int maxAliveYear(Person[] people, int min, int max) { int[] births = getSortedYears(people, true); int[] deaths = getSortedYears(people, false); int birthIndex = 0; int deathIndex = 0; int currentlyAlive = 0; int maxAlive = 0; int maxAliveYear = min; /* Walk through arrays. */ while (birthIndex < births.length) { if (births[birthIndex] <= deaths[deathIndex]) { currentlyAlive++; // include birth if (currentlyAlive > maxAlive) { maxAlive = currentlyAlive; maxAliveYear = births[birthIndex]; } birthIndex++; // move birth index } else { currentlyAlive--; // include death deathIndex++; // move death index } } return maxAliveYear; } /* Copy birth years or death years (depending on the value of copyBirthYear) * into integer array, then sort array. */ public static int[] getSortedYears(Person[] people, boolean copyBirthYear) { int[] years = new int[people.length]; for (int i = 0; i < people.length; i++) { years[i] = copyBirthYear ? people[i].birth : people[i].death; } Arrays.sort(years); return years; } public static void main(String[] args) { int n = 3; int first = 1900; int last = 2000; Random random = new Random(); Person[] people = new Person[n]; for (int i = 0; i < n; i++) { int birth = first + random.nextInt(last - first); int death = birth + random.nextInt(last - birth); people[i] = new Person(birth, death); System.out.println(birth + ", " + death); } int year = maxAliveYear(people, first, last); System.out.println(year); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_10_Living_People/QuestionD.java ================================================ package Q16_10_Living_People; import java.util.Random; public class QuestionD { public static int maxAliveYear(Person[] people, int min, int max) { /* Build population delta array. */ int[] populationDeltas = getPopulationDeltas(people, min, max); int maxAliveYear = getMaxAliveYear(populationDeltas); return maxAliveYear + min; } /* Add birth and death years to deltas array. */ public static int[] getPopulationDeltas(Person[] people, int min, int max) { int[] populationDeltas = new int[max - min + 2]; for (Person person : people) { int birth = person.birth - min; populationDeltas[birth]++; int death = person.death - min; populationDeltas[death + 1]--; } return populationDeltas; } /* Compute running sums and return index with max. */ public static int getMaxAliveYear(int[] deltas) { int maxAliveYear = 0; int maxAlive = 0; int currentlyAlive = 0; for (int year = 0; year < deltas.length; year++) { currentlyAlive += deltas[year]; if (currentlyAlive > maxAlive) { maxAliveYear = year; maxAlive = currentlyAlive; } } return maxAliveYear; } public static void main(String[] args) { int n = 3; int first = 1900; int last = 2000; Random random = new Random(); Person[] people = new Person[n]; for (int i = 0; i < n; i++) { int birth = first + random.nextInt(last - first); int death = birth + random.nextInt(last - birth); people[i] = new Person(birth, death); System.out.println(birth + ", " + death); } int year = maxAliveYear(people, first, last); System.out.println(year); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_10_Living_People/Tester.java ================================================ package Q16_10_Living_People; import java.util.Random; public class Tester { public static void main(String[] args) { int n = 100; int first = 1900; int last = 2000; Random random = new Random(); Person[] people = new Person[n + 1]; for (int i = 0; i < n; i++) { int birth = first + random.nextInt(last - first); int death = birth + random.nextInt(last - birth); people[i] = new Person(birth, death); //System.out.println(birth + ", " + death); } people[n] = new Person(first, first); int yearA = QuestionA.maxAliveYear(people, first, last); int yearB = QuestionB.maxAliveYear(people, first, last); int yearC = QuestionC.maxAliveYear(people, first, last); int yearD = QuestionD.maxAliveYear(people, first, last); System.out.println("A: " + yearA); System.out.println("B: " + yearB); System.out.println("C: " + yearC); System.out.println("D: " + yearD); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_11_Diving_Board/QuestionA.java ================================================ package Q16_11_Diving_Board; import java.util.HashSet; public class QuestionA { public static int counter = 0; public static HashSet allLengths(int k, int shorter, int longer) { HashSet lengths = new HashSet(); getAllLengths(k, 0, shorter, longer, lengths); return lengths; } public static void getAllLengths(int k, int total, int shorter, int longer, HashSet lengths) { counter++; if (k == 0) { lengths.add(total); return; } getAllLengths(k - 1, total + shorter, shorter, longer, lengths); getAllLengths(k - 1, total + longer, shorter, longer, lengths); } public static void main(String[] args) { HashSet lengths = allLengths(12, 1, 3); System.out.println(lengths.toString()); System.out.println(counter); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_11_Diving_Board/QuestionB.java ================================================ package Q16_11_Diving_Board; import java.util.HashSet; public class QuestionB { public static int counter = 0; public static HashSet allLengths(int k, int shorter, int longer) { HashSet lengths = new HashSet(); HashSet visited = new HashSet(); getAllLengths(k, 0, shorter, longer, lengths, visited); return lengths; } public static void getAllLengths(int k, int total, int shorter, int longer, HashSet lengths, HashSet visited) { counter++; if (k == 0) { lengths.add(total); return; } String key = k + " " + total; if (visited.contains(key)) { return; } getAllLengths(k - 1, total + shorter, shorter, longer, lengths, visited); getAllLengths(k - 1, total + longer, shorter, longer, lengths, visited); visited.add(key); } public static void main(String[] args) { HashSet lengths = allLengths(12, 1, 3); System.out.println(lengths.toString()); System.out.println(counter); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_11_Diving_Board/QuestionC.java ================================================ package Q16_11_Diving_Board; import java.util.HashSet; public class QuestionC { public static int counter = 0; public static HashSet allLengths(int k, int shorter, int longer) { counter++; HashSet lengths = new HashSet(); for (int nShorter = 0; nShorter <= k; nShorter++) { int nLonger = k - nShorter; int length = nShorter * shorter + nLonger * longer; lengths.add(length); } return lengths; } public static void main(String[] args) { HashSet lengths = allLengths(12, 1, 3); System.out.println(lengths.toString()); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_11_Diving_Board/Tester.java ================================================ package Q16_11_Diving_Board; import java.util.HashSet; public class Tester { public static void main(String[] args) { int nSticks = 12; int shorter = 2; int longer = 3; HashSet lengthsA = QuestionA.allLengths(nSticks, shorter, longer); HashSet lengthsB = QuestionB.allLengths(nSticks, shorter, longer); HashSet lengthsC = QuestionC.allLengths(nSticks, shorter, longer); System.out.println(QuestionB.counter); System.out.println(lengthsA.toString()); System.out.println(lengthsB.toString()); System.out.println(lengthsC.toString()); System.out.println(lengthsA.equals(lengthsB) && lengthsA.equals(lengthsC)); System.out.println("Calls for A: " + QuestionA.counter); System.out.println("Calls for B: " + QuestionB.counter); System.out.println("Calls for C: " + QuestionC.counter); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_12_XML_Encoding/Attribute.java ================================================ package Q16_12_XML_Encoding; public class Attribute { public String tag; public String value; public Attribute(String t, String v) { tag = t; value = v; } public String getTagCode() { if (tag == "family") { return "1"; } else if (tag == "person") { return "2"; } else if (tag == "firstName") { return "3"; } else if (tag == "lastName") { return "4"; } else if (tag == "state") { return "5"; } return "--"; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_12_XML_Encoding/Element.java ================================================ package Q16_12_XML_Encoding; import java.util.ArrayList; public class Element { public ArrayList attributes; public ArrayList children; public String name; public String value; public Element(String n) { name = n; attributes = new ArrayList(); children = new ArrayList(); } public Element(String n, String v) { name = n; value = v; attributes = new ArrayList(); children = new ArrayList(); } public String getNameCode() { if (name == "family") { return "1"; } else if (name == "person") { return "2"; } else if (name == "firstName") { return "3"; } else if (name == "lastName") { return "4"; } else if (name == "state") { return "5"; } return "--"; } public void insert(Attribute attribute) { attributes.add(attribute); } public void insert(Element child) { children.add(child); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_12_XML_Encoding/QuestionOO.java ================================================ package Q16_12_XML_Encoding; public class QuestionOO { public static void encode(String v, StringBuilder sb) { v = v.replace("0", "\\0"); sb.append(v); sb.append(" "); } public static void encodeEnd(StringBuilder sb) { sb.append("0"); sb.append(" "); } public static void encode(Attribute attr, StringBuilder sb) { encode(attr.getTagCode(), sb); encode(attr.value, sb); } public static void encode(Element root, StringBuilder sb) { encode(root.getNameCode(), sb); for (Attribute a : root.attributes) { encode(a, sb); } encodeEnd(sb); if (root.value != null && root.value != "") { encode(root.value, sb); } else { for (Element e : root.children) { encode(e, sb); } } encodeEnd(sb); } public static String encodeToString(Element root) { StringBuilder sb = new StringBuilder(); encode(root, sb); return sb.toString(); } public static void main(String args[]) { Element root = new Element("family"); Attribute a1 = new Attribute("lastName", "mcdowell"); Attribute a2 = new Attribute("state", "CA"); root.insert(a1); root.insert(a2); Element child = new Element("person", "Some Message"); Attribute a3 = new Attribute("firstName", "Gayle"); child.insert(a3); root.insert(child); String s = encodeToString(root); System.out.println(s); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_12_XML_Encoding/QuestionString.java ================================================ package Q16_12_XML_Encoding; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class QuestionString { private Map tagMap; private static final Byte[] END = { 0, 1 }; private ArrayList tokens; private int currentTokenIndex; public QuestionString(Map tagMap) {this.tagMap = tagMap;} public byte[] encode(char[] input) throws IOException { // tokenize tokenize(input); currentTokenIndex = 0; // parse ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); encodeTokens(outputStream); return outputStream.toByteArray(); } private void encodeTokens(ByteArrayOutputStream output) throws IOException { nextToken("<"); // read tag name String tagName = nextToken(); output.write(getTagCode(tagName)); // read attributes while (!hasNextToken(">") && !hasNextTokens("/", ">")) { // read next attribute String key = nextToken(); nextToken("="); String value = nextToken(); output.write(getTagCode(key)); for (char c : value.toCharArray()) { output.write(c); } output.write(END[0]); output.write(END[1]); } // end of attributes output.write(END[0]); output.write(END[1]); // finish this element if (hasNextTokens("/", ">")) { nextToken("/"); nextToken(">"); } else { nextToken(">"); // while not the end tag while (!hasNextTokens("<", "/")) { // encode child encodeTokens(output); } // ending tag nextToken("<"); nextToken("/"); nextToken(tagName); nextToken(">"); } output.write(END[0]); output.write(END[1]); } private String nextToken() throws IOException { if (currentTokenIndex >= tokens.size()) { throw new IOException("Unexpected end of input."); } String token = tokens.get(currentTokenIndex); currentTokenIndex++; return token; } private void nextToken(String expectedToken) throws IOException { if (currentTokenIndex >= tokens.size()) { throw new IOException("Unexpected end of input."); } String token = tokens.get(currentTokenIndex); if (token.equals(expectedToken)) { currentTokenIndex++; } else { throw new IOException("Unexpected input. Expected '" + expectedToken + "'; found '" + token + "'."); } } private boolean hasNextToken(String expectedToken) { if (currentTokenIndex < tokens.size()) { return tokens.get(currentTokenIndex).equals(expectedToken); } else { return false; } } private boolean hasNextTokens(String... expectedTokens) { if (currentTokenIndex + expectedTokens.length > tokens.size()) { return false; } for (int i = 0; i < expectedTokens.length; i++) { if (!tokens.get(currentTokenIndex + i) .equals(expectedTokens[i])) return false; } return true; } private void tokenize(char[] input) { tokens = new ArrayList(); int i = 0; while (i < input.length) { i = setNextToken(input, i); } } private int setNextToken(char[] input, int inputIndex) { int i = inputIndex; while (i < input.length && input[i] == ' ') i++; if (i == input.length) return i; // get 1 char token char c = input[i]; if (c == '<' || c == '>' || c == '=' || c == '/') { tokens.add(String.valueOf(c)); return i + 1; } // get multiple char token StringBuilder string = new StringBuilder(); do { string.append(c); i++; c = input[i]; if (c == '<' || c == '>' || c == '=' || c == '/' || c == ' ') { break; } } while (i < input.length); tokens.add(string.toString()); return i; } private byte getTagCode(String tag) throws IOException { Byte tagCode = tagMap.get(tag); if (tagCode == null) { throw new IOException("Unknown tag: " + tag); } return tagCode; } public static void main(String args[]) { try { Map tagMap = new HashMap(); tagMap.put("a", (byte) 10); tagMap.put("root", (byte) 11); tagMap.put("href", (byte) 20); tagMap.put("target", (byte) 21); tagMap.put("name", (byte) 50); tagMap.put("id", (byte) 51); QuestionString encoder = new QuestionString(tagMap); String input; byte[] output; input = ""; output = encoder.encode(input.toCharArray()); print(output); input = ""; output = encoder.encode(input.toCharArray()); print(output); input = ""; output = encoder.encode(input.toCharArray()); print(output); } catch (Exception ex) { System.out.println(ex); } } public static void print(byte[] output) { for (byte b : output) { System.out.print(b); System.out.print(" "); } System.out.println(); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_13_Bisect_Squares/Line.java ================================================ package Q16_13_Bisect_Squares; public class Line { public Point start; public Point end; public Line(Point start, Point end) { this.start = start; this.end = end; } public String toString() { return "Line from " + start.toString() + " to " + end.toString(); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_13_Bisect_Squares/Point.java ================================================ package Q16_13_Bisect_Squares; public class Point { public double x; public double y; public Point(double x, double y) { this.x = x; this.y = y; } public boolean isEqual(Point p) { return (p.x == x && p.y == y); } public String toString() { return "(" + x + ", " + y + ")"; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_13_Bisect_Squares/Question.java ================================================ package Q16_13_Bisect_Squares; public class Question { public static int randomInt(int n) { return (int) (Math.random() * n); } public static void printLine(Line l) { System.out.println(l.start.x + "\t" + l.start.y); System.out.println(l.end.x + "\t" + l.end.y); } public static void printSquare(Square s) { System.out.println(s.left + "\t" + s.top + "\t" + s.size); } public static boolean isApproxEqual(double d1, double d2) { double epsilon = .001; if (Math.abs(d1 - d2) < epsilon) { return true; } return false; } public static boolean isApproxEqual(Point p1, Point p2) { return isApproxEqual(p1.x, p2.x) && isApproxEqual(p1.y, p2.y); } public static boolean doTest(Square s1, Square s2, Point start, Point end) { Line line = s1.cut(s2); boolean r = (isApproxEqual(line.start, start) && isApproxEqual(line.end, end)) || (isApproxEqual(line.start, end) && isApproxEqual(line.end, start)); if (!r) { printSquare(s1); printSquare(s2); printLine(line); System.out.println(start.toString()); System.out.println(end.toString()); System.out.println(); return r; } return r; } public static boolean doTestFull(Square s1, Square s2, Point start, Point end) { return doTest(s1, s2, start, end) && doTest(s2, s1, start, end); } public static void doTests() { // Equal doTestFull(new Square(1, 1, 5), new Square(1, 1, 5), new Point(3.5, 1), new Point(3.5, 6)); // Concentric doTestFull(new Square(1, 1, 5), new Square(2, 2, 3), new Point(3.5, 1), new Point(3.5, 6)); // Partially overlapping -- side by side doTestFull(new Square(10, 10, 10), new Square(8, 10, 10), new Point(8, 15), new Point(20, 15)); // Partially overlapping -- corners doTestFull(new Square(10, 10, 10), new Square(8, 7, 7), new Point(8.777777, 7), new Point(18.8888888, 20)); // Partially overlapping -- on top of each other doTestFull(new Square(10, 10, 10), new Square(8, 7, 15), new Point(8, 22), new Point(23, 7)); // Not overlapping -- side by side doTestFull(new Square(10, 10, 10), new Square(19, 25, 4), new Point(12.5, 10), new Point(22, 29)); // Not overlapping -- on top of each other doTestFull(new Square(10, 10, 10), new Square(4, 4, 3), new Point(4, 4), new Point(20, 20)); // Contained doTestFull(new Square(10, 10, 10), new Square(12, 14, 3), new Point(10, 16.66666), new Point(20, 13.333)); } public static void main(String[] args) { /* For an easy way to test these, open up Square Cut Tester.xlsx * in the Chapter 7, Problem 5 folder. Copy and paste the exact * output from below into the file (including all tabs). */ doTests(); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_13_Bisect_Squares/Square.java ================================================ package Q16_13_Bisect_Squares; public class Square { public double left; public double top; public double bottom; public double right; public double size; public Square(double left, double top, double size) { this.left = left; this.top = top; this.bottom = top + size; this.right = left + size; this.size = size; } public Point middle() { return new Point((this.left + this.right)/2.0, (this.top + this.bottom)/2.0); } public boolean contains(Square other) { if (this.left <= other.left && this.right >= other.right && this.top <= other.top && this.bottom >= other.bottom) { return true; } return false; } /* Return the point where the line segment connecting mid1 and * mid2 intercepts the edge of square 1. That is, draw a line * from mid2 to mid1, and continue it out until the edge of * the square. */ public Point extend(Point mid1, Point mid2, double size) { /* Find what direction the line mid2 -> mid1 goes */ double xdir = mid1.x < mid2.x ? -1 : 1; double ydir = mid1.y < mid2.y ? -1 : 1; /* If mid1 and mid2 have the same x value, then the slope * calculation will throw a divide by 0 exception. So, we * compute this specially. */ if (mid1.x == mid2.x) { return new Point(mid1.x, mid1.y + ydir * size / 2.0); } double slope = (mid1.y - mid2.y) / (mid1.x - mid2.x); double x1 = 0; double y1 = 0; /* Calculate slope using the equation (y1 - y2) / (x1 - x2). * Note: if the slope is �steep� (>1) then the end of the * line segment will hit size / 2 units away from the middle * on the y axis. If the slope is �shallow� (<1) the end of * the line segment will hit size / 2 units away from the * middle on the x axis. */ if (Math.abs(slope) == 1) { x1 = mid1.x + xdir * size / 2.0; y1 = mid1.y + ydir * size / 2.0; } else if (Math.abs(slope) < 1) { x1 = mid1.x + xdir * size / 2.0; y1 = slope * (x1 - mid1.x) + mid1.y; } else { y1 = mid1.y + ydir * size / 2.0; x1 = (y1 - mid1.y) / slope + mid1.x; } return new Point(x1, y1); } public Line cut(Square other) { /* Calculate where a line between each middle would collide with the edges of the squares */ Point p1 = extend(this.middle(), other.middle(), this.size); Point p2 = extend(this.middle(), other.middle(), -1 * this.size); Point p3 = extend(other.middle(), this.middle(), other.size); Point p4 = extend(other.middle(), this.middle(), -1 * other.size); /* Of above points, find start and end of lines. Start is farthest left (with top most as a tie breaker) * and end is farthest right (with bottom most as a tie breaker */ Point start = p1; Point end = p1; Point[] points = {p2, p3, p4}; for (int i = 0; i < points.length; i++) { if (points[i].x < start.x || (points[i].x == start.x && points[i].y < start.y)) { start = points[i]; } else if (points[i].x > end.x || (points[i].x == end.x && points[i].y > end.y)) { end = points[i]; } } return new Line(start, end); } public String toString() { return "(" + left + ", " + top + ")|(" + right + "," + bottom + ")"; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_14_Best_Line/GraphPoint.java ================================================ package Q16_14_Best_Line; public class GraphPoint { public double x; public double y; public GraphPoint(double x1, double y1) { x = x1; y = y1; } public String toString() { return "(" + x + ", " + y + ")"; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_14_Best_Line/Line.java ================================================ package Q16_14_Best_Line; public class Line { public static double epsilon = .5; public double slope; public double intercept; private boolean infinite_slope = false; public Line(GraphPoint p, GraphPoint q) { if (Math.abs(p.x - q.x) > epsilon) { // if x�s are different slope = (p.y - q.y) / (p.x - q.x); // compute slope intercept = p.y - slope * p.x; // y intercept from y=mx+b } else { infinite_slope = true; intercept = p.x; // x-intercept, since slope is infinite } } public boolean isEquivalent(double a, double b) { return (Math.abs(a - b) < epsilon); } public void Print() { System.out.println("y = " + slope + "x + " + intercept); } public static double floorToNearestEpsilon(double d) { int r = (int) (d / epsilon); return ((double) r) * epsilon; } public boolean isEquivalent(Object o) { Line l = (Line) o; if (isEquivalent(l.slope, slope) && isEquivalent(l.intercept, intercept) && (infinite_slope == l.infinite_slope)) { return true; } return false; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_14_Best_Line/Question.java ================================================ package Q16_14_Best_Line; import java.util.ArrayList; import java.util.HashMap; import java.util.Set; import CtCILibrary.HashMapList; public class Question { /* Find line that goes through most number of points. */ public static Line findBestLine(GraphPoint[] points) { HashMapList linesBySlope = getListOfLines(points); return getBestLine(linesBySlope); } /* Add each pair of points as a line to the list. */ public static HashMapList getListOfLines(GraphPoint[] points) { HashMapList linesBySlope = new HashMapList(); for (int i = 0; i < points.length; i++) { for (int j = i + 1; j < points.length; j++) { Line line = new Line(points[i], points[j]); double key = Line.floorToNearestEpsilon(line.slope); linesBySlope.put(key, line); } } return linesBySlope; } /* Return the line with the most equivalent other lines. */ public static Line getBestLine(HashMapList linesBySlope) { Line bestLine = null; int bestCount = 0; Set slopes = linesBySlope.keySet(); for (double slope : slopes) { ArrayList lines = linesBySlope.get(slope); for (Line line : lines) { /* count lines that are equivalent to current line */ int count = countEquivalentLines(linesBySlope, line); /* if better than current line, replace it */ if (count > bestCount) { bestLine = line; bestCount = count; bestLine.Print(); System.out.println(bestCount); } } } return bestLine; } /* Check hashmap for lines that are equivalent. Note that we need to check one epsilon above and below the actual slope * since we're defining two lines as equivalent if they're within an epsilon of each other. */ public static int countEquivalentLines(HashMapList linesBySlope, Line line) { double key = Line.floorToNearestEpsilon(line.slope); int count = countEquivalentLines(linesBySlope.get(key), line); count += countEquivalentLines(linesBySlope.get(key - Line.epsilon), line); count += countEquivalentLines(linesBySlope.get(key + Line.epsilon), line); return count; } /* Count lines within an array of lines which are "equivalent" (slope and y-intercept are within an epsilon value) to a given line */ public static int countEquivalentLines(ArrayList lines, Line line) { if (lines == null) { return 0; } int count = 0; for (Line parallelLine : lines) { if (parallelLine.isEquivalent(line)) { count++; } } return count; } public static GraphPoint[] createPoints() { int n_points = 100; System.out.println("Points on Graph\n***************"); GraphPoint[] points = new GraphPoint[n_points - 1]; for (int i = 0; i < n_points / 2; i++) { GraphPoint p = new GraphPoint(i, 2.3 * ((double)i) + 20.0); points[i] = p; System.out.println(p.toString()); } for (int i = 0; i < n_points / 2 - 1; i++) { GraphPoint p = new GraphPoint(i, 3.0 * ((double)i) + 1.0); points[n_points / 2 + i] = p; System.out.println(p.toString()); } System.out.println("****************\n"); return points; } public static int validate(Line line, GraphPoint[] points) { int count = 0; for (int i = 0; i < points.length; i++) { for (int j = i + 1; j < points.length; j++) { Line other = new Line(points[i], points[j]); if (line.isEquivalent(other)) { count++; } } } return count; } public static void main(String[] args) { GraphPoint[] points = createPoints(); Line line = findBestLine(points); line.Print(); System.out.println(validate(line, points)); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_15_Master_Mind/Question.java ================================================ package Q16_15_Master_Mind; public class Question { public static int code(char c) { switch (c) { case 'B': return 0; case 'G': return 1; case 'R': return 2; case 'Y': return 3; default: return -1; } } public static char letterFromCode(int k) { switch (k) { case 0: return 'B'; case 1: return 'G'; case 2: return 'R'; case 3: return 'Y'; default: return '0'; } } public static int MAX_COLORS = 4; public static Result estimate(String guess, String solution) { if (guess.length() != solution.length()) return null; Result res = new Result(0, 0); int[] frequencies = new int[MAX_COLORS]; /* Compute hits and built frequency table */ for (int i = 0; i < guess.length(); i++) { if (guess.charAt(i) == solution.charAt(i)) { res.hits++; } else { /* Only increment the frequency table (which will be used for pseudo-hits) if * it's not a hit. If it's a hit, the slot has already been "used." */ int code = code(solution.charAt(i)); if (code >= 0) { frequencies[code]++; } } } /* Compute pseudo-hits */ for (int i = 0; i < guess.length(); i++) { int code = code(guess.charAt(i)); if (code >= 0 && frequencies[code] > 0 && guess.charAt(i) != solution.charAt(i)) { res.pseudoHits++; frequencies[code]--; } } return res; } public static void main(String[] args) { Result res = estimate("GGRR", "RGBY"); System.out.println(res.toString()); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_15_Master_Mind/Result.java ================================================ package Q16_15_Master_Mind; public class Result { public int hits; public int pseudoHits; public Result(int h, int p) { hits = h; pseudoHits = p; } @Override public String toString() { return "Result [hits=" + hits + ", pseudoHits=" + pseudoHits + "]"; } }; ================================================ FILE: Java/Ch 16. Moderate/Q16_15_Master_Mind/Tester.java ================================================ package Q16_15_Master_Mind; import java.util.Random; public class Tester { public static Result estimateBad(String g, String s) { char[] guess = g.toCharArray(); char[] solution = s.toCharArray(); int hits = 0; for (int i = 0; i < guess.length; i++) { if (guess[i] == solution[i]) { hits++; solution[i] = '0'; guess[i] = '0'; } } int pseudohits = 0; for (int i = 0; i < guess.length; i++) { if (guess[i] != '0') { for (int j = 0; j < solution.length; j++) { if (solution[j] != '0') { if (solution[j] == guess[i]) { pseudohits++; solution[j] = '0'; break; } } } } } return new Result(hits, pseudohits); } public static String randomString() { int length = 4; char[] str = new char[length]; Random generator = new Random(); for (int i = 0; i < length; i++) { int v = generator.nextInt(4); char c = Question.letterFromCode(v); str[i] = c; } return String.valueOf(str); } public static boolean test(String guess, String solution) { Result res1 = Question.estimate(guess, solution); Result res2 = estimateBad(guess, solution); if (res1.hits == res2.hits && res1.pseudoHits == res2.pseudoHits) { return true; } else { System.out.println("FAIL: (" + guess + ", " + solution + "): " + res1.toString() + " | " + res2.toString()); return false; } } public static boolean testRandom() { String guess = randomString(); String solution = randomString(); return test(guess, solution); } public static boolean test(int count) { for (int i = 0; i < count; i++) { if (!testRandom()) { return true; } } return false; } public static void main(String[] args) { test(1000); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_16_Sub_Sort/Question.java ================================================ package Q16_16_Sub_Sort; public class Question { public static int findEndOfLeftSubsequence(int[] array) { for (int i = 1; i < array.length; i++) { if (array[i] < array[i - 1]) { return i - 1; } } return array.length - 1; } public static int findStartOfRightSubsequence(int[] array) { for (int i = array.length - 2; i >= 0; i--) { if (array[i] > array[i + 1]) { return i + 1; } } return 0; } public static int shrinkLeft(int[] array, int min_index, int start) { int comp = array[min_index]; for (int i = start - 1; i >= 0; i--) { if (array[i] <= comp) { return i + 1; } } return 0; } public static int shrinkRight(int[] array, int max_index, int start) { int comp = array[max_index]; for (int i = start; i < array.length; i++) { if (array[i] >= comp) { return i - 1; } } return array.length - 1; } public static Range findUnsortedSequence(int[] array) { // find left subsequence int end_left = findEndOfLeftSubsequence(array); if (end_left >= array.length - 1) { //System.out.println("The array is already sorted."); return new Range(0, 0); // Already sorted } // find right subsequence int start_right = findStartOfRightSubsequence(array); int max_index = end_left; // max of left side int min_index = start_right; // min of right side for (int i = end_left + 1; i < start_right; i++) { if (array[i] < array[min_index]) { min_index = i; } if (array[i] > array[max_index]) { max_index = i; } } // slide left until less than array[min_index] int left_index = shrinkLeft(array, min_index, end_left); // slide right until greater than array[max_index] int right_index = shrinkRight(array, max_index, start_right); return new Range(left_index, right_index); } /* Validate that sorting between these indices will sort the array. Note that this is not a complete * validation, as it does not check if these are the best possible indices. */ public static boolean validate(int[] array, int left_index, int right_index) { int[] middle = new int[right_index - left_index + 1]; for (int i = left_index; i <= right_index; i++) { middle[i - left_index] = array[i]; } java.util.Arrays.sort(middle); for (int i = left_index; i <= right_index; i++) { array[i] = middle[i - left_index]; } for (int i = 1; i < array.length; i++) { if (array[i-1] > array[i]) { return false; } } return true; } public static void main(String[] args) { int[] array = {1, 2, 4, 7, 10, 11, 8, 12, 5, 6, 16, 18, 19}; Range r = findUnsortedSequence(array); System.out.println(r.toString()); System.out.println(array[r.start] + ", " + array[r.end]); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_16_Sub_Sort/QuestionB.java ================================================ package Q16_16_Sub_Sort; public class QuestionB { public static int findRightSequenceStart(int[] array) { int max = Integer.MIN_VALUE; int lastNo = 0; for (int i = 0; i < array.length; i++) { if (max > array[i]) { lastNo = i; } max = Math.max(array[i], max); } return lastNo; } public static int findLeftSequenceEnd(int[] array) { int min = Integer.MAX_VALUE; int lastNo = 0; for (int i = array.length - 1; i >= 0; i--) { if (min < array[i]) { lastNo = i; } min = Math.min(array[i], min); } return lastNo; } public static Range findUnsortedSequence(int[] array) { int leftSequenceEnd = findRightSequenceStart(array); int rightSequenceEnd = findLeftSequenceEnd(array); return new Range(leftSequenceEnd, rightSequenceEnd); } public static void main(String[] args) { int[] array = {1, 2, 4, 7, 10, 11, 8, 12, 5, 6, 16, 18, 19}; Range r = findUnsortedSequence(array); System.out.println(r.toString()); System.out.println(array[r.start] + ", " + array[r.end]); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_16_Sub_Sort/Range.java ================================================ package Q16_16_Sub_Sort; public class Range { public int start, end; public Range(int start, int end) { this.start = start; this.end = end; } @Override public String toString() { return "Range [start=" + start + ", end=" + end + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + end; result = prime * result + start; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Range other = (Range) obj; if (end != other.end) return false; if (start != other.start) return false; return true; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_16_Sub_Sort/Tester.java ================================================ package Q16_16_Sub_Sort; import CtCILibrary.AssortedMethods; public class Tester { public static void main(String[] args) { for (int i = 0; i < 1000; i++) { int[] array = AssortedMethods.randomArray(7, 1, 3); Range r1 = Question.findUnsortedSequence(array); Range r2 = Question.findUnsortedSequence(array); if (r1 == null && r2 == null) { continue; } if (r1 == null || !r1.equals(r2)) { System.out.println("ERROR"); System.out.println(AssortedMethods.arrayToString(array)); System.out.println(r1 == null ? "null" : r1.toString()); System.out.println(r2 == null ? "null" : r2.toString()); } } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_17_Contiguous_Sequence/Question.java ================================================ package Q16_17_Contiguous_Sequence; public class Question { public static int getMaxSum(int[] a) { int maxSum = 0; int runningSum = 0; for (int i = 0; i < a.length; i++) { runningSum += a[i]; if (maxSum < runningSum) { maxSum = runningSum; } else if (runningSum < 0) { runningSum = 0; } } return maxSum; } public static void main(String[] args) { int[] a = {2, -8, 3, -2, 4, -10}; System.out.println(getMaxSum(a)); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_18_Pattern_Matcher/QuestionA.java ================================================ package Q16_18_Pattern_Matcher; public class QuestionA { public static boolean doesMatch(String pattern, String value) { if (pattern.length() == 0) return value.length() == 0; int size = value.length(); for (int mainSize = 0; mainSize <= size; mainSize++) { String main = value.substring(0, mainSize); for (int altStart = mainSize; altStart <= size; altStart++) { for (int altEnd = altStart; altEnd <= size; altEnd++) { String alt = value.substring(altStart, altEnd); String cand = buildFromPattern(pattern, main, alt); if (cand.equals(value)) { System.out.println(main + ", " + alt); return true; } } } } return false; } public static String buildFromPattern(String pattern, String main, String alt) { StringBuffer sb = new StringBuffer(); char first = pattern.charAt(0); for (char c : pattern.toCharArray()) { if (c == first) { sb.append(main); } else { sb.append(alt); } } return sb.toString(); } public static void main(String[] args) { String[][] tests = {{"ababb", "backbatbackbatbat"}, {"abab", "backsbatbackbats"}, {"aba", "backsbatbacksbat"}}; for (String[] test : tests) { String pattern = test[0]; String value = test[1]; System.out.println(pattern + ", " + value + ": " + doesMatch(pattern, value)); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_18_Pattern_Matcher/QuestionB.java ================================================ package Q16_18_Pattern_Matcher; public class QuestionB { public static String formStringFromPattern(String pattern, String first, String second) { if (pattern.length() == 0) return null; StringBuffer sb = new StringBuffer(); char firstChar = pattern.charAt(0); for (char c : pattern.toCharArray()) { if (c == firstChar) { sb.append(first); } else if (c != firstChar) { sb.append(second); } else { return null; } } return sb.toString(); } public static int countOf(String pattern, char ch) { int count = 0; for (char c : pattern.toCharArray()) { if (c == ch) { count++; } } return count; } public static String canonical(String pattern) { if (pattern.charAt(0) == 'a') return pattern; StringBuffer sb = new StringBuffer(); for (char c : pattern.toCharArray()) { if (c == 'a') { sb.append('b'); } else { sb.append('a'); } } return sb.toString(); } public static boolean doesMatch(String pattern, String value) { if (pattern.length() == 0) return value.length() == 0; pattern = canonical(pattern); int countOfAs = countOf(pattern, 'a'); int countOfBs = pattern.length() - countOfAs; int firstB = pattern.indexOf('b'); for (int aSize = 0; aSize <= value.length() / countOfAs; aSize++) { int remainingLength = value.length() - aSize * countOfAs; String first = value.substring(0, aSize); if (countOfBs == 0 || remainingLength % countOfBs == 0) { int bIndex = firstB * aSize; int bSize = countOfBs == 0 ? 0 : remainingLength / countOfBs; String second = countOfBs == 0 ? "" : value.substring(bIndex, bSize + bIndex); String candidate = formStringFromPattern(pattern, first, second); if (candidate.equals(value)) { System.out.println(first + ", " + second); return true; } } } return false; } public static void main(String[] args) { String[][] tests = {{"ababb", "backbatbackbatbat"}, {"abab", "backsbatbackbats"}, {"aba", "backsbatbacksbat"}}; for (String[] test : tests) { String pattern = test[0]; String value = test[1]; System.out.println(pattern + ", " + value + ": " + doesMatch(pattern, value)); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_18_Pattern_Matcher/QuestionC.java ================================================ package Q16_18_Pattern_Matcher; public class QuestionC { public static String buildFromPattern(String pattern, String main, String alt) { StringBuffer sb = new StringBuffer(); char first = pattern.charAt(0); for (char c : pattern.toCharArray()) { if (c == first) { sb.append(main); } else { sb.append(alt); } } return sb.toString(); } public static int countOf(String pattern, char c) { int count = 0; for (int i = 0; i < pattern.length(); i++) { if (pattern.charAt(i) == c) { count++; } } return count; } public static boolean doesMatch(String pattern, String value) { if (pattern.length() == 0) return value.length() == 0; char mainChar = pattern.charAt(0); char altChar = mainChar == 'a' ? 'b' : 'a'; int size = value.length(); int countOfMain = countOf(pattern, mainChar); int countOfAlt = pattern.length() - countOfMain; int firstAlt = pattern.indexOf(altChar); int maxMainSize = size / countOfMain; for (int mainSize = 0; mainSize <= maxMainSize; mainSize++) { int remainingLength = size - mainSize * countOfMain; String first = value.substring(0, mainSize); if (countOfAlt == 0 || remainingLength % countOfAlt == 0) { int altIndex = firstAlt * mainSize; int altSize = countOfAlt == 0 ? 0 : remainingLength / countOfAlt; String second = countOfAlt == 0 ? "" : value.substring(altIndex, altSize + altIndex); String candidate = buildFromPattern(pattern, first, second); if (candidate.equals(value)) { System.out.println(first + ", " + second); return true; } } } return false; } public static void main(String[] args) { String[][] tests = {{"ababb", "backbatbackbatbat"}, {"abab", "backsbatbackbats"}, {"aba", "backsbatbacksbat"}}; for (String[] test : tests) { String pattern = test[0]; String value = test[1]; System.out.println(pattern + ", " + value + ": " + doesMatch(pattern, value)); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_18_Pattern_Matcher/QuestionD.java ================================================ package Q16_18_Pattern_Matcher; public class QuestionD { public static boolean doesMatch(String pattern, String value) { if (pattern.length() == 0) return value.length() == 0; char mainChar = pattern.charAt(0); char altChar = mainChar == 'a' ? 'b' : 'a'; int size = value.length(); int countOfMain = countOf(pattern, mainChar); int countOfAlt = pattern.length() - countOfMain; int firstAlt = pattern.indexOf(altChar); int maxMainSize = size / countOfMain; for (int mainSize = 0; mainSize <= maxMainSize; mainSize++) { int remainingLength = size - mainSize * countOfMain; if (countOfAlt == 0 || remainingLength % countOfAlt == 0) { int altIndex = firstAlt * mainSize; int altSize = countOfAlt == 0 ? 0 : remainingLength / countOfAlt; if (matches(pattern, value, mainSize, altSize, altIndex)) { return true; } } } return false; } public static boolean matches(String pattern, String value, int mainSize, int altSize, int firstAlt) { int stringIndex = mainSize; for (int i = 1; i < pattern.length(); i++) { int size = pattern.charAt(i) == pattern.charAt(0) ? mainSize : altSize; int offset = pattern.charAt(i) == pattern.charAt(0) ? 0 : firstAlt; if (!isEqual(value, offset, stringIndex, size)) { return false; } stringIndex += size; } return true; } public static boolean isEqual(String s1, int offset1, int offset2, int size) { for (int i = 0; i < size; i++) { if (s1.charAt(offset1 + i) != s1.charAt(offset2 + i)) { return false; } } return true; } public static int countOf(String pattern, char c) { int count = 0; for (int i = 0; i < pattern.length(); i++) { if (pattern.charAt(i) == c) { count++; } } return count; } public static void main(String[] args) { String[][] tests = {{"ababb", "backbatbackbatbat"}, {"abab", "backsbatbackbats"}, {"aba", "backsbatbacksbat"}}; for (String[] test : tests) { String pattern = test[0]; String value = test[1]; System.out.println(pattern + ", " + value + ": " + doesMatch(pattern, value)); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_18_Pattern_Matcher/Tester.java ================================================ package Q16_18_Pattern_Matcher; public class Tester { public static String invert(String pattern) { String inverted = ""; for (char c : pattern.toCharArray()) { if (c == 'a') { inverted += 'b'; } else if (c == 'b') { inverted += 'a'; } } return inverted; } public static void main(String[] args) { String[][] tests = {{"ababb", "backbatbackbatbat"}, {"ababaa", "batgobatgobatbat"}, {"bb", "backback"}, {"ababb", "backbatbackbatbat"}, {"ababb", "backbatbackbatbackbat"}, {"abab", "backsbatbackbats"}, {"aba", "backsbatbacksbat"}}; for (String[] test : tests) { for (int i = 0; i <= 1; i++) { String pattern = i == 0 ? test[0] : invert(test[0]); String value = test[1]; boolean aMatches = QuestionA.doesMatch(pattern, value); boolean bMatches = QuestionB.doesMatch(pattern, value); boolean cMatches = QuestionC.doesMatch(pattern, value); boolean dMatches = QuestionD.doesMatch(pattern, value); if (aMatches != bMatches || aMatches != cMatches || aMatches != dMatches) { System.out.println("ERROR"); } System.out.println(pattern + ", " + value + ": " + aMatches); System.out.println(pattern + ", " + value + ": " + bMatches); System.out.println(pattern + ", " + value + ": " + cMatches); System.out.println(pattern + ", " + value + ": " + dMatches); } } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_19_Pond_Sizes/QuestionA.java ================================================ package Q16_19_Pond_Sizes; import java.util.ArrayList; public class QuestionA { public static ArrayList computePondSizes(int[][] land) { ArrayList pondSizes = new ArrayList(); for (int r = 0; r < land.length; r++) { for (int c = 0; c < land[r].length; c++) { if (land[r][c] == 0) { int size = computeSize(land, r, c); pondSizes.add(size); } } } return pondSizes; } public static int computeSize(int[][] land, int row, int col) { /* If out of bounds or already visited. */ if (row < 0 || col < 0 || row >= land.length || col >= land[row].length || land[row][col] != 0) { return 0; } int size = 1; land[row][col] = -1; for (int dr = -1; dr <= 1; dr++) { for (int dc = -1; dc <= 1; dc++) { size += computeSize(land, row + dr, col + dc); } } return size; } public static void main(String[] args) { int[][] land = {{0, 2, 1, 0}, {0, 1, 0, 1}, {1, 1, 0, 1}, {0, 1, 0, 1}}; ArrayList sizes = computePondSizes(land); for (int sz : sizes) { System.out.println(sz); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_19_Pond_Sizes/QuestionB.java ================================================ package Q16_19_Pond_Sizes; import java.util.ArrayList; public class QuestionB { public static ArrayList computePondSizes(int[][] land) { boolean[][] visited = new boolean[land.length][land[0].length]; ArrayList pondSizes = new ArrayList(); for (int r = 0; r < land.length; r++) { for (int c = 0; c < land[r].length; c++) { int size = computeSize(land, visited, r, c); if (size > 0) { pondSizes.add(size); } } } return pondSizes; } public static int computeSize(int[][] land, boolean[][] visited, int row, int col) { /* If out of bounds or already visited. */ if (row < 0 || col < 0 || row >= land.length || col >= land[row].length || visited[row][col] || land[row][col] != 0) { return 0; } int size = 1; visited[row][col] = true; for (int dr = -1; dr <= 1; dr++) { for (int dc = -1; dc <= 1; dc++) { size += computeSize(land, visited, row + dr, col + dc); } } return size; } public static void main(String[] args) { int[][] land = {{0, 2, 1, 0}, {0, 1, 0, 1}, {1, 1, 0, 1}, {0, 1, 0, 1}}; ArrayList sizes = computePondSizes(land); for (int sz : sizes) { System.out.println(sz); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_20_T9/QuestionA.java ================================================ package Q16_20_T9; import java.util.ArrayList; import java.util.HashSet; import CtCILibrary.AssortedMethods; import CtCILibrary.TrieNode; public class QuestionA { public static char[][] t9Letters = { null, // 0 null, // 1 {'a', 'b', 'c'}, // 2 {'d', 'e', 'f'}, // 3 {'g', 'h', 'i'}, // 4 {'j', 'k', 'l'}, // 5 {'m', 'n', 'o'}, // 6 {'p', 'q', 'r', 's'}, // 7 {'t', 'u', 'v'}, // 8 {'w', 'x', 'y', 'z'} // 9 }; public static char[] getT9Chars(char digit) { if (!Character.isDigit(digit)) { return null; } int dig = Character.getNumericValue(digit) - Character.getNumericValue('0'); return t9Letters[dig]; } public static void getValidWords(String number, int index, String prefix, HashSet wordSet, ArrayList results) { /* If it's a complete word, print it. */ if (index == number.length() ) { if (wordSet.contains(prefix)) { results.add(prefix); } return; } /* Get characters that match this digit */ char digit = number.charAt(index); char[] letters = getT9Chars(digit); /* Go through all remaining options. */ if (letters != null) { for (char letter : letters) { getValidWords(number, index + 1, prefix + letter, wordSet, results); } } } public static ArrayList getValidT9Words(String number, HashSet wordList) { ArrayList results = new ArrayList(); getValidWords(number, 0, "", wordList, results); return results; } public static void main(String[] args) { ArrayList words = getValidT9Words("33835676368", AssortedMethods.getWordListAsHashSet()); for (String w: words) { System.out.println(w); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_20_T9/QuestionB.java ================================================ package Q16_20_T9; import java.util.ArrayList; import java.util.HashSet; import CtCILibrary.AssortedMethods; import CtCILibrary.Trie; import CtCILibrary.TrieNode; public class QuestionB { public static char[][] t9Letters = { null, // 0 null, // 1 {'a', 'b', 'c'}, // 2 {'d', 'e', 'f'}, // 3 {'g', 'h', 'i'}, // 4 {'j', 'k', 'l'}, // 5 {'m', 'n', 'o'}, // 6 {'p', 'q', 'r', 's'}, // 7 {'t', 'u', 'v'}, // 8 {'w', 'x', 'y', 'z'} // 9 }; public static char[] getT9Chars(char digit) { if (!Character.isDigit(digit)) { return null; } int dig = Character.getNumericValue(digit) - Character.getNumericValue('0'); return t9Letters[dig]; } public static void getValidWords(String number, int index, String prefix, TrieNode trieNode, ArrayList results) { /* If it's a complete word, print it. */ if (index == number.length()) { if (trieNode.terminates()) { // Is complete word results.add(prefix); } return; } /* Get characters that match this digit */ char digit = number.charAt(index); char[] letters = getT9Chars(digit); /* Go through all remaining options. */ if (letters != null) { for (char letter : letters) { TrieNode child = trieNode.getChild(letter); if (child != null) { /* If there are words that start with prefix + letter, continue */ getValidWords(number, index + 1, prefix + letter, child, results); } } } } public static ArrayList getValidT9Words(String number, Trie trie) { ArrayList results = new ArrayList(); getValidWords(number, 0, "", trie.getRoot(), results); return results; } public static void main(String[] args) { ArrayList words = getValidT9Words("8733", AssortedMethods.getTrieDictionary()); for (String w: words) { System.out.println(w); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_20_T9/QuestionC.java ================================================ package Q16_20_T9; import java.util.ArrayList; import java.util.HashMap; import CtCILibrary.AssortedMethods; import CtCILibrary.HashMapList; public class QuestionC { public static int numLetters = 26; public static char[][] t9Letters = { null, // 0 null, // 1 {'a', 'b', 'c'}, // 2 {'d', 'e', 'f'}, // 3 {'g', 'h', 'i'}, // 4 {'j', 'k', 'l'}, // 5 {'m', 'n', 'o'}, // 6 {'p', 'q', 'r', 's'}, // 7 {'t', 'u', 'v'}, // 8 {'w', 'x', 'y', 'z'} // 9 }; /* Convert from a string to its T9 representation. */ public static String convertToT9(String word, HashMap letterToNumberMap) { StringBuilder sb = new StringBuilder(); for (char c : word.toCharArray()) { if (letterToNumberMap.containsKey(c)) { char digit = letterToNumberMap.get(c); sb.append(digit); } } return sb.toString(); } /* Convert mapping of number->letters into letter->number */ public static HashMap createLetterToNumberMap() { HashMap letterToNumberMap = new HashMap(); for (int i = 0; i < t9Letters.length; i++) { char[] letters = t9Letters[i]; if (letters != null) { for (char letter : letters) { char c = Character.forDigit(i, 10); letterToNumberMap.put(letter, c); } } } return letterToNumberMap; } /* Create a hash table that maps from a number to all words that * have this numerical representation. */ public static HashMapList initializeDictionary(String[] words) { /* Create hash table that maps from a letter to the digit */ HashMap letterToNumberMap = createLetterToNumberMap(); /* Create word -> number map */ HashMapList wordsToNumbers = new HashMapList(); for (String word : words) { String numbers = convertToT9(word, letterToNumberMap); wordsToNumbers.put(numbers, word); } return wordsToNumbers; } public static ArrayList getValidT9Words(String numbers, HashMapList dictionary) { return dictionary.get(numbers); } public static void main(String[] args) { HashMapList dictionary = initializeDictionary(AssortedMethods.getListOfWords()); ArrayList words = getValidT9Words("8733", dictionary); for (String w: words) { System.out.println(w); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_21_Sum_Swap/QuestionA.java ================================================ package Q16_21_Sum_Swap; public class QuestionA { public static int sum(int[] array) { int s = 0; for (int a : array) { s += a; } return s; } public static int[] findSwapValues(int[] array1, int[] array2) { int sum1 = sum(array1); int sum2 = sum(array2); for (int one : array1) { for (int two : array2) { int newSum1 = sum1 - one + two; int newSum2 = sum2 - two + one; if (newSum1 == newSum2) { int[] values = {one, two}; return values; } } } return null; } public static void main(String[] args) { int[] array1 = {1, 1, 1, 2, 2, 4}; int[] array2 = {3, 3, 3, 6}; int[] swaps = findSwapValues(array1, array2); if (swaps == null) { System.out.println("null"); } else { System.out.println(swaps[0] + " " + swaps[1]); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_21_Sum_Swap/QuestionB.java ================================================ package Q16_21_Sum_Swap; public class QuestionB { public static int[] findSwapValues(int[] array1, int[] array2) { Integer target = getTarget(array1, array2); if (target == null) return null; for (int one : array1) { for (int two : array2) { if (one - two == target) { int[] values = {one, two}; return values; } } } return null; } public static Integer getTarget(int[] array1, int[] array2) { int sum1 = sum(array1); int sum2 = sum(array2); if ((sum1 - sum2) % 2 != 0) return null; return (sum1 - sum2) / 2; } public static int sum(int[] array) { int s = 0; for (int a : array) { s += a; } return s; } public static void main(String[] args) { int[] array1 = {1, 1, 1, 2, 2, 4}; int[] array2 = {3, 3, 3, 6}; int[] swaps = findSwapValues(array1, array2); if (swaps == null) { System.out.println("null"); } else { System.out.println(swaps[0] + " " + swaps[1]); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_21_Sum_Swap/QuestionC.java ================================================ package Q16_21_Sum_Swap; import java.util.HashSet; public class QuestionC { public static int sum(int[] array) { int s = 0; for (int a : array) { s += a; } return s; } public static int[] findSwapValues(int[] array1, int[] array2) { Integer target = getTarget(array1, array2); if (target == null) return null; return findDifference(array1, array2, target); } public static int[] findDifference(int[] array1, int[] array2, int target) { HashSet contents2 = getContents(array2); for (int one : array1) { int two = one - target; if (contents2.contains(two)) { int[] values = {one, two}; return values; } } return null; } public static Integer getTarget(int[] array1, int[] array2) { int sum1 = sum(array1); int sum2 = sum(array2); if ((sum1 - sum2) % 2 != 0) return null; return (sum1 - sum2) / 2; } public static HashSet getContents(int[] array) { HashSet set = new HashSet(); for (int a : array) { set.add(a); } return set; } public static void main(String[] args) { int[] array1 = {-9, -1, -4, 8, 9, 6, -5, -7, 3, 9}; int[] array2 = {6, 6, 4, -1, 7, -6, -9, 4, -8, 8}; int[] swaps = findSwapValues(array1, array2); if (swaps == null) { System.out.println("null"); } else { System.out.println(swaps[0] + " " + swaps[1]); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_21_Sum_Swap/QuestionD.java ================================================ package Q16_21_Sum_Swap; import java.util.Arrays; import java.util.HashSet; public class QuestionD { public static int sum(int[] array) { int s = 0; for (int a : array) { s += a; } return s; } public static Integer getTarget(int[] array1, int[] array2) { int sum1 = sum(array1); int sum2 = sum(array2); if ((sum1 - sum2) % 2 != 0) return null; return (sum1 - sum2) / 2; } public static int[] findSwapValues(int[] array1, int[] array2) { Integer target = getTarget(array1, array2); if (target == null) return null; return findDifference(array1, array2, target); } public static int[] findDifference(int[] array1, int[] array2, int target) { Arrays.sort(array1); Arrays.sort(array2); int a = 0; int b = 0; while (a < array1.length && b < array2.length) { int difference = array1[a] - array2[b]; /* Compare difference to target. If difference is too small, then * make it bigger by moving a to a bigger value. If it is too big, * then make it smaller by moving b to a bigger value. If it's * just right, return this pair. */ if (difference == target) { int[] values = {array1[a], array2[b]}; return values; } else if (difference < target) { a++; } else { b++; } } return null; } public static void main(String[] args) { int[] array1 = {1, 1, 1, 2, 2, 4}; int[] array2 = {3, 3, 3, 6}; int[] swaps = findSwapValues(array1, array2); if (swaps == null) { System.out.println("null"); } else { System.out.println(swaps[0] + " " + swaps[1]); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_21_Sum_Swap/Tester.java ================================================ package Q16_21_Sum_Swap; import CtCILibrary.AssortedMethods; public class Tester { public static boolean isEquivalent(int[] a, int[] b, int[] c, int[] d) { if (a == null || b == null || c == null || d == null) { return a == null && b == null && c == null && d == null; } return difference(a) == difference(b) && difference(a) == difference(c) && difference(a) == difference(d); } public static int difference(int[] a) { if (a.length != 2) { return -1; } return a[0] - a[1]; } public static String arrayToString(int[] array) { StringBuffer sb = new StringBuffer(); for (int a : array) { sb.append(a + " "); } return sb.toString(); } public static void main(String[] args) { int count = 0; int max = 100; while (count < max) { int[] array1 = AssortedMethods.randomArray(10, -10, 10); int[] array2 = AssortedMethods.randomArray(10, -10, 10);; int[] swapsA = QuestionA.findSwapValues(array1, array2); int[] swapsB = QuestionB.findSwapValues(array1, array2); int[] swapsC = QuestionC.findSwapValues(array1, array2); int[] swapsD = QuestionD.findSwapValues(array1, array2); if (swapsA != null || swapsB != null || swapsC != null || swapsD != null) { count++; } if (!isEquivalent(swapsA, swapsB, swapsC, swapsD)) { System.out.println("Error"); System.out.println(AssortedMethods.arrayToString(array1)); System.out.println(AssortedMethods.arrayToString(array2)); System.out.println(AssortedMethods.arrayToString(swapsA)); System.out.println(AssortedMethods.arrayToString(swapsB)); System.out.println(AssortedMethods.arrayToString(swapsC)); System.out.println(AssortedMethods.arrayToString(swapsD)); break; } else { System.out.println("Equivalent."); System.out.println(AssortedMethods.arrayToString(array1)); System.out.println(AssortedMethods.arrayToString(array2)); System.out.println(AssortedMethods.arrayToString(swapsA)); System.out.println(AssortedMethods.arrayToString(swapsB)); System.out.println(AssortedMethods.arrayToString(swapsC)); System.out.println(AssortedMethods.arrayToString(swapsD)); System.out.println("\n"); } } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_22_Langtons_Ant/Ant.java ================================================ package Q16_22_Langtons_Ant; public class Ant { public Position position = new Position(0, 0); public Orientation orientation = Orientation.right; public void turn(boolean clockwise) { orientation = orientation.getTurn(clockwise); } public void move() { if (orientation == Orientation.left) { position.column--; } else if (orientation == Orientation.right) { position.column++; } else if (orientation == Orientation.up) { position.row--; } else if (orientation == Orientation.down) { position.row++; } } public void adjustPosition(int shiftRow, int shiftColumn) { position.row += shiftRow; position.column += shiftColumn; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_22_Langtons_Ant/Board.java ================================================ package Q16_22_Langtons_Ant; import java.util.HashSet; public class Board { private HashSet blackCells = new HashSet(); private Ant ant = new Ant(); private Position topLeftCorner = new Position(0, 0); private Position bottomRightCorner = new Position(0, 0); public Board() { } /* Move ant. */ public void move() { ant.turn(!isBlack(ant.position)); // Turn clockwise on white, counter on black flip(ant.position); // flip ant.move(); // move ensureFit(ant.position); } /* Flip color of cells. */ private void flip(Position position) { if (blackCells.contains(position)) { blackCells.remove(position); } else { blackCells.add(position.clone()); } } /* "Grow" the grid by tracking the most top-left and * bottom-right position that we've seen. */ private void ensureFit(Position position) { int row = position.row; int column = position.column; topLeftCorner.row = Math.min(topLeftCorner.row, row); topLeftCorner.column = Math.min(topLeftCorner.column, column); bottomRightCorner.row = Math.max(bottomRightCorner.row, row); bottomRightCorner.column = Math.max(bottomRightCorner.column, column); } /* Check if cell is white. */ public boolean isBlack(Position p) { return blackCells.contains(p); } /* Check if cell is white. */ public boolean isBlack(int row, int column) { return blackCells.contains(new Position(row, column)); } /* Print board. */ public String toString() { StringBuilder sb = new StringBuilder(); int rowMin = topLeftCorner.row; int rowMax = bottomRightCorner.row; int colMin = topLeftCorner.column; int colMax = bottomRightCorner.column; for (int r = rowMin; r <= rowMax; r++) { for (int c = colMin; c <= colMax; c++) { if (r == ant.position.row && c == ant.position.column) { sb.append(ant.orientation); } else if (isBlack(r, c)) { sb.append("X"); } else { sb.append("_"); } } sb.append("\n"); } sb.append("Ant: " + ant.orientation + ". \n"); return sb.toString(); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_22_Langtons_Ant/Grid.java ================================================ package Q16_22_Langtons_Ant; public class Grid { private boolean[][] grid; // false is white, true is black private Ant ant = new Ant(); public Grid() { grid = new boolean[1][1]; } /* Copy old values into new array, with an offset/shift applied to the row and columns. */ private void copyWithShift(boolean[][] oldGrid, boolean[][] newGrid, int shiftRow, int shiftColumn) { for (int r = 0; r < oldGrid.length; r++) { for (int c = 0; c < oldGrid[0].length; c++) { newGrid[r + shiftRow][c + shiftColumn] = oldGrid[r][c]; } } } /* Ensure that the given position will fit on the array. If * necessary, double the size of the matrix, copy the old values * over, and adjust the ant's position so that it's in a positive * ranges. */ private void ensureFit(Position position) { int shiftRow = 0; int shiftColumn = 0; /* Calculate new number of rows. */ int numRows = grid.length; if (position.row < 0) { shiftRow = numRows; numRows *= 2; } else if (position.row >= numRows) { numRows *= 2; } /* Calculate new number of columns. */ int numColumns = grid[0].length; if (position.column < 0) { shiftColumn = numColumns; numColumns *= 2; } else if (position.column >= numColumns) { numColumns *= 2; } /* Grow array, if necessary. Shift ant's position too. */ if (numRows != grid.length || numColumns != grid[0].length) { boolean[][] newGrid = new boolean[numRows][numColumns]; copyWithShift(grid, newGrid, shiftRow, shiftColumn); ant.adjustPosition(shiftRow, shiftColumn); grid = newGrid; } } /* Flip color of cells. */ private void flip(Position position) { int row = position.row; int column = position.column; grid[row][column] = grid[row][column] ? false : true; } /* Move ant. */ public void move() { ant.turn(!grid[ant.position.row][ant.position.column]); // Turn clockwise on white, counterclockwise on black flip(ant.position); // flip ant.move(); // move ensureFit(ant.position); // grow } /* Print board. The first loop of this is a "compression" which only prints the active parts of the board. The active * board is the smallest rectangle that contains all the black cells and the ant. This is fairly optional. Nice to do * but also not essential. * FULL BOARD: ACTIVE BOARD: * _____ _X * ___X_ XX * __XX_ X * ___X_ * _____ * _____*/ public String toString() { int firstActiveRow = grid.length; int firstActiveColumn = grid[0].length; int lastActiveRow = 0; int lastActiveColumn = 0; for (int r = 0; r < grid.length; r++) { for (int c = 0; c < grid[r].length; c++) { if (grid[r][c] || (ant.position.row == r && ant.position.column == c)) { // If there's something there firstActiveRow = Math.min(firstActiveRow, r); firstActiveColumn = Math.min(firstActiveColumn, c); lastActiveRow = Math.max(lastActiveRow, r); lastActiveColumn = Math.max(lastActiveColumn, c); } } } StringBuilder sb = new StringBuilder(); for (int r = firstActiveRow; r <= lastActiveRow; r++) { for (int c = firstActiveColumn; c <= lastActiveColumn; c++) { if (r == ant.position.row && c == ant.position.column) { sb.append(ant.orientation); } else if (grid[r][c]) { sb.append("X"); } else { sb.append("_"); } } sb.append("\n"); } sb.append("Ant: " + ant.orientation + ". \n"); return sb.toString(); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_22_Langtons_Ant/Orientation.java ================================================ package Q16_22_Langtons_Ant; public enum Orientation { left, up, right, down; public Orientation getTurn(boolean clockwise) { if (this == left) { return clockwise ? up : down; } else if (this == up) { return clockwise ? right : left; } else if (this == right) { return clockwise ? down : up; } else { // down return clockwise ? left : right; } } @Override public String toString() { if (this == left) { return "\u2190"; } else if (this == up) { return "\u2191"; } else if (this == right) { return "\u2192"; } else { // down return "\u2193"; } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_22_Langtons_Ant/Position.java ================================================ package Q16_22_Langtons_Ant; public class Position { public int row; public int column; public Position(int row, int column) { this.row = row; this.column = column; } @Override public boolean equals(Object o) { if (o instanceof Position) { Position p = (Position) o; return p.row == row && p.column == column; } return false; } @Override public int hashCode() { return (row * 31) ^ column; } public Position clone() { return new Position(row, column); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_22_Langtons_Ant/Question.java ================================================ package Q16_22_Langtons_Ant; public class Question { public static void main(String[] args) { Board board = new Board(); Grid grid = new Grid(); System.out.println(board.toString()); for (int i = 0; i < 100; i++) { System.out.println("\n\n---- MOVE " + i + " ----"); board.move(); String bs = board.toString(); System.out.println(bs); grid.move(); String gs = grid.toString(); System.out.println(gs); boolean equals = bs.equals(gs); System.out.println(equals); if (!equals) { break; } } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_23_Rand7_From_Rand5/Question.java ================================================ package Q16_23_Rand7_From_Rand5; public class Question { public static int rand7() { while (true) { int num = 5 * rand5() + rand5(); if (num < 21) { return num % 7; } } } public static int rand5() { return (int) (Math.random() * 100) % 5; } public static void main(String[] args) { /* Test: call rand7 many times and inspect the results. */ int[] arr = new int[7]; int test_size = 1000000; for(int k = 0; k < test_size; k++){ arr[rand7()]++; } for (int i = 0; i < 7; i++) { double percent = 100.0 * arr[i] / test_size; System.out.println(i + " appeared " + percent + "% of the time."); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_23_Rand7_From_Rand5/QuestionB.java ================================================ package Q16_23_Rand7_From_Rand5; public class QuestionB { public static int rand7() { while (true) { int r1 = 2 * rand5(); /* evens between 0 and 9 */ int r2 = rand5(); /* will be later used to generate a 0 or 1 */ if (r2 != 4) { /* r2 has an extra even number, so discard the extra */ int rand1 = r2 % 2; /* Generate 0 or 1 */ int num = r1 + rand1; /* will be in the range 0 through 9 */ if (num < 7) { return num; } } } } public static int rand5() { return (int) (Math.random() * 100) % 5; } public static void main(String[] args) { /* Test: call rand7 many times and inspect the results. */ int[] arr = new int[7]; int test_size = 1000000; for(int k = 0; k < test_size; k++){ arr[rand7()]++; } for (int i = 0; i < 7; i++) { double percent = 100.0 * arr[i] / test_size; System.out.println(i + " appeared " + percent + "% of the time."); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_24_Pairs_With_Sum/Pair.java ================================================ package Q16_24_Pairs_With_Sum; public class Pair { public int first; public int second; public Pair(int first, int second) { this.first = first; this.second = second; } @Override public String toString() { return "(" + first + ", " + second + ")"; } } ================================================ FILE: Java/Ch 16. Moderate/Q16_24_Pairs_With_Sum/QuestionA.java ================================================ package Q16_24_Pairs_With_Sum; import java.util.ArrayList; public class QuestionA { public static ArrayList printPairSums(int[] array, int sum) { ArrayList result = new ArrayList(); for (int i = 0 ; i < array.length; i++) { for (int j = i + 1; j < array.length; j++) { if (array[i] + array[j] == sum) { result.add(new Pair(array[i], array[j])); } } } return result; } public static void main(String[] args) { int[] test = {9, 3, 6, 5, 5, 7, -1, 13, 14, -2, 12, 0}; ArrayList pairs = printPairSums(test, 12); for (Pair p : pairs) { System.out.println(p.toString()); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_24_Pairs_With_Sum/QuestionB.java ================================================ package Q16_24_Pairs_With_Sum; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; public class QuestionB { public static ArrayList printPairSums(int[] array, int sum) { ArrayList result = new ArrayList(); HashMap unpairedCount = new HashMap(); for (int x : array) { int complement = sum - x; if (unpairedCount.getOrDefault(complement, 0) > 0) { result.add(new Pair(x, complement)); adjustCounterBy(unpairedCount, complement, -1); // decrement complement } else { adjustCounterBy(unpairedCount, x, 1); // increment x } } return result; } public static void adjustCounterBy(HashMap counter, int key, int delta) { counter.put(key, counter.getOrDefault(key, 0) + delta); } public static void main(String[] args) { int[] test = {-1, -1, -1, -1, 0, 0, 0, 0, 1, 1}; ArrayList pairs = printPairSums(test, -1); for (Pair p : pairs) { System.out.println(p.toString()); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_24_Pairs_With_Sum/QuestionC.java ================================================ package Q16_24_Pairs_With_Sum; import java.util.ArrayList; import java.util.Arrays; public class QuestionC { public static ArrayList printPairSums(int[] array, int sum) { ArrayList result = new ArrayList(); Arrays.sort(array); int first = 0; int last = array.length - 1; while (first < last) { int s = array[first] + array[last]; if (s == sum) { result.add(new Pair(array[first], array[last])); ++first; --last; } else { if (s < sum) { ++first; } else { --last; } } } return result; } public static void main(String[] args) { int[] test = {9, 3, 6, 5, 7, 7, -1, 13, 14, -2, 12, 0}; ArrayList pairs = printPairSums(test, 12); for (Pair p : pairs) { System.out.println(p.toString()); } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_24_Pairs_With_Sum/Tester.java ================================================ package Q16_24_Pairs_With_Sum; import java.util.ArrayList; import CtCILibrary.AssortedMethods; public class Tester { public static void print(ArrayList pairs) { for (Pair p : pairs) { System.out.print(p.toString() + ", "); } System.out.println(); } public static void main(String[] args) { int[] array = {9, 3, 6, 5, 7, 7, -1, 13, 14, -2, 12, 0}; int sum = 12; ArrayList pairsA = QuestionA.printPairSums(array, sum); ArrayList pairsB = QuestionB.printPairSums(array, sum); ArrayList pairsC = QuestionC.printPairSums(array, sum); System.out.println(AssortedMethods.arrayToString(array)); System.out.println("sum: " + sum); print(pairsA); print(pairsB); print(pairsC); System.out.println(); System.out.println(); System.out.println(); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_25_LRU_Cache/Cache.java ================================================ package Q16_25_LRU_Cache; import java.util.HashMap; public class Cache { private int maxCacheSize; private HashMap map = new HashMap(); private LinkedListNode listHead = null; public LinkedListNode listTail = null; public Cache(int maxSize) { maxCacheSize = maxSize; } /* Get value for key and mark as most recently used. */ public String getValue(int key) { LinkedListNode item = map.get(key); if (item == null) { return null; } /* Move to front of list to mark as most recently used. */ if (item != listHead) { removeFromLinkedList(item); insertAtFrontOfLinkedList(item); } return item.value; } /* Remove node from linked list. */ private void removeFromLinkedList(LinkedListNode node) { if (node == null) { return; } if (node.prev != null) { node.prev.next = node.next; } if (node.next != null) { node.next.prev = node.prev; } if (node == listTail) { listTail = node.prev; } if (node == listHead) { listHead = node.next; } } /* Insert node at front of linked list. */ private void insertAtFrontOfLinkedList(LinkedListNode node) { if (listHead == null) { listHead = node; listTail = node; } else { listHead.prev = node; node.next = listHead; listHead = node; listHead.prev = null; } } /* Remove key, value pair from cache, deleting from hash table * and linked list. */ public boolean removeKey(int key) { LinkedListNode node = map.get(key); removeFromLinkedList(node); map.remove(key); return true; } /* Put key, value pair in cache. Removes old value for key if * necessary. Inserts pair into linked list and hash table.*/ public void setKeyValue(int key, String value) { /* Remove if already there. */ removeKey(key); /* If full, remove least recently used item from cache. */ if (map.size() >= maxCacheSize && listTail != null) { removeKey(listTail.key); } /* Insert new node. */ LinkedListNode node = new LinkedListNode(key, value); insertAtFrontOfLinkedList(node); map.put(key, node); } public String getCacheAsString() { if (listHead == null) return ""; return listHead.printForward(); } private class LinkedListNode { private LinkedListNode next; private LinkedListNode prev; public int key; public String value; public LinkedListNode(int k, String v) { key = k; value = v; } public String printForward() { String data = "(" + key + "," + value + ")"; if (next != null) { return data + "->" + next.printForward(); } else { return data; } } } } ================================================ FILE: Java/Ch 16. Moderate/Q16_25_LRU_Cache/Question.java ================================================ package Q16_25_LRU_Cache; public class Question { /** * @param args */ public static void main(String[] args) { int cache_size = 5; Cache cache = new Cache(cache_size); cache.setKeyValue(1, "1"); System.out.println(cache.getCacheAsString()); cache.setKeyValue(2, "2"); System.out.println(cache.getCacheAsString()); cache.setKeyValue(3, "3"); System.out.println(cache.getCacheAsString()); cache.getValue(1); System.out.println(cache.getCacheAsString()); cache.setKeyValue(4, "4"); System.out.println(cache.getCacheAsString()); cache.getValue(2); System.out.println(cache.getCacheAsString()); cache.setKeyValue(5, "5"); System.out.println(cache.getCacheAsString()); cache.getValue(5); System.out.println(cache.getCacheAsString()); cache.setKeyValue(6, "6"); System.out.println(cache.getCacheAsString()); cache.getValue(1); System.out.println(cache.getCacheAsString()); cache.setKeyValue(5, "5a"); System.out.println(cache.getCacheAsString()); cache.getValue(3); System.out.println(cache.getCacheAsString()); // 6->5->2->4->1 } } ================================================ FILE: Java/Ch 16. Moderate/Q16_26_Calculator/Operator.java ================================================ package Q16_26_Calculator; public enum Operator { ADD, SUBTRACT, MULTIPLY, DIVIDE, BLANK } ================================================ FILE: Java/Ch 16. Moderate/Q16_26_Calculator/QuestionA.java ================================================ package Q16_26_Calculator; import java.util.ArrayList; public class QuestionA { public static Term collapseTerm(Term primary, Term secondary) { if (primary == null) return secondary; if (secondary == null) return primary; double value = applyOp(primary.getNumber(), secondary.getOperator(), secondary.getNumber()); primary.setNumber(value); return primary; } public static double applyOp(double left, Operator op, double right) { if (op == Operator.ADD) { return left + right; } else if (op == Operator.SUBTRACT) { return left - right; } else if (op == Operator.MULTIPLY) { return left * right; } else if (op == Operator.DIVIDE) { return left / right; } else { return right; } } /* Compute the result of the arithmetic sequence. This works by reading left to right and applying each term to a result. When we see a multiplication or division, we instead apply this sequence to a temporary variable. */ public static double compute(String sequence) { ArrayList terms = Term.parseTermSequence(sequence); if (terms == null) return Integer.MIN_VALUE; double result = 0; Term processing = null; for (int i = 0; i < terms.size(); i++) { Term current = terms.get(i); Term next = i + 1 < terms.size() ? terms.get(i + 1) : null; /* Apply the current term to “processing”. */ processing = collapseTerm(processing, current); /* If next term is + or -, then this cluster is done * and we should apply “processing” to “result”. */ if (next == null || next.getOperator() == Operator.ADD || next.getOperator() == Operator.SUBTRACT) { result = applyOp(result, processing.getOperator(), processing.getNumber()); processing = null; } } return result; } public static void main(String[] args) { String expression = "6/5*3+4*5/2-12/6*3/3+3+3"; double result = compute(expression); System.out.println(result); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_26_Calculator/QuestionB.java ================================================ package Q16_26_Calculator; import java.util.Stack; public class QuestionB { public enum Operator { ADD, SUBTRACT, MULTIPLY, DIVIDE, BLANK } /* Return the operator that occurs as offset. */ public static Operator parseNextOperator(String sequence, int offset) { if (offset < sequence.length()) { char op = sequence.charAt(offset); switch(op) { case '+': return Operator.ADD; case '-': return Operator.SUBTRACT; case '*': return Operator.MULTIPLY; case '/': return Operator.DIVIDE; } } return Operator.BLANK; } /* Return the number that starts at offset. */ public static int parseNextNumber(String seq, int offset) { StringBuilder sb = new StringBuilder(); while (offset < seq.length() && Character.isDigit(seq.charAt(offset))) { sb.append(seq.charAt(offset)); offset++; } return Integer.parseInt(sb.toString()); } /* Apply operator: left [op] right. */ public static double applyOp(double left, Operator op, double right) { if (op == Operator.ADD) { return left + right; } else if (op == Operator.SUBTRACT) { return left - right; } else if (op == Operator.MULTIPLY) { return left * right; } else if (op == Operator.DIVIDE) { return left / right; } else { return right; } } /* Return priority of operator. Mapped so that: * addition == subtraction < multiplication == division. */ public static int priorityOfOperator(Operator op) { switch (op) { case ADD: return 1; case SUBTRACT: return 1; case MULTIPLY: return 2; case DIVIDE: return 2; case BLANK: return 0; } return 0; } /* Collapse top until priority(futureTop) > priority(top). * Collapsing means to pop the top 2 numbers and apply the * operator popped from the top of the operator stack, and then * push that onto the numbers stack.*/ public static void collapseTop(Operator futureTop, Stack numberStack, Stack operatorStack) { while (operatorStack.size() >= 1 && numberStack.size() >= 2) { if (priorityOfOperator(futureTop) <= priorityOfOperator(operatorStack.peek())) { double second = numberStack.pop(); double first = numberStack.pop(); Operator op = operatorStack.pop(); double collapsed = applyOp(first, op, second); numberStack.push(collapsed); } else { break; } } } public static double compute(String sequence) { Stack numberStack = new Stack(); Stack operatorStack = new Stack(); for (int i = 0; i < sequence.length(); i++) { try { /* Get number and push. */ int value = parseNextNumber(sequence, i); numberStack.push((double) value); /* Move to the operator. */ i += Integer.toString(value).length(); if (i >= sequence.length()) { break; } /* Get operator, collapse top as needed, push operator. */ Operator op = parseNextOperator(sequence, i); collapseTop(op, numberStack, operatorStack); operatorStack.push(op); } catch (NumberFormatException ex) { return Integer.MIN_VALUE; } } /* Do final collapse. */ collapseTop(Operator.BLANK, numberStack, operatorStack); if (numberStack.size() == 1 && operatorStack.size() == 0) { return numberStack.pop(); } return 0; } public static void main(String[] args) { String expression = "6/5*3+4*5/2-12/6*3/3+3+3"; double result = compute(expression); System.out.println(result); } } ================================================ FILE: Java/Ch 16. Moderate/Q16_26_Calculator/Term.java ================================================ package Q16_26_Calculator; import java.util.ArrayList; public class Term { private double value; private Operator operator = Operator.BLANK; public Term(double v, Operator op) { value = v; operator = op; } public double getNumber() { return value; } public Operator getOperator() { return operator; } public void setNumber(double v) { value = v; } public static ArrayList parseTermSequence(String sequence) { ArrayList terms = new ArrayList(); int offset = 0; while (offset < sequence.length()) { Operator op = Operator.BLANK; if (offset > 0) { op = parseOperator(sequence.charAt(offset)); if (op == Operator.BLANK) { return null; } offset++; } try { int value = parseNextNumber(sequence, offset); offset += Integer.toString(value).length(); Term term = new Term(value, op); terms.add(term); } catch (NumberFormatException ex) { return null; } } return terms; } public static Operator parseOperator(char op) { switch(op) { case '+': return Operator.ADD; case '-': return Operator.SUBTRACT; case '*': return Operator.MULTIPLY; case '/': return Operator.DIVIDE; } return Operator.BLANK; } public static int parseNextNumber(String sequence, int offset) { StringBuilder sb = new StringBuilder(); while (offset < sequence.length() && Character.isDigit(sequence.charAt(offset))) { sb.append(sequence.charAt(offset)); offset++; } return Integer.parseInt(sb.toString()); } } ================================================ FILE: Java/Ch 17. Hard/Q17_01_Add_Without_Plus/QuestionA.java ================================================ package Q17_01_Add_Without_Plus; public class QuestionA { public static int add(int a, int b) { if (b == 0) return a; int sum = a ^ b; // add without carrying int carry = (a & b) << 1; // carry, but don�t add return add(sum, carry); // recurse } public static void main(String[] args) { int a = Integer.MAX_VALUE - 50; int b = 92; int sum = add(a, b); int intendedSum = a + b; if (sum != intendedSum) { System.out.println("ERROR"); } else { System.out.println("SUCCESS"); } System.out.println(a + " + " + b + " = " + sum + " vs " + intendedSum); } } ================================================ FILE: Java/Ch 17. Hard/Q17_01_Add_Without_Plus/QuestionB.java ================================================ package Q17_01_Add_Without_Plus; public class QuestionB { public static int add(int a, int b) { while (b != 0) { int sum = a ^ b; // add without carrying int carry = (a & b) << 1; // carry, but don't add a = sum; b = carry; } return a; } public static void main(String[] args) { int a = Integer.MAX_VALUE - 50; int b = 92; int sum = add(a, b); int intendedSum = a + b; if (sum != intendedSum) { System.out.println("ERROR"); } else { System.out.println("SUCCESS"); } System.out.println(a + " + " + b + " = " + sum + " vs " + intendedSum); } } ================================================ FILE: Java/Ch 17. Hard/Q17_01_Add_Without_Plus/Tester.java ================================================ package Q17_01_Add_Without_Plus; public class Tester { public static int randomInt(int n) { return (int) (Math.random() * n); } public static void main(String[] args) { for (int a = 0; a < 1000; a++) { for (int b = 0; b < 1000; b++) { int sumA = QuestionA.add(a, b); int sumB = QuestionB.add(a, b); int sum = a + b; if (sumA != sum || sumB != sum) { System.out.println("ERROR: " + a + " + " + b + " = " + sum + " vs: " + sumA + ", " + sumB); } else { System.out.println("SUCCESS: " + a + " + " + b + " = " + sum); } } } } } ================================================ FILE: Java/Ch 17. Hard/Q17_02_Shuffle/Question.java ================================================ package Q17_02_Shuffle; import java.util.Random; import CtCILibrary.AssortedMethods; public class Question { public static int[] shuffleArrayRecursively(int[] cards, int i) { if (i == 0) { return cards; } /* shuffle elements 0 through index - 1 */ shuffleArrayRecursively(cards, i - 1); Random rand = new Random(); int k = rand.nextInt(i + 1); // Generate random between 0 and i (inclusive) /* Swap element k and index */ int temp = cards[k]; cards[k] = cards[i]; cards[i] = temp; /* Return shuffled array */ return cards; } public static void shuffleArrayIteratively(int[] cards) { Random rand = new Random(); for (int i = 0; i < cards.length; i++) { int k = rand.nextInt(i + 1); // Generate random between 0 and i (inclusive) int temp = cards[k]; cards[k] = cards[i]; cards[i] = temp; } } public static void main(String[] args) { int[] cards = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; System.out.println(AssortedMethods.arrayToString(cards)); shuffleArrayIteratively(cards); System.out.println(AssortedMethods.arrayToString(cards)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_03_Random_Set/Question.java ================================================ package Q17_03_Random_Set; import java.util.Random; import CtCILibrary.AssortedMethods; public class Question { /* pick M elements from original array. Clone original array so that * we don�t destroy the input. */ public static int[] pickMRandomly(int[] original, int m) { Random rand = new Random(); for (int i = 0; i < original.length; i++) { int k = rand.nextInt(i + 1); // Generate random between 0 and i (inclusive) int temp = original[k]; original[k] = original[i]; original[i] = temp; } return original; } public static void main(String[] args) { int[] cards = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; System.out.println(AssortedMethods.arrayToString(cards)); int[] set = pickMRandomly(cards, 4); System.out.println(AssortedMethods.arrayToString(set)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_03_Random_Set/QuestionAlternate.java ================================================ package Q17_03_Random_Set; import java.util.Random; import CtCILibrary.AssortedMethods; public class QuestionAlternate { /* pick M elements from original array, using only elements 0 through i (inclusive).*/ public static int[] pickMRecursively(int[] original, int m, int i) { if (i + 1 < m) { // Not enough elements return null; } else if (i + 1 == m) { // Base case -- copy first m elements into array int[] set = new int[m]; for (int k = 0; k < m; k++) { set[k] = original[k]; } return set; } else { int[] set = pickMRecursively(original, m, i - 1); Random rand = new Random(); int k = rand.nextInt(i + 1); // Generate random between 0 and i (inclusive) if (k < m) { set[k] = original[i]; } return set; } } /* pick M elements from original array.*/ public static int[] pickMIteratively(int[] original, int m) { if (m > original.length) return null; int[] subset = new int[m]; /* Fill in subset array with first part of original array */ for (int i = 0; i < m ; i++) { subset[i] = original[i]; } Random rand = new Random(); /* Go through rest of original array. */ for (int i = m; i < original.length; i++) { int k = rand.nextInt(i + 1); // Generate random between 0 and i (inclusive) if (k < m) { subset[k] = original[i]; } } return subset; } public static void main(String[] args) { int[] cards = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; System.out.println(AssortedMethods.arrayToString(cards)); int[] set = pickMIteratively(cards, 4); System.out.println(AssortedMethods.arrayToString(set)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_04_Missing_Number/BitInteger.java ================================================ package Q17_04_Missing_Number; public class BitInteger { public static int INTEGER_SIZE; private boolean[] bits; public BitInteger() { bits = new boolean[INTEGER_SIZE]; } /* Creates a number equal to given value. Takes time proportional * to INTEGER_SIZE. */ public BitInteger(int value){ bits = new boolean[INTEGER_SIZE]; for (int j = 0; j < INTEGER_SIZE; j++){ if (((value >> j) & 1) == 1) bits[INTEGER_SIZE - 1 - j] = true; else bits[INTEGER_SIZE - 1 - j] = false; } } /** Returns k-th most-significant bit. */ public int fetch(int k){ if (bits[k]) return 1; else return 0; } /** Sets k-th most-significant bit. */ public void set(int k, int bitValue){ if (bitValue == 0 ) bits[k] = false; else bits[k] = true; } /** Sets k-th most-significant bit. */ public void set(int k, char bitValue){ if (bitValue == '0' ) bits[k] = false; else bits[k] = true; } /** Sets k-th most-significant bit. */ public void set(int k, boolean bitValue){ bits[k] = bitValue; } public void swapValues(BitInteger number) { for (int i = 0; i < INTEGER_SIZE; i++) { int temp = number.fetch(i); number.set(i, this.fetch(i)); this.set(i, temp); } } public int toInt() { int number = 0; for (int j = INTEGER_SIZE - 1; j >= 0; j--){ number = number | fetch(j); if (j > 0) { number = number << 1; } } return number; } } ================================================ FILE: Java/Ch 17. Hard/Q17_04_Missing_Number/Question.java ================================================ package Q17_04_Missing_Number; import java.util.ArrayList; import java.util.Random; public class Question { /* Create a random array of numbers from 0 to n, but skip 'missing' */ public static ArrayList initialize(int n, int missing) { BitInteger.INTEGER_SIZE = Integer.toBinaryString(n).length(); ArrayList array = new ArrayList(); for (int i = 1; i <= n; i++) { array.add(new BitInteger(i == missing ? 0 : i)); } // Shuffle the array once. for (int i = 0; i < n; i++){ int rand = i + (int) (Math.random() * (n-i)); array.get(i).swapValues(array.get(rand)); } return array; } public static int findMissing(ArrayList array) { return findMissing(array, BitInteger.INTEGER_SIZE - 1); } private static int findMissing(ArrayList input, int column) { if (column < 0) { // Base case and error condition return 0; } ArrayList oneBits = new ArrayList(input.size()/2); ArrayList zeroBits = new ArrayList(input.size()/2); for (BitInteger t : input) { if (t.fetch(column) == 0) { zeroBits.add(t); } else { oneBits.add(t); } } if (zeroBits.size() <= oneBits.size()) { int v = findMissing(zeroBits, column - 1); System.out.print("0"); return (v << 1) | 0; } else { int v = findMissing(oneBits, column - 1); System.out.print("1"); return (v << 1) | 1; } } public static void main(String[] args) { Random rand = new Random(); int n = rand.nextInt(300000) + 1; int missing = rand.nextInt(n+1); ArrayList array = initialize(n, missing); System.out.println("The array contains all numbers but one from 0 to " + n + ", except for " + missing); int result = findMissing(array); if (result != missing) { System.out.println("Error in the algorithm!\n" + "The missing number is " + missing + ", but the algorithm reported " + result); } else { System.out.println("The missing number is " + result); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_05_Letters_and_Numbers/QuestionA.java ================================================ package Q17_05_Letters_and_Numbers; public class QuestionA { public static char[] extractSubarray(char[] array, int start, int end) { if (start > end) return null; char[] subarray = new char[end - start + 1]; for (int i = start; i <= end; i++) { subarray[i - start] = array[i]; } return subarray; } public static boolean hasEqualLettersNumbers(char[] array, int start, int end) { int counter = 0; for (int i = start; i <= end; i++) { if (Character.isLetter(array[i])) { counter++; } else if (Character.isDigit(array[i])) { counter--; } } return counter == 0; } public static char[] findLongestSubarray(char[] array) { for (int len = array.length; len > 1; len--) { for (int i = 0; i <= array.length - len; i++) { if (hasEqualLettersNumbers(array, i, i + len - 1)) { return extractSubarray(array, i, i + len - 1); } } } return null; } public static void main(String[] args) { char b = '1'; char a = 'a'; char[] array = {a, b, a, b, a, b, b, b, b, b, a, a, a, a, a, b, a, b, a, b, b, a, a, a, a, a, a, a}; for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } System.out.println(); char[] max = findLongestSubarray(array); System.out.println(max.length); for (int i = 0; i < max.length; i++) { System.out.print(max[i] + " "); } System.out.println("\nIs Valid? " + hasEqualLettersNumbers(max, 0, max.length - 1)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_05_Letters_and_Numbers/QuestionB.java ================================================ package Q17_05_Letters_and_Numbers; import java.util.HashMap; public class QuestionB { /* Compute the difference between the number of letters and * numbers between the beginning of the array and each index. */ public static int[] computeDeltaArray(char[] array) { int[] deltas = new int[array.length]; int delta = 0; for (int i = 0; i < array.length; i++) { if (Character.isLetter(array[i])) { delta++; } else if (Character.isDigit(array[i])) { delta--; } deltas[i] = delta; } return deltas; } /* Find the matching pair of values in the deltas array with the * largest difference in indices. */ public static int[] findLongestMatch(int[] deltas) { HashMap map = new HashMap(); map.put(0, -1); int[] max = new int[2]; for (int i = 0; i < deltas.length; i++) { if (!map.containsKey(deltas[i])) { map.put(deltas[i], i); } else { int match = map.get(deltas[i]); int distance = i - match; int longest = max[1] - max[0]; if (distance > longest) { max[1] = i; max[0] = match; } } } return max; } public static char[] extract(char[] array, int start, int end) { if (start > end) return null; char[] subarray = new char[end - start + 1]; for (int i = start; i <= end; i++) { subarray[i - start] = array[i]; } return subarray; } public static char[] findLongestSubarray(char[] array) { /* Compute deltas betw count of numbers and count of letters. */ int[] deltas = computeDeltaArray(array); /* Find pair in deltas with matching values and largest span. */ int[] match = findLongestMatch(deltas); /* Return the subarray. Note that it starts one *after* the * initial occurence of this delta. */ return extract(array, match[0] + 1, match[1]); } public static boolean isEqual(char[] array, int start, int end) { int counter = 0; for (int i = start; i < end; i++) { if (Character.isLetter(array[i])) { counter++; } else if (Character.isDigit(array[i])) { counter--; } } return counter == 0; } public static void main(String[] args) { char b = '1'; char a = 'a'; char[] array = {a, b, a, b, a, b, b, b, b, b, a, a, a, a, a, b, a, b, a, b, b, a, a, a, a, a, a, a}; for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } System.out.println(); char[] max = findLongestSubarray(array); if (max == null) { System.out.println("No equal subarray"); } else { System.out.println(max.length); for (int i = 0; i < max.length; i++) { System.out.print(max[i] + " "); } System.out.println("\nIs Valid? " + isEqual(max, 0, max.length)); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_05_Letters_and_Numbers/Tester.java ================================================ package Q17_05_Letters_and_Numbers; public class Tester { /** * @param args */ public static void main(String[] args) { char b = 'b'; char a = '1'; char[] array = {a, b, a, b, a, b, b, b, b, b, a, a, a, a, a, b, a, b, a, b, b, a, a, a, a, a, a, a}; for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } System.out.println(); System.out.println(); char[] maxA = QuestionA.findLongestSubarray(array); char[] maxB = QuestionB.findLongestSubarray(array); if (maxA == null) { System.out.println("A is null."); } else { System.out.println("A: " + maxA.length); for (int i = 0; i < maxA.length; i++) { System.out.print(maxA[i] + " "); } System.out.println("\nIs Valid? " + QuestionA.hasEqualLettersNumbers(maxA, 0, maxA.length - 1)); System.out.println(); } if (maxB == null) { System.out.println("B is null."); } else { System.out.println("B: " + maxB.length); for (int i = 0; i < maxB.length; i++) { System.out.print(maxB[i] + " "); } System.out.println("\nIs Valid? " + QuestionA.hasEqualLettersNumbers(maxB, 0, maxB.length - 1)); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_06_Count_of_2s/Question.java ================================================ package Q17_06_Count_of_2s; public class Question { public static int count2sInRangeAtDigit(int number, int d) { int powerOf10 = (int) Math.pow(10, d); int nextPowerOf10 = powerOf10 * 10; int right = number % powerOf10; int roundDown = number - number % nextPowerOf10; int roundUp = roundDown + nextPowerOf10; int digit = (number / powerOf10) % 10; if (digit < 2) { // if the digit in spot digit is return roundDown / 10; } else if (digit == 2) { return roundDown / 10 + right + 1; } else { return roundUp / 10; } } public static int count2sInRange(int number) { int count = 0; int len = String.valueOf(number).length(); for (int digit = 0; digit < len; digit++) { count += count2sInRangeAtDigit(number, digit); } return count; } public static int count2sR(int n) { /* Alternate, messier, solution */ // Example: n = 513 // Base case if (n == 0) { return 0; } // Split apart 513 into 5 * 100 + 13. // [Power = 100; First = 5; Remainder = 13] int power = 1; while (10 * power < n) { power *= 10; } int first = n / power; int remainder = n % power; // Counts 2s from first digit int nTwosFirst = 0; if (first > 2) { nTwosFirst += power; } else if (first == 2) { nTwosFirst += remainder + 1; } // Count 2s from all other digits int nTwosOther = first * count2sR(power - 1) + count2sR(remainder); return nTwosFirst + nTwosOther; } public static void main(String[] args) { for (int i = 0; i < 10000; i++) { int v1 = count2sR(i); int v2 = count2sInRange(i); System.out.println("Between 0 and " + i + ": " + v1 + " " + v2); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_06_Count_of_2s/QuestionBrute.java ================================================ package Q17_06_Count_of_2s; public class QuestionBrute { public static int numberOf2s(int n) { int count = 0; while (n > 0) { if (n % 10 == 2) { count++; } n = n / 10; } return count; } public static int numberOf2sInRange(int n) { int count = 0; for (int i = 2; i <= n; i++) { // Might as well start at 2 count += numberOf2s(i); } return count; } public static void main(String[] args) { for (int i = 0; i < 1000; i++) { int v = numberOf2sInRange(i); System.out.println("Between 0 and " + i + ": " + v); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_07_Baby_Names/Graph.java ================================================ package Q17_07_Baby_Names; import java.util.ArrayList; import java.util.HashMap; public class Graph { private ArrayList nodes; private HashMap map; public Graph() { map = new HashMap(); nodes = new ArrayList(); } public boolean hasNode(String name) { return map.containsKey(name); } public GraphNode createNode(String name, int freq) { if (map.containsKey(name)) { return getNode(name); } GraphNode node = new GraphNode(name, freq); nodes.add(node); map.put(name, node); return node; } private GraphNode getNode(String name) { return map.get(name); } public ArrayList getNodes() { return nodes; } public void addEdge(String startName, String endName) { GraphNode start = getNode(startName); GraphNode end = getNode(endName); if (start != null && end != null) { start.addNeighbor(end); end.addNeighbor(start); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_07_Baby_Names/GraphNode.java ================================================ package Q17_07_Baby_Names; import java.util.ArrayList; import java.util.HashMap; public class GraphNode { private ArrayList neighbors; private HashMap map; private String name; private int frequency; private boolean visited = false; public GraphNode(String nm, int freq) { name = nm; frequency = freq; neighbors = new ArrayList(); map = new HashMap(); } public String getName() { return name; } public int getFrequency() { return frequency; } public boolean addNeighbor(GraphNode node) { if (map.containsKey(node.getName())) { return false; } neighbors.add(node); map.put(node.getName(), node); return true; } public ArrayList getNeighbors() { return neighbors; } public boolean isVisited() { return visited; } public void setIsVisited(boolean v) { visited = v; } } ================================================ FILE: Java/Ch 17. Hard/Q17_07_Baby_Names/NameSet.java ================================================ package Q17_07_Baby_Names; import java.util.HashSet; import java.util.Set; public class NameSet { private Set names = new HashSet(); private int frequency = 0; private String rootName; public NameSet(String name, int freq) { names.add(name); frequency = freq; rootName = name; } public Set getNames() { return names; } public String getRootName() { return rootName; } public void copyNamesWithFrequency(Set more, int freq) { names.addAll(more); frequency += freq; } public int getFrequency() { return frequency; } public int size() { return names.size(); } } ================================================ FILE: Java/Ch 17. Hard/Q17_07_Baby_Names/QuestionA.java ================================================ package Q17_07_Baby_Names; import java.util.HashMap; import java.util.HashSet; import java.util.Map.Entry; import java.util.Set; public class QuestionA { /* Read through (name, frequency) pairs and initialize a mapping * of names to NameSets (equivalence classes).*/ public static HashMap constructGroups(HashMap names) { HashMap groups = new HashMap(); for (Entry entry : names.entrySet()) { String name = entry.getKey(); int frequency = entry.getValue(); NameSet group = new NameSet(name, frequency); groups.put(name, group); } return groups; } public static void mergeClasses(HashMap groups, String[][] synonyms) { for (String[] entry : synonyms) { String name1 = entry[0]; String name2 = entry[1]; NameSet set1 = groups.get(name1); NameSet set2 = groups.get(name2); if (set1 != set2) { /* Always merge the smaller set into the bigger one. */ NameSet smaller = set2.size() < set1.size() ? set2 : set1; NameSet bigger = set2.size() < set1.size() ? set1 : set2; /* Merge lists */ Set otherNames = smaller.getNames(); int frequency = smaller.getFrequency(); bigger.copyNamesWithFrequency(otherNames, frequency); /* Update mapping */ for (String name : otherNames) { groups.put(name, bigger); } } } } public static HashMap convertToMap(HashMap groups) { HashMap list = new HashMap(); for (NameSet group : groups.values()) { list.put(group.getRootName(), group.getFrequency()); } return list; } public static HashMap trulyMostPopular(HashMap names, String[][] synonyms) { HashMap groups = constructGroups(names); mergeClasses(groups, synonyms); return convertToMap(groups); } public static void main(String[] args) { HashMap names = new HashMap(); names.put("John", 3); names.put("Jonathan", 4); names.put("Johnny", 5); names.put("Chris", 1); names.put("Kris", 3); names.put("Brian", 2); names.put("Bryan", 4); names.put("Carleton", 4); String[][] synonyms = {{"John", "Jonathan"}, {"Jonathan", "Johnny"}, {"Chris", "Kris"}, {"Brian", "Bryan"}}; HashMap finalList = trulyMostPopular(names, synonyms); for (Entry entry : finalList.entrySet()) { String name = entry.getKey(); int frequency = entry.getValue(); System.out.println(name + ": " + frequency); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_07_Baby_Names/QuestionB.java ================================================ package Q17_07_Baby_Names; import java.util.HashMap; import java.util.Map.Entry; public class QuestionB { /* Add all names to graph as nodes. */ public static Graph constructGraph(HashMap names) { Graph graph = new Graph(); for (Entry entry : names.entrySet()) { String name = entry.getKey(); int frequency = entry.getValue(); graph.createNode(name, frequency); } return graph; } /* Connect synonymous spellings. */ public static void connectEdges(Graph graph, String[][] synonyms) { for (String[] entry : synonyms) { String name1 = entry[0]; String name2 = entry[1]; graph.addEdge(name1, name2); } } /* Do depth-first search to find the total frequency of this * component, and mark each node as visited.*/ public static int getComponentFrequency(GraphNode node) { if (node.isVisited()) { return 0; } node.setIsVisited(true); int sum = node.getFrequency(); for (GraphNode child : node.getNeighbors()) { sum += getComponentFrequency(child); } return sum; } /* Do DFS of each component. If a node has been visited before, * then its component has already been computed. */ public static HashMap getTrueFrequencies(Graph graph) { HashMap rootNames = new HashMap(); for (GraphNode node : graph.getNodes()) { if (!node.isVisited()) { int frequency = getComponentFrequency(node); String name = node.getName(); rootNames.put(name, frequency); } } return rootNames; } public static HashMap trulyMostPopular(HashMap names, String[][] synonyms) { Graph graph = constructGraph(names); connectEdges(graph, synonyms); HashMap rootNames = getTrueFrequencies(graph); return rootNames; } public static void main(String[] args) { HashMap names = new HashMap(); names.put("John", 3); names.put("Jonathan", 4); names.put("Johnny", 5); names.put("Chris", 1); names.put("Kris", 3); names.put("Brian", 2); names.put("Bryan", 4); names.put("Carleton", 4); String[][] synonyms = {{"John", "Jonathan"}, {"Jonathan", "Johnny"}, {"Chris", "Kris"}, {"Brian", "Bryan"}}; HashMap rootNames = trulyMostPopular(names, synonyms); for (Entry entry : rootNames.entrySet()) { String name = entry.getKey(); int frequency = entry.getValue(); System.out.println(name + ": " + frequency); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_08_Circus_Tower/HtWt.java ================================================ package Q17_08_Circus_Tower; public class HtWt implements Comparable { private int height; private int weight; public HtWt(int h, int w) { height = h; weight = w; } public int compareTo(HtWt second) { if (this.height != second.height) { return ((Integer)this.height).compareTo(second.height); } else { return ((Integer)this.weight).compareTo(second.weight); } } public String toString() { return "(" + height + ", " + weight + ")"; } /* Returns true if "this" should be lined up before "other". Note * that it's possible that this.isBefore(other) and * other.isBefore(this) are both false. This is different from the * compareTo method, where if a < b then b > a. */ public boolean isBefore(HtWt other) { if (height < other.height && weight < other.weight) { return true; } else { return false; } } } ================================================ FILE: Java/Ch 17. Hard/Q17_08_Circus_Tower/QuestionA.java ================================================ package Q17_08_Circus_Tower; import java.util.ArrayList; import java.util.*; public class QuestionA { public static ArrayList longestIncreasingSeq(ArrayList items) { Collections.sort(items); return bestSeqAtIndex(items, new ArrayList(), 0); } // Returns longer sequence private static ArrayList max(ArrayList seq1, ArrayList seq2) { if (seq1 == null) { return seq2; } else if (seq2 == null) { return seq1; } return seq1.size() > seq2.size() ? seq1 : seq2; } private static boolean canAppend(ArrayList solution, HtWt value) { if (solution == null) { return false; } if (solution.size() == 0) { return true; } HtWt last = solution.get(solution.size() - 1); return last.isBefore(value); } private static ArrayList bestSeqAtIndex(ArrayList array, ArrayList sequence, int index) { if (index >= array.size()) return sequence; HtWt value = array.get(index); ArrayList bestWith = null; if (canAppend(sequence, value)) { ArrayList sequenceWith = (ArrayList) sequence.clone(); sequenceWith.add(value); bestWith = bestSeqAtIndex(array, sequenceWith, index + 1); } ArrayList bestWithout = bestSeqAtIndex(array, sequence, index + 1); return max(bestWith, bestWithout); } public static ArrayList initialize() { ArrayList items = new ArrayList(); HtWt item = new HtWt(65, 60); items.add(item); item = new HtWt(70, 150); items.add(item); item = new HtWt(56, 90); items.add(item); item = new HtWt(75, 190); items.add(item); item = new HtWt(60, 95); items.add(item); item = new HtWt(68, 110); items.add(item); item = new HtWt(35, 65); items.add(item); item = new HtWt(40, 60); items.add(item); item = new HtWt(45, 63); items.add(item); return items; } public static void printList(ArrayList list) { for (HtWt item : list) { System.out.println(item.toString() + " "); } } public static void main(String[] args) { ArrayList items = initialize(); ArrayList solution = longestIncreasingSeq(items); printList(solution); } } ================================================ FILE: Java/Ch 17. Hard/Q17_08_Circus_Tower/QuestionB.java ================================================ package Q17_08_Circus_Tower; import java.util.ArrayList; import java.util.*; public class QuestionB { // Returns longer sequence private static ArrayList max(ArrayList seq1, ArrayList seq2) { if (seq1 == null) { return seq2; } else if (seq2 == null) { return seq1; } return seq1.size() > seq2.size() ? seq1 : seq2; } private static boolean canAppend(ArrayList solution, HtWt value) { if (solution == null) { return false; } if (solution.size() == 0) { return true; } HtWt last = solution.get(solution.size() - 1); return last.isBefore(value); } public static ArrayList longestIncreasingSeq(ArrayList array) { Collections.sort(array); ArrayList> solutions = new ArrayList>(); ArrayList bestSequence = null; for (int i = 0; i < array.size(); i++) { ArrayList longestAtIndex = bestSeqAtIndex(array, solutions, i); solutions.add(i, longestAtIndex); bestSequence = max(bestSequence, longestAtIndex); } return bestSequence; } private static ArrayList bestSeqAtIndex(ArrayList array, ArrayList> solutions, int index) { HtWt value = array.get(index); ArrayList bestSequence = new ArrayList(); for (int i = 0; i < index; i++) { ArrayList solution = solutions.get(i); if (canAppend(solution, value)) { bestSequence = max(solution, bestSequence); } } ArrayList best = (ArrayList) bestSequence.clone(); best.add(value); return best; } public static ArrayList initialize() { ArrayList items = new ArrayList(); HtWt item = new HtWt(65, 60); items.add(item); item = new HtWt(70, 150); items.add(item); item = new HtWt(56, 90); items.add(item); item = new HtWt(75, 190); items.add(item); item = new HtWt(60, 95); items.add(item); item = new HtWt(68, 110); items.add(item); item = new HtWt(35, 65); items.add(item); item = new HtWt(40, 60); items.add(item); item = new HtWt(45, 63); items.add(item); return items; } public static void printList(ArrayList list) { for (HtWt item : list) { System.out.println(item.toString() + " "); } } public static void main(String[] args) { ArrayList items = initialize(); ArrayList solution = longestIncreasingSeq(items); printList(solution); } } ================================================ FILE: Java/Ch 17. Hard/Q17_08_Circus_Tower/QuestionOld.java ================================================ package Q17_08_Circus_Tower; import java.util.ArrayList; import java.util.*; public class QuestionOld { // Returns longer sequence private static ArrayList seqWithMaxLength(ArrayList seq1, ArrayList seq2) { if (seq1 == null) { return seq2; } else if (seq2 == null) { return seq1; } return seq1.size() > seq2.size() ? seq1 : seq2; } private static void longestIncreasingSubsequence(ArrayList array, ArrayList> solutions, int current_index) { if (current_index >= array.size() || current_index < 0) { return; } HtWt current_element = array.get(current_index); // Find longest sequence that we can append current_element to ArrayList best_sequence = null; for (int i = 0; i < current_index; i++) { if (array.get(i).isBefore(current_element)) { // If current_element is bigger than list tail best_sequence = seqWithMaxLength(best_sequence, solutions.get(i)); // Set best_sequence to our new max } } // Append current_element ArrayList new_solution = new ArrayList(); if (best_sequence != null) { new_solution.addAll(best_sequence); } new_solution.add(current_element); // Add to list and recurse solutions.add(current_index, new_solution); longestIncreasingSubsequence(array, solutions, current_index + 1); } public static ArrayList longestIncreasingSeq(ArrayList array) { Collections.sort(array); ArrayList> solutions = new ArrayList>(); longestIncreasingSubsequence(array, solutions, 0); ArrayList best_sequence = null; for (int i = 0; i < array.size(); i++) { best_sequence = seqWithMaxLength(best_sequence, solutions.get(i)); } return best_sequence; } public static ArrayList initialize() { ArrayList items = new ArrayList(); HtWt item = new HtWt(65, 60); items.add(item); item = new HtWt(70, 150); items.add(item); item = new HtWt(56, 90); items.add(item); item = new HtWt(75, 190); items.add(item); item = new HtWt(60, 95); items.add(item); item = new HtWt(68, 110); items.add(item); item = new HtWt(35, 65); items.add(item); item = new HtWt(40, 60); items.add(item); item = new HtWt(45, 63); items.add(item); return items; } public static void printList(ArrayList list) { for (HtWt item : list) { System.out.println(item.toString() + " "); } } public static void main(String[] args) { ArrayList items = initialize(); ArrayList solution = longestIncreasingSeq(items); printList(solution); } } ================================================ FILE: Java/Ch 17. Hard/Q17_08_Circus_Tower/Tester.java ================================================ package Q17_08_Circus_Tower; import java.util.ArrayList; public class Tester { public static int randomInt(int n) { return (int) (Math.random() * n); } public static boolean validate(ArrayList seq) { for (int i = 1; i < seq.size(); i++) { HtWt prev = seq.get(i - 1); HtWt curr = seq.get(i); if (!prev.isBefore(curr)) { return false; } } return true; } public static void main(String[] args) { for (int j = 0; j < 100; j++) { ArrayList arrayA = new ArrayList(); ArrayList arrayB = new ArrayList(); ArrayList arrayC = new ArrayList(); for (int i = 0; i < 10; i++) { HtWt value = new HtWt(randomInt(100), randomInt(100)); arrayA.add(value); arrayB.add(value); arrayC.add(value); } ArrayList seq1 = QuestionA.longestIncreasingSeq(arrayA); ArrayList seq2 = QuestionB.longestIncreasingSeq(arrayB); ArrayList seq3 = QuestionOld.longestIncreasingSeq(arrayC); if (seq1.size() != seq2.size() || seq1.size() != seq3.size()) { System.out.println("ERROR: " + seq1.size() + ", " + seq2.size() + ", " + seq3.size()); System.out.println(seq1.toString()); System.out.println(seq2.toString()); break; } else { System.out.println("SUCCESS: " + seq1.size() + " == " + seq2.size() + " == " + seq3.size()); System.out.println(seq1.toString()); System.out.println(seq2.toString()); System.out.println(seq3.toString()); } } } } ================================================ FILE: Java/Ch 17. Hard/Q17_09_Kth_Multiple/QuestionA.java ================================================ package Q17_09_Kth_Multiple; import java.util.ArrayList; import java.util.Collections; public class QuestionA { public static ArrayList allPossibleKFactors(int k) { ArrayList values = new ArrayList(); for (int a = 0; a <= k; a++) { // 3 int powA = (int) Math.pow(3, a); for (int b = 0; b <= k; b++) { // 5 int powB = (int) Math.pow(5, b); for (int c = 0; c <= k; c++) { // 7 int powC = (int) Math.pow(7, c); int value = powA * powB * powC; if (value < 0 || powA == Integer.MAX_VALUE || powB == Integer.MAX_VALUE || powC == Integer.MAX_VALUE) { value = Integer.MAX_VALUE; } values.add(value); } } } return values; } public static int getKthMagicNumber(int k) { ArrayList possibilities = allPossibleKFactors(k); Collections.sort(possibilities); return possibilities.get(k); } public static void main(String[] args) { for (int i = 0; i < 50; i++) { System.out.println(i + " : " + getKthMagicNumber(i)); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_09_Kth_Multiple/QuestionB.java ================================================ package Q17_09_Kth_Multiple; import java.util.Queue; import java.util.LinkedList; public class QuestionB { public static int removeMin(Queue q) { int min = q.peek(); for (Integer v : q) { if (min > v) { min = v; } } while (q.contains(min)) { q.remove(min); } return min; } public static void addProducts(Queue q, int v) { q.add(v * 3); q.add(v * 5); q.add(v * 7); } public static int getKthMagicNumber(int k) { if (k < 0) { return 0; } int val = 1; Queue q = new LinkedList(); addProducts(q, 1); for (int i = 0; i < k; i++) { // Start at 1 since we've already done one iteration val = removeMin(q); addProducts(q, val); } return val; } public static void main(String[] args) { for (int i = 0; i < 14; i++) { System.out.println(i + " : " + getKthMagicNumber(i)); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_09_Kth_Multiple/QuestionC.java ================================================ package Q17_09_Kth_Multiple; import java.util.Queue; import java.util.LinkedList; public class QuestionC { public static void printQueue(Queue q, int x) { System.out.print(x + ": "); for (Integer a : q) { System.out.print(a / x + ", "); } System.out.println(""); } public static int getKthMagicNumber(int k) { if (k < 0) { return 0; } int val = 0; Queue queue3 = new LinkedList(); Queue queue5 = new LinkedList(); Queue queue7 = new LinkedList(); queue3.add(1); for (int i = 0; i <= k; i++) { // Include 0th iteration through kth iteration int v3 = queue3.size() > 0 ? queue3.peek() : Integer.MAX_VALUE; int v5 = queue5.size() > 0 ? queue5.peek() : Integer.MAX_VALUE; int v7 = queue7.size() > 0 ? queue7.peek() : Integer.MAX_VALUE; val = Math.min(v3, Math.min(v5, v7)); if (val == v3) { queue3.remove(); queue3.add(3 * val); queue5.add(5 * val); } else if (val == v5) { queue5.remove(); queue5.add(5 * val); } else if (val == v7) { queue7.remove(); } queue7.add(7 * val); } return val; } public static void main(String[] args) { for (int i = 0; i < 14; i++) { System.out.println(i + " : " + getKthMagicNumber(i)); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_10_Majority_Element/QuestionA.java ================================================ package Q17_10_Majority_Element; public class QuestionA { public static boolean validate(int[] array, int majority) { int count = 0; for (int n : array) { if (n == majority) { count++; } } return count > array.length / 2; } public static int findMajorityElement(int[] array) { for (int x : array) { if (validate(array, x)) { return x; } } return -1; } public static void main(String[] args) { int[] array = {0, 0, 1, 2, 2, 0, 1, 0, 1, 1, 1, 1, 1}; System.out.println(array.length); System.out.println(findMajorityElement(array)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_10_Majority_Element/QuestionB.java ================================================ package Q17_10_Majority_Element; public class QuestionB { public static int getCandidate(int[] array) { int majority = 0; int count = 0; for (int n : array) { if (count == 0) { majority = n; } if (n == majority) { count++; } else { count--; } } return majority; } public static boolean validate(int[] array, int majority) { int count = 0; for (int n : array) { if (n == majority) { count++; } } return count > array.length / 2; } public static int findMajorityElement(int[] array) { int candidate = getCandidate(array); return validate(array, candidate) ? candidate : -1; } public static void main(String[] args) { int[] array = {0, 0, 1, 2, 2, 0, 1, 0, 1, 1, 1, 1, 1}; System.out.println(array.length); System.out.println(findMajorityElement(array)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_11_Word_Distance/LocationPair.java ================================================ package Q17_11_Word_Distance; public class LocationPair { public int location1; public int location2; public LocationPair(int first, int second) { setLocations(first, second); } public void setLocations(int first, int second) { this.location1 = first; this.location2 = second; } public void setLocations(LocationPair loc) { setLocations(loc.location1, loc.location2); } public int distance() { return Math.abs(location1 - location2); } public boolean isValid() { return location1 >= 0 && location2 >= 0; } public void updateWithMin(LocationPair loc) { if (!isValid() || loc.distance() < distance()) { setLocations(loc); } } @Override public String toString() { return "(" + location1 + ", " + location2 + ")"; } } ================================================ FILE: Java/Ch 17. Hard/Q17_11_Word_Distance/QuestionA.java ================================================ package Q17_11_Word_Distance; import CtCILibrary.AssortedMethods; public class QuestionA { public static LocationPair findClosest(String[] words, String word1, String word2) { LocationPair best = new LocationPair(-1, -1); LocationPair current = new LocationPair(-1, -1); for (int i = 0; i < words.length; i++) { String word = words[i]; if (word.equals(word1)) { current.location1 = i; best.updateWithMin(current); } else if (word.equals(word2)) { current.location2 = i; best.updateWithMin(current); } } return best; } public static void main(String[] args) { String[] wordlist = AssortedMethods.getLongTextBlobAsStringList(); String word1 = "river"; String word2 = "life"; LocationPair pair = findClosest(wordlist, word1, word2); System.out.println("Distance between <" + word1 + "> and <" + word2 + ">: " + pair.toString()); } } ================================================ FILE: Java/Ch 17. Hard/Q17_11_Word_Distance/QuestionB.java ================================================ package Q17_11_Word_Distance; import java.util.ArrayList; import java.util.HashMap; import CtCILibrary.AssortedMethods; import CtCILibrary.HashMapList; public class QuestionB { public static HashMapList getWordLocations(String[] words) { HashMapList locations = new HashMapList(); for (int i = 0; i < words.length; i++) { locations.put(words[i], i); } return locations; } public static LocationPair findMinDistancePair(ArrayList array1, ArrayList array2) { if (array1 == null || array2 == null || array1.size() == 0 || array2.size() == 0) { return null; } int index1 = 0; int index2 = 0; LocationPair best = new LocationPair(array1.get(0), array2.get(0)); LocationPair current = new LocationPair(array1.get(0), array2.get(0)); while (index1 < array1.size() && index2 < array2.size()) { current.setLocations(array1.get(index1), array2.get(index2)); best.updateWithMin(current); if (current.location1 < current.location2) { index1++; } else { index2++; } } return best; } public static LocationPair findClosest(String word1, String word2, HashMapList locations) { ArrayList locations1 = locations.get(word1); ArrayList locations2 = locations.get(word2); return findMinDistancePair(locations1, locations2); } public static void main(String[] args) { String[] wordlist = AssortedMethods.getLongTextBlobAsStringList(); String word1 = "river"; String word2 = "life"; HashMapList locations = getWordLocations(wordlist); LocationPair pair = findClosest(word1, word2, locations); System.out.println("Distance between <" + word1 + "> and <" + word2 + ">: " + pair.toString()); } } ================================================ FILE: Java/Ch 17. Hard/Q17_11_Word_Distance/Tester.java ================================================ package Q17_11_Word_Distance; import java.util.ArrayList; import java.util.HashMap; import CtCILibrary.AssortedMethods; import CtCILibrary.HashMapList; public class Tester { public static String wordAtLocation(String[] words, int loc) { if (loc < 0 || loc >= words.length) { return null; } return words[loc]; } // Method to confirm other result public static boolean searchConfirm(String[] words, String word1, String word2, int distance) { boolean found_at_distance = false; for (int i = 0; i < words.length; i++) { if (words[i].equals(word1)) { for (int j = 1; j < distance; j++) { String loc2a = wordAtLocation(words, i - j); String loc2b = wordAtLocation(words, i + j); if (word2.equals(loc2a) || word2.equals(loc2b)) { return false; } } String loc2a = wordAtLocation(words, i - distance); String loc2b = wordAtLocation(words, i + distance); if (word2.equals(loc2a) || word2.equals(loc2b)) { found_at_distance = true; } } } return found_at_distance; } public static void main(String[] args) { String[] wordlist = AssortedMethods.getLongTextBlobAsStringList(); System.out.println(AssortedMethods.stringArrayToString(wordlist)); HashMapList locations = QuestionB.getWordLocations(wordlist); String[][] pairs = {{"Lara", "the"}, {"river", "life"}, {"path", "their"}, {"life", "a"}}; for (String[] pair : pairs) { String word1 = pair[0]; String word2 = pair[1]; LocationPair pairA = QuestionA.findClosest(wordlist, word1, word2); LocationPair pairB = QuestionB.findClosest(word1, word2, locations); boolean confirmC = searchConfirm(wordlist, word1, word2, pairA.distance()); System.out.println("Distance between <" + word1 + "> and <" + word2 + ">: " + confirmC); System.out.println(pairA.toString() + ": " + pairA.distance()); System.out.println(pairB.toString() + ": " + pairB.distance()); System.out.println(); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_12_BiNode/BiNode.java ================================================ package Q17_12_BiNode; public class BiNode { public BiNode node1; public BiNode node2; public int data; public BiNode(int d) { data = d; } } ================================================ FILE: Java/Ch 17. Hard/Q17_12_BiNode/QuestionA.java ================================================ package Q17_12_BiNode; public class QuestionA { private static class NodePair { BiNode head; BiNode tail; public NodePair(BiNode head, BiNode tail) { this.head = head; this.tail = tail; } } public static NodePair convert(BiNode root) { if (root == null) { return null; } NodePair part1 = convert(root.node1); NodePair part2 = convert(root.node2); if (part1 != null) { concat(part1.tail, root); } if (part2 != null) { concat(root, part2.head); } return new NodePair(part1 == null ? root : part1.head, part2 == null ? root : part2.tail); } public static void concat(BiNode x, BiNode y) { x.node2 = y; y.node1 = x; } public static void printLinkedListTree(BiNode root) { for (BiNode node = root; node != null; node = node.node2) { if (node.node2 != null && node.node2.node1 != node) { System.out.print("inconsistent node: " + node); } System.out.print(node.data + "->"); } System.out.println(); } public static BiNode createTree() { BiNode[] nodes = new BiNode[7]; for (int i = 0; i < nodes.length; i++) { nodes[i] = new BiNode(i); } nodes[4].node1 = nodes[2]; nodes[4].node2 = nodes[5]; nodes[2].node1 = nodes[1]; nodes[2].node2 = nodes[3]; nodes[5].node2 = nodes[6]; nodes[1].node1 = nodes[0]; return nodes[4]; } public static void printAsTree(BiNode root, String spaces) { if (root == null) { System.out.println(spaces + "- null"); return; } System.out.println(spaces + "- " + root.data); printAsTree(root.node1, spaces + " "); printAsTree(root.node2, spaces + " "); } public static void main(String[] args) { BiNode root = createTree(); printAsTree(root, ""); NodePair n = convert(root); printLinkedListTree(n.head); } } ================================================ FILE: Java/Ch 17. Hard/Q17_12_BiNode/QuestionB.java ================================================ package Q17_12_BiNode; public class QuestionB { static int count = 0; public static BiNode convert(BiNode root) { if (root == null) { return null; } BiNode part1 = convert(root.node1); BiNode part2 = convert(root.node2); if (part1 != null) { concat(getTail(part1), root); } if (part2 != null) { concat(root, part2); } return part1 == null ? root : part1; } public static BiNode getTail(BiNode node) { if (node == null) { return null; } while (node.node2 != null) { count++; node = node.node2; } return node; } public static void concat(BiNode x, BiNode y) { x.node2 = y; y.node1 = x; } public static void printLinkedListTree(BiNode root) { for (BiNode node = root; node != null; node = node.node2) { if (node.node2 != null && node.node2.node1 != node) { System.out.print("inconsistent node: " + node); } System.out.print(node.data + "->"); } System.out.println(); } public static BiNode createTree() { BiNode[] nodes = new BiNode[7]; for (int i = 0; i < nodes.length; i++) { nodes[i] = new BiNode(i); } nodes[4].node1 = nodes[2]; nodes[4].node2 = nodes[5]; nodes[2].node1 = nodes[1]; nodes[2].node2 = nodes[3]; nodes[5].node2 = nodes[6]; nodes[1].node1 = nodes[0]; return nodes[4]; } public static void printAsTree(BiNode root, String spaces) { if (root == null) { System.out.println(spaces + "- null"); return; } System.out.println(spaces + "- " + root.data); printAsTree(root.node1, spaces + " "); printAsTree(root.node2, spaces + " "); } public static void main(String[] args) { BiNode root = createTree(); printAsTree(root, ""); BiNode n = convert(root); printLinkedListTree(n); System.out.println(count); } } ================================================ FILE: Java/Ch 17. Hard/Q17_12_BiNode/QuestionC.java ================================================ package Q17_12_BiNode; public class QuestionC { public static void printAsTree(BiNode root, String spaces) { if (root == null) { System.out.println(spaces + "- null"); return; } System.out.println(spaces + "- " + root.data); printAsTree(root.node1, spaces + " "); printAsTree(root.node2, spaces + " "); } public static BiNode createTree() { BiNode[] nodes = new BiNode[7]; for (int i = 0; i < nodes.length; i++) { nodes[i] = new BiNode(i); } nodes[4].node1 = nodes[2]; nodes[4].node2 = nodes[5]; nodes[2].node1 = nodes[1]; nodes[2].node2 = nodes[3]; nodes[5].node2 = nodes[6]; nodes[1].node1 = nodes[0]; return nodes[4]; } public static void printLinkedListTree(BiNode root) { for (BiNode node = root; node != null; node = node.node2) { if (node.node2 != null && node.node2.node1 != node) { System.out.print("inconsistent node: " + node); } System.out.print(node.data + "->"); } System.out.println(); } public static BiNode convertToCircular(BiNode root) { if (root == null) { return null; } BiNode part1 = convertToCircular(root.node1); BiNode part3 = convertToCircular(root.node2); if (part1 == null && part3 == null) { root.node1 = root; root.node2 = root; return root; } BiNode tail3 = part3 == null ? null : part3.node1; /* join left to root */ if (part1 == null) { concat(part3.node1, root); } else { concat(part1.node1, root); } /* join right to root */ if (part3 == null) { concat(root, part1); } else { concat(root, part3); } /* join right to left */ if (part1 != null && part3 != null) { concat(tail3, part1); } return part1 == null ? root : part1; } public static BiNode convert(BiNode root) { BiNode head = convertToCircular(root); head.node1.node2 = null; head.node1 = null; return head; } public static void concat(BiNode x, BiNode y) { x.node2 = y; y.node1 = x; } public static void main(String[] args) { BiNode root = createTree(); printAsTree(root, ""); BiNode r = convert(root); printLinkedListTree(r); } } ================================================ FILE: Java/Ch 17. Hard/Q17_13_ReSpace/ParseResult.java ================================================ package Q17_13_ReSpace; public class ParseResult { public int invalid = Integer.MAX_VALUE; public String parsed = ""; public ParseResult(int inv, String p) { invalid = inv; parsed = p; } public ParseResult clone() { return new ParseResult(this.invalid, this.parsed); } public static ParseResult min(ParseResult r1, ParseResult r2) { if (r1 == null) { return r2; } else if (r2 == null) { return r1; } return r2.invalid < r1.invalid ? r2 : r1; } } ================================================ FILE: Java/Ch 17. Hard/Q17_13_ReSpace/QuestionA.java ================================================ package Q17_13_ReSpace; import java.util.HashSet; import CtCILibrary.AssortedMethods; public class QuestionA { public static String bestSplit(HashSet dictionary, String sentence) { ParseResult r = split(dictionary, sentence, 0); return r == null ? null : r.parsed; } public static ParseResult split(HashSet dictionary, String sentence, int start) { if (start >= sentence.length()) { return new ParseResult(0, ""); } int bestInvalid = Integer.MAX_VALUE; String bestParsing = null; String partial = ""; int index = start; while (index < sentence.length()) { char c = sentence.charAt(index); partial += c; int invalid = dictionary.contains(partial) ? 0 : partial.length(); if (invalid < bestInvalid) { // Short circuit /* Recurse, putting a space after this character. If this * is better than the current best option, replace the best * option. */ ParseResult result = split(dictionary, sentence, index + 1); if (invalid + result.invalid < bestInvalid) { bestInvalid = invalid + result.invalid; bestParsing = partial + " " + result.parsed; if (bestInvalid == 0) break; } } index++; } return new ParseResult(bestInvalid, bestParsing); } public static String clean(String str) { char[] punctuation = {',', '"', '!', '.', '\'', '?', ','}; for (char c : punctuation) { str = str.replace(c, ' '); } return str.replace(" ", "").toLowerCase(); } public static void main(String[] args) { HashSet dictionary = AssortedMethods.getWordListAsHashSet(); String sentence = "As one of the top companies in the world, Google"; // will surely attract the attention of computer gurus. This does not, however, mean the company is for everyone."; sentence = clean(sentence); System.out.println(sentence); //Result v = parse(0, 0, new HashMap()); //System.out.println(v.parsed); System.out.println(bestSplit(dictionary, sentence)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_13_ReSpace/QuestionB.java ================================================ package Q17_13_ReSpace; import java.util.HashSet; import CtCILibrary.AssortedMethods; public class QuestionB { public static String bestSplit(HashSet dictionary, String sentence) { ParseResult[] memo = new ParseResult[sentence.length()]; ParseResult r = split(dictionary, sentence, 0, memo); return r == null ? null : r.parsed; } public static ParseResult split(HashSet dictionary, String sentence, int start, ParseResult[] memo) { if (start >= sentence.length()) { return new ParseResult(0, ""); } if (memo[start] != null) { return memo[start]; } int bestInvalid = Integer.MAX_VALUE; String bestParsing = null; String partial = ""; int index = start; while (index < sentence.length()) { char c = sentence.charAt(index); partial += c; int invalid = dictionary.contains(partial) ? 0 : partial.length(); if (invalid < bestInvalid) { // Short circuit /* Recurse, putting a space after this character. If this * is better than the current best option, replace the best * option. */ ParseResult result = split(dictionary, sentence, index + 1, memo); if (invalid + result.invalid < bestInvalid) { bestInvalid = invalid + result.invalid; bestParsing = partial + " " + result.parsed; if (bestInvalid == 0) break; // Short circuit } } index++; } memo[start] = new ParseResult(bestInvalid, bestParsing); return memo[start]; } public static String clean(String str) { char[] punctuation = {',', '"', '!', '.', '\'', '?', ','}; for (char c : punctuation) { str = str.replace(c, ' '); } return str.replace(" ", "").toLowerCase(); } public static void main(String[] args) { HashSet dictionary = AssortedMethods.getWordListAsHashSet(); String sentence = "As one of the topk companies in the world, Google will surely attract the attention of computer gurus. This does not, however, mean the company is for everyone."; sentence = clean(sentence); System.out.println(sentence); //Result v = parse(0, 0, new HashMap()); //System.out.println(v.parsed); System.out.println(bestSplit(dictionary, sentence)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_14_Smallest_K/QuestionA.java ================================================ package Q17_14_Smallest_K; import java.util.Arrays; import CtCILibrary.AssortedMethods; public class QuestionA { public static int[] smallestK(int[] array, int k) { if (k <= 0 || k > array.length) { throw new IllegalArgumentException(); } /* Sort array. */ Arrays.sort(array); /* Copy first k elements. */ int[] smallest = new int[k]; for (int i = 0; i < k; i++) { smallest[i] = array[i]; } return smallest; } public static void main(String[] args) { int[] array = {1, 5, 2, 9, 1, 11, 6, 13, 15}; int[] smallest = smallestK(array, 3); System.out.println(AssortedMethods.arrayToString(smallest)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_14_Smallest_K/QuestionB.java ================================================ package Q17_14_Smallest_K; import java.util.Comparator; import java.util.PriorityQueue; import CtCILibrary.AssortedMethods; public class QuestionB { public static class MaxHeapComparator implements Comparator { public int compare(Integer x, Integer y) { return y - x; } } public static int[] smallestK(int[] array, int k) { if (k <= 0 || k > array.length) { throw new IllegalArgumentException(); } PriorityQueue heap = getKMaxHeap(array, k); return heapToIntArray(heap); } /* Convert heap to int array. */ public static int[] heapToIntArray(PriorityQueue heap) { int[] array = new int[heap.size()]; while (!heap.isEmpty()) { array[heap.size() - 1] = heap.poll(); } return array; } /* Create max heap of smallest k elements. */ public static PriorityQueue getKMaxHeap(int[] array, int k) { PriorityQueue heap = new PriorityQueue(k, new MaxHeapComparator()); for (int a : array) { if (heap.size() < k) { // If space remaining heap.add(a); } else if (a < heap.peek()) { // If full and top is small heap.poll(); // remove highest heap.add(a); // insert new element } } return heap; } public static void main(String[] args) { int[] array = {1, 5, 2, 9, -1, 11, 6, 13, 15}; int[] smallest = smallestK(array, 3); System.out.println(AssortedMethods.arrayToString(smallest)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_14_Smallest_K/QuestionC.java ================================================ package Q17_14_Smallest_K; import java.util.Random; import CtCILibrary.AssortedMethods; public class QuestionC { public static int[] smallestK(int[] array, int k) { if (k <= 0 || k > array.length) { throw new IllegalArgumentException(); } int threshold = rank(array, k - 1); int[] smallest = new int[k]; int count = 0; for (int a : array) { if (a <= threshold) { smallest[count] = a; count++; } } return smallest; } /* Get item with rank. */ public static int rank(int[] array, int rank) { return rank(array, 0, array.length - 1, rank); } /* Get element with rank between left and right indices. */ public static int rank(int[] array, int left, int right, int rank) { int pivot = array[randomIntInRange(left, right)]; int leftEnd = partition(array, left, right, pivot); // returns end of left partition int leftSize = leftEnd - left + 1; if (rank == leftSize - 1) { return max(array, left, leftEnd); } else if (rank < leftSize) { return rank(array, left, leftEnd, rank); } else { return rank(array, leftEnd + 1, right, rank - leftSize); } } /* Partition array around pivot such that all elements <= pivot * come before all elements > pivot. */ public static int partition(int[] array, int left, int right, int pivot) { while (left <= right) { if (array[left] > pivot) { /* Left is bigger than pivot. Swap it to the right * side, where we know it should be. */ swap(array, left, right); right--; } else if (array[right] <= pivot) { /* Right is smaller than the pivot. Swap it to the  * left side, where we know it should be. */ swap(array, left, right); left++; } else { /* Left and right are in correct places. Expand both * sides. */ left++; right--; } } return left - 1; } /* Get random integer within range, inclusive. */ public static int randomIntInRange(int min, int max) { Random rand = new Random(); return rand.nextInt(max + 1 - min) + min; } /* Swap values at index i and j. */ public static void swap(int[] array, int i, int j) { int t = array[i]; array[i] = array[j]; array[j] = t; } /* Get largest element in array between left and right indices. */ public static int max(int[] array, int left, int right) { int max = Integer.MIN_VALUE; for (int i = left; i <= right; i++) { max = Math.max(array[i], max); } return max; } public static void main(String[] args) { int[] array = {1, 5, 2, 9, -1, 11, 6, 13, 15}; int[] smallest = smallestK(array, 3); System.out.println(AssortedMethods.arrayToString(smallest)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_14_Smallest_K/QuestionD.java ================================================ package Q17_14_Smallest_K; import java.util.Random; import CtCILibrary.AssortedMethods; public class QuestionD { public static class PartitionResult { int leftSize; int middleSize; public PartitionResult(int left, int middle) { this.leftSize = left; this.middleSize = middle; } } public static int[] smallestK(int[] array, int k) { if (k <= 0 || k > array.length) throw new IllegalArgumentException(); int threshold = rank(array, k - 1); int[] smallest = new int[k]; int count = 0; for (int a : array) { if (a < threshold) { smallest[count] = a; count++; } } while (count < k) { smallest[count] = threshold; count++; } return smallest; } /* Find value with rank k in array. */ public static int rank(int[] array, int k) { if (k >= array.length) { throw new IllegalArgumentException(); } return rank(array, k, 0, array.length - 1); } /* Find value with rank k in sub array between start and end. */ private static int rank(int[] array, int k, int start, int end) { /* Partition array around an arbitrary pivot. */ int pivot = array[randomIntInRange(start, end)]; PartitionResult partition = partition(array, start, end, pivot); int leftSize = partition.leftSize; int middleSize = partition.middleSize; if (k < leftSize) { // Rank k is on left half return rank(array, k, start, start + leftSize - 1); } else if (k < leftSize + middleSize) { // Rank k is in middle return pivot; // middle is all pivot values } else { // Rank k is on right return rank(array, k - leftSize - middleSize, start + leftSize + middleSize, end); } } /* Partition result into < pivot, equal to pivot -> bigger than pivot. */ private static PartitionResult partition(int[] array, int start, int end, int pivot) { int left = start; /* Stays at (right) edge of left side. */ int right = end; /* Stays at (left) edge of right side. */ int middle = start; /* Stays at (right) edge of middle. */ while (middle <= right) { if (array[middle] < pivot) { /* Middle is smaller than the pivot. Left is either * smaller or equal to the pivot. Either way, swap * them. Then middle and left should move by one. */ swap(array, middle, left); middle++; left++; } else if (array[middle] > pivot) { /* Middle is bigger than the pivot. Right could have * any value. Swap them, then we know that the new * right is bigger than the pivot. Move right by one. */ swap(array, middle, right); right--; } else if (array[middle] == pivot) { /* Middle is equal to the pivot. Move by one. */ middle++; } } /* Return sizes of left and middle. */ return new PartitionResult(left - start, right - left + 1); } public static int randomIntInRange(int min, int max) { Random rand = new Random(); return rand.nextInt(max + 1 - min) + min; } /* Swap values at index i and j. */ public static void swap(int[] array, int i, int j) { int t = array[i]; array[i] = array[j]; array[j] = t; } public static void main(String[] args) { int[] array = {1, 5, 2, 3, 2, 9, -1, 11, 6, 13, 15, 2}; int[] smallest = smallestK(array, 6); System.out.println(AssortedMethods.arrayToString(smallest)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_14_Smallest_K/Tester.java ================================================ package Q17_14_Smallest_K; import java.util.Arrays; import CtCILibrary.AssortedMethods; public class Tester { public static int rankB(int[] array, int rank) { int[] cloned = array.clone(); Arrays.sort(cloned); return cloned[rank]; } public static void swap(int[] array, int i, int j) { int t = array[i]; array[i] = array[j]; array[j] = t; } public static boolean isUnique(int[] array) { int[] cloned = array.clone(); Arrays.sort(cloned); for (int i = 1; i < cloned.length; i++) { if (cloned[i] == cloned[i - 1]) { return false; } } return true; } public static int max(int[] array, int left, int right) { int max = Integer.MIN_VALUE; for (int i = left; i <= right; i++) { max = Math.max(array[i], max); } return max; } public static int randomInt(int n) { return (int) (Math.random() * n); } public static int randomIntInRange(int min, int max) { return randomInt(max + 1 - min) + min; } public static boolean isEqual(int[] array1, int[] array2) { if (array1.length != array2.length) { return false; } for (int i = 0; i < array1.length; i++) { if (array1[i] != array2[i]) { return false; } } return true; } public static boolean isEquivalent(int[] array1, int[] array2) { Arrays.sort(array1); Arrays.sort(array2); return isEqual(array1, array2); } public static boolean testArray(int[] array1) { int[] copy = array1.clone(); int[] array2 = new int[array1.length]; for (int i = 0; i < array1.length; i++) { array2[i] = QuestionD.rank(array1, i); } Arrays.sort(array1); if (!isEqual(array1, array2)) { System.out.println("ERROR"); System.out.println("Original Array: " + AssortedMethods.arrayToString(copy)); System.out.println("Ranked Array: " + AssortedMethods.arrayToString(array2)); System.out.println("Sorted Array: " + AssortedMethods.arrayToString(array1)); return false; } return true; } public static void main(String[] args) { int numberOfTests = 1000; int countWithC = 0; int countTotal = 0; for (int i = 0; i < numberOfTests; i++) { int length = AssortedMethods.randomIntInRange(1, 10); int rank = AssortedMethods.randomIntInRange(1, length); int minRange = -1 * i; int maxRange = i; int[] array = AssortedMethods.randomArray(length, minRange, maxRange); int[] smallestA = QuestionA.smallestK(array.clone(), rank); int[] smallestB = QuestionB.smallestK(array.clone(), rank); int[] smallestD = QuestionD.smallestK(array.clone(), rank); int[] smallestC = smallestD; if (isUnique(array)) { smallestC = QuestionC.smallestK(array.clone(), rank); countWithC++; } countTotal++; if (!isEquivalent(smallestA, smallestB) || !isEquivalent(smallestB, smallestD) || !isEquivalent(smallestD, smallestC)) { System.out.println("ERROR"); System.out.println(array); System.out.println("ArrayA: " + AssortedMethods.arrayToString(smallestA)); System.out.println("ArrayA: " + AssortedMethods.arrayToString(smallestA)); System.out.println("ArrayB: " + AssortedMethods.arrayToString(smallestB)); System.out.println("ArrayC: " + AssortedMethods.arrayToString(smallestC)); System.out.println("ArrayD: " + AssortedMethods.arrayToString(smallestD)); break; } } System.out.println("Completed " + countTotal + " runs, including " + countWithC + " with C"); } } ================================================ FILE: Java/Ch 17. Hard/Q17_15_Longest_Word/LengthComparator.java ================================================ package Q17_15_Longest_Word; import java.util.Comparator; public class LengthComparator implements Comparator { public int compare(String o1, String o2) { if (o1.length() < o2.length()) return 1; if (o1.length() > o2.length()) return -1; return 0; } } ================================================ FILE: Java/Ch 17. Hard/Q17_15_Longest_Word/Question.java ================================================ package Q17_15_Longest_Word; import java.util.Arrays; import java.util.HashMap; public class Question { public static String printLongestWord(String arr[]) { HashMap map = new HashMap(); for (String str : arr) { map.put(str, true); } Arrays.sort(arr, new LengthComparator()); // Sort by length for (String s : arr) { if (canBuildWord(s, true, map)) { System.out.println(s); return s; } } return ""; } public static boolean canBuildWord(String str, boolean isOriginalWord, HashMap map) { if (map.containsKey(str) && !isOriginalWord) { return map.get(str); } for (int i = 1; i < str.length(); i++) { String left = str.substring(0, i); String right = str.substring(i); if (map.containsKey(left) && map.get(left) == true && canBuildWord(right, false, map)) { return true; } } map.put(str, false); return false; } public static void main(String[] args) { String[] arr = createGiantArray(); printLongestWord(arr); } public static String[] createGiantArray() { String arr[] = {"a", "able", "about", "account", "acid", "across", "act", "addition", "adjustment", "advertisement", "after", "again", "against", "agreement", "air", "all", "almost", "among", "amount", "amusement", "and", "angle", "angry", "animal", "answer", "ant", "any", "apparatus", "apple", "approval", "arch", "argument", "arm", "army", "art", "as", "at", "attack", "attempt", "attention", "attraction", "authority", "automatic", "awake", "baby", "back", "bad", "bag", "balance", "ball", "band", "base", "basin", "basket", "bath", "be", "beautiful", "because", "bed", "bee", "before", "behaviour", "belief", "bell", "bent", "berry", "between", "bird", "birth", "bit", "bite", "bitter", "black", "blade", "blood", "blow", "blue", "board", "boat", "body", "boiling", "bone", "book", "boot", "bottle", "box", "boy", "brain", "brake", "branch", "brass", "bread", "breath", "brick", "bridge", "bright", "broken", "brother", "brown", "brush", "bucket", "building", "bulb", "burn", "burst", "business", "but", "butter", "button", "by", "cake", "camera", "canvas", "card", "care", "carriage", "cart", "cat", "cause", "certain", "chain", "chalk", "chance", "change", "cheap", "cheese", "chemical", "chest", "chief", "chin", "church", "circle", "clean", "clear", "clock", "cloth", "cloud", "coal", "coat", "cold", "collar", "colour", "comb", "come", "comfort", "committee", "common", "company", "comparison", "competition", "complete", "complex", "condition", "connection", "conscious", "control", "cook", "copper", "copy", "cord", "cork", "cotton", "cough", "country", "cover", "cow", "crack", "credit", "crime", "cruel", "crush", "cry", "cup", "cup", "current", "curtain", "curve", "cushion", "damage", "danger", "dark", "daughter", "day", "dead", "dear", "death", "debt", "decision", "deep", "degree", "delicate", "dependent", "design", "desire", "destruction", "detail", "development", "different", "digestion", "direction", "dirty", "discovery", "discussion", "disease", "disgust", "distance", "distribution", "division", "do", "dog", "door", "doubt", "down", "drain", "drawer", "dress", "drink", "driving", "drop", "dry", "dust", "ear", "early", "earth", "east", "edge", "education", "effect", "egg", "elastic", "electric", "end", "engine", "enough", "equal", "error", "even", "event", "ever", "every", "example", "exchange", "existence", "expansion", "experience", "expert", "eye", "face", "fact", "fall", "FALSE", "family", "far", "farm", "fat", "father", "fear", "feather", "feeble", "feeling", "female", "fertile", "fiction", "field", "fight", "finger", "fire", "first", "fish", "fixed", "flag", "flame", "flat", "flight", "floor", "flower", "fly", "fold", "food", "foolish", "foot", "for", "force", "fork", "form", "forward", "fowl", "frame", "free", "frequent", "friend", "from", "front", "fruit", "full", "future", "garden", "general", "get", "girl", "give", "glass", "glove", "go", "goat", "gold", "good", "government", "grain", "grass", "great", "green", "grey", "grip", "group", "growth", "guide", "gun", "hair", "hammer", "hand", "hanging", "happy", "harbour", "hard", "harmony", "hat", "hate", "have", "he", "head", "healthy", "hear", "hearing", "heart", "heat", "help", "high", "history", "hole", "hollow", "hook", "hope", "horn", "horse", "hospital", "hour", "house", "how", "humour", "I", "ice", "idea", "if", "ill", "important", "impulse", "in", "increase", "industry", "ink", "insect", "instrument", "insurance", "interest", "invention", "iron", "island", "jelly", "jewel", "join", "journey", "judge", "jump", "keep", "kettle", "key", "kick", "kind", "kiss", "knee", "knife", "knot", "knowledge", "land", "language", "last", "late", "laugh", "law", "lead", "leaf", "learning", "leather", "left", "leg", "let", "letter", "level", "library", "lift", "light", "like", "limit", "line", "linen", "lip", "liquid", "list", "little", "living", "lock", "long", "look", "loose", "loss", "loud", "love", "low", "machine", "make", "male", "man", "manager", "map", "mark", "market", "married", "mass", "match", "material", "may", "meal", "measure", "meat", "medical", "meeting", "memory", "metal", "middle", "military", "milk", "mind", "mine", "minute", "mist", "mixed", "money", "monkey", "month", "moon", "morning", "mother", "motion", "mountain", "mouth", "move", "much", "muscle", "music", "nail", "name", "narrow", "nation", "natural", "near", "necessary", "neck", "need", "needle", "nerve", "net", "new", "news", "night", "no", "noise", "normal", "north", "nose", "not", "note", "now", "number", "nut", "observation", "of", "off", "offer", "office", "oil", "old", "on", "only", "open", "operation", "opinion", "opposite", "or", "orange", "order", "organization", "ornament", "other", "out", "oven", "over", "owner", "page", "pain", "paint", "paper", "parallel", "parcel", "part", "past", "paste", "payment", "peace", "pen", "pencil", "person", "physical", "picture", "pig", "pin", "pipe", "place", "plane", "plant", "plate", "play", "please", "pleasure", "plough", "pocket", "point", "poison", "polish", "political", "poor", "porter", "position", "possible", "pot", "potato", "powder", "power", "present", "price", "print", "prison", "private", "probable", "process", "produce", "profit", "property", "prose", "protest", "public", "pull", "pump", "punishment", "purpose", "push", "put", "quality", "question", "quick", "quiet", "quite", "rail", "rain", "range", "rat", "rate", "ray", "reaction", "reading", "ready", "reason", "receipt", "record", "red", "regret", "regular", "relation", "religion", "representative", "request", "respect", "responsible", "rest", "reward", "rhythm", "rice", "right", "ring", "river", "road", "rod", "roll", "roof", "room", "root", "rough", "round", "rub", "rule", "run", "sad", "safe", "sail", "salt", "same", "sand", "say", "scale", "school", "science", "scissors", "screw", "sea", "seat", "second", "secret", "secretary", "see", "seed", "seem", "selection", "self", "send", "sense", "separate", "serious", "servant", "sex", "shade", "shake", "shame", "sharp", "sheep", "shelf", "ship", "shirt", "shock", "shoe", "short", "shut", "side", "sign", "silk", "silver", "simple", "sister", "size", "skin", "skirt", "sky", "sleep", "slip", "slope", "slow", "small", "smash", "smell", "smile", "smoke", "smooth", "snake", "sneeze", "snow", "so", "soap", "society", "sock", "soft", "solid", "some", "", "son", "song", "sort", "sound", "soup", "south", "space", "spade", "special", "sponge", "spoon", "spring", "square", "stage", "stamp", "star", "start", "statement", "station", "steam", "steel", "stem", "step", "stick", "sticky", "stiff", "still", "stitch", "stocking", "stomach", "stone", "stop", "store", "story", "straight", "strange", "street", "stretch", "strong", "structure", "substance", "such", "sudden", "sugar", "suggestion", "summer", "sun", "support", "surprise", "sweet", "swim", "system", "table", "tail", "take", "talk", "tall", "taste", "tax", "teaching", "tendency", "test", "than", "that", "the", "then", "theory", "there", "thick", "thin", "thing", "this", "thought", "thread", "throat", "through", "through", "thumb", "thunder", "ticket", "tight", "till", "time", "tin", "tired", "to", "toe", "together", "tomorrow", "tongue", "tooth", "top", "touch", "town", "trade", "train", "transport", "tray", "tree", "trick", "trouble", "trousers", "TRUE", "turn", "twist", "umbrella", "under", "unit", "up", "use", "value", "verse", "very", "vessel", "view", "violent", "voice", "waiting", "walk", "wall", "war", "warm", "wash", "waste", "watch", "water", "wave", "wax", "way", "weather", "week", "weight", "well", "west", "wet", "wheel", "when", "where", "while", "whip", "whistle", "white", "who", "why", "wide", "will", "wind", "window", "wine", "wing", "winter", "wire", "wise", "with", "woman", "wood", "wool", "word", "work", "worm", "wound", "writing", "wrong", "year", "yellow", "yes", "yesterday", "you", "young"}; return arr; /* To see performance on a larger array, comment / delete the above "return arr;" line and uncomment the below code. * This will create a giant array by concatenating words from the above list.*/ /*ArrayList list = new ArrayList(); for (int i = 0; i < arr.length; i++) { int n = AssortedMethods.randomIntInRange(0, 1000); String s = arr[i]; for (int j = 0; j < n; j++) { int index = AssortedMethods.randomIntInRange(0, i); s += arr[index]; } list.add(s); list.add(arr[i]); } String[] ar = new String[list.size()]; for (int i = 0; i < list.size(); i++) { ar[i] = list.get(i); } return ar; */ } } ================================================ FILE: Java/Ch 17. Hard/Q17_16_The_Masseuse/QuestionA.java ================================================ package Q17_16_The_Masseuse; public class QuestionA { public static int maxMinutes(int[] massages) { return maxMinutes(massages, 0); } public static int maxMinutes(int[] massages, int index) { if (index >= massages.length) { // Out of bounds return 0; } /* Best with this reservation. */ int bestWith = massages[index] + maxMinutes(massages, index + 2); /* Best without this reservation. */ int bestWithout = maxMinutes(massages, index + 1); /* Return best of this subarray, starting from index. */ return Math.max(bestWith, bestWithout); } public static void main(String[] args) { int[] massages = {30, 15, 60, 75, 45, 15, 15, 45}; System.out.println(maxMinutes(massages)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_16_The_Masseuse/QuestionB.java ================================================ package Q17_16_The_Masseuse; public class QuestionB { public static int maxMinutes(int[] massages) { int[] memo = new int[massages.length]; return maxMinutes(massages, 0, memo); } public static int maxMinutes(int[] massages, int index, int[] memo) { if (index >= massages.length) { return 0; } if (memo[index] == 0) { int bestWith = massages[index] + maxMinutes(massages, index + 2, memo); int bestWithout = maxMinutes(massages, index + 1, memo); memo[index] = Math.max(bestWith, bestWithout); } return memo[index]; } public static void main(String[] args) { int[] massages = {2*15, 1*15, 4*15, 5*15, 3*15, 1*15, 1*15, 3*15}; System.out.println(maxMinutes(massages)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_16_The_Masseuse/QuestionC.java ================================================ package Q17_16_The_Masseuse; public class QuestionC { public static int maxMinutes(int[] massages) { /* Allocating two extra slots in the array so we don't have to do bounds * checking on lines 7 and 8. */ int[] memo = new int[massages.length + 2]; memo[massages.length] = 0; memo[massages.length + 1] = 0; for (int i = massages.length - 1; i >= 0; i--) { int bestWith = massages[i] + memo[i + 2]; int bestWithout = memo[i + 1]; memo[i] = Math.max(bestWith, bestWithout); } return memo[0]; } public static void main(String[] args) { int[] massages = {2*15, 1*15, 4*15, 5*15, 3*15, 1*15, 1*15, 3*15}; System.out.println(maxMinutes(massages)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_16_The_Masseuse/QuestionD.java ================================================ package Q17_16_The_Masseuse; public class QuestionD { public static int maxMinutes(int[] massages) { int oneAway = 0; int twoAway = 0; for (int i = massages.length - 1; i >= 0; i--) { int bestWith = massages[i] + twoAway; int bestWithout = oneAway; int current = Math.max(bestWith, bestWithout); twoAway = oneAway; oneAway = current; } return oneAway; } public static void main(String[] args) { int[] massages = {2*15, 1*15, 4*15, 5*15, 3*15, 1*15, 1*15, 3*15}; System.out.println(maxMinutes(massages)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_16_The_Masseuse/Tester.java ================================================ package Q17_16_The_Masseuse; import CtCILibrary.AssortedMethods; public class Tester { public static int[] generateRandomArray(int size) { int[] array = AssortedMethods.randomArray(size, 1, 10); for (int i = 0; i < array.length; i++) { array[i] *= 15; } return array; } public static int[] sumEveryOther(int[] array) { int first = 0; for (int i = 0; i < array.length; i += 2) { first += array[i]; } int second = 0; for (int i = 1; i < array.length; i += 2) { second += array[i]; } int[] a = {first, second}; return a; } public static void main(String[] args) { int cutOff = 5; int numTests = 100; for (int i = 1; i < cutOff; i++) { int[] massages = generateRandomArray(i); int maxA = QuestionA.maxMinutes(massages); int maxB = QuestionB.maxMinutes(massages); int maxC = QuestionC.maxMinutes(massages); int maxD = QuestionD.maxMinutes(massages); int[] list = sumEveryOther(massages); if (maxA != list[0] && maxA != list[1]) { System.out.println(AssortedMethods.arrayToString(massages)); System.out.println(maxA + ", " + maxB + ", " + maxC + ", " + maxD); } if (maxA != maxB || maxB != maxC || maxC != maxD) { System.out.println("Error at " + i + ": " + maxA + ", " + maxB + ", " + maxC + ", " + maxD); } } for (int i = cutOff; i < numTests; i++) { int[] massages = generateRandomArray(i); int maxB = QuestionB.maxMinutes(massages); int maxC = QuestionC.maxMinutes(massages); int maxD = QuestionD.maxMinutes(massages); int[] list = sumEveryOther(massages); if (maxB != list[0] && maxB != list[1]) { System.out.println(AssortedMethods.arrayToString(massages)); System.out.println(maxB + ", " + maxC + ", " + maxD); } if (maxB != maxC || maxC != maxD) { System.out.println("Error at " + i + ": " + maxB + ", " + maxC + ", " + maxD); } } System.out.println("All tests have run."); } } ================================================ FILE: Java/Ch 17. Hard/Q17_17_Multi_Search/QuestionA.java ================================================ package Q17_17_Multi_Search; import java.util.ArrayList; import java.util.HashMap; import CtCILibrary.HashMapList; public class QuestionA { public static boolean isSubstringAtLocation(String big, String small, int offset) { for (int i = 0; i < small.length(); i++) { if (big.charAt(offset + i) != small.charAt(i)) { return false; } } return true; } public static ArrayList search(String big, String small) { ArrayList locations = new ArrayList(); for (int i = 0; i < big.length() - small.length() + 1; i++) { if (isSubstringAtLocation(big, small, i)) { locations.add(i); } } return locations; } public static HashMapList searchAll(String big, String[] smalls) { HashMapList lookup = new HashMapList(); for (String small : smalls) { ArrayList locations = search(big, small); lookup.put(small, locations); } return lookup; } public static void main(String[] args) { String big = "mississippi"; String[] smalls = {"is", "ppi", "hi", "sis", "i", "mississippi"}; HashMapList locations = searchAll(big, smalls); System.out.println(locations.toString()); } } ================================================ FILE: Java/Ch 17. Hard/Q17_17_Multi_Search/QuestionB.java ================================================ package Q17_17_Multi_Search; import java.util.ArrayList; import java.util.HashMap; import CtCILibrary.HashMapList; public class QuestionB { public static void subtractValue(ArrayList locations, int delta) { if (locations == null) return; for (int i = 0; i < locations.size(); i++) { locations.set(i, locations.get(i) - delta); } } public static Trie createTrieFromString(String s) { Trie trie = new Trie(); for (int i = 0; i < s.length(); i++) { String suffix = s.substring(i); trie.insertString(suffix, i); } return trie; } public static HashMapList searchAll(String big, String[] smalls) { HashMapList lookup = new HashMapList(); Trie tree = createTrieFromString(big); for (String s : smalls) { /* Get terminating location of each occurrence.*/ ArrayList locations = tree.search(s); /* Adjust to starting location. */ subtractValue(locations, s.length()); /* Insert. */ lookup.put(s, locations); } return lookup; } public static void main(String[] args) { String big = "mississippi"; String[] smalls = {"is", "ppi", "hi", "sis", "i", "mississippi"}; HashMapList locations = searchAll(big, smalls); System.out.println(locations.toString()); } } ================================================ FILE: Java/Ch 17. Hard/Q17_17_Multi_Search/QuestionC.java ================================================ package Q17_17_Multi_Search; import java.util.ArrayList; import CtCILibrary.HashMapList; public class QuestionC { public static Trie createTreeFromStrings(String[] smalls, int maxSize) { Trie tree = new Trie(); for (String s : smalls) { if (s.length() <= maxSize) { tree.insertString(s, 0); } } return tree; } public static ArrayList findStringsAtLoc(TrieNode root, String big, int start) { ArrayList strings = new ArrayList(); int index = start; while (index < big.length()) { root = root.getChild(big.charAt(index)); if (root == null) break; if (root.terminates()) { strings.add(big.substring(start, index + 1)); } index++; } return strings; } public static void insertIntoHashMap(ArrayList strings, HashMapList map, int index) { for (String s : strings) { map.put(s, index); } } public static HashMapList searchAll(String big, String[] smalls) { HashMapList lookup = new HashMapList(); TrieNode root = createTreeFromStrings(smalls, big.length()).getRoot(); for (int i = 0; i < big.length(); i++) { ArrayList strings = findStringsAtLoc(root, big, i); insertIntoHashMap(strings, lookup, i); } return lookup; } public static void main(String[] args) { String big = "mississippi"; String[] smalls = {"is", "ppi", "hi", "sis", "i", "mississippi"}; HashMapList locations = searchAll(big, smalls); System.out.println(locations.toString()); } } ================================================ FILE: Java/Ch 17. Hard/Q17_17_Multi_Search/Trie.java ================================================ package Q17_17_Multi_Search; import java.util.ArrayList; public class Trie { private TrieNode root = new TrieNode(); public ArrayList search(String s) { return root.search(s); } public void insertString(String str, int location) { root.insertString(str, location); } public TrieNode getRoot() { return root; } } ================================================ FILE: Java/Ch 17. Hard/Q17_17_Multi_Search/TrieNode.java ================================================ package Q17_17_Multi_Search; import java.util.ArrayList; import java.util.HashMap; public class TrieNode { private HashMap children; private ArrayList indexes; public TrieNode() { children = new HashMap(); indexes = new ArrayList(); } public void insertString(String s, int index) { if (s == null) return; indexes.add(index); if (s.length() > 0) { char value = s.charAt(0); TrieNode child = null; if (children.containsKey(value)) { child = children.get(value); } else { child = new TrieNode(); children.put(value, child); } String remainder = s.substring(1); child.insertString(remainder, index + 1); } else { children.put('\0', null); } } public ArrayList search(String s) { if (s == null || s.length() == 0) { return indexes; } else { char first = s.charAt(0); if (children.containsKey(first)) { String remainder = s.substring(1); return children.get(first).search(remainder); } } return null; } public boolean terminates() { return children.containsKey('\0'); } public TrieNode getChild(char c) { return children.get(c); } } ================================================ FILE: Java/Ch 17. Hard/Q17_18_Shortest_Supersequence/HeapNode.java ================================================ package Q17_18_Shortest_Supersequence; public class HeapNode implements Comparable { public int locationWithinList; public int listId; public HeapNode(int location, int list) { locationWithinList = location; listId = list; } @Override public int compareTo(HeapNode n) { return locationWithinList - n.locationWithinList; } } ================================================ FILE: Java/Ch 17. Hard/Q17_18_Shortest_Supersequence/QuestionA.java ================================================ package Q17_18_Shortest_Supersequence; public class QuestionA { /* Find next instance of element starting from index. */ public static int findNextInstance(int[] array, int element, int index) { for (int i = index; i < array.length; i++) { if (array[i] == element) { return i; } } return -1; } /* Given an index, find the closure (i.e., the element which terminates a complete * subarray containing all elements in smallArray). This will be the max of the * next locations of each element in smallArray. */ public static int findClosure(int[] bigArray, int[] smallArray, int index) { int max = -1; for (int i = 0; i < smallArray.length; i++) { int next = findNextInstance(bigArray, smallArray[i], index); if (next == -1) { return -1; } max = Math.max(next, max); } return max; } public static Range shortestSupersequence(int[] bigArray, int[] smallArray) { int bestStart = -1; int bestEnd = -1; for (int i = 0; i < bigArray.length; i++) { int end = findClosure(bigArray, smallArray, i); if (end == -1) break; if (bestStart == -1 || end - i < bestEnd - bestStart) { bestStart = i; bestEnd = end; } } if (bestStart < 0 || bestEnd < 0) { return null; } return new Range(bestStart, bestEnd); } public static void main(String[] args) { int[] array = {7, 5, 9, 0, 2, 1, 3, 5, 7, 9, 1, 1, 5, 8, 9, 7}; int[] set = {1, 5, 9}; System.out.println(array.length); Range shortest = shortestSupersequence(array, set); System.out.println(shortest.getStart() + ", " + shortest.getEnd()); } } ================================================ FILE: Java/Ch 17. Hard/Q17_18_Shortest_Supersequence/QuestionB.java ================================================ package Q17_18_Shortest_Supersequence; public class QuestionB { /* Do backwards sweep to get a list of the next occurrence of value from each index. */ public static int[] getNextElement(int[] bigArray, int value) { int next = -1; int[] nexts = new int[bigArray.length]; for (int i = bigArray.length - 1; i >= 0; i--) { if (bigArray[i] == value) { next = i; } nexts[i] = next; } return nexts; } /* Create table of next occurrences. */ public static int[][] getNextElementsMulti(int[] big, int[] small) { int[][] nextElements = new int[small.length][big.length]; for (int i = 0; i < small.length; i++) { nextElements[i] = getNextElement(big, small[i]); } return nextElements; } /* Given an index and the table of next elements, find the closure * for this index (which will be the min of this column. */ public static int getClosureForIndex(int[][] nextElements, int index) { int max = -1; for (int i = 0; i < nextElements.length; i++) { if (nextElements[i][index] == -1) { return -1; } max = Math.max(max, nextElements[i][index]); } return max; } /* Get closure for each index. */ public static int[] getClosures(int[][] nextElements) { int[] maxNextElement = new int[nextElements[0].length]; for (int i = 0; i < nextElements[0].length; i++) { maxNextElement[i] = getClosureForIndex(nextElements, i); } return maxNextElement; } /* Get shortest closure. */ public static Range getShortestClosure(int[] closures) { int bestStart = -1; int bestEnd = -1; for (int i = 0; i < closures.length; i++) { if (closures[i] == -1) { break; } int current = closures[i] - i; if (bestStart == -1 || current < bestEnd - bestStart) { bestStart = i; bestEnd = closures[i]; } } if (bestStart < 0 || bestEnd < 0) { return null; } return new Range(bestStart, bestEnd); } public static Range shortestSupersequence(int[] big, int[] small) { int[][] nextElements = getNextElementsMulti(big, small); int[] closures = getClosures(nextElements); return getShortestClosure(closures); } public static void main(String[] args) { int[] array = {9, 5, 1, 0, 2, 1, 3, 5, 7, 9, 1, 1, 5, 8, 9, 7}; int[] set = {1, 5, 9}; System.out.println(array.length); Range shortest = shortestSupersequence(array, set); System.out.println(shortest.getStart() + ", " + shortest.getEnd()); } } ================================================ FILE: Java/Ch 17. Hard/Q17_18_Shortest_Supersequence/QuestionC.java ================================================ package Q17_18_Shortest_Supersequence; public class QuestionC { public static Range shortestSupersequence(int[] big, int[] small) { int[] closures = getClosures(big, small); return getShortestClosure(closures); } /* Get closure for each index. */ public static int[] getClosures(int[] big, int[] small) { int[] closure = new int[big.length]; for (int i = 0; i < small.length; i++) { sweepForClosure(big, closure, small[i]); } return closure; } /* Do backwards sweep and update the closures list with the next occurrence of value, if it's later than the current closure*/ public static void sweepForClosure(int[] big, int[] closures, int value) { int next = -1; for (int i = big.length - 1; i >= 0; i--) { if (big[i] == value) { next = i; } if ((next == -1 || closures[i] < next) && (closures[i] != -1)) { closures[i] = next; } } } /* Get shortest closure. */ public static Range getShortestClosure(int[] closures) { if (closures == null || closures.length == 0) return null; Range shortest = new Range(0, closures[0]); for (int i = 1; i < closures.length; i++) { if (closures[i] == -1) { break; } Range range = new Range(i, closures[i]); if (!shortest.shorterThan(range)) { shortest = range; } } if (shortest.length() <= 0) return null; return shortest; } public static void main(String[] args) { int[] array = {9, 2, 4, 6, 2, 5, 9}; int[] set = {1, 5, 9}; System.out.println(array.length); Range shortest = shortestSupersequence(array, set); if (shortest == null) { System.out.println("No valid subsequence."); } else { System.out.println(shortest.getStart() + ", " + shortest.getEnd()); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_18_Shortest_Supersequence/QuestionD.java ================================================ package Q17_18_Shortest_Supersequence; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.PriorityQueue; import java.util.Queue; import CtCILibrary.HashMapList; public class QuestionD { public static Range getShortestClosure(ArrayList> lists) { PriorityQueue minHeap = new PriorityQueue(); int max = Integer.MIN_VALUE; /* Insert min element from each list. */ for (int i = 0; i < lists.size(); i++) { Queue list = lists.get(i); if (list == null || list.size() == 0) { return null; } int head = list.remove(); minHeap.add(new HeapNode(head, i)); max = Math.max(max, head); } int min = minHeap.peek().locationWithinList; int bestRangeMin = min; int bestRangeMax = max; while (true) { /* Remove min node. */ HeapNode n = minHeap.poll(); Queue list = lists.get(n.listId); /* Compare range to best range. */ min = n.locationWithinList; if (max - min < bestRangeMax - bestRangeMin) { bestRangeMax = max; bestRangeMin = min; } /* If there are no more elements, then there's no more subsequences and we can break. */ if (list.size() == 0) { break; } /* Add new head of list to heap. */ n.locationWithinList = list.remove(); minHeap.add(n); max = Math.max(max, n.locationWithinList); } return new Range(bestRangeMin, bestRangeMax); } /* Get list of queues (linked lists) storing the indices at which * each element in smallArray appears in bigArray. */ public static ArrayList> getLocationsForElements(int[] big, int[] small) { /* Initialize hash map from item value to locations. */ HashMap> itemLocations = new HashMap>(); for (int s : small) { Queue queue = new LinkedList(); itemLocations.put(s, queue); } /* Walk through big array, adding the item locations to hash map */ for (int i = 0; i < big.length; i++) { Queue queue = itemLocations.get(big[i]); if (queue != null) { queue.add(i); } } ArrayList> allLocations = new ArrayList>(); allLocations.addAll(itemLocations.values()); return allLocations; } public static Range shortestSupersequence(int[] big, int[] small) { ArrayList> locations = getLocationsForElements(big, small); if (locations == null) return null; return getShortestClosure(locations); } public static void main(String[] args) { int[] array = {7, 5, 9, 0, 2, 1, 3, 5, 7, 9, 1, 1, 5, 8, 8, 9, 7}; int[] set = {1, 5, 9}; System.out.println(array.length); Range shortest = shortestSupersequence(array, set); if (shortest == null) { System.out.println("not found"); } else { System.out.println(shortest.getStart() + ", " + shortest.getEnd()); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_18_Shortest_Supersequence/QuestionE.java ================================================ package Q17_18_Shortest_Supersequence; import java.util.HashMap; public class QuestionE { /* CountedLookup acts a simple hash table with increment/decrement functions * which can efficiently tell you how many values in the hash table are * at least one. */ public static class CountedLookup { HashMap lookup = new HashMap(); int fulfilled = 0; public CountedLookup(int[] array) { for (int a : array) { lookup.put(a, 0); } } public boolean contains(int v) { return lookup.containsKey(v); } public void incrementIfFound(int v) { if (!contains(v)) return; if (lookup.getOrDefault(v, 0) == 0) { fulfilled += 1; } lookup.put(v, lookup.getOrDefault(v, 0) + 1); } public void decrementIfFound(int v) { if (!contains(v)) return; lookup.put(v, lookup.getOrDefault(v, 0) - 1); if (lookup.getOrDefault(v, 0) == 0) { fulfilled -= 1; } } public boolean areAllFulfilled() { return fulfilled == lookup.keySet().size(); } } /* Find shortest subarray which contains all elements from small. */ public static Range shortestSupersequence(int[] big, int[] small) { if (big.length < small.length) return null; CountedLookup countedLookup = new CountedLookup(small); Range best = null; int right = 0; countedLookup.incrementIfFound(big[0]); // Take in left for (int left = 0; left < big.length; left++) { right = findClosure(big, right, countedLookup); // Move right to closure end if (!countedLookup.areAllFulfilled()) { // No closure -> break break; } /* Update biggest range. */ int length = right - left + 1; if (best == null || best.length() > length) { best = new Range(left, right); } countedLookup.decrementIfFound(big[left]); // Drop leftmost element } return best; } /* Find closure for index, and update countedlookup */ public static int findClosure(int[] big, int startIndex, CountedLookup countedLookup) { int index = startIndex; /* Move forward until everything is fulfilled. */ while (!countedLookup.areAllFulfilled() && index + 1 < big.length) { index++; countedLookup.incrementIfFound(big[index]); } return index; } public static void main(String[] args) { int[] array = {7, 5, 9, 0, 2, 1, 3, 5, 7, 9, 1, 1, 5, 8, 8, 9, 7}; int[] set = {1, 5, 9}; Range shortest = shortestSupersequence(array, set); if (shortest == null) { System.out.println("not found"); } else { System.out.println(shortest.toString()); for (int i = shortest.getStart(); i <= shortest.getEnd(); i++) { System.out.print(array[i] + ", "); } } } } ================================================ FILE: Java/Ch 17. Hard/Q17_18_Shortest_Supersequence/Range.java ================================================ package Q17_18_Shortest_Supersequence; public class Range { private int start; private int end; public Range(int s, int e) { start = s; end = e; } public int length() { return end - start + 1; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + end; result = prime * result + start; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Range other = (Range) obj; if (end != other.end) return false; if (start != other.start) return false; return true; } @Override public String toString() { return "Range [start=" + start + ", end=" + end + "]"; } public boolean shorterThan(Range other) { return length() < other.length(); } public int getStart() { return start; } public int getEnd() { return end; } } ================================================ FILE: Java/Ch 17. Hard/Q17_18_Shortest_Supersequence/Tester.java ================================================ package Q17_18_Shortest_Supersequence; import CtCILibrary.AssortedMethods; public class Tester { public static boolean equivalent(Range[] ranges) { if (ranges[0] == null) { for (Range r : ranges) { if (r != null) return false; } return true; } int targetLength = ranges[0].length(); for (Range r : ranges) { int length = r == null ? 0 : r.length(); if (targetLength != length) { return false; } } return true; } public static void main(String[] args) { for (int i = 0; i < 100; i++) { int[] array = AssortedMethods.randomArray(i, 0, 15); int[] set = {0, 5, 8, 10}; Range[] ranges = new Range[5]; ranges[0] = QuestionA.shortestSupersequence(array, set); ranges[1] = QuestionB.shortestSupersequence(array, set); ranges[2] = QuestionC.shortestSupersequence(array, set); ranges[3] = QuestionD.shortestSupersequence(array, set); ranges[4] = QuestionE.shortestSupersequence(array, set); if (!equivalent(ranges)) { System.out.println("Mismatching."); } else { int length = ranges[0] == null ? 0 : ranges[0].length(); System.out.println("Matching: " + length); } } } } ================================================ FILE: Java/Ch 17. Hard/Q17_19_Missing_Two/QuestionA.java ================================================ package Q17_19_Missing_Two; import java.math.BigInteger; public class QuestionA { public static BigInteger productToN(int n) { BigInteger fullProduct = new BigInteger("1"); for (int i = 2; i <= n; i++) { fullProduct = fullProduct.multiply(new BigInteger(i + "")); } return fullProduct; } public static int missingOne(int[] array) { BigInteger fullProduct = productToN(array.length + 1); BigInteger actualProduct = new BigInteger("1"); for (int i = 0; i < array.length; i++) { BigInteger value = new BigInteger(array[i] + ""); actualProduct = actualProduct.multiply(value); } BigInteger missingNumber = fullProduct.divide(actualProduct); return Integer.parseInt(missingNumber.toString()); } public static void main(String[] args) { int max = 100; int x = 8; int len = max - 1; int count = 0; int[] array = new int[len]; for (int i = 1; i <= max; i++) { if (i != x) { array[count] = i; count++; } } System.out.println(x); int solution = missingOne(array); System.out.println(solution); } } ================================================ FILE: Java/Ch 17. Hard/Q17_19_Missing_Two/QuestionB.java ================================================ package Q17_19_Missing_Two; public class QuestionB { public static int missingOne(int[] array) { int max_value = array.length + 1; int remainder = max_value * (max_value + 1) / 2; for (int i = 0; i < array.length; i++) { remainder -= array[i]; } return remainder; } public static void main(String[] args) { int max = 100; int x = 8; int len = max - 1; int count = 0; int[] array = new int[len]; for (int i = 1; i <= max; i++) { if (i != x) { array[count] = i; count++; } } System.out.println(x); int solution = missingOne(array); System.out.println(solution); } } ================================================ FILE: Java/Ch 17. Hard/Q17_19_Missing_Two/QuestionC.java ================================================ package Q17_19_Missing_Two; public class QuestionC { public static int squareSumToN(int n, int power) { int sum = 0; for (int i = 1; i <= n; i++) { sum += (int) Math.pow(i, power); } return sum; } public static int[] solveEquation(int r1, int r2) { /* ax^2 + bx + c * --> * x = [-b +- sqrt(b^2 - 4ac)] / 2a * In this case, it has to be a + not a - * */ int a = 2; int b = -2 * r1; int c = r1 * r1 - r2; double part1 = -1 * b; double part2 = Math.sqrt(b*b - 4 * a * c); double part3 = 2 * a; int solutionX = (int) ((part1 + part2) / part3); int solutionY = r1 - solutionX; int solutionX2 = (int) ((part1 - part2) / part3); int solutionY2 = r1 - solutionX2; System.out.println("Alternate: (" + solutionX2 + ", " + solutionY2 + ")"); int[] solution = {solutionX, solutionY}; return solution; } public static int[] missingTwo(int[] array) { int max_value = array.length + 2; int rem_square = squareSumToN(max_value, 2); int rem_one = max_value * (max_value + 1) / 2; for (int i = 0; i < array.length; i++) { rem_square -= array[i] * array[i]; rem_one -= array[i]; } return solveEquation(rem_one, rem_square); } public static void main(String[] args) { int max = 100; for (int x = 1; x < max; x++) { for (int y = 1; y < max; y++) { if (x != y) { int len = max - 2; int count = 0; int[] array = new int[len]; for (int i = 1; i <= max; i++) { if (i != x && i != y) { array[count] = i; count++; } } int[] solution = missingTwo(array); if ((solution[0] == x && solution[1] == y) || (solution[1] == x && solution[0] == y)) { System.out.println("Success: " + solution[0] + ", " + solution[1]); } else { System.out.println("Error: " + x + ", " + y + " | " + solution[0] + ", " + solution[1]); } } } } } } ================================================ FILE: Java/Ch 17. Hard/Q17_20_Continuous_Median/MaxHeapComparator.java ================================================ package Q17_20_Continuous_Median; import java.util.Comparator; public class MaxHeapComparator implements Comparator{ // Comparator that sorts integers from highest to lowest @Override public int compare(Integer o1, Integer o2) { // TODO Auto-generated method stub if (o1 < o2) return 1; else if (o1 == o2) return 0; else return -1; } } ================================================ FILE: Java/Ch 17. Hard/Q17_20_Continuous_Median/MinHeapComparator.java ================================================ package Q17_20_Continuous_Median; import java.util.Comparator; public class MinHeapComparator implements Comparator{ // Comparator that sorts integers from lowest to highest @Override public int compare(Integer o1, Integer o2) { if (o1 > o2) return 1; else if (o1 == o2) return 0; else return -1; } } ================================================ FILE: Java/Ch 17. Hard/Q17_20_Continuous_Median/Question.java ================================================ package Q17_20_Continuous_Median; import java.util.Arrays; import java.util.Comparator; import java.util.PriorityQueue; public class Question { private static Comparator maxHeapComparator; private static Comparator minHeapComparator; private static PriorityQueue maxHeap; private static PriorityQueue minHeap; public static void addNewNumber(int randomNumber) { /* Note: addNewNumber maintains a condition that maxHeap.size() >= minHeap.size() */ if (maxHeap.size() == minHeap.size()) { if ((minHeap.peek() != null) && randomNumber > minHeap.peek()) { maxHeap.offer(minHeap.poll()); minHeap.offer(randomNumber); } else { maxHeap.offer(randomNumber); } } else { if(randomNumber < maxHeap.peek()){ minHeap.offer(maxHeap.poll()); maxHeap.offer(randomNumber); } else { minHeap.offer(randomNumber); } } } public static double getMedian() { /* maxHeap is always at least as big as minHeap. So if maxHeap is empty, then minHeap is also. */ if (maxHeap.isEmpty()) { return 0; } if (maxHeap.size() == minHeap.size()) { return ((double)minHeap.peek() + (double) maxHeap.peek()) / 2; } else { /* If maxHeap and minHeap are of different sizes, then maxHeap must have one extra element. Return maxHeap�s top element.*/ return maxHeap.peek(); } } public static void addNewNumberAndPrintMedian(int randomNumber) { addNewNumber(randomNumber); System.out.println("Random Number = " + randomNumber); printMinHeapAndMaxHeap(); System.out.println("\nMedian = " + getMedian() + "\n"); } public static void printMinHeapAndMaxHeap(){ Integer[] minHeapArray = minHeap.toArray( new Integer[minHeap.size()]); Integer[] maxHeapArray = maxHeap.toArray( new Integer[maxHeap.size()]); Arrays.sort(minHeapArray, maxHeapComparator); Arrays.sort(maxHeapArray, maxHeapComparator); System.out.print("MinHeap ="); for (int i = minHeapArray.length - 1; i >= 0 ; i--){ System.out.print(" " + minHeapArray[i]); } System.out.print("\nMaxHeap ="); for (int i = 0; i < maxHeapArray.length; i++){ System.out.print(" " + maxHeapArray[i]); } } public static void main(String[] args) { int arraySize = 10; int range = 7; maxHeapComparator = new MaxHeapComparator(); minHeapComparator = new MinHeapComparator(); maxHeap = new PriorityQueue(arraySize - arraySize/2, maxHeapComparator); minHeap = new PriorityQueue(arraySize/2, minHeapComparator); for(int i = 0; i < arraySize; i++) { int randomNumber = (int) (Math.random( ) * (range+1)); addNewNumberAndPrintMedian(randomNumber); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_21_Volume_of_Histogram/HistogramData.java ================================================ package Q17_21_Volume_of_Histogram; public class HistogramData { private int height; private int leftMaxIndex = -1; private int rightMaxIndex = -1; public HistogramData(int v) { height = v; } public int getHeight() { return height; } public int getLeftMaxIndex() { return leftMaxIndex; } public void setLeftMaxIndex(int idx) { leftMaxIndex = idx; }; public int getRightMaxIndex() { return rightMaxIndex; } public void setRightMaxIndex(int idx) { rightMaxIndex = idx; }; } ================================================ FILE: Java/Ch 17. Hard/Q17_21_Volume_of_Histogram/QuestionA.java ================================================ package Q17_21_Volume_of_Histogram; public class QuestionA { public static int findIndexOfMax(int[] histogram, int start, int end) { int indexOfMax = start; for (int i = start + 1; i <= end; i++) { if (histogram[i] > histogram[indexOfMax]) { indexOfMax = i; } } return indexOfMax; } public static int borderedVolume(int[] histogram, int start, int end) { if (start >= end) return 0; int min = Math.min(histogram[start], histogram[end]); int sum = 0; for (int i = start + 1; i < end; i++) { sum += min - histogram[i]; } return sum; } public static int subgraphVolume(int[] histogram, int start, int end, boolean isLeft) { if (start >= end) return 0; int sum = 0; if (isLeft) { int max = findIndexOfMax(histogram, start, end - 1); sum += borderedVolume(histogram, max, end); sum += subgraphVolume(histogram, start, max, isLeft); } else { int max = findIndexOfMax(histogram, start + 1, end); sum += borderedVolume(histogram, start, max); sum += subgraphVolume(histogram, max, end, isLeft); } return sum; } public static int computeHistogramVolume(int[] histogram) { int start = 0; int end = histogram.length - 1; int max = findIndexOfMax(histogram, start, end); int leftVolume = subgraphVolume(histogram, start, max, true); int rightVolume = subgraphVolume(histogram, max, end, false); return leftVolume + rightVolume; } public static void main(String[] args) { int[] histogram = {0, 0, 4, 0, 0, 6, 0, 0, 3, 0, 8, 0, 2, 0, 5, 2, 0, 3, 0, 0}; int result = computeHistogramVolume(histogram); System.out.println(result); } } ================================================ FILE: Java/Ch 17. Hard/Q17_21_Volume_of_Histogram/QuestionB.java ================================================ package Q17_21_Volume_of_Histogram; public class QuestionB { public static int borderedVolume(HistogramData[] data, int start, int end) { if (start >= end) return 0; int min = Math.min(data[start].getHeight(), data[end].getHeight()); int sum = 0; for (int i = start + 1; i < end; i++) { sum += min - data[i].getHeight(); } return sum; } public static int subgraphVolume(HistogramData[] histogram, int start, int end, boolean isLeft) { if (start >= end) return 0; int sum = 0; if (isLeft) { int max = histogram[end - 1].getLeftMaxIndex(); sum += borderedVolume(histogram, max, end); sum += subgraphVolume(histogram, start, max, isLeft); } else { int max = histogram[start + 1].getRightMaxIndex(); sum += borderedVolume(histogram, start, max); sum += subgraphVolume(histogram, max, end, isLeft); } return sum; } public static HistogramData[] createHistogramData(int[] histo) { HistogramData[] histogram = new HistogramData[histo.length]; for (int i = 0; i < histo.length; i++) { histogram[i] = new HistogramData(histo[i]); } /* Set left max index. */ int maxIndex = 0; for (int i = 0; i < histo.length; i++) { if (histo[maxIndex] < histo[i]) { maxIndex = i; } histogram[i].setLeftMaxIndex(maxIndex); } /* Set right max index. */ maxIndex = histogram.length - 1; for (int i = histogram.length - 1; i >= 0; i--) { if (histo[maxIndex] < histo[i]) { maxIndex = i; } histogram[i].setRightMaxIndex(maxIndex); } return histogram; } public static int computeHistogramVolume(int[] histogram) { int start = 0; int end = histogram.length - 1; HistogramData[] data = createHistogramData(histogram); int max = data[0].getRightMaxIndex(); int leftVolume = subgraphVolume(data, start, max, true); int rightVolume = subgraphVolume(data, max, end, false); return leftVolume + rightVolume; } public static void main(String[] args) { int[] histogram = {0, 0, 4, 0, 0, 6, 0, 0, 3, 0, 8, 0, 2, 0, 5, 2, 0, 3, 0, 0}; int result = computeHistogramVolume(histogram); System.out.println(result); } } ================================================ FILE: Java/Ch 17. Hard/Q17_21_Volume_of_Histogram/QuestionC.java ================================================ package Q17_21_Volume_of_Histogram; public class QuestionC { /* Go through each bar and compute the volume of water above it. * Volume of water at a bar = * height - min(tallest bar on left, tallest bar on right) * [where above equation is positive] * Compute the left max in the first sweep, then sweep again to * compute the right max, minimum of the bar heights, and the * delta. */ public static int computeHistogramVolume(int[] histo) { /* Get left max */ int[] leftMaxes = new int[histo.length]; int leftMax = histo[0]; for (int i = 0; i < histo.length; i++) { leftMax = Math.max(leftMax, histo[i]); leftMaxes[i] = leftMax; } int sum = 0; /* Get right max */ int rightMax = histo[histo.length - 1]; for (int i = histo.length - 1; i >= 0; i--) { rightMax = Math.max(rightMax, histo[i]); int secondTallest = Math.min(rightMax, leftMaxes[i]); /* If there are taller things on the left and right side, then there is * water above this bar. Compute the volume and add to the sum. */ if (secondTallest > histo[i]) { sum += secondTallest - histo[i]; } } return sum; } public static void main(String[] args) { int[] histogram = {0, 0, 4, 0, 0, 6, 0, 0, 3, 0, 8, 0, 2, 0, 5, 2, 0, 3, 0, 0}; int result = computeHistogramVolume(histogram); System.out.println(result); } } ================================================ FILE: Java/Ch 17. Hard/Q17_21_Volume_of_Histogram/Tester.java ================================================ package Q17_21_Volume_of_Histogram; public class Tester { /** * @param args */ public static void main(String[] args) { String[][] tests = {{"6 1 8 1 2 1 5", "16"}, {"5 1 2 1 8", "11"}, {"15 12 20 16 17 25", "10"}, {"28 25 26", "1"}, {"28 25 28", "3"}, {"22", "0"}, {"22 22", "0"}, {"0 0 4 0 0 6 0 0 3 0 8 0 2 0 5 2 0 3 0 0", "46"}}; for (int i = 0; i < tests.length; i++) { String input = tests[i][0]; String output = tests[i][1]; String[] inputStringArray = input.split(" "); int[] histogram = new int[inputStringArray.length]; for (int j = 0; j < inputStringArray.length; j++) { histogram[j] = Integer.parseInt(inputStringArray[j]); } int targetVolume = Integer.parseInt(output); int volumeA = QuestionA.computeHistogramVolume(histogram); int volumeB = QuestionB.computeHistogramVolume(histogram); int volumeC = QuestionC.computeHistogramVolume(histogram); if (volumeA != targetVolume || volumeB != targetVolume || volumeC != targetVolume) { System.out.println("FAILURE: " + input + " -> wanted " + output + " but got (" + volumeA + ", " + volumeB + ", " + volumeC + ")"); } else { System.out.println("SUCCESS: " + input + " -> " + targetVolume); } } } } ================================================ FILE: Java/Ch 17. Hard/Q17_22_Word_Transformer/BFSData.java ================================================ package Q17_22_Word_Transformer; import java.util.HashMap; import java.util.LinkedList; import java.util.Queue; public class BFSData { public Queue toVisit = new LinkedList(); public HashMap visited = new HashMap(); public BFSData(String root) { PathNode sourcePath = new PathNode(root, null); toVisit.add(sourcePath); visited.put(root, sourcePath); } public boolean isFinished() { return toVisit.isEmpty(); } } ================================================ FILE: Java/Ch 17. Hard/Q17_22_Word_Transformer/PathNode.java ================================================ package Q17_22_Word_Transformer; import java.util.LinkedList; public class PathNode { private String word = null; private PathNode previousNode = null; public PathNode(String word, PathNode previous) { this.word = word; previousNode = previous; } public String getWord() { return word; } /* Traverse path and return linked list of nodes. */ public LinkedList collapse(boolean startsWithRoot) { LinkedList path = new LinkedList(); PathNode node = this; while (node != null) { if (startsWithRoot) { path.addLast(node.word); } else { path.addFirst(node.word); } node = node.previousNode; } return path; } } ================================================ FILE: Java/Ch 17. Hard/Q17_22_Word_Transformer/QuestionA.java ================================================ package Q17_22_Word_Transformer; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; import java.util.Map; import java.util.Queue; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; public class QuestionA { public static ArrayList wordsOneAway(String word) { ArrayList words = new ArrayList(); for (int i = 0; i < word.length(); i++) { for (char c = 'a'; c <= 'z'; c++) { String w = word.substring(0, i) + c + word.substring(i + 1); words.add(w); } } return words; } public static LinkedList transform(HashSet visited, String startWord, String stopWord, Set dictionary) { if (startWord.equals(stopWord)) { LinkedList path = new LinkedList(); path.add(startWord); return path; } else if (visited.contains(startWord) || !dictionary.contains(startWord)) { return null; } visited.add(startWord); ArrayList words = wordsOneAway(startWord); for (String word : words) { LinkedList path = transform(visited, word, stopWord, dictionary); if (path != null) { path.addFirst(startWord); return path; } } return null; } public static LinkedList transform(String start, String stop, String[] words) { HashSet dict = setupDictionary(words); HashSet visited = new HashSet(); return transform(visited, start, stop, dict); } public static HashSet setupDictionary(String[] words) { HashSet hash = new HashSet(); for (String word : words) { hash.add(word.toLowerCase()); } return hash; } public static void main(String[] args) { String[] words = {"maps", "tan", "tree", "apple", "cans", "help", "aped", "pree", "pret", "apes", "flat", "trap", "fret", "trip", "trie", "frat", "fril"}; LinkedList list = transform("tree", "flat", words); if (list == null) { System.out.println("No path."); } else { System.out.println(list.toString()); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_22_Word_Transformer/QuestionB.java ================================================ package Q17_22_Word_Transformer; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; import CtCILibrary.HashMapList; public class QuestionB { /* find path to transform startWord into endWord. */ public static LinkedList transform(String start, String stop, String[] words) { HashMapList wildcardToWordList = createWildcardToWordMap(words); HashSet visited = new HashSet(); return transform(visited, start, stop, wildcardToWordList); } /* Do a depth-first search from start to stop, traveling through each word that is one edit away. */ public static LinkedList transform(HashSet visited, String start, String stop, HashMapList wildcardToWordList) { if (start.equals(stop)) { LinkedList path = new LinkedList(); path.add(start); return path; } else if (visited.contains(start)) { return null; } visited.add(start); ArrayList words = getValidLinkedWords(start, wildcardToWordList); for (String word : words) { LinkedList path = transform(visited, word, stop, wildcardToWordList); if (path != null) { path.addFirst(start); return path; } } return null; } /* Insert words in dictionary into mapping from wildcard form -> word. */ public static HashMapList createWildcardToWordMap(String[] words) { HashMapList wildcardToWords = new HashMapList(); for (String word : words) { ArrayList linked = getWildcardRoots(word); for (String linkedWord : linked) { wildcardToWords.put(linkedWord, word); } } return wildcardToWords; } /* Get list of wildcards associated with word. */ public static ArrayList getWildcardRoots(String w) { ArrayList words = new ArrayList(); for (int i = 0; i < w.length(); i++) { String word = w.substring(0, i) + "_" + w.substring(i + 1); words.add(word); } return words; } /* Return words that are one edit away. */ public static ArrayList getValidLinkedWords(String word, HashMapList wildcardToWords) { ArrayList wildcards = getWildcardRoots(word); ArrayList linkedWords = new ArrayList(); for (String wildcard : wildcards) { ArrayList words = wildcardToWords.get(wildcard); for (String linkedWord : words) { if (!linkedWord.equals(word)) { linkedWords.add(linkedWord); } } } return linkedWords; } public static void main(String[] args) { String[] words = {"maps", "tan", "tree", "apple", "cans", "help", "aped", "pree", "pret", "apes", "flat", "trap", "fret", "trip", "trie", "frat", "fril"}; LinkedList list = transform("tree", "flat", words); if (list == null) { System.out.println("No path."); } else { System.out.println(list.toString()); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_22_Word_Transformer/QuestionC.java ================================================ package Q17_22_Word_Transformer; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; import CtCILibrary.HashMapList; public class QuestionC { public static LinkedList transform(String startWord, String stopWord, String[] words) { HashMapList wildcardToWordList = getWildcardToWordList(words); BFSData sourceData = new BFSData(startWord); BFSData destData = new BFSData(stopWord); while (!sourceData.isFinished() && !destData.isFinished()) { /* Search out from source. */ String collision = searchLevel(wildcardToWordList, sourceData, destData); if (collision != null) { return mergePaths(sourceData, destData, collision); } /* Search out from destination. */ collision = searchLevel(wildcardToWordList, destData, sourceData); if (collision != null) { return mergePaths(sourceData, destData, collision); } } return null; } /* Search one level and return collision, if any. */ public static String searchLevel(HashMapList wildcardToWordList, BFSData primary, BFSData secondary) { /* We only want to search one level at a time. Count how many nodes are currently in the primary's * level and only do that many nodes. We'll continue to add nodes to the end. */ int count = primary.toVisit.size(); for (int i = 0; i < count; i++) { /* Pull out first node. */ PathNode pathNode = primary.toVisit.poll(); String word = pathNode.getWord(); /* Check if it's already been visited. */ if (secondary.visited.containsKey(word)) { return pathNode.getWord(); } /* Add friends to queue. */ ArrayList words = getValidLinkedWords(word, wildcardToWordList); for (String w : words) { if (!primary.visited.containsKey(w)) { PathNode next = new PathNode(w, pathNode); primary.visited.put(w, next); primary.toVisit.add(next); } } } return null; } public static LinkedList mergePaths(BFSData bfs1, BFSData bfs2, String connection) { PathNode end1 = bfs1.visited.get(connection); // end1 -> source PathNode end2 = bfs2.visited.get(connection); // end2 -> dest LinkedList pathOne = end1.collapse(false); // forward: source -> connection LinkedList pathTwo = end2.collapse(true); // reverse: connection -> dest pathTwo.removeFirst(); // remove connection pathOne.addAll(pathTwo); // add second path return pathOne; } public static ArrayList getWildcardRoots(String word) { ArrayList words = new ArrayList(); for (int i = 0; i < word.length(); i++) { String w = word.substring(0, i) + "_" + word.substring(i + 1); words.add(w); } return words; } public static HashMapList getWildcardToWordList(String[] words) { HashMapList wildcardToWords = new HashMapList(); for (String word : words) { ArrayList linked = getWildcardRoots(word); for (String linkedWord : linked) { wildcardToWords.put(linkedWord, word); } } return wildcardToWords; } public static ArrayList getValidLinkedWords(String word, HashMapList wildcardToWords) { ArrayList wildcards = getWildcardRoots(word); ArrayList linkedWords = new ArrayList(); for (String wildcard : wildcards) { ArrayList words = wildcardToWords.get(wildcard); for (String linkedWord : words) { if (!linkedWord.equals(word)) { linkedWords.add(linkedWord); } } } return linkedWords; } public static void main(String[] args) { String[] words = {"maps", "tan", "tree", "apple", "cans", "help", "aped", "pree", "pret", "apes", "flat", "trap", "fret", "trip", "trie", "frat", "fril"}; LinkedList list = transform("tree", "flat", words); if (list == null) { System.out.println("No path."); } else { System.out.println(list.toString()); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_22_Word_Transformer/Tester.java ================================================ package Q17_22_Word_Transformer; import java.util.LinkedList; public class Tester { public static void printList(LinkedList list) { if (list == null) { System.out.println("No path."); } else { System.out.println(list.toString()); } } public static void main(String[] args) { String[] words = {"maps", "tan", "tree", "apple", "cans", "help", "aped", "pree", "pret", "apes", "flat", "trap", "fret", "trip", "trie", "frat", "fril"}; LinkedList listA = QuestionA.transform("tree", "flat", words); LinkedList listB = QuestionB.transform("tree", "flat", words); LinkedList listC = QuestionC.transform("tree", "flat", words); printList(listA); printList(listB); printList(listC); } } ================================================ FILE: Java/Ch 17. Hard/Q17_23_Max_Black_Square/Question.java ================================================ package Q17_23_Max_Black_Square; import CtCILibrary.AssortedMethods; public class Question { public static Subsquare findSquareWithSize(int[][] matrix, int squareSize) { // On an edge of length N, there are (N - sz + 1) squares of length sz. int count = matrix.length - squareSize + 1; // Iterate through all squares with side length square_size. for (int row = 0; row < count; row++) { for (int col = 0; col < count; col++) { if (isSquare(matrix, row, col, squareSize)) { return new Subsquare(row, col, squareSize); } } } return null; } public static Subsquare findSquare(int[][] matrix){ assert(matrix.length > 0); for (int row = 0; row < matrix.length; row++){ assert(matrix[row].length == matrix.length); } int N = matrix.length; for (int i = N; i >= 1; i--) { Subsquare square = findSquareWithSize(matrix, i); if (square != null) { return square; } } return null; } private static boolean isSquare(int[][] matrix, int row, int col, int size) { // Check top and bottom border. for (int j = 0; j < size; j++){ if (matrix[row][col+j] == 1) { return false; } if (matrix[row+size-1][col+j] == 1) { return false; } } // Check left and right border. for (int i = 1; i < size - 1; i++) { if (matrix[row+i][col] == 1){ return false; } if (matrix[row+i][col+size-1] == 1) { return false; } } return true; } public static void main(String[] args) { int[][] matrix = AssortedMethods.randomMatrix(7, 7, 0, 1); AssortedMethods.printMatrix(matrix); Subsquare square = findSquare(matrix); square.print(); } } ================================================ FILE: Java/Ch 17. Hard/Q17_23_Max_Black_Square/QuestionEff.java ================================================ package Q17_23_Max_Black_Square; import CtCILibrary.AssortedMethods; public class QuestionEff { public static Subsquare findSquareWithSize(SquareCell[][] processed, int square_size) { // On an edge of length N, there are (N - sz + 1) squares of length sz. int count = processed.length - square_size + 1; // Iterate through all squares with side length square_size. for (int row = 0; row < count; row++) { for (int col = 0; col < count; col++) { if (isSquare(processed, row, col, square_size)) { return new Subsquare(row, col, square_size); } } } return null; } public static Subsquare findSquare(int[][] matrix){ assert(matrix.length > 0); for (int row = 0; row < matrix.length; row++){ assert(matrix[row].length == matrix.length); } SquareCell[][] processed = processSquare(matrix); int N = matrix.length; for (int i = N; i >= 1; i--) { Subsquare square = findSquareWithSize(processed, i); if (square != null) { return square; } } return null; } private static boolean isSquare(SquareCell[][] matrix, int row, int col, int size) { SquareCell topLeft = matrix[row][col]; SquareCell topRight = matrix[row][col + size - 1]; SquareCell bottomRight = matrix[row + size - 1][col]; if (topLeft.zerosRight < size) { // Check top edge return false; } if (topLeft.zerosBelow < size) { // Check left edge return false; } if (topRight.zerosBelow < size) { // Check right edge return false; } if (bottomRight.zerosRight < size) { // Check bottom edge return false; } return true; } public static SquareCell[][] processSquare(int[][] matrix) { SquareCell[][] processed = new SquareCell[matrix.length][matrix.length]; for (int r = matrix.length - 1; r >= 0; r--) { for (int c = matrix.length - 1; c >= 0; c--) { int rightZeros = 0; int belowZeros = 0; if (matrix[r][c] == 0) { // only need to process if it's a black cell rightZeros++; belowZeros++; if (c + 1 < matrix.length) { // next column over is on same row SquareCell previous = processed[r][c + 1]; rightZeros += previous.zerosRight; } if (r + 1 < matrix.length) { SquareCell previous = processed[r + 1][c]; belowZeros += previous.zerosBelow; } } processed[r][c] = new SquareCell(rightZeros, belowZeros); } } return processed; } public static void main(String[] args) { int[][] matrix = AssortedMethods.randomMatrix(7, 7, 0, 1); AssortedMethods.printMatrix(matrix); Subsquare square = findSquare(matrix); square.print(); } } ================================================ FILE: Java/Ch 17. Hard/Q17_23_Max_Black_Square/SquareCell.java ================================================ package Q17_23_Max_Black_Square; public class SquareCell { public int zerosRight = 0; public int zerosBelow = 0; public SquareCell(int right, int below) { zerosRight = right; zerosBelow = below; } public void setZerosRight(int right) { zerosRight = right; } public void setZerosBelow(int below) { zerosBelow = below; } } ================================================ FILE: Java/Ch 17. Hard/Q17_23_Max_Black_Square/Subsquare.java ================================================ package Q17_23_Max_Black_Square; public class Subsquare { public int row, column, size; public Subsquare(int r, int c, int sz) { row = r; column = c; size = sz; } public void print() { System.out.println("(" + row + ", " + column + ", " + size + ")"); } } ================================================ FILE: Java/Ch 17. Hard/Q17_24_Max_Submatrix/QuestionA.java ================================================ package Q17_24_Max_Submatrix; import CtCILibrary.*; public class QuestionA { public static SubMatrix getMaxMatrix(int[][] matrix) { int rowCount = matrix.length; int columnCount = matrix[0].length; SubMatrix best = null; for (int row1 = 0; row1 < rowCount; row1++) { for (int row2 = row1; row2 < rowCount; row2++) { for (int col1 = 0; col1 < columnCount; col1++) { for (int col2 = col1; col2 < columnCount; col2++) { int sum = sum(matrix, row1, col1, row2, col2); if (best == null || best.getSum() < sum) { best = new SubMatrix(row1, col1, row2, col2, sum); } } } } } return best; } private static int sum(int[][] matrix, int row1, int col1, int row2, int col2) { int sum = 0; for (int r = row1; r <= row2; r++) { for (int c = col1; c <= col2; c++) { sum += matrix[r][c]; } } return sum; } public static void main(String[] args) { int[][] matrix = AssortedMethods.randomMatrix(10, 10, -5, 5); AssortedMethods.printMatrix(matrix); SubMatrix sub = getMaxMatrix(matrix); System.out.println(sub.toString()); } } ================================================ FILE: Java/Ch 17. Hard/Q17_24_Max_Submatrix/QuestionB.java ================================================ package Q17_24_Max_Submatrix; import CtCILibrary.*; public class QuestionB { public static SubMatrix getMaxMatrix(int[][] matrix) { SubMatrix best = null; int rowCount = matrix.length; int columnCount = matrix[0].length; int[][] sumThrough = precomputeSums(matrix); for (int row1 = 0; row1 < rowCount; row1++) { for (int row2 = row1; row2 < rowCount; row2++) { for (int col1 = 0; col1 < columnCount; col1++) { for (int col2 = col1; col2 < columnCount; col2++) { int sum = sum(sumThrough, row1, col1, row2, col2); if (best == null || best.getSum() < sum) { best = new SubMatrix(row1, col1, row2, col2, sum); } } } } } return best; } private static int[][] precomputeSums(int[][] matrix) { int[][] sumThrough = new int[matrix.length][matrix[0].length]; for (int r = 0; r < matrix.length; r++) { for (int c = 0; c < matrix[0].length; c++) { int left = c > 0 ? sumThrough[r][c - 1] : 0; int top = r > 0 ? sumThrough[r - 1][c] : 0; int overlap = r > 0 && c > 0 ? sumThrough[r - 1][c - 1] : 0; sumThrough[r][c] = left + top - overlap + matrix[r][c]; } } return sumThrough; } private static int sum(int[][] sumThrough, int r1, int c1, int r2, int c2) { int topAndLeft = r1 > 0 && c1 > 0 ? sumThrough[r1 - 1][c1 - 1] : 0; int left = c1 > 0 ? sumThrough[r2][c1 - 1] : 0; int top = r1 > 0 ? sumThrough[r1 - 1][c2] : 0; int full = sumThrough[r2][c2]; return full - left - top + topAndLeft; } public static void main(String[] args) { int[][] matrix = AssortedMethods.randomMatrix(10, 10, -5, 5); AssortedMethods.printMatrix(matrix); System.out.println(getMaxMatrix(matrix)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_24_Max_Submatrix/QuestionC.java ================================================ package Q17_24_Max_Submatrix; import CtCILibrary.AssortedMethods; public class QuestionC { public static SubMatrix getMaxMatrix(int[][] matrix) { int rowCount = matrix.length; int colCount = matrix[0].length; SubMatrix best = null; for (int rowStart = 0; rowStart < rowCount; rowStart++) { int[] partialSum = new int[colCount]; for (int rowEnd = rowStart; rowEnd < rowCount; rowEnd++) { /* Add values at row rowEnd. */ for (int i = 0; i < colCount; i++) { partialSum[i] += matrix[rowEnd][i]; } Range bestRange = maxSubArray(partialSum, colCount); if (best == null || best.getSum() < bestRange.sum) { best = new SubMatrix(rowStart, bestRange.start, rowEnd, bestRange.end, bestRange.sum); } } } return best; } public static Range maxSubArray(int[] array, int N) { Range best = null; int start = 0; int sum = 0; for (int i = 0; i < N; i++) { sum += array[i]; if (best == null || sum > best.sum) { best = new Range(start, i, sum); } /* If running_sum is < 0 no point in trying to continue the * series. Reset. */ if (sum < 0) { start = i + 1; sum = 0; } } return best; } public static void main(String[] args) { int[][] matrix = AssortedMethods.randomMatrix(10, 10, -5, 5); AssortedMethods.printMatrix(matrix); System.out.println(getMaxMatrix(matrix)); } } ================================================ FILE: Java/Ch 17. Hard/Q17_24_Max_Submatrix/Range.java ================================================ package Q17_24_Max_Submatrix; public class Range { public int start, end, sum; public Range(int start, int end, int sum) { this.start = start; this.end = end; this.sum = sum; } } ================================================ FILE: Java/Ch 17. Hard/Q17_24_Max_Submatrix/SubMatrix.java ================================================ package Q17_24_Max_Submatrix; public class SubMatrix { private int row1, row2, col1, col2, sum; public SubMatrix(int r1, int c1, int r2, int c2, int sm) { row1 = r1; col1 = c1; row2 = r2; col2 = c2; sum = sm; } public int getSum() { return sum; } @Override public String toString() { return "[(" + row1 + "," + col1 + ") -> (" + row2 + "," + col2 + ") = " + sum + "]"; } } ================================================ FILE: Java/Ch 17. Hard/Q17_24_Max_Submatrix/Tester.java ================================================ package Q17_24_Max_Submatrix; import CtCILibrary.AssortedMethods; public class Tester { public static void main(String[] args) { int[][] matrix = AssortedMethods.randomMatrix(10, 10, -5, 5); AssortedMethods.printMatrix(matrix); SubMatrix subA = QuestionA.getMaxMatrix(matrix); System.out.println(subA.toString()); SubMatrix subB = QuestionB.getMaxMatrix(matrix); System.out.println(subB.toString()); SubMatrix subC = QuestionC.getMaxMatrix(matrix); System.out.println(subC.toString()); } } ================================================ FILE: Java/Ch 17. Hard/Q17_25_Word_Rectangle/Question.java ================================================ package Q17_25_Word_Rectangle; import java.util.ArrayList; import CtCILibrary.AssortedMethods; import CtCILibrary.Trie; public class Question { private int maxWordLength; private WordGroup[] groupList ; private Trie trieList[]; public Question(String[] list) { groupList = WordGroup.createWordGroups(list); maxWordLength = groupList.length; // Initialize trieList to store trie of groupList[i] at ith position. trieList = new Trie[maxWordLength]; } /* This function finds a rectangle of letters of the largest * possible area (length x breadth) such that every row forms a * word (reading left to right) from the list and every column * forms a word (reading top to bottom) from the list. */ public Rectangle maxRectangle() { // The dimensions of the largest possible rectangle. int maxSize = maxWordLength * maxWordLength; for (int z = maxSize; z > 0; z--) { // Find out all pairs i,j less than maxWordLength // such that i * j = z for (int i = 1; i <= maxWordLength; i ++ ) { if (z % i == 0) { int j = z / i; if (j <= maxWordLength) { // Check if a Rectangle of length i and height // j can be created. Rectangle rectangle = makeRectangle(i,j); if (rectangle != null) { return rectangle; } } } } } return null; } /* This function takes the length and height of a rectangle as * arguments. It tries to form a rectangle of the given length and * height using words of the specified length as its rows, in which * words whose length is the specified height form the columns. It * returns the rectangle so formed, and null if such a rectangle * cannot be formed. */ private Rectangle makeRectangle(int length, int height) { if (groupList[length - 1] == null || groupList[height - 1] == null) { return null; } if (trieList[height - 1] == null) { ArrayList words = groupList[height - 1].getWords(); trieList[height - 1] = new Trie(words); } return makePartialRectangle(length, height, new Rectangle(length)); } /* This function recursively tries to form a rectangle with words * of length l from the dictionary as rows and words of length h * from the dictionary as columns. To do so, we start with an empty * rectangle and add in a word with length l as the first row. We * then check the trie of words of length h to see if each partial * column is a prefix of a word with length h. If so we branch * recursively and check the next word till we've formed a complete * rectangle. When we have a complete rectangle check if every * column is a word in the dictionary. */ private Rectangle makePartialRectangle(int l, int h, Rectangle rectangle) { // Check if we have formed a complete rectangle by seeing if each column // is in the dictionary if (rectangle.height == h) { if (rectangle.isComplete(l, h, groupList[h - 1])) { return rectangle; } else { return null; } } // If the rectangle is not empty, validate that each column is a // substring of a word of length h in the dictionary using the // trie of words of length h. if (!rectangle.isPartialOK(l, trieList[h - 1])) { return null; } // For each word of length l, try to make a new rectangle by adding // the word to the existing rectangle. for (int i = 0; i < groupList[l-1].length(); i++) { Rectangle orgPlus = rectangle.append(groupList[l-1].getWord(i)); Rectangle rect = makePartialRectangle(l, h, orgPlus); if (rect != null) { return rect; } } return null; } // Test harness. public static void main(String[] args) { Question dict = new Question(AssortedMethods.getListOfWords()); Rectangle rect = dict.maxRectangle(); if (rect != null) { rect.print(); } else { System.out.println ("No rectangle exists"); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_25_Word_Rectangle/Rectangle.java ================================================ package Q17_25_Word_Rectangle; import CtCILibrary.Trie; /* A class that represents a rectangular array of letters. */ public class Rectangle { // Rectangle data. public int height; public int length; public char [][] matrix; public Rectangle(int len) { this.length = len; } /* Construct a rectangular array of letters of the specified length * and height, and backed by the specified matrix of letters. (It is * assumed that the length and height specified as arguments are * consistent with the array argument's dimensions.) */ public Rectangle(int length, int height, char[][] letters) { this.height = letters.length; this.length = letters[0].length; matrix = letters; } /* Return the letter present at the specified location in the array. */ public char getLetter (int i, int j) { return matrix[i][j]; } public String getColumn(int i) { char[] column = new char[height]; for (int j = 0; j < height; j++) { column[j] = getLetter(j, i); } return new String(column); } public boolean isComplete(int l, int h, WordGroup groupList) { // Check if we have formed a complete rectangle. if (height == h) { // Check if each column is a word in the dictionary. for (int i = 0; i < l; i++) { String col = getColumn(i); if (!groupList.containsWord(col)) { return false; // Invalid rectangle. } } return true; // Valid Rectangle! } return false; } public boolean isPartialOK(int l, Trie trie) { if (height == 0) { return true; } for (int i = 0; i < l ; i++ ) { String col = getColumn(i); if (!trie.contains(col)) { return false; // Invalid rectangle. } } return true; } /* If the length of the argument s is consistent with that of this * Rectangle object, then return a Rectangle whose matrix is constructed by * appending s to the underlying matrix. Otherwise, return null. The * underlying matrix of this Rectangle object is /not/ modified. */ public Rectangle append(String s) { if (s.length() == length) { char temp[][] = new char[height + 1][length]; for (int i = 0; i < height; i++) { for (int j = 0; j < length; j++) { temp[i][j] = matrix[i][j]; } } s.getChars(0, length, temp[height], 0); return new Rectangle(length, height + 1, temp); } return null; } /* Print the rectangle out, row by row. */ public void print() { for (int i = 0; i < height ; i++) { for (int j = 0; j < length; j++) { System.out.print(matrix[i][j]); } System.out.println(" "); } } } ================================================ FILE: Java/Ch 17. Hard/Q17_25_Word_Rectangle/WordGroup.java ================================================ package Q17_25_Word_Rectangle; import java.util.ArrayList; import java.util.HashMap; /* A container for a group of words of the same length. */ public class WordGroup { private HashMap lookup = new HashMap(); private ArrayList group = new ArrayList(); public WordGroup() { } public boolean containsWord(String s) { return lookup.containsKey(s); } public void addWord (String s) { group.add(s); lookup.put(s, true); } public int length() { return group.size(); } public String getWord(int i) { return group.get(i); } public ArrayList getWords(){ return group; } public static WordGroup[] createWordGroups(String[] list) { WordGroup[] groupList; int maxWordLength = 0; // Find out the length of the longest word for (int i = 0; i < list.length; i++) { if (list[i].length() > maxWordLength) { maxWordLength = list[i].length(); } } /* Group the words in the dictionary into lists of words of * same length.groupList[i] will contain a list of words, each * of length (i+1). */ groupList = new WordGroup[maxWordLength]; for (int i = 0; i < list.length; i++) { /* We do wordLength - 1 instead of just wordLength since this is used as * an index and no words are of length 0 */ int wordLength = list[i].length() - 1; if (groupList[wordLength] == null) { groupList[wordLength] = new WordGroup(); } groupList[wordLength].addWord(list[i]); } return groupList; } } ================================================ FILE: Java/Ch 17. Hard/Q17_26_Sparse_Similarity/DocPair.java ================================================ package Q17_26_Sparse_Similarity; public class DocPair { public int doc1; public int doc2; public DocPair(int d1, int d2) { doc1 = d1; doc2 = d2; } @Override public boolean equals(Object o) { if (o instanceof DocPair) { DocPair p = (DocPair) o; return p.doc1 == doc1 && p.doc2 == doc2; } return false; } @Override public int hashCode() { return (doc1 * 31) ^ doc2; } } ================================================ FILE: Java/Ch 17. Hard/Q17_26_Sparse_Similarity/Document.java ================================================ package Q17_26_Sparse_Similarity; import java.util.ArrayList; public class Document { private ArrayList words; private int docId; public Document(int id, ArrayList w) { docId = id; words = w; } public ArrayList getWords() { return words; } public int getId() { return docId; } public int size() { return words == null ? 0 : words.size(); } } ================================================ FILE: Java/Ch 17. Hard/Q17_26_Sparse_Similarity/QuestionA.java ================================================ package Q17_26_Sparse_Similarity; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map.Entry; import CtCILibrary.AssortedMethods; public class QuestionA { public static HashMap computeSimilarities(HashMap documents) { ArrayList docs = new ArrayList(); for (Document doc : documents.values()) { docs.add(doc); } return computeSimilarities(docs); } public static HashMap computeSimilarities(ArrayList documents) { HashMap similarities = new HashMap(); for (int i = 0; i < documents.size(); i++) { for (int j = i + 1; j < documents.size(); j++) { Document doc1 = documents.get(i); Document doc2 = documents.get(j); double sim = computeSimilarity(doc1, doc2); if (sim > 0) { DocPair pair = new DocPair(doc1.getId(), doc2.getId()); similarities.put(pair, sim); } } } return similarities; } public static double computeSimilarity(Document doc1, Document doc2) { int intersection = 0; HashSet set1 = new HashSet(); set1.addAll(doc1.getWords()); for (int word : doc2.getWords()) { if (set1.contains(word)) { intersection++; } } double union = doc1.size() + doc2.size() - intersection; return intersection / union; } public static ArrayList removeDups(int[] array) { HashSet set = new HashSet(); for (int a : array) { set.add(a); } ArrayList list = new ArrayList(); list.addAll(set); return list; } public static void main(String[] args) { int numDocuments = 10; int docSize = 5; HashMap documents = new HashMap(); for (int i = 0; i < numDocuments; i++) { int[] words = AssortedMethods.randomArray(docSize, 0, 10); ArrayList w = Tester.removeDups(words); System.out.println(i + ": " + w.toString()); Document doc = new Document(i, w); documents.put(i, doc); } HashMap similarities = computeSimilarities(documents); Tester.printSim(similarities); } } ================================================ FILE: Java/Ch 17. Hard/Q17_26_Sparse_Similarity/QuestionB.java ================================================ package Q17_26_Sparse_Similarity; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Map.Entry; import java.util.Set; import CtCILibrary.AssortedMethods; import CtCILibrary.HashMapList; public class QuestionB { public static HashMap computeSimilarities(HashMap documents) { HashMapList wordToDocs = groupWords(documents); HashMap similarities = computeIntersections(wordToDocs); adjustToSimilarities(documents, similarities); return similarities; } /* Create hash table from each word to where it appears. */ public static HashMapList groupWords(HashMap documents) { HashMapList wordToDocs = new HashMapList(); for (Document doc : documents.values()) { ArrayList words = doc.getWords(); for (int word : words) { wordToDocs.put(word, doc.getId()); } } return wordToDocs; } /* Compute intersections of documents. Iterate through each list of * documents and then each pair within that list, incrementing the * intersection of each page. */ public static HashMap computeIntersections(HashMapList wordToDocs) { HashMap similarities = new HashMap(); Set words = wordToDocs.keySet(); for (int word : words) { ArrayList docs = wordToDocs.get(word); Collections.sort(docs); for (int i = 0; i < docs.size(); i++) { for (int j = i + 1; j < docs.size(); j++) { increment(similarities, docs.get(i), docs.get(j)); } } } return similarities; } /* Increment the intersection size of each document pair. */ public static void increment(HashMap similarities, int doc1, int doc2) { DocPair pair = new DocPair(doc1, doc2); if (!similarities.containsKey(pair)) { similarities.put(pair, 1.0); } else { similarities.put(pair, similarities.get(pair) + 1); } } /* Adjust the intersection value to become the similarity. */ public static void adjustToSimilarities(HashMap documents, HashMap similarities) { for (Entry entry : similarities.entrySet()) { DocPair pair = entry.getKey(); Double intersection = entry.getValue(); Document doc1 = documents.get(pair.doc1); Document doc2 = documents.get(pair.doc2); double union = (double) doc1.size() + doc2.size() - intersection; entry.setValue(intersection / union); } } public static void main(String[] args) { int numDocuments = 10; int docSize = 5; HashMap documents = new HashMap(); for (int i = 0; i < numDocuments; i++) { int[] words = AssortedMethods.randomArray(docSize, 0, 10); ArrayList w = Tester.removeDups(words); System.out.println(i + ": " + w.toString()); Document doc = new Document(i, w); documents.put(i, doc); } HashMap similarities = computeSimilarities(documents); Tester.printSim(similarities); } } ================================================ FILE: Java/Ch 17. Hard/Q17_26_Sparse_Similarity/QuestionC.java ================================================ package Q17_26_Sparse_Similarity; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map.Entry; import CtCILibrary.AssortedMethods; public class QuestionC { public static class Element implements Comparable { public int word; public int document; public Element(int w, int d) { word = w; document = d; } public int compareTo(Element e) { if (word == e.word) { return document - e.document; } return word - e.word; } } public static HashMap computeSimilarities(HashMap documents) { ArrayList elements = sortWords(documents); HashMap similarities = computeIntersections(elements); adjustToSimilarities(documents, similarities); return similarities; } /* Throw all words into one list, sorting by the word then the document. */ public static ArrayList sortWords(HashMap docs) { ArrayList elements = new ArrayList(); for (Document doc : docs.values()) { ArrayList words = doc.getWords(); for (int word : words) { elements.add(new Element(word, doc.getId())); } } Collections.sort(elements); return elements; } /* Increment the intersection size of each document pair. */ public static void increment(HashMap similarities, int doc1, int doc2) { DocPair pair = new DocPair(doc1, doc2); if (!similarities.containsKey(pair)) { similarities.put(pair, 1.0); } else { similarities.put(pair, similarities.get(pair) + 1); } } /* Adjust the intersection value to become the similarity. */ public static HashMap computeIntersections(ArrayList elements) { HashMap similarities = new HashMap(); for (int i = 0; i < elements.size(); i++) { Element left = elements.get(i); for (int j = i + 1; j < elements.size(); j++) { Element right = elements.get(j); if (left.word != right.word) { break; } increment(similarities, left.document, right.document); } } return similarities; } /* Adjust the intersection value to become the similarity. */ public static void adjustToSimilarities(HashMap documents, HashMap similarities) { for (Entry entry : similarities.entrySet()) { DocPair pair = entry.getKey(); Double intersection = entry.getValue(); Document doc1 = documents.get(pair.doc1); Document doc2 = documents.get(pair.doc2); double union = (double) doc1.size() + doc2.size() - intersection; entry.setValue(intersection / union); } } public static void main(String[] args) { int numDocuments = 10; int docSize = 5; HashMap documents = new HashMap(); for (int i = 0; i < numDocuments; i++) { int[] words = AssortedMethods.randomArray(docSize, 0, 10); ArrayList w = Tester.removeDups(words); System.out.println(i + ": " + w.toString()); Document doc = new Document(i, w); documents.put(i, doc); } HashMap similarities = computeSimilarities(documents); Tester.printSim(similarities); } } ================================================ FILE: Java/Ch 17. Hard/Q17_26_Sparse_Similarity/Tester.java ================================================ package Q17_26_Sparse_Similarity; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map.Entry; public class Tester { public static ArrayList removeDups(int[] array) { HashSet set = new HashSet(); for (int a : array) { set.add(a); } ArrayList list = new ArrayList(); list.addAll(set); return list; } public static boolean isEqual(HashMap one, HashMap two) { if (one.size() != two.size()) { return false; } for (Entry a : one.entrySet()) { if (!two.containsKey(a.getKey())) { return false; } double sim1 = a.getValue(); double sim2 = two.get(a.getKey()); if (sim1 != sim2) { return false; } } return true; } public static void printSim(HashMap similarities) { for (Entry result : similarities.entrySet()) { DocPair pair = result.getKey(); Double sim = result.getValue(); System.out.println(pair.doc1 + ", " + pair.doc2 + " : " + sim); } } public static void addTo(HashMap documents, int id, int[] array) { ArrayList w = removeDups(array); Document doc = new Document(id, w); documents.put(id, doc); } public static void main(String[] args) { /*int numDocuments = 5; int docSize = 5; HashMap documents = new HashMap(); for (int i = 0; i < numDocuments; i++) { int[] words = AssortedMethods.randomArray(docSize, 0, 10); ArrayList w = removeDups(words); System.out.println(i + ": " + w.toString()); Document doc = new Document(i, w); documents.put(i, doc); }*/ HashMap documents = new HashMap(); int[] array1 = {14, 15, 100, 9, 3}; addTo(documents, 13, array1); int[] array2 = {32, 1, 9, 3, 5}; addTo(documents, 16, array2); int[] array3 = {15, 29, 2, 6, 8, 7}; addTo(documents, 19, array3); int[] array4 = {7, 10}; addTo(documents, 24, array4); HashMap simA = QuestionA.computeSimilarities(documents); HashMap simB = QuestionB.computeSimilarities(documents); HashMap simC = QuestionC.computeSimilarities(documents); System.out.println("----------"); printSim(simA); System.out.println("----------"); printSim(simB); System.out.println("----------"); printSim(simC); System.out.println("----------"); System.out.println(isEqual(simA, simB)); System.out.println(isEqual(simB, simC)); System.out.println(isEqual(simA, simC)); } } ================================================ FILE: Java/CtCILibrary/CtCILibrary/AssortedMethods.java ================================================ package CtCILibrary; import java.util.*; import java.awt.*; public class AssortedMethods { public static int randomInt(int n) { return (int) (Math.random() * n); } public static int randomIntInRange(int min, int max) { return randomInt(max + 1 - min) + min; } public static boolean randomBoolean() { return randomIntInRange(0, 1) == 0; } public static boolean randomBoolean(int percentTrue) { return randomIntInRange(1, 100) <= percentTrue; } public static boolean[][] randomBooleanMatrix(int M, int N, int percentTrue) { boolean[][] matrix = new boolean[M][N]; for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { matrix[i][j] = randomBoolean(percentTrue); } } return matrix; } public static int[][] randomMatrix(int M, int N, int min, int max) { int[][] matrix = new int[M][N]; for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { matrix[i][j] = randomIntInRange(min, max); } } return matrix; } public static int[] randomArray(int N, int min, int max) { int[] array = new int[N]; for (int j = 0; j < N; j++) { array[j] = randomIntInRange(min, max); } return array; } public static LinkedListNode randomLinkedList(int N, int min, int max) { LinkedListNode root = new LinkedListNode(randomIntInRange(min, max), null, null); LinkedListNode prev = root; for (int i = 1; i < N; i++) { int data = randomIntInRange(min, max); LinkedListNode next = new LinkedListNode(data, null, null); prev.setNext(next); prev = next; } return root; } public static LinkedListNode linkedListWithValue(int N, int value) { LinkedListNode root = new LinkedListNode(value, null, null); LinkedListNode prev = root; for (int i = 1; i < N; i++) { LinkedListNode next = new LinkedListNode(value, null, null); prev.setNext(next); prev = next; } return root; } public static LinkedListNode createLinkedListFromArray(int[] vals) { 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 String arrayToString(int[] array) { if (array == null) return ""; return arrayToString(array, 0, array.length - 1); } public static String arrayToString(int[] array, int start, int end) { StringBuilder sb = new StringBuilder(); for (int i = start; i <= end; i++) { int v = array[i]; sb.append(v + ", "); } return sb.toString(); } public static String stringArrayToString(String[] array) { StringBuilder sb = new StringBuilder(); for (String v : array) { sb.append(v + ", "); } return sb.toString(); } public static String toFullBinaryString(int a) { String s = ""; for (int i = 0; i < 32; i++) { Integer lsb = new Integer(a & 1); s = lsb.toString() + s; a = a >> 1; } return s; } public static String toBaseNString(int a, int base) { String s = ""; while (true) { int lastdigit = a % base; s = lastdigit + s; a = a / base; if (a == 0) break; } return s; } public static void printMatrix(int[][] matrix) { for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[i].length; j++) { if (matrix[i][j] < 10 && matrix[i][j] > -10) { System.out.print(" "); } if (matrix[i][j] < 100 && matrix[i][j] > -100) { System.out.print(" "); } if (matrix[i][j] >= 0) { System.out.print(" "); } System.out.print(" " + matrix[i][j]); } System.out.println(); } } public static void printMatrix(boolean[][] matrix) { for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[i].length; j++) { if (matrix[i][j]) { System.out.print("1"); } else { System.out.print("0"); } } System.out.println(); } } public static void printIntArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } System.out.println(""); } public static String charArrayToString(char[] array) { StringBuilder buffer = new StringBuilder(array.length); for (char c : array) { if (c == 0) { break; } buffer.append(c); } return buffer.toString(); } public static String listOfPointsToString(ArrayList list) { StringBuilder buffer = new StringBuilder(); for (Point p : list) { buffer.append("(" + p.x + "," + p.y + ")"); } return buffer.toString(); } public static TreeNode randomBST(int N, int min, int max) { int d = randomIntInRange(min, max); TreeNode root = new TreeNode(d); for (int i = 1; i < N; i++) { root.insertInOrder(randomIntInRange(min, max)); } return root; } /* Creates tree by mapping the array left to right, top to bottom. */ public static TreeNode createTreeFromArray(int[] array) { if (array.length > 0) { TreeNode root = new TreeNode(array[0]); java.util.Queue queue = new java.util.LinkedList(); queue.add(root); boolean done = false; int i = 1; while (!done) { TreeNode r = (TreeNode) queue.element(); if (r.left == null) { r.left = new TreeNode(array[i]); i++; queue.add(r.left); } else if (r.right == null) { r.right = new TreeNode(array[i]); i++; queue.add(r.right); } else { queue.remove(); } if (i == array.length) { done = true; } } return root; } else { return null; } } public static String getLongTextBlob() { String book = "As they rounded a bend in the path that ran beside the river, Lara recognized the silhouette of a fig tree atop a nearby hill. The weather was hot and the days were long. The fig tree was in full leaf, but not yet bearing fruit. " + "Soon Lara spotted other landmarks�an outcropping of limestone beside the path that had a silhouette like a man�s face, a marshy spot beside the river where the waterfowl were easily startled, a tall tree that looked like a man with his arms upraised. They were drawing near to the place where there was an island in the river. The island was a good spot to make camp. They would sleep on the island tonight." + "Lara had been back and forth along the river path many times in her short life. Her people had not created the path�it had always been there, like the river�but their deerskin-shod feet and the wooden wheels of their handcarts kept the path well worn. Lara�s people were salt traders, and their livelihood took them on a continual journey. "; String book_mod = book.replace('.', ' ').replace(',', ' ') .replace('-', ' '); return book_mod; } public static String[] getLongTextBlobAsStringList() { return getLongTextBlob().split(" "); } public static Trie getTrieDictionary() { return new Trie(getListOfWords()); } public static HashSet getWordListAsHashSet() { String[] wordList = getListOfWords(); HashSet wordSet = new HashSet(); for (String s : wordList) { wordSet.add(s); } return wordSet; } public static String getLongSampleText(boolean forceLower) { String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi enim magna, rhoncus at risus at, tincidunt pretium sapien. Maecenas vitae sagittis urna. Donec egestas, mauris ut porttitor eleifend, lectus felis sollicitudin sapien, luctus tempor ligula lacus sit amet quam. Quisque gravida est dolor, vel cursus lacus cursus vel. Morbi vulputate ligula nec libero ullamcorper iaculis. Sed finibus tincidunt scelerisque. Cras condimentum lectus ac sem ornare, non pellentesque enim bibendum. Quisque tincidunt eget elit ut iaculis. Aliquam purus sapien, tincidunt non imperdiet eu, venenatis quis turpis. Vestibulum finibus porta urna sed consequat. Phasellus at rutrum enim. In euismod tellus nec ligula placerat dapibus. Quisque mauris urna, malesuada sit amet scelerisque at, euismod vitae nulla. Sed cursus lacus vitae leo venenatis, id ultrices ex fermentum.\r\n" + "\r\n" + "Duis non libero iaculis, euismod sapien non, lacinia odio. Nunc at est sodales, posuere nisl sit amet, bibendum tellus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc condimentum pretium congue. Sed viverra nibh ut tellus accumsan, non viverra sapien blandit. Integer convallis aliquam lacus, ut congue lectus feugiat sit amet. Nunc vel nisl sed nisi iaculis pharetra nec quis lacus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec laoreet in ex a facilisis. Aenean tincidunt dapibus augue, eu ultricies odio hendrerit ut. Nunc turpis sapien, blandit nec nibh quis, efficitur sodales dolor. Sed fringilla id quam eu vestibulum.\r\n" + "\r\n" + "Cras rutrum lorem rutrum tortor auctor cursus. Aenean tempor sed tellus eget vulputate. Nulla velit tellus, volutpat nec massa eget, fermentum euismod justo. Pellentesque scelerisque lobortis nulla ac vestibulum. Pellentesque ac scelerisque nibh. Duis tristique, nunc a posuere fermentum, felis sem egestas leo, id pellentesque ex augue in nibh. Nullam in eros lobortis, convallis nulla at, malesuada turpis. Aliquam consectetur efficitur orci bibendum tempus. Aenean ut lorem in arcu pellentesque accumsan a bibendum tortor. Maecenas neque nisi, mattis eget ex eget, porttitor ullamcorper erat. Maecenas varius ligula sed ullamcorper fermentum. In placerat ut dui nec placerat. Cras condimentum velit nec porttitor tincidunt. Cras et neque eu dolor condimentum imperdiet. Ut bibendum quam a erat varius hendrerit.\r\n" + "\r\n" + "In hac habitasse platea dictumst. Ut eleifend sem sit amet metus tincidunt euismod. Donec vel placerat mauris. Nulla facilisi. Nam vel purus et velit blandit ultricies. Aliquam non gravida erat. Ut non aliquam orci. Mauris ultrices condimentum dapibus.\r\n" + "\r\n" + "Cras ipsum sem, luctus eget suscipit sit amet, fermentum id elit. Morbi consectetur, tellus quis pretium interdum, erat nisi finibus massa, eget molestie ligula nisi egestas lorem. Praesent vitae consectetur erat, vitae lacinia dolor. Praesent placerat ut sapien eget bibendum. Phasellus malesuada lacus in metus bibendum, vel dapibus dolor imperdiet. Etiam ut nibh in risus iaculis commodo. Cras a elementum risus. Aenean luctus, dolor id accumsan egestas, dolor dui auctor augue, vitae commodo massa lacus at odio. In ut dignissim ex, sed tristique odio.\r\n" + "\r\n" + "Aenean ac malesuada lorem, eget placerat dui. Etiam at libero dictum, posuere neque non, interdum leo. Vivamus tempus sem id orci tempor, sit amet mattis augue aliquam. Aenean efficitur nunc sed lobortis egestas. Vivamus aliquet mi sit amet nisi convallis, sed volutpat neque fringilla. Duis blandit risus vitae felis pellentesque, quis facilisis ante suscipit. Proin vehicula metus commodo, aliquet nunc a, dignissim odio. In laoreet tortor ut nisl tempus fermentum. Maecenas auctor elementum leo, at tempor nisi feugiat et. Cras pulvinar arcu sit amet sem efficitur, vitae dictum eros lobortis. Pellentesque at orci consectetur, facilisis dui vel, lacinia dolor. Nullam rutrum porta dui, a sollicitudin neque aliquam vel. Sed sodales diam ac lorem feugiat, ut vulputate quam lacinia. Phasellus tincidunt dictum nibh et ultrices.\r\n" + "\r\n" + "Cras odio diam, euismod eu libero vitae, iaculis venenatis justo. Suspendisse pretium lectus nec suscipit mollis. Aenean eleifend ac turpis et tempor. Morbi turpis tortor, dictum sed condimentum id, commodo ut ligula. Aenean interdum nibh ante, nec cursus turpis facilisis nec. Aliquam scelerisque mollis mauris, quis rutrum nisl aliquet eget. Mauris condimentum tellus quis libero pretium feugiat. Nulla facilisi. Maecenas pharetra ultricies purus, nec fermentum quam eleifend non. Aliquam iaculis accumsan tellus quis pretium. Sed in ex sollicitudin, varius nibh in, scelerisque felis.\r\n" + "\r\n" + "Duis et lacus eu lorem scelerisque lacinia vitae eu odio. Ut mi dolor, vehicula eget libero ut, imperdiet sodales justo. Suspendisse pulvinar dignissim sagittis. Nam arcu velit, tempor non tortor id, sodales egestas nibh. Morbi dictum a felis quis pretium. Mauris dignissim ligula vel nunc blandit, in dapibus augue dignissim. Quisque non risus non augue aliquam semper at in tortor. Ut sed massa varius odio ultrices aliquet. In tempor augue ex, eu rutrum ex malesuada eu.\r\n" + "\r\n" + "Ut dignissim nisl ut purus placerat rutrum eu vel diam. Nulla aliquam lectus quis neque tempor iaculis. Quisque non ligula in nibh dapibus scelerisque. Duis aliquam venenatis odio sed congue. Aenean vel dui nulla. Curabitur at maximus metus. Integer non lectus vel lacus gravida eleifend. Aenean sed sapien molestie dui consectetur mollis nec non erat. Vestibulum facilisis in massa nec posuere. Nam nec elit vulputate, commodo urna non, mollis magna. Duis dolor lorem, tincidunt eget volutpat in, viverra ut nunc. Aenean lacinia ornare mi id accumsan.\r\n" + "\r\n" + "Donec non cursus nibh. Duis eu dolor sollicitudin nisi consectetur blandit vitae nec tortor. Praesent tempor condimentum magna at tincidunt. Nullam nisi lacus, maximus eget euismod ut, tristique sit amet augue. Mauris a dui justo. Pellentesque convallis ullamcorper lectus eget pellentesque. Integer scelerisque fermentum egestas. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque suscipit a mauris a rhoncus. Ut pulvinar, mi id porta pulvinar, urna tortor dapibus mauris, ut cursus tellus tellus in tortor. Curabitur at nunc placerat, vehicula libero quis, iaculis odio. Mauris id porttitor leo, et ultricies ex. Sed cursus egestas ante in tristique.\r\n" + "\r\n" + "Pellentesque nec lobortis elit, eu fermentum leo. Aliquam elementum at orci pulvinar laoreet. Aenean eu vulputate sapien, quis vestibulum nunc. Aliquam tincidunt mollis mi, ac consectetur felis tempor porta. Nulla facilisi. In porta elementum hendrerit. Nulla mattis quis eros quis lobortis. Quisque semper enim at finibus fringilla. Duis nunc orci, semper sit amet magna hendrerit, rhoncus posuere libero.\r\n" + "\r\n" + "Fusce facilisis sem massa, eget ultricies sem laoreet nec. Praesent non blandit felis. Nulla facilisi. Sed orci velit, tristique at pharetra cursus, euismod sit amet turpis. Nulla quis euismod elit, ut dapibus diam. Nam pulvinar convallis interdum. Phasellus nunc ante, porttitor quis dignissim vel, dictum a neque. Fusce quis augue quis ipsum pulvinar ultricies. Ut nec nunc vitae lectus vehicula elementum eu quis magna. Aliquam euismod iaculis lorem nec pretium. Integer eget sagittis mi. Interdum et malesuada fames ac ante ipsum primis in faucibus.\r\n" + "\r\n" + "Vestibulum at mattis ex. Cras eu ligula quis eros gravida aliquet. Pellentesque non lorem ac ante laoreet porttitor. Vestibulum eget consequat lacus. Ut at arcu velit. Aenean mattis aliquet urna a hendrerit. Nam condimentum finibus fermentum. Cras id est at ex tincidunt fringilla. Maecenas ultricies vel nisi eu semper. Vivamus a volutpat justo. Quisque cursus vulputate eros, eu dictum eros. Maecenas tempus magna semper egestas feugiat. Donec interdum sagittis mi, eu vulputate nisi. Ut accumsan rutrum faucibus.\r\n" + "\r\n" + "Mauris id ultricies mauris. Vivamus purus magna, dictum at posuere non, ullamcorper sagittis magna. Etiam dictum consequat justo, a euismod purus ornare quis. Suspendisse hendrerit pulvinar metus, id malesuada purus scelerisque et. Suspendisse dui quam, convallis nec libero non, hendrerit aliquet leo. Nam eget accumsan massa. Proin vel ante neque. Donec dapibus, est nec ullamcorper auctor, ligula lorem molestie augue, at luctus sapien lorem eget libero. Duis porttitor massa id purus sollicitudin, sed gravida massa porta. Mauris sollicitudin id sem ac maximus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin vulputate justo vel dignissim lacinia. Donec quam justo, venenatis id ex dignissim, malesuada posuere neque. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam lacus turpis, semper vel orci vitae, condimentum hendrerit ligula.\r\n" + "\r\n" + "Morbi ut dui risus. Sed eu est velit. Sed vel congue risus. Praesent pulvinar eu arcu tempor sagittis. Integer fringilla mollis pellentesque. Aliquam sed lobortis lacus. Quisque rhoncus maximus odio et mollis. Sed egestas, lectus ut fringilla mattis, velit massa ullamcorper metus, a feugiat metus nunc sit amet tellus. Praesent egestas, metus nec mollis laoreet, elit est pellentesque tellus, mollis dictum nunc mauris eu nisi. Sed laoreet tempus risus at ornare.\r\n" + "\r\n" + "Sed lorem tortor, egestas sit amet ligula ac, sollicitudin porttitor elit. Praesent consectetur id metus mollis suscipit. Phasellus non dictum mauris. In porta nisl sit amet tincidunt porta. Nullam sollicitudin, odio ac vehicula fermentum, arcu purus gravida lacus, at tempor felis odio sit amet lorem. Integer euismod eros sed gravida mattis. Vestibulum nec justo eros. Nunc fermentum molestie mauris sit amet imperdiet. Maecenas pulvinar sit amet ligula vitae aliquam. Aliquam hendrerit orci sed ex pellentesque porta.\r\n" + "\r\n" + "Mauris tempor quis nunc vel consequat. Donec a aliquet tortor, et mollis est. Nullam a cursus lectus. Quisque non laoreet magna, sit amet elementum justo. Vestibulum fringilla metus eu magna scelerisque venenatis. Proin fringilla massa in lobortis finibus. Suspendisse dignissim est at leo tincidunt mollis. Curabitur luctus velit fringilla nisi blandit semper.\r\n" + "\r\n" + "Suspendisse potenti. Duis at semper arcu. Mauris aliquam non augue a luctus. Praesent aliquet tristique turpis id imperdiet. Nullam at enim id tellus finibus faucibus eu auctor eros. Praesent lobortis cursus suscipit. Ut porta lacus at risus aliquet, non sagittis orci sollicitudin. Ut viverra sapien sed tincidunt sagittis. Fusce luctus diam vitae ante fermentum, non cursus est sollicitudin. Maecenas at tincidunt augue, scelerisque tincidunt arcu. Etiam interdum nisl at blandit laoreet. Phasellus in sapien id purus auctor fringilla. Donec erat nunc, finibus eu porta nec, vulputate sit amet neque. In hac habitasse platea dictumst.\r\n" + "\r\n" + "Duis ornare lectus luctus magna scelerisque, quis convallis erat feugiat. Ut at libero pellentesque, congue lectus at, tincidunt nunc. Curabitur elementum, metus eget tincidunt ultrices, ante orci feugiat velit, quis fermentum enim leo a diam. Quisque ultricies pulvinar orci, vitae pharetra nisi auctor a. Nullam eu condimentum neque, id congue purus. Ut eros sapien, sollicitudin quis risus tristique, ultrices pulvinar mauris. Nunc ullamcorper suscipit nulla, ac fringilla ipsum dignissim vitae. Cras porttitor sed ex eu finibus. Praesent tincidunt, libero in maximus bibendum, nibh turpis rhoncus neque, sed commodo tortor orci ac tellus. Sed eget lacinia dolor, non pellentesque magna. Suspendisse et ipsum vestibulum, suscipit urna sit amet, ullamcorper nisi. Ut ut ante sit amet velit varius hendrerit. Proin in massa sit amet ex posuere vestibulum. Ut egestas sodales magna ut mollis. Fusce vitae leo iaculis, posuere leo ut, pretium neque. Nullam tincidunt dui eu dui tristique, non venenatis libero maximus.\r\n" + "\r\n" + "Quisque sed auctor dolor. Nam sit amet cursus nisl. Nunc et pretium risus. Ut tempor massa nec dolor malesuada ultricies. Praesent hendrerit vestibulum tincidunt. Suspendisse et magna eget turpis hendrerit rhoncus ut at purus. Vestibulum non tellus mattis, lacinia justo id, iaculis lorem. Vestibulum tincidunt sapien nec lorem dapibus, egestas mollis turpis tempor. Nunc id imperdiet tortor, vel sodales ex. Duis ut libero nec nibh sollicitudin sollicitudin.\r\n" + "\r\n" + "Integer viverra quam at metus elementum, in ornare ex gravida. Suspendisse sed velit cursus, pellentesque mauris in, gravida ligula. Maecenas et nibh auctor, molestie urna in, euismod mi. Integer lobortis lacinia enim eu egestas. Praesent nisl enim, consectetur eu libero eget, convallis semper ex. Maecenas commodo velit nec erat ultricies, et dapibus neque dignissim. Nullam dictum velit et ipsum egestas volutpat. Ut feugiat diam id eros convallis sagittis. Aenean viverra justo eu enim malesuada, ut interdum neque sollicitudin. Aliquam erat volutpat. Sed aliquam leo nunc, id laoreet sapien posuere at. Nunc imperdiet lacus ac efficitur hendrerit.\r\n" + "\r\n" + "Vivamus dignissim erat eu erat aliquam luctus. Sed varius lacinia mauris, placerat facilisis massa finibus quis. Proin ac turpis a neque vulputate maximus vel non libero. Nunc ornare tempor tortor, vitae dignissim augue ullamcorper et. Cras at auctor risus, at interdum tortor. Proin finibus convallis ex, et pulvinar augue tincidunt sed. Suspendisse laoreet velit non mi viverra rhoncus. Fusce tristique pulvinar mauris, et tempor dolor. In gravida felis metus, eu venenatis ante aliquet non. Sed condimentum orci at urna aliquam, vitae ornare quam pellentesque. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;\r\n" + "\r\n" + "Quisque lacinia, lacus sit amet cursus semper, risus felis convallis ipsum, vitae condimentum tellus nunc non dui. Sed semper, magna at laoreet convallis, diam erat imperdiet leo, sit amet fringilla felis purus eget justo. Sed accumsan odio eget sem tristique mattis. In hac habitasse platea dictumst. Etiam aliquet ultricies augue, ac consequat risus semper volutpat. Praesent sollicitudin dolor enim, quis egestas ex vestibulum quis. Quisque vehicula, lectus eget dapibus sodales, orci massa facilisis justo, vel semper ante nunc nec augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nullam a lorem dignissim, accumsan erat sit amet, ornare purus. Curabitur sit amet tempus odio, id laoreet libero. Quisque augue nisi, sodales ac finibus vitae, pharetra vel turpis. Ut interdum sodales feugiat. Maecenas facilisis, eros eu blandit volutpat, est risus lobortis tortor, in interdum elit odio eget nunc. Fusce et aliquet tortor, quis consectetur tortor. Nullam ut urna non massa bibendum semper.\r\n" + "\r\n" + "Vivamus dui tortor, mattis eu iaculis viverra, rutrum sit amet quam. Sed non mollis dui, quis pretium dolor. In consequat nisl nec orci ultrices condimentum sit amet nec arcu. In cursus velit a congue fringilla. Curabitur hendrerit faucibus faucibus. Phasellus aliquet ut risus at rhoncus. Praesent tellus orci, scelerisque vel elit varius, lobortis porttitor erat.\r\n" + "\r\n" + "Sed ac neque vehicula, interdum ligula ac, pharetra mauris. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed ipsum erat, lobortis sed mollis sit amet, porttitor elementum dui. Nunc in massa ut mauris rutrum sollicitudin. Pellentesque nec sem auctor mauris fermentum faucibus id at odio. Nullam ut libero at tortor egestas commodo. Aenean vitae est nec leo fermentum iaculis ut ut dui. Nulla elementum non dolor vitae cursus.\r\n" + "\r\n" + "Nulla lorem neque, sodales vel erat non, pretium gravida nibh. Vivamus vestibulum tempor rutrum. Maecenas risus dolor, congue in ullamcorper eu, consequat id magna. Cras pretium gravida purus eu aliquet. Sed pellentesque lorem ac metus posuere dapibus. Sed at ligula at dui porta semper at vitae sem. Sed elementum nunc eget blandit hendrerit. Curabitur sit amet dui nulla. Nam leo orci, consequat sit amet urna quis, faucibus sagittis ligula. Pellentesque nec tincidunt ante, a ornare mauris. Phasellus vehicula feugiat nisl, et fermentum velit tempus eget.\r\n" + "\r\n" + "Cras vel nunc vitae leo viverra laoreet eget non dolor. Duis eleifend, metus tincidunt auctor ultricies, leo tellus condimentum velit, eget vulputate dolor mauris a felis. Nunc hendrerit, velit id molestie pharetra, nulla diam mollis erat, quis cursus erat orci eget lacus. Donec in massa vehicula, aliquet sapien et, congue libero. In quis ex faucibus est pharetra suscipit. Nunc quis dictum leo. Donec urna leo, pretium tempus vulputate a, iaculis sit amet odio. Aenean dictum consequat elit, in gravida erat aliquam sit amet. Praesent nec urna mi. Fusce quis malesuada lacus, id mollis ex. Nullam felis eros, vestibulum id luctus a, eleifend in lacus. Nullam iaculis tempus tortor, quis porttitor magna scelerisque sit amet.\r\n" + "\r\n" + "Nunc et nisi ac ligula vulputate pharetra eu sit amet tellus. Integer eleifend, nulla sit amet auctor posuere, libero tellus finibus magna, quis maximus sapien ipsum vel nibh. Vestibulum dictum risus et justo efficitur tempus. Ut eu hendrerit libero, nec rhoncus sapien. Integer et est magna. Quisque ullamcorper lacinia ex, et elementum turpis molestie sit amet. Integer placerat pharetra aliquet. Praesent id sodales erat. Donec iaculis, nibh et dapibus rhoncus, sem enim dignissim leo, eget porttitor neque diam eu sem. Duis consequat dignissim libero at aliquet. Maecenas pharetra nisi sit amet mollis interdum. Aenean vestibulum orci lacinia, porta lorem in, pharetra nibh. Duis sem elit, rutrum id nunc ac, lobortis aliquet mauris. Nullam ornare tortor ac erat venenatis, vitae tincidunt nunc posuere.\r\n" + "\r\n" + "Aenean id arcu tellus. Cras justo odio, tempor a lacus ultricies, hendrerit condimentum urna. Curabitur lobortis blandit nulla eget aliquam. Pellentesque placerat efficitur molestie. Nullam ac libero maximus, volutpat magna condimentum, consequat nisi. Donec sagittis est nec tincidunt convallis. Nullam blandit neque augue. Suspendisse diam lacus, mollis quis condimentum nec, varius ut mi. Donec aliquam quam non nulla commodo, ac ultricies nisl gravida. Nullam ante purus, aliquam id urna vitae, interdum ultricies dolor. Nulla ipsum nulla, egestas facilisis nisl vel, rutrum feugiat erat.\r\n" + "\r\n" + "Fusce ornare dapibus commodo. In gravida, nibh gravida cursus pretium, lorem massa blandit diam, quis vestibulum dolor dui at felis. Maecenas eget ornare ex. Nunc blandit laoreet gravida. Nulla efficitur euismod nisl non interdum. Vestibulum eleifend porta venenatis. Suspendisse mattis consequat ligula, tincidunt mollis nisl. In molestie, mauris a bibendum tempus, justo nisl congue libero, id euismod leo odio et odio. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent in volutpat tellus, sagittis ullamcorper tortor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras tincidunt ultricies dolor hendrerit iaculis. Vestibulum sodales dignissim felis porttitor ultrices. Ut condimentum nunc id nisi egestas, non finibus dui accumsan.\r\n" + "\r\n" + "Sed eget nibh vitae lorem condimentum rhoncus. Vivamus tincidunt molestie nisl non viverra. Nulla facilisi. Cras eu dolor erat. Suspendisse fringilla in risus sed rhoncus. Quisque eu dolor libero. Integer dictum est quis felis luctus sagittis. Ut auctor nibh iaculis nibh consequat tempor. Proin ex tortor, dapibus gravida mauris et, pretium elementum risus. Vivamus venenatis tempus diam quis varius. Fusce at ultricies mauris. Cras consequat est mattis dolor ultrices, ac mattis nibh porttitor. Donec fringilla, velit eget viverra dignissim, augue tortor tempus velit, in fringilla dolor dolor a nibh. Duis quis gravida sapien. Etiam aliquam semper ante sed consequat. Sed urna sem, semper sodales urna et, sollicitudin luctus nunc.\r\n" + "\r\n" + "Nam nisl arcu, pharetra ac tincidunt non, bibendum nec magna. Cras lobortis felis non lectus maximus, id dapibus nisi pellentesque. Maecenas id velit eros. Donec volutpat orci sed risus malesuada vestibulum. Nunc metus arcu, auctor eu nisl eget, varius ornare erat. Sed mollis ante non lectus gravida iaculis. Proin nunc lectus, convallis nec interdum vitae, sodales eu dui. Ut ipsum tortor, efficitur a leo in, imperdiet maximus felis. Ut iaculis libero id arcu dapibus, vel ullamcorper mi consequat. In varius elementum est at pretium. Aenean accumsan dapibus risus, vel sollicitudin justo facilisis a.\r\n" + "\r\n" + "Sed ultrices, erat in varius tempor, felis sem vulputate dui, vel accumsan enim lorem eget purus. Duis feugiat fringilla elit, non ultricies massa lobortis non. Proin nec molestie massa, id tincidunt elit. Aliquam purus orci, condimentum nec ante lacinia, vulputate semper nisl. Maecenas vitae nibh pulvinar est gravida pulvinar. Praesent tincidunt tellus sed ex pretium, et aliquam odio egestas. Nunc eget iaculis velit. Aenean est erat, eleifend ut eros ac, bibendum pellentesque felis. Nulla convallis, arcu sit amet bibendum egestas, massa augue tincidunt lacus, ac posuere magna justo sit amet magna. Donec id ante ex.\r\n" + "\r\n" + "Fusce sit amet feugiat risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent fringilla est sit amet iaculis gravida. Morbi urna magna, hendrerit sollicitudin ex sit amet, aliquam volutpat dolor. Vivamus fermentum quis augue ut luctus. In eu nibh mi. Mauris ipsum metus, auctor quis mattis convallis, commodo id arcu. Aenean semper id lorem pulvinar auctor. Cras fringilla egestas lectus, nec fermentum neque eleifend non. Nunc scelerisque est posuere laoreet imperdiet. Morbi in dignissim mauris, sed sagittis libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Maecenas dapibus tincidunt blandit.\r\n" + "\r\n" + "Vivamus ac risus magna. Etiam venenatis ac ligula at mollis. Morbi elit nulla, molestie sit amet nunc id, fermentum imperdiet leo. Morbi vitae gravida felis, dapibus aliquet neque. Ut eu urna cursus eros placerat porta. Donec vitae faucibus quam. Proin ac dolor sit amet turpis pellentesque tristique. Pellentesque quis iaculis nisl. Morbi gravida imperdiet orci, eget ultricies diam egestas ac. Mauris elit ante, pharetra quis ligula ut, condimentum imperdiet tortor. Donec egestas libero eu mauris pellentesque lobortis.\r\n" + "\r\n" + "Mauris sollicitudin leo a lectus mattis, in convallis dolor dapibus. Nam dapibus vitae velit ac tincidunt. Etiam facilisis, urna eu dictum mollis, nisl libero fermentum lectus, nec lacinia quam massa a arcu. Etiam mollis sodales ante, in vulputate nibh blandit eget. Maecenas sit amet felis libero. Sed congue sed eros nec lacinia. Praesent magna ipsum, vehicula quis magna et, condimentum elementum arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam erat volutpat. Mauris rhoncus tortor id imperdiet tincidunt.\r\n" + "\r\n" + "Donec mollis quis metus nec scelerisque. Integer nec leo eu massa semper mattis vel eu nisi. Nullam tellus urna, lacinia quis interdum quis, accumsan consectetur odio. Curabitur mauris mauris, consequat et porta ac, elementum at massa. Maecenas bibendum, quam ac posuere tincidunt, turpis arcu convallis neque, sit amet condimentum orci ex ut purus. Duis sit amet malesuada leo. Fusce nulla nibh, condimentum quis enim ut, lacinia mattis erat. Quisque varius nulla tempus, feugiat lorem et, mattis nisi. In at eleifend nibh, at commodo ipsum. Proin et massa sollicitudin, volutpat justo non, lacinia est. Etiam imperdiet libero nec dolor ornare condimentum. Sed ante neque, pharetra at suscipit a, efficitur non lacus.\r\n" + "\r\n" + "Sed elementum ut ex ac scelerisque. Proin metus erat, laoreet ut orci et, consectetur tincidunt elit. Pellentesque placerat egestas metus, a fringilla erat tristique sed. Donec sagittis, ipsum ac mattis auctor, tortor nunc imperdiet nibh, eu pretium lacus lacus sed dui. Quisque elementum elit arcu, sed aliquet sapien consequat at. Suspendisse accumsan ultricies dolor, sit amet finibus dolor luctus quis. Pellentesque sed porttitor diam, vitae ultrices metus. Vivamus ornare malesuada nibh. Donec vehicula facilisis dui, eu accumsan velit porttitor in. Phasellus sagittis, augue nec maximus cursus, lorem orci hendrerit nibh, eget ullamcorper velit sem non justo. Vestibulum sed nunc nisl. Donec et nunc fermentum, molestie est in, tristique eros. Vivamus tincidunt auctor odio, at lobortis ante bibendum sit amet. Sed in justo consectetur nisi viverra rhoncus quis posuere elit.\r\n" + "\r\n" + "Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam a tristique odio. Pellentesque sed mattis ex. Pellentesque dignissim varius lectus. Proin hendrerit lacus diam, ac porttitor libero dapibus sed. Maecenas sit amet leo posuere orci auctor pretium. Nam gravida, arcu eget convallis porttitor, felis leo ultrices est, sed pulvinar lorem nisi et sapien. Nulla eu enim a mauris pretium lacinia. Curabitur lacinia urna enim, a tempor nunc venenatis non. Integer at sem id odio luctus mollis hendrerit id enim.\r\n" + "\r\n" + "Nunc sagittis, dolor vel lacinia mattis, erat erat vehicula diam, at commodo quam neque a felis. Sed efficitur, felis a rutrum imperdiet, ex nisi elementum orci, a tempus turpis nibh eget velit. Cras dictum dictum odio condimentum bibendum. Sed finibus, justo eget tempus blandit, ligula est sodales purus, eget convallis risus mauris et neque. Nunc vulputate, felis in posuere congue, diam orci sollicitudin orci, ut blandit arcu tortor quis sem. Maecenas posuere fermentum ullamcorper. In congue elit eget orci ultrices, in consequat libero venenatis. Morbi luctus feugiat malesuada. Nunc ut mi sed mauris imperdiet porttitor quis quis urna. Pellentesque fermentum augue commodo eleifend rhoncus. Aliquam a erat facilisis mi interdum cursus. Duis ligula magna, pharetra vitae accumsan sed, accumsan eget ligula.\r\n" + "\r\n" + "Nullam enim dolor, facilisis dapibus pretium sit amet, posuere non nunc. Aenean volutpat, erat consectetur semper accumsan, augue nisi feugiat sem, ut consequat elit nisl sit amet lacus. Donec sodales libero eu dui tincidunt, vitae pulvinar magna faucibus. Etiam euismod nisl justo. Donec lorem massa, vulputate sit amet velit id, molestie sagittis massa. Nullam vel efficitur ante. Nullam dignissim ligula nisl, non posuere elit accumsan vitae. Pellentesque placerat lacinia maximus. Aenean in suscipit massa. Suspendisse egestas leo diam, a aliquet eros condimentum vitae.\r\n" + "\r\n" + "Aenean sed nunc lobortis nulla sollicitudin commodo. Duis dictum, turpis id fermentum vestibulum, risus urna semper erat, egestas auctor leo est vitae mi. Etiam lectus felis, venenatis ac posuere a, hendrerit non velit. Proin id mattis neque, et eleifend magna. Praesent congue eros a pretium blandit. Vestibulum vulputate lectus id erat scelerisque, at sollicitudin metus volutpat. Curabitur hendrerit eu nisi eget rutrum. Nulla facilisi. Mauris varius enim neque, a luctus mauris dapibus nec. Nunc porttitor, nisi eget ultricies ornare, nunc dolor blandit felis, vestibulum iaculis sapien nisi et diam. Donec vehicula dui sit amet placerat aliquet. Aenean finibus ex urna, in consequat massa fringilla et. Aliquam at ullamcorper eros. Vivamus sem lorem, iaculis ac imperdiet eget, mollis vel neque.\r\n" + "\r\n" + "Donec justo nisl, lobortis sit amet elit at, consequat accumsan leo. Phasellus at justo urna. Phasellus molestie felis vitae volutpat dignissim. Nam vel leo eu diam ultricies tincidunt. Vestibulum venenatis urna a libero accumsan, eu posuere enim finibus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In pretium pulvinar convallis.\r\n" + "\r\n" + "Donec ultrices in felis et tincidunt. Suspendisse volutpat blandit erat, non malesuada eros mattis in. In elementum turpis at mi porttitor accumsan. Pellentesque viverra, orci et viverra sollicitudin, nulla turpis maximus diam, id pulvinar odio augue eu ipsum. In porttitor leo sit amet velit rhoncus molestie. Nam in tempus nisl. Phasellus hendrerit consequat sem. Nulla sollicitudin velit eu nunc congue, id tincidunt diam congue. Nulla lacinia malesuada blandit. Curabitur vehicula erat at urna eleifend commodo. Ut ultricies fringilla sapien, in tincidunt magna. Nunc vel enim eget arcu imperdiet cursus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.\r\n" + "\r\n" + "Aenean rutrum orci a tempor pulvinar. Aliquam ut nibh sed quam hendrerit ultrices. Proin sodales ac leo in tempor. Nulla id condimentum urna. Vivamus vitae metus nec risus mollis porttitor. Donec quis euismod neque, gravida malesuada tellus. Nunc sem lacus, fringilla at lectus nec, semper tempus ipsum.\r\n" + "\r\n" + "Sed iaculis sit amet neque id molestie. Suspendisse ipsum enim, eleifend ut imperdiet sollicitudin, auctor vitae eros. Praesent venenatis nisi velit, id maximus risus congue blandit. Cras cursus eget augue vel sollicitudin. Interdum et malesuada fames ac ante ipsum primis in faucibus. Etiam congue, ligula nec semper pretium, diam urna sagittis turpis, at venenatis mauris ipsum quis velit. Suspendisse elementum cursus pellentesque. Proin accumsan mauris arcu, a pretium lectus lobortis id. Nullam congue tellus in ullamcorper varius. Quisque non mi quis est pharetra tincidunt eget congue enim. Nulla tempus ac neque ac suscipit. Sed porta, dui vel euismod sagittis, velit nibh malesuada ipsum, in consequat est nibh eget arcu. Nam imperdiet sagittis justo et fermentum. Etiam lobortis nibh interdum orci bibendum, a interdum risus fermentum. Proin in ante tincidunt neque molestie sodales at non diam.\r\n" + "\r\n" + "Nulla est dui, eleifend non aliquam sed, posuere ut ex. Aliquam dolor justo, blandit at arcu id, dignissim vestibulum sapien. Phasellus tristique ipsum vel risus facilisis cursus. Suspendisse hendrerit dignissim est ac pulvinar. Mauris tempor auctor orci, vitae commodo arcu laoreet sit amet. Aliquam hendrerit turpis a risus pharetra consectetur. Sed convallis quis nunc vel laoreet. Morbi sollicitudin pharetra dui sed porttitor. Praesent quis elementum quam, vitae rutrum mi.\r\n" + "\r\n" + "In tempus sollicitudin ultrices. Vivamus hendrerit ligula id maximus dapibus. Integer a aliquet nunc, sed accumsan diam. Curabitur faucibus varius enim, non elementum felis venenatis nec. Etiam purus tortor, rutrum at arcu ac, ornare vulputate dui. In consectetur luctus volutpat. Nulla sed eros pharetra, porta elit eu, pellentesque erat. Maecenas faucibus cursus malesuada. Praesent blandit mauris ullamcorper massa congue, sagittis sodales neque varius. Vivamus viverra sodales tortor non gravida. Proin in nibh nec orci maximus porta quis sed arcu. Morbi a dapibus ipsum, quis ornare lectus. Donec ut ante turpis. Sed felis justo, molestie vel felis ac, auctor blandit lacus. In at auctor mauris. Aenean consectetur vulputate blandit.\r\n" + "\r\n" + "Maecenas luctus, enim vel suscipit convallis, lorem libero volutpat eros, ut laoreet augue mauris non diam. Curabitur ut ornare leo. Vivamus nec augue sed velit sagittis hendrerit sed nec tortor. Nullam volutpat velit id feugiat convallis. Mauris non mi id nibh ornare sagittis. Fusce luctus quis ex vestibulum consectetur. Proin fermentum neque et varius ornare. Vivamus quis nibh quam. Nullam et neque eget augue euismod pretium consectetur sit amet mi. Curabitur fringilla nibh vitae massa aliquam, ut finibus lorem facilisis. Nullam sodales tristique magna convallis viverra. Morbi interdum, nisi vel posuere congue, orci purus hendrerit turpis, non pellentesque tellus libero eget sem.\r\n" + "\r\n" + "Nulla nec euismod quam, in mattis enim. In dapibus non eros eu dapibus. Nam lorem leo, luctus id cursus et, euismod et eros. Quisque eget interdum nisl. Vestibulum sed nibh non quam iaculis scelerisque. Quisque ut fermentum mauris, sit amet scelerisque mauris. Vestibulum vel eros at enim rhoncus porttitor. Duis vel mauris scelerisque, interdum quam vel, mollis leo. Praesent sit amet tortor facilisis, dictum leo sit amet, ullamcorper ex. Donec ultrices scelerisque nunc accumsan vehicula. Curabitur ultricies mollis turpis, eget ornare massa congue in. Donec nisl neque, pellentesque rhoncus nunc rutrum, porta commodo elit. Suspendisse potenti. Cras non est quis ligula molestie sodales in eget ex.\r\n" + "\r\n" + "Nulla sed tincidunt felis. Phasellus gravida odio in eros aliquet tincidunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vitae aliquam sapien. Vivamus tincidunt rhoncus pretium. Integer pellentesque feugiat sapien nec tristique. Suspendisse libero dui, consectetur eu nibh sed, sodales interdum nulla. Nunc in risus porta nunc lacinia laoreet at ut odio. Duis velit metus, pharetra in quam lobortis, porta accumsan turpis. Donec in sapien egestas, cursus diam sit amet, eleifend nisl. Integer at augue id nunc sagittis vulputate cursus ac mauris.\r\n" + "\r\n" + "Vestibulum est est, sodales non ultrices non, venenatis eu felis. Nulla felis urna, consectetur a purus ut, fermentum tempus magna. Phasellus ut dui tincidunt neque interdum congue ut at ante. Nulla blandit eros id libero vestibulum consequat. Maecenas gravida tincidunt felis ut auctor. In vehicula, ligula eu eleifend pulvinar, neque ex interdum quam, id cursus neque turpis non lorem. Nunc id libero dapibus, iaculis mi et, tempor massa. Vestibulum id gravida dui. Nulla vitae ipsum at lectus commodo blandit ac sed neque.\r\n" + "\r\n" + "Morbi magna purus, volutpat sed pulvinar non, bibendum quis est. Cras semper nulla augue, quis elementum orci congue malesuada. Nulla et rutrum arcu. Pellentesque dignissim pharetra lacus. Etiam eu quam tincidunt, commodo tortor non, dictum mauris. Fusce aliquam maximus ante a pretium. Nulla ut lacus orci. Morbi sollicitudin auctor placerat. Integer at porttitor orci. Ut volutpat orci ante, nec venenatis quam mollis sit amet.\r\n" + "\r\n" + "Donec volutpat, leo auctor congue iaculis, tellus urna feugiat lorem, id laoreet velit sem porttitor diam. Quisque interdum volutpat metus ac pellentesque. Etiam nec nunc sed urna vestibulum posuere ut vitae metus. Duis ac tortor scelerisque, fermentum erat a, blandit purus. Donec ac nunc ipsum. Duis."; return forceLower ? text.toLowerCase() : text; } public static String[] getListOfWords() { // Words in the dictionary. String[] wordList = { "the", "of", "and", "a", "to", "in", "is", "be", "that", "was", "world", "awesome", "he", "for", "it", "with", "as", "his", "I", "on", "have", "at", "by", "not", "surely", "they", "this", "attract", "computer", "had", "are", "but", "from", "or", "she", "an", "which", "you", "one", "we", "all", "were", "her", "would", "there", "their", "will", "when", "who", "him", "been", "has", "more", "if", "no", "out", "do", "so", "can", "what", "up", "said", "about", "other", "into", "than", "its", "time", "only", "could", "new", "them", "man", "some", "these", "then", "two", "first", "May", "any", "like", "now", "my", "such", "make", "over", "our", "even", "most", "me", "state", "after", "also", "made", "many", "did", "must", "before", "back", "see", "through", "way", "where", "get", "much", "go", "well", "your", "know", "should", "down", "work", "year", "because", "come", "people", "just", "say", "each", "those", "take", "day", "good", "how", "long", "Mr", "own", "too", "little", "use", "us", "very", "great", "still", "men", "here", "life", "both", "between", "old", "under", "last", "never", "place", "same", "another", "think", "abuse", "house", "while", "high", "right", "might", "came", "off", "find", "states", "since", "used", "give", "against", "three", "himself", "look", "few", "general", "heart", "hand", "school", "resin", "part", "small", "American", "home", "during", "number", "again", "Mrs", "around", "thought", "went", "without", "however", "govern", "don't", "does", "got", "public", "United", "point", "end", "become", "head", "once", "course", "fact", "upon", "need", "system", "set", "every", "trend", "war", "put", "form", "water", "took", "program", "present", "government", "thing", "told", "possible", "group", "large", "until", "always", "city", "didn't", "order", "away", "called", "want", "eyes", "something", "unite", "going", "face", "far", "asked", "interest", "later", "show", "knew", "though", "less", "night", "early", "almost", "let", "open", "enough", "side", "case", "days", "yet", "better", "nothing", "tell", "problem", "toward", "given", "why", "national", "room", "young", "social", "light", "business", "president", "help", "power", "country", "next", "things", "word", "looked", "real", "John", "line", "second", "church", "seem", "certain", "big", "Four", "felt", "several", "children", "service", "feel", "important", "rather", "name", "per", "among", "often", "turn", "development", "developmentcomputer", "keep", "family", "seemed", "white", "company", "mind", "members", "others", "within", "done", "along", "turned", "god", "sense", "week", "best", "change", "kind", "began", "child", "ever", "law", "matter", "least", "means", "question", "act", "close", "mean", "leave", "itself", "force", "study", "York", "action", "it's", "door", "experience", "human", "result", "times", "run", "different", "car", "example", "hands", "whole", "center", "although", "call", "Five", "inform", "gave", "plan", "woman", "boy", "feet", "provide", "taken", "thus", "body", "play", "seen", "today", "having", "cost", "perhaps", "field", "local", "really", "am", "increase", "reason", "themselves", "clear", "I'm", "information", "figure", "late", "above", "history", "love", "girl", "held", "special", "move", "person", "whether", "college", "sure", "probably", "either", "seems", "cannot", "art", "free", "across", "death", "quite", "street", "value", "anything", "making", "past", "brought", "moment", "control", "office", "heard", "problems", "became", "full", "near", "half", "nature", "hold", "live", "available", "known", "board", "effect", "already", "Economic", "money", "position", "believe", "age", "together", "shall", "TRUE", "political", "court", "report", "level", "rate", "air", "pay", "community", "complete", "music", "necessary", "society", "behind", "type", "read", "idea", "wanted", "land", "party", "class", "organize", "return", "department", "education", "following", "mother", "sound", "ago", "nation", "voice", "six", "bring", "wife", "common", "south", "strong", "town", "book", "students", "hear", "hope", "able", "industry", "stand", "tax", "west", "meet", "particular", "cut", "short", "stood", "university", "spirit", "start", "total", "future", "front", "low", "century", "Washington", "usually", "care", "recent", "evidence", "further", "million", "simple", "road", "sometimes", "support", "view", "fire", "says", "hard", "morning", "table", "left", "situation", "try", "outside", "lines", "surface", "ask", "modern", "top", "peace", "personal", "member", "minutes", "lead", "schools", "talk", "consider", "gone", "soon", "father", "ground", "living", "months", "therefore", "America", "started", "longer", "Dr", "dark", "various", "finally", "hour", "north", "third", "fall", "greater", "pressure", "stage", "expected", "secretary", "needed", "That's", "kept", "eye", "values", "union", "private", "alone", "black", "required", "space", "subject", "english", "month", "understand", "I'll", "nor", "answer", "moved", "amount", "conditions", "direct", "red", "student", "rest", "nations", "heart", "costs", "record", "picture", "taking", "couldn't", "hours", "deal", "forces", "everything", "write", "coming", "effort", "market", "island", "wall", "purpose", "basis", "east", "lost", "St", "except", "letter", "looking", "property", "Miles", "difference", "entire", "else", "color", "followed", "feeling", "son", "makes", "friend", "basic", "cold", "including", "single", "attention", "note", "cause", "hundred", "step", "paper", "developed", "tried", "simply", "can't", "story", "committee", "inside", "reached", "easy", "appear", "include", "accord", "Actually", "remember", "beyond", "dead", "shown", "fine", "religious", "continue", "ten", "defense", "getting", "Central", "beginning", "instead", "river", "received", "doing", "employ", "trade", "terms", "trying", "friends", "sort", "administration", "higher", "cent", "expect", "food", "building", "religion", "meeting", "ready", "walked", "follow", "earth", "speak", "passed", "foreign", "NATURAL", "medical", "training", "County", "list", "floor", "piece", "especially", "indeed", "stop", "wasn't", "England", "difficult", "likely", "Suddenly", "moral", "plant", "bad", "club", "needs", "international", "working", "countries", "develop", "drive", "reach", "police", "sat", "charge", "farm", "fear", "test", "determine", "hair", "results", "stock", "trouble", "happened", "growth", "square", "William", "cases", "effective", "serve", "miss", "involved", "doctor", "earlier", "increased", "being", "blue", "hall", "particularly", "boys", "paid", "sent", "production", "district", "using", "thinking", "concern", "Christian", "press", "girls", "wide", "usual", "direction", "feed", "trial", "walk", "begin", "weeks", "points", "respect", "certainly", "ideas", "industrial", "methods", "operation", "addition", "association", "combine", "knowledge", "decided", "temperature", "statement", "Yes", "below", "game", "nearly", "science", "directly", "horse", "influence", "size", "showed", "build", "throughout", "questions", "character", "foot", "Kennedy", "firm", "reading", "husband", "doubt", "services", "according", "lay", "stay", "programs", "anyone", "average", "French", "spring", "former", "summer", "bill", "lot", "chance", "due", "comes", "army", "actual", "Southern", "neither", "relate", "rise", "evening", "normal", "wish", "visit", "population", "remain", "measure", "merely", "arrange", "condition", "decision", "account", "opportunity", "pass", "demand", "strength", "window", "active", "deep", "degree", "ran", "western", "E", "sales", "continued", "fight", "heavy", "arm", "standard", "generally", "carry", "hot", "provided", "serious", "led", "wait", "hotel", "opened", "performance", "maybe", "station", "changes", "literature", "marry", "claim", "works", "bed", "wrong", "main", "unit", "George", "hit", "planning", "supply", "systems", "add", "chief", "officer", "Soviet", "pattern", "stopped", "price", "success", "lack", "myself", "truth", "freedom", "manner", "quality", "gun", "manufacture", "clearly", "share", "movement", "length", "ways", "burn", "forms", "Organization", "break", "somewhat", "efforts", "cover", "meaning", "progress", "treatment", "beautiful", "placed", "happy", "attack", "apparently", "blood", "groups", "carried", "sign", "radio", "dance", "I've", "regard", "man's", "train", "herself", "numbers", "corner", "REACTION", "immediately", "language", "running", "recently", "shake", "larger", "lower", "machine", "attempt", "learn", "couple", "race", "audience", "Oh", "middle", "brown", "date", "health", "persons", "understanding", "arms", "daily", "suppose", "additional", "hospital", "pool", "technical", "served", "declare", "described", "current", "poor", "steps", "reported", "sun", "based", "produce", "determined", "receive", "park", "staff", "faith", "responsibility", "Europe", "latter", "British", "season", "equal", "learned", "practice", "green", "writing", "ones", "choice", "fiscal", "term", "watch", "scene", "activity", "product", "types", "ball", "heat", "clothe", "lived", "distance", "parent", "letters", "returned", "forward", "obtained", "offer", "specific", "straight", "fix", "division", "slowly", "shot", "poet", "seven", "moving", "mass", "plane", "proper", "propose", "drink", "obviously", "plans", "whatever", "afternoon", "figures", "parts", "approve", "saying", "born", "immediate", "fame", "gives", "extent", "justice", "cars", "mark", "pretty", "opinion", "ahead", "glass", "refuse", "enter", "completely", "send", "desire", "judge", "none", "waiting", "popular", "Democratic", "film", "mouth", "Corps", "importance", "touch", "director", "ship", "there's", "council", "EFFECTS", "event", "worth", "existence", "designed", "hardly", "indicated", "analysis", "established", "products", "growing", "patient", "rule", "bridge", "pain", "base", "check", "cities", "elements", "leaders", "discussion", "limited", "sit", "Thomas", "agreement", "gas", "factors", "marriage", "easily", "closed", "excite", "accept", "applied", "allow", "bit", "married", "oil", "Rhode", "shape", "interested", "strange", "compose", "professional", "remained", "news", "Despite", "beauty", "responsible", "wonder", "spent", "tear", "unless", "eight", "permit", "covered", "Negro", "played", "I'd", "vote", "balance", "Charles", "loss", "Commission", "original", "fair", "reasons", "studies", "exactly", "built", "behavior", "enemy", "teeth", "bank", "die", "James", "relations", "weight", "prepared", "related", "sea", "bar", "warn", "post", "trees", "official", "separate", "clay", "Sunday", "raised", "events", "thin", "dropped", "cattle", "invite", "playing", "prevent", "detail", "standing", "grow", "places", "someone", "bright", "Talking", "meant", "print", "capital", "happen", "sides", "everyone", "facilities", "filled", "lip", "essential", "techniques", "June", "knows", "stain", "hadn't", "dinner", "dog", "dollars", "caught", "shout", "buy", "divide", "entered", "Chicago", "speed", "jazz", "appoint", "governor", "institutions", "fit", "materials", "sight", "store", "dependence", "explain", "gain", "he'd", "leadership", "quiet", "realize", "parents", "Communist", "neighbor", "round", "included", "kitchen", "thousand", "Christ", "isn't", "radiation", "broad", "stops", "failure", "retire", "election", "primary", "king", "books", "command", "edge", "ember", "March", "sitting", "conference", "bottom", "lady", "advise", "churches", "model", "battle", "giving", "sport", "address", "considerable", "spread", "funds", "trip", "youth", "CONSTRUCTION", "rock", "regular", "changed", "boat", "memory", "successful", "captain", "hell", "brother", "murder", "quick", "moreover", "highly", "difficulty", "inch", "saw", "clean", "collect", "camp", "experiment", "shows", "Authority", "older", "lord", "variety", "material", "frame", "distinguish", "scientific", "introduce", "principal", "Jack", "kill", "collection", "fell", "entertain", "pieces", "management", "otherwise", "security", "danger", "entirely", "civil", "frequently", "advertise", "records", "secret", "title", "impossible", "yesterday", "fast", "Mike", "produced", "favor", "noted", "caused", "lose", "purposes", "solid", "song", "corporation", "lie", "winter", "dress", "electric", "key", "dry", "reduce", "fresh", "goes", "hill", "names", "slow", "quickly", "telephone", "threaten", "oppose", "deliver", "officers", "expression", "published", "famous", "pray", "adopt", "London", "clothes", "laws", "citizens", "announced", "minute", "master", "sharp", "advantage", "greatest", "relation", "Mary", "leaving", "gray", "manager", "animal", "object", "bottle", "draw", "honor", "recognize", "drop", "intend", "relationship", "opposite", "sources", "poetry", "ability", "assistance", "operating", "bear", "join", "climb", "companies", "exist", "fixed", "gradual", "possibility", "hunt", "spoke", "satisfy", "units", "neck", "sleep", "doesn't", "finished", "carefully", "facts", "nice", "practical", "save", "takes", "allowed", "wine", "remind", "rich", "financial", "dream", "knife", "stations", "civilize", "Rose", "cool", "died", "thick", "imagine", "literary", "bind", "inches", "earn", "familiar", "seeing", "distribution", "marked", "coffee", "rules", "slip", "apply", "page", "beside", "daughter", "Relatively", "classes", "explore", "stated", "German", "musical", "smile", "significant", "block", "mix", "reports", "PROPOSED", "shelter", "presence", "Affairs", "named", "ordinary", "circumstances", "mile", "sweep", "remains", "admire", "Catholic", "dust", "operations", "rain", "tree", "nobody", "Henry", "Robert", "village", "advance", "offered", "agree", "mechanic", "upper", "occasion", "requirements", "capacity", "appears", "travel", "article", "houses", "valley", "beat", "opening", "box", "evil", "succeed", "surround", "application", "slightly", "remembered", "interests", "warm", "subjects", "search", "presented", "shoe", "sweet", "interesting", "membership", "suggest", "notice", "connection", "extreme", "exchange", "flow", "spend", "everybody", "poems", "campaign", "win", "forced", "freeze", "nine", "eat", "newspaper", "please", "escape", "lives", "swim", "file", "wind", "provides", "shop", "apartment", "fashion", "reasonable", "created", "Germany", "watched", "cells", "session", "somehow", "fully", "whose", "teacher", "raise", "recognized", "unity", "Providence", "reference", "explained", "twenty", "Russian", "features", "shoulder", "sir", "forest", "studied", "Sam", "signal", "chair", "reduced", "procedure", "forth", "limit", "disturb", "universe", "mentioned", "pick", "reality", "differences", "soft", "traditional", "Mission", "flat", "looks", "picked", "weather", "smaller", "leg", "chairman", "ancient", "narrow", "fellow", "twist", "belief", "excellent", "rights", "vocational", "laid", "politics", "fill", "response", "struggle", "disappear", "prove", "duty", "FOLLOWS", "editor", "welcome", "anode", "possess", "hearing", "BUILDINGS", "ideal", "scientist", "formed", "watching", "circle", "ought", "garden", "library", "accuse", "message", "slight", "junior", "knock", "empty", "protection", "treated", "birth", "expressed", "planned", "choose", "confuse", "Virginia", "killed", "frighten", "stayed", "worry", "surprise", "aside", "photograph", "removed", "turning", "Jr", "pull", "personnel", "agency", "pointed", "speech", "listen", "November", "sample", "Louis", "motor", "selected", "Berlin", "CLAIMS", "spot", "strike", "increasing", "exercise", "handle", "hole", "Leader", "baby", "ride", "avoid", "cross", "twice", "commercial", "failed", "prompt", "fat", "fourth", "visitor", "interior", "Jewish", "wing", "desk", "faculty", "forget", "operate", "stair", "besides", "relief", "standards", "France", "perfect", "pour", "Nevertheless", "brief", "Jones", "kick", "attend", "plus", "solution", "wage", "individuals", "powers", "minister", "taste", "discovered", "pulled", "hire", "writer", "verb", "preach", "friendly", "observed", "fan", "connect", "Fig", "count", "egg", "items", "mention", "Texas", "calculate", "platform", "drag", "mere", "tomorrow", "faces", "pure", "fighting", "resources", "increases", "assumed", "broke", "coast", "strict", "whom", "Russia", "qualify", "Morgan", "victory", "fields", "pleasure", "contain", "fold", "review", "April", "teach", "Richard", "whisper", "chosen", "metal", "PRINCIPLES", "competition", "railroad", "safe", "proved", "carrying", "horses", "kiss", "Mercer", "wheel", "sail", "wants", "compared", "relieve", "approximately", "wood", "historical", "persuade", "smiled", "crowd", "motion", "shore", "suit", "calls", "seat", "deserve", "San", "snow", "double", "educational", "neighborhood", "relative", "teachers", "Independent", "puzzle", "nose", "dogs", "waited", "naturally", "stone", "origin", "Rome", "wild", "scale", "tremble", "drawn", "guess", "communism", "absence", "roof", "sections", "sky", "walls", "Aircraft", "complain", "independence", "busy", "elect", "revolution", "roar", "willing", "League", "mine", "nurse", "liberal", "completed", "poem", "dollar", "ordered", "levels", "ton", "settled", "allowance", "bitter", "realized", "let's", "moon", "sensitive", "servant", "hunger", "China", "sale", "appearance", "lips", "policies", "actions", "strengthen", "Monday", "onto", "directed", "leading", "machinery", "theater", "Paris", "Frank", "somewhere", "Statements", "mill", "projects", "starting", "hat", "ruin", "depend", "stands", "signs", "families", "stir", "Khrushchev", "largely", "punish", "drew", "breathe", "amuse", "characteristic", "electronic", "pale", "pictures", "destroy", "expense", "somebody", "completion", "disappoint", "fifty", "found", "soil", "flame", "enjoy", "bless", "emotional", "promise", "she'd", "wave", "commerce", "Jury", "bay", "tempt", "correct", "asking", "content", "estimated", "conscious", "shine", "teaching", "catch", "dish", "Saturday", "greet", "background", "flood", "insect", "worse", "yellow", "occurred", "afraid", "ceremony", "decrease", "trust", "yourself", "legs", "you've", "communication", "describe", "sincere", "decide", "leaf", "encourage", "rub", "declared", "cry", "bite", "July", "lung", "significance", "helped", "gross", "apart", "disease", "issues", "scratch", "dictionary", "risk", "broadcast", "drum", "representative", "uncle", "cutting", "Jesus", "neglect", "depth", "substantial", "GETS", "adventure", "beg", "entrance", "plays", "throw", "ends", "Arts", "alive", "confidence", "intellectual", "cheer", "properties", "experiments", "nut", "plenty", "beneath", "closely", "description", "melt", "swear", "tall", "loose", "area", "bury", "measured", "request", "ourselves", "stream", "wipe", "band", "fingers", "creature", "Hanover", "attorney", "load", "passing", "billion", "earnest", "discussed", "translate", "achievement", "headquarters", "inquiry", "rapidly", "express", "hesitate", "guard", "jobs", "borrow", "owe", "Phil", "California", "ambition", "supposed", "lake", "they're", "slope", "Typical", "spite", "wore", "dear", "employees", "map", "pair", "spin", "one's", "praise", "imagination", "hung", "instrument", "plow", "holding", "objects", "straighten", "dominant", "scarce", "ring", "matters", "creep", "plain", "resolution", "credit", "period", "improve", "maintenance", "seize", "Laos", "we'll", "dozen", "located", "dig", "towards", "curse", "major", "breath", "weigh", "comfort", "federal", "guests", "priest", "sell", "bodies", "female", "primarily", "cousin", "grew", "spiritual", "dine", "engine", "politician", "custom", "educate", "individual", "job", "Tom", "cook", "grass", "mail", "salesman", "nail", "tap", "wet", "bedroom", "sufficient", "chest", "dramatic", "silence", "behave", "breakfast", "sudden", "passage", "scatter", "objection", "unusual", "argument", "policy", "powerful", "throat", "formal", "rapid", "Parker", "wrap", "luck", "grind", "rifle", "HIGHEST", "loan", "represent", "skill", "spell", "broken", "arch", "angle", "sick", "swell", "blind", "Contemporary", "engineer", "military", "boundary", "location", "homes", "boil", "officials", "operator", "Senate", "lend", "hearts", "embers", "abused", "resins", "trendy", "ssdsy" }; return wordList; } } ================================================ FILE: Java/CtCILibrary/CtCILibrary/BTreePrinter.java ================================================ package CtCILibrary; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class BTreePrinter { public static > void printNode(TreeNode root) { int maxLevel = BTreePrinter.maxLevel(root); printNodeInternal(Collections.singletonList(root), 1, maxLevel); } private static > void printNodeInternal(List nodes, int level, int maxLevel) { if (nodes.isEmpty() || BTreePrinter.isAllElementsNull(nodes)) return; int floor = maxLevel - level; int endgeLines = (int) Math.pow(2, (Math.max(floor - 1, 0))); int firstSpaces = (int) Math.pow(2, (floor)) - 1; int betweenSpaces = (int) Math.pow(2, (floor + 1)) - 1; BTreePrinter.printWhitespaces(firstSpaces); List newNodes = new ArrayList(); for (TreeNode node : nodes) { if (node != null) { System.out.print(node.data); newNodes.add(node.left); newNodes.add(node.right); } else { newNodes.add(null); newNodes.add(null); System.out.print(" "); } BTreePrinter.printWhitespaces(betweenSpaces); } System.out.println(""); for (int i = 1; i <= endgeLines; i++) { for (int j = 0; j < nodes.size(); j++) { BTreePrinter.printWhitespaces(firstSpaces - i); if (nodes.get(j) == null) { BTreePrinter.printWhitespaces(endgeLines + endgeLines + i + 1); continue; } if (nodes.get(j).left != null) System.out.print("/"); else BTreePrinter.printWhitespaces(1); BTreePrinter.printWhitespaces(i + i - 1); if (nodes.get(j).right != null) System.out.print("\\"); else BTreePrinter.printWhitespaces(1); BTreePrinter.printWhitespaces(endgeLines + endgeLines - i); } System.out.println(""); } printNodeInternal(newNodes, level + 1, maxLevel); } private static void printWhitespaces(int count) { for (int i = 0; i < count; i++) System.out.print(" "); } private static > int maxLevel(TreeNode node) { if (node == null) return 0; return Math.max(BTreePrinter.maxLevel(node.left), BTreePrinter.maxLevel(node.right)) + 1; } private static boolean isAllElementsNull(List list) { for (Object object : list) { if (object != null) return false; } return true; } } ================================================ FILE: Java/CtCILibrary/CtCILibrary/BitVector.java ================================================ package CtCILibrary; public class BitVector { private static int DATA_SIZE = 32; private int length; private int[] vector; public BitVector(int length) { this.length = length; if (length % DATA_SIZE == 0) { vector = new int[length / DATA_SIZE]; } else { vector = new int[length / DATA_SIZE + 1]; } } public int length() { return length; } public boolean get(int i) { int b = vector[i / DATA_SIZE]; int bit_index = i % DATA_SIZE; if (((b >> bit_index) & 1) == 1) { return true; } else { return false; } } public void print() { for (int k : vector) { for (int i = 0; i < DATA_SIZE; i++) { if ((k >> i & 1) == 1) { System.out.print(1); } else { System.out.print(0); } } System.out.println(); } } public void set(int i, boolean flag) { if (i >= 0 && i < length) { int mask = ~(1 << i); int b = vector[i / DATA_SIZE] & mask; if (flag) { vector[i / DATA_SIZE] = b | (1 << i); } else { vector[i / DATA_SIZE] = b; } } } } ================================================ FILE: Java/CtCILibrary/CtCILibrary/HashMapList.java ================================================ package CtCILibrary; import java.util.ArrayList; import java.util.HashMap; import java.util.Set; public class HashMapList { private HashMap> map = new HashMap>(); /* Insert item into list at key. */ public void put(T key, E item) { if (!map.containsKey(key)) { map.put(key, new ArrayList()); } map.get(key).add(item); } /* Insert list of items at key. */ public void put(T key, ArrayList items) { map.put(key, items); } /* Get list of items at key. */ public ArrayList get(T key) { return map.get(key); } /* Check if hashmaplist contains key. */ public boolean containsKey(T key) { return map.containsKey(key); } /* Check if list at key contains value. */ public boolean containsKeyValue(T key, E value) { ArrayList list = get(key); if (list == null) return false; return list.contains(value); } /* Get the list of keys. */ public Set keySet() { return map.keySet(); } @Override public String toString() { return map.toString(); } } ================================================ FILE: Java/CtCILibrary/CtCILibrary/LinkedListNode.java ================================================ package CtCILibrary; public class LinkedListNode { public LinkedListNode next; public LinkedListNode prev; public LinkedListNode last; public int data; public LinkedListNode(int d, LinkedListNode n, LinkedListNode p) { data = d; setNext(n); setPrevious(p); } public LinkedListNode(int d) { data = d; } public LinkedListNode() { } public void setNext(LinkedListNode n) { next = n; if (this == last) { last = n; } if (n != null && n.prev != this) { n.setPrevious(this); } } public void setPrevious(LinkedListNode p) { prev = p; if (p != null && p.next != this) { p.setNext(this); } } public String printForward() { if (next != null) { return data + "->" + next.printForward(); } else { return ((Integer) data).toString(); } } public LinkedListNode clone() { LinkedListNode next2 = null; if (next != null) { next2 = next.clone(); } LinkedListNode head2 = new LinkedListNode(data, next2, null); return head2; } } ================================================ FILE: Java/CtCILibrary/CtCILibrary/TreeNode.java ================================================ package CtCILibrary; /* 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; public TreeNode parent; private int size = 0; public TreeNode(int d) { data = d; size = 1; } private void setLeftChild(TreeNode left) { this.left = left; if (left != null) { left.parent = this; } } private void setRightChild(TreeNode right) { this.right = right; if (right != null) { right.parent = this; } } public void insertInOrder(int d) { if (d <= data) { if (left == null) { setLeftChild(new TreeNode(d)); } else { left.insertInOrder(d); } } else { if (right == null) { setRightChild(new TreeNode(d)); } else { right.insertInOrder(d); } } size++; } public int size() { return size; } public boolean isBST() { if (left != null) { if (data < left.data || !left.isBST()) { return false; } } if (right != null) { if (data >= right.data || !right.isBST()) { return false; } } return true; } public int height() { int leftHeight = left != null ? left.height() : 0; int rightHeight = right != null ? right.height() : 0; return 1 + Math.max(leftHeight, rightHeight); } 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; } private static TreeNode createMinimalBST(int arr[], int start, int end){ if (end < start) { return null; } int mid = (start + end) / 2; TreeNode n = new TreeNode(arr[mid]); n.setLeftChild(createMinimalBST(arr, start, mid - 1)); n.setRightChild(createMinimalBST(arr, mid + 1, end)); return n; } public static TreeNode createMinimalBST(int[] array) { return createMinimalBST(array, 0, array.length - 1); } public void print() { BTreePrinter.printNode(this); } } ================================================ FILE: Java/CtCILibrary/CtCILibrary/Trie.java ================================================ package CtCILibrary; import java.util.ArrayList; /* Implements a trie. We store the input list of words in tries so * that we can efficiently find words with a given prefix. */ public class Trie { // The root of this trie. private TrieNode root; /* Takes a list of strings as an argument, and constructs a trie that stores these strings. */ public Trie(ArrayList list) { root = new TrieNode(); for (String word : list) { root.addWord(word); } } /* Takes a list of strings as an argument, and constructs a trie that stores these strings. */ public Trie(String[] list) { root = new TrieNode(); for (String word : list) { root.addWord(word); } } /* Checks whether this trie contains a string with the prefix passed * in as argument. */ public boolean contains(String prefix, boolean exact) { TrieNode lastNode = root; int i = 0; for (i = 0; i < prefix.length(); i++) { lastNode = lastNode.getChild(prefix.charAt(i)); if (lastNode == null) { return false; } } return !exact || lastNode.terminates(); } public boolean contains(String prefix) { return contains(prefix, false); } public TrieNode getRoot() { return root; } } ================================================ FILE: Java/CtCILibrary/CtCILibrary/TrieNode.java ================================================ package CtCILibrary; import java.util.HashMap; /* One node in the trie. Most of the logic of the trie is implemented * in this class. */ public class TrieNode { /* The children of this node in the trie.*/ private HashMap children; private boolean terminates = false; // The character stored in this node as data. private char character; /* Constructs a trie node and stores this character as the node's value. * Initializes the list of child nodes of this node to an empty hash map. */ public TrieNode() { children = new HashMap(); } /* Constructs a trie node and stores in the node the char passed in * as the argument. Initializes the list of child nodes of this * node to an empty hash map. */ public TrieNode(char character) { this(); this.character = character; } /* Returns the character data stored in this node. */ public char getChar() { return character; } /* Add this word to the trie, and recursively create the child * nodes. */ public void addWord(String word) { if (word == null || word.isEmpty()) { return; } char firstChar = word.charAt(0); TrieNode child = getChild(firstChar); if (child == null) { child = new TrieNode(firstChar); children.put(firstChar, child); } if (word.length() > 1) { child.addWord(word.substring(1)); } else { child.setTerminates(true); } } /* Find a child node of this node that has the char argument as its * data. Return null if no such child node is present in the trie. */ public TrieNode getChild(char c) { return children.get(c); } /* Returns whether this node represents the end of a complete word. */ public boolean terminates() { return terminates; } /* Set whether this node is the end of a complete word.*/ public void setTerminates(boolean t) { terminates = t; } } ================================================ FILE: Java/Introduction/Big_O/Ex_01.java ================================================ package Big_O; public class Ex_01 { public static int sum(int n) { if (n <= 0) { return 0; } return n + sum(n-1); } public static void main(String[] args) { int s = sum(4); System.out.println(s); } } ================================================ FILE: Java/Introduction/Big_O/Ex_02.java ================================================ package Big_O; public class Ex_02 { public static int pairSum(int a, int b) { return a + b; } public static int pairSumSequence(int n) { int sum = 0; for (int i = 0; i < n; i++) { sum += pairSum(i, i + 1); } return sum; } public static void main(String[] args) { int s = pairSumSequence(4); System.out.println(s); } } ================================================ FILE: Java/Introduction/Big_O/Ex_03.java ================================================ package Big_O; public class Ex_03 { public static void minAndMax1(int[] array) { int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; for (int x : array) { if (x < min) min = x; if (x > max) max = x; } System.out.println(min + ", " + max); } public static void minAndMax2(int[] array) { int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; for (int x : array) { if (x < min) min = x; } for (int x : array) { if (x > max) max = x; } System.out.println(min + ", " + max); } public static void main(String[] args) { int[] array = {1, 2, 5, 2, 2, 5, -1, 9, 3}; minAndMax1(array); minAndMax2(array); } } ================================================ FILE: Java/Introduction/Big_O/Ex_04.java ================================================ package Big_O; public class Ex_04 { public static void foo(int[] arrA, int[] arrB) { for (int a : arrA) { System.out.println(a); } for (int b : arrB) { System.out.println(b); } } public static void bar(int[] arrA, int[] arrB) { for (int a : arrA) { for (int b : arrB) { System.out.println(a + "," + b); } } } public static void main(String[] args) { int[] arrA = {1, 2, 5, 2, 2, 5, -1, 9, 3}; int[] arrB = {5, 2, 1, 0, 2}; foo(arrA, arrB); bar(arrA, arrB); } } ================================================ FILE: Java/Introduction/Big_O/Ex_05.java ================================================ package Big_O; public class Ex_05 { public static int f(int n) { if (n <= 0) { return 1; } return f(n - 1) + f(n - 1); } public static void main(String[] args) { f(1); } } ================================================ FILE: Java/Introduction/Big_O/Ex_06.java ================================================ package Big_O; public class Ex_06 { public static void foo(int[] array) { int sum = 0; int product = 1; for (int i = 0; i < array.length; i++) { sum += array[i]; } for (int i = 0; i < array.length; i++) { product *= array[i]; } System.out.println(sum + ", " + product); } public static void main(String[] args) { int[] array = {1, 2, 5, 2, 2, 5, -1, 9, 3}; foo(array); } } ================================================ FILE: Java/Introduction/Big_O/Ex_07.java ================================================ package Big_O; public class Ex_07 { public static void printPairs(int[] array) { for (int i = 0; i < array.length; i++) { for (int j = 0; j < array.length; j++) { System.out.println(array[i] + "," + array[j]); } } } public static void main(String[] args) { int[] array = {0, 1, 2, 3}; printPairs(array); } } ================================================ FILE: Java/Introduction/Big_O/Ex_08.java ================================================ package Big_O; public class Ex_08 { public static void printUnorderedPairs(int[] array) { for (int i = 0; i < array.length; i++) { for (int j = i; j < array.length; j++) { System.out.println(array[i] + "," + array[j]); } } } public static void main(String[] args) { int[] array = {0, 1, 2, 3}; printUnorderedPairs(array); } } ================================================ FILE: Java/Introduction/Big_O/Ex_09.java ================================================ package Big_O; public class Ex_09 { public static void printUnorderedPairs(int[] arrayA, int[] arrayB) { for (int i = 0; i < arrayA.length; i++) { for (int j = 0; j < arrayB.length; j++) { if (arrayA[i] < arrayB[j]) { System.out.println(arrayA[i] + "," + arrayB[j]); } } } } public static void main(String[] args) { int[] arrayA = {0, 1, 2, 3}; int[] arrayB = {4, 5, 6}; printUnorderedPairs(arrayA, arrayB); } } ================================================ FILE: Java/Introduction/Big_O/Ex_10.java ================================================ package Big_O; public class Ex_10 { public static void printUnorderedPairs(int[] arrayA, int[] arrayB) { for (int i = 0; i < arrayA.length; i++) { for (int j = 0; j < arrayB.length; j++) { for (int k = 0; k < 1000; k++) { System.out.println(arrayA[i] + "," + arrayB[j]); } } } } public static void main(String[] args) { int[] arrayA = {0, 1, 2, 3}; int[] arrayB = {4, 5, 6}; printUnorderedPairs(arrayA, arrayB); } } ================================================ FILE: Java/Introduction/Big_O/Ex_11.java ================================================ package Big_O; public class Ex_11 { public static void reverse(int[] array) { for (int i = 0; i < array.length / 2; i++) { int other = array.length - i - 1; int temp = array[i]; array[i] = array[other]; array[other] = temp; } } public static void main(String[] args) { int[] array = {0, 1, 2, 3, 4, 5}; reverse(array); for (int x : array) { System.out.println(x); } } } ================================================ FILE: Java/Introduction/Big_O/Ex_14.java ================================================ package Big_O; public class Ex_14 { public static boolean isPrime(int n) { for (int x = 2; x * x <= n; x++) { if (n % x == 0) { return false; } } return true; } public static void main(String[] args) { int[] array = {2, 3, 4, 5, 6, 7, 8, 9, 10}; for (int x : array) { boolean isPrimeNumber = isPrime(x); if (isPrimeNumber) { System.out.println(x + ": prime"); } else { System.out.println(x + ": not prime"); } } } } ================================================ FILE: Java/Introduction/Big_O/Ex_15.java ================================================ package Big_O; public class Ex_15 { public static int factorial(int n) { if (n < 0) { return -1; } else if (n == 0) { return 1; } else { return n * factorial(n - 1); } } public static void main(String[] args) { System.out.println(factorial(4)); } } ================================================ FILE: Java/Introduction/Big_O/Ex_16.java ================================================ package Big_O; public class Ex_16 { public static void permutation(String str) { permutation(str, ""); } public static void permutation(String str, String prefix) { if (str.length() == 0) { System.out.println(prefix); } else { for (int i = 0; i < str.length(); i++) { String rem = str.substring(0, i) + str.substring(i + 1); permutation(rem, prefix + str.charAt(i)); } } } public static void main(String[] args) { permutation("abc"); } } ================================================ FILE: Java/Introduction/Big_O/Ex_17.java ================================================ package Big_O; public class Ex_17 { public static int fib(int n) { if (n <= 0) return 0; else if (n == 1) return 1; return fib(n - 1) + fib(n - 2); } public static void main(String[] args) { for (int i = 0; i < 6; i++) { System.out.println(i + ": " + fib(i)); } } } ================================================ FILE: Java/Introduction/Big_O/Ex_18.java ================================================ package Big_O; public class Ex_18 { public static void allFib(int n) { for (int i = 0; i < n; i++) { System.out.println(i + ": " + fib(i)); } } public static int fib(int n) { if (n <= 0) return 0; else if (n == 1) return 1; return fib(n - 1) + fib(n - 2); } public static void main(String[] args) { allFib(6); } } ================================================ FILE: Java/Introduction/Big_O/Ex_19.java ================================================ package Big_O; public class Ex_19 { public static void allFib(int n) { int[] memo = new int[n + 1]; for (int i = 0; i < n; i++) { System.out.println(i + ": " + fib(i, memo)); } } public static int fib(int n, int[] memo) { if (n <= 0) return 0; else if (n == 1) return 1; else if (memo[n] > 0) return memo[n]; memo[n] = fib(n - 1, memo) + fib(n - 2, memo); return memo[n]; } public static void main(String[] args) { allFib(6); } } ================================================ FILE: Java/Introduction/Big_O/Ex_20.java ================================================ package Big_O; public class Ex_20 { public static int powersOf2(int n) { 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(100); } } ================================================ FILE: Java/Introduction/Big_O/Q_01.java ================================================ package Big_O; public class Q_01 { public static int product(int a, int b) { int sum = 0; for (int i = 0; i < b; i++) { sum += a; } return sum; } public static void main(String[] args) { System.out.println(product(5, 6)); } } ================================================ FILE: Java/Introduction/Big_O/Q_02.java ================================================ package Big_O; public class Q_02 { public static int power(int a, int b) { if (b < 0) { return 0; // error } else if (b == 0) { return 1; } else { return a * power(a, b - 1); } } public static void main(String[] args) { System.out.println(power(3, 4)); } } ================================================ FILE: Java/Introduction/Big_O/Q_03.java ================================================ package Big_O; public class Q_03 { public static int mod(int a, int b) { if (b <= 0) { return -1; } int div = a / b; return a - div * b; } public static void main(String[] args) { System.out.println(mod(3, 6)); } } ================================================ FILE: Java/Introduction/Big_O/Q_04.java ================================================ package Big_O; public class Q_04 { public static int div(int a, int b) { int count = 0; int sum = b; while (sum <= a) { sum += b; count++; } return count; } public static void main(String[] args) { System.out.println(div(12, 4)); } } ================================================ FILE: Java/Introduction/Big_O/Q_05.java ================================================ package Big_O; public class Q_05 { public static int sqrt(int n) { return sqrt_helper(n, 1, n); } public static int sqrt_helper(int n, int min, int max) { if (max < min) return -1; // no square root int guess = (min + max) / 2; if (guess * guess == n) { // found it! return guess; } else if (guess * guess < n) { // too low return sqrt_helper(n, guess + 1, max); // try higher } else { // too high return sqrt_helper(n, min, guess - 1); // try lower } } public static void main(String[] args) { System.out.println(sqrt(26)); } } ================================================ FILE: Java/Introduction/Big_O/Q_06.java ================================================ package Big_O; public class Q_06 { public static int sqrt(int n) { for (int guess = 1; guess * guess <= n; guess++) { if (guess * guess == n) { return guess; } } return -1; } public static void main(String[] args) { System.out.println(sqrt(26)); } } ================================================ FILE: Java/Introduction/Big_O/Q_09.java ================================================ package Big_O; public class Q_09 { public static int[] copyArray(int[] array) { int[] copy = new int[0]; for (int value : array) { copy = appendToNew(copy, value); } return copy; } public static int[] appendToNew(int[] array, int value) { // copy all elements over to new array int[] bigger = new int[array.length + 1]; for (int i = 0; i < array.length; i++) { bigger[i] = array[i]; } // add new element bigger[bigger.length - 1] = value; return bigger; } public static void main(String[] args) { int[] array = {1, 2, 3, 4, 5, 6}; int[] copy = copyArray(array); for (int x : copy) { System.out.println(x); } } } ================================================ FILE: Java/Introduction/Big_O/Q_10.java ================================================ package Big_O; public class Q_10 { public static int sumDigits(int n) { int sum = 0; while (n > 0) { sum += n % 10; n /= 10; } return sum; } public static void main(String[] args) { System.out.println(sumDigits(1252)); } } ================================================ FILE: Java/Introduction/Big_O/Q_11.java ================================================ package Big_O; public class Q_11 { public static int numChars = 26; public static void printSortedStrings(int remaining) { printSortedStrings(remaining, ""); } public static void printSortedStrings(int remaining, String prefix) { if (remaining == 0) { 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) { for (int i = 1; i < s.length(); i++) { int prev = ithLetter(s.charAt(i - 1)); int curr = ithLetter(s.charAt(i)); if (prev > curr) { return false; } } return true; } public static char ithLetter(int i) { return (char) (((int) 'a') + i); } public static void main(String[] args) { printSortedStrings(3); } } ================================================ FILE: Java/Introduction/Big_O/Q_12.java ================================================ package Big_O; public class Q_12 { public static int binarySearch(int[] a, int x) { int low = 0; int high = a.length - 1; int mid; while (low <= high) { mid = (low + high) / 2; if (a[mid] < x) { low = mid + 1; } else if (a[mid] > x) { high = mid - 1; } else { return mid; } } return -1; } public static void mergesort(int[] array) { int[] helper = new int[array.length]; mergesort(array, helper, 0, array.length - 1); } public static void mergesort(int[] array, int[] helper, int low, int high) { if (low < high) { int middle = (low + high) / 2; mergesort(array, helper, low, middle); // Sort left half mergesort(array, helper, middle+1, high); // Sort right half merge(array, helper, low, middle, high); // Merge them } } public static void merge(int[] array, int[] helper, int low, int middle, int high) { /* Copy both halves into a helper array */ for (int i = low; i <= high; i++) { helper[i] = array[i]; } int helperLeft = low; int helperRight = middle + 1; int current = low; /* Iterate through helper array. Compare the left and right * half, copying back the smaller element from the two halves * into the original array. */ while (helperLeft <= middle && helperRight <= high) { if (helper[helperLeft] <= helper[helperRight]) { array[current] = helper[helperLeft]; helperLeft++; } else { // If right element is smaller than left element array[current] = helper[helperRight]; helperRight++; } current++; } /* Copy the rest of the left side of the array into the * target array */ int remaining = middle - helperLeft; for (int i = 0; i <= remaining; i++) { array[current + i] = helper[helperLeft + i]; } } public static int intersection(int[] a, int[] b) { mergesort(b); int intersect = 0; for (int x : a) { if (binarySearch(b, x) >= 0) { intersect++; } } return intersect; } public static void main(String[] args) { int[] a = {1, 3, 5, 7}; int[] b = {1, 9, 2, 7}; int x = intersection(a, b); System.out.println(x); } } ================================================ FILE: Java/Introduction/CompareBinaryToHex/CompareBinaryToHex.java ================================================ package CompareBinaryToHex; public class CompareBinaryToHex { public static int digitToValue(char c) { if (c >= '0' && c <= '9') { return c - '0'; } else if (c >= 'A' && c <= 'F') { return 10 + c - 'A'; } else if (c >= 'a' && c <= 'f') { return 10 + c - 'a'; } return -1; } public static int convertFromBase(String number, int base) { if (base < 2 || (base > 10 && base != 16)) return -1; int value = 0; for (int i = number.length() - 1; i >= 0; i--) { int digit = digitToValue(number.charAt(i)); if (digit < 0 || digit >= base) { return -1; } int exp = number.length() - 1 - i; value += digit * Math.pow(base, exp); } return value; } public static boolean compareBinToHex(String binary, String hex) { int n1 = convertFromBase(binary, 2); int n2 = convertFromBase(hex, 16); if (n1 < 0 || n2 < 0) { return false; } return n1 == n2; } public static void main(String[] args) { System.out.println(compareBinToHex("111001011", "1CB")); } } ================================================ FILE: Java/Introduction/SwapMinMax/SwapMinMax.java ================================================ package SwapMinMax; import CtCILibrary.AssortedMethods; public class SwapMinMax { public static int getMinIndex(int[] array) { int minIndex = 0; for (int i = 1; i < array.length; i++) { if (array[i] < array[minIndex]) { minIndex = i; } } return minIndex; } public static int getMaxIndex(int[] array) { int maxIndex = 0; for (int i = 1; i < array.length; i++) { if (array[i] > array[maxIndex]) { maxIndex = i; } } return maxIndex; } public static void swap(int[] array, int m, int n) { int temp = array[m]; array[m] = array[n]; array[n] = temp; } public static void swapMinMaxBetter(int[] array) { int minIndex = getMinIndex(array); int maxIndex = getMaxIndex(array); swap(array, minIndex, maxIndex); } public static void swapMinMax(int[] array) { int minIndex = 0; for (int i = 1; i < array.length; i++) { if (array[i] < array[minIndex]) { minIndex = i; } } int maxIndex = 0; for (int i = 1; i < array.length; i++) { if (array[i] > array[maxIndex]) { maxIndex = i; } } int temp = array[minIndex]; array[minIndex] = array[maxIndex]; array[maxIndex] = temp; } public static void main(String[] args) { int[] array = AssortedMethods.randomArray(10, -10, 10); System.out.println(AssortedMethods.arrayToString(array)); swapMinMaxBetter(array); System.out.println(AssortedMethods.arrayToString(array)); } } ================================================ FILE: README.md ================================================ # CtCI-6th-Edition Solutions for [Cracking the Coding Interview 6th Edition](http://www.amazon.com/Cracking-Coding-Interview-6th-Edition/dp/0984782850) by [Gayle Laakmann McDowell](http://www.gayle.com/). Crowdsourcing solutions for every widely used programming language. **Contributions welcome**. ## Cloning Solutions in Java are contained directly in this repo and are the same solutions found in [the book](http://www.amazon.com/Cracking-Coding-Interview-6th-Edition/dp/0984782850). Solutions in other programming languages are contributed by the community and each have their own dedicated repos which are referenced from this repo as git submodules. What this means for cloning: - If you want to make a local clone of solutions in all languages, you should use the `--recursive` option: git clone --recursive https://github.com/careercup/CtCI-6th-Edition.git - If you're only interested in the Java solutions: git clone https://github.com/careercup/CtCI-6th-Edition.git - If you originally cloned without `--recursive`, and then later decide you want the git submodules too, run: git submodule update --init --recursive ## Contributing ### Work Flow 1. Fork the appropriate repo for your language to your GitHub user. (see [Where to submit pull requests](#where-to-submit-pull-requests)) 2. Write quality code and lint if applicable. 3. Add tests if applicable. 4. Open a pull request and provide a descriptive comment for what you did. ### Where to submit pull requests Pull requests pertaining to Java solutions should be submitted to the main [CtCI-6th-Edition repo](https://github.com/careercup/CtCI-6th-Edition). Please submit pull requests for all other languages to the appropriate language-specific repo. - [CtCI-6th-Edition-Clojure](https://github.com/careercup/CtCI-6th-Edition-Clojure) - [CtCI-6th-Edition-C](https://github.com/careercup/CtCI-6th-Edition-C) - [CtCI-6th-Edition-cpp](https://github.com/careercup/CtCI-6th-Edition-cpp) - [CtCI-6th-Edition-CSharp](https://github.com/careercup/CtCI-6th-Edition-CSharp) - [CtCI-6th-Edition-Go](https://github.com/careercup/CtCI-6th-Edition-Go) - [CtCI-6th-Edition-Groovy](https://github.com/careercup/CtCI-6th-Edition-Groovy) - [CtCI-6th-Edition-Haskell](https://github.com/careercup/CtCI-6th-Edition-Haskell) - [CtCI-6th-Edition-JavaScript](https://github.com/careercup/CtCI-6th-Edition-JavaScript) - [CtCI-6th-Edition-JavaScript-ES2015](https://github.com/careercup/CtCI-6th-Edition-JavaScript-ES2015) - [CtCI-6th-Edition-Julia](https://github.com/careercup/CtCI-6th-Edition-Julia) - [CtCI-6th-Edition-Kotlin](https://github.com/careercup/CtCI-6th-Edition-Kotlin) - [CtCI-6th-Edition-Objective-C](https://github.com/careercup/CtCI-6th-Edition-Objective-C) - [CtCI-6th-Edition-php](https://github.com/careercup/CtCI-6th-Edition-php) - [CtCI-6th-Edition-Python](https://github.com/careercup/CtCI-6th-Edition-Python) - [CtCI-6th-Edition-Ruby](https://github.com/careercup/CtCI-6th-Edition-Ruby) - [CtCI-6th-Edition-Swift](https://github.com/careercup/CtCI-6th-Edition-Swift) ### Adding a new Language Solutions in other languages are welcome too and should follow this workflow: 1. Create the new repo under your own GitHub user account and start contributing solutions. The repo name should follow this naming convention: `CtCI-6th-Edition-`. 2. Open an [issue on the CtCI-6th-Edition repo](https://github.com/careercup/CtCI-6th-Edition/issues) to request that your solution repo be promoted to join the careercup GitHub organization and referenced from the main repo as a git submodule. 3. If your request is approved, navigate to your repo's settings page and select the "Transfer Ownership" option, and specify "careercup" as the new owner.