├── .gitignore ├── LICENSE ├── README.md ├── cpp ├── .clang-format ├── 0-1_knapsack.cc ├── 0-sum_subset.cc ├── 2-difference.cc ├── 2-exists.cc ├── 2-for-all.cc ├── 2_sum.cc ├── 2_sum.h ├── 3-sum-closest.cc ├── 3-sum.cc ├── 4-sum.cc ├── Add_operators_in_string.cc ├── AddingCredits.cc ├── Anagrams.cc ├── Anonymous_letter.cc ├── Approximate_sort.cc ├── Arbitrage.cc ├── BST_lowest_common_ancestor.cc ├── BST_parent_prototype.h ├── BST_prototype.h ├── BST_prototype_shared_ptr.h ├── BST_sorted_order.cc ├── BST_to_sorted_doubly_list.cc ├── Balanced_binary_tree.cc ├── Bentleybsearch.cc ├── Biggest_product_n-1.cc ├── Biggest_product_n-1_math.cc ├── Bignumber_multiplication.cc ├── Binary_search_Ai=i.cc ├── Binary_search_circular_array.cc ├── Binary_search_circular_array_with_duplicates.cc ├── Binary_search_first_k.cc ├── Binary_search_larger_k.cc ├── Binary_search_unknown_length.cc ├── Binary_tree_level_order.cc ├── Binary_tree_lock.cc ├── Binary_tree_prototype.h ├── Binary_tree_to_doubly_linked_list.cc ├── Binary_tree_utils.h ├── Binary_tree_with_parent_prototype.h ├── Build_BST_from_sorted_array.cc ├── CMakeLists.txt ├── Can_string_be_palindrome.cc ├── Can_string_be_palindrome_hash.h ├── Can_string_be_palindrome_sorting.h ├── Celebrity_finding.cc ├── Checking_cycle.cc ├── Checking_cycle.h ├── Checking_cycle_alternative.cc ├── Circular_queue.cc ├── Close_search.cc ├── Closest_int_same_bits.cc ├── Closest_pair_points.cc ├── Closest_palindrome.cc ├── Closest_stars.cc ├── Closest_to_median.cc ├── Collatz_conjecture.cc ├── Compare_k-th_largest_in_heap.cc ├── Completion_search.cc ├── Completion_search_space_efficient.cc ├── Computing_binomial_coefficients.cc ├── Computing_x^n.cc ├── Connect_leaves_binary_tree.cc ├── Conversion_sorted_array.cc ├── Convert_base.cc ├── Copying_postings_list.cc ├── Count_inversions.cc ├── Count_occurrences_in_sentence.cc ├── Deletion_list.cc ├── Descendant_and_ancestor.cc ├── Division.cc ├── DivisionFloat.cc ├── Division_no_operator.cc ├── Doors.cc ├── Doubly_linked_list_prototype.h ├── Drawing_skylines.cc ├── Dutch_national_flag.cc ├── Elias_coding.cc ├── Eliminate_duplicate.cc ├── Equiv_classes.cc ├── Even_odd_merge_linked_list.cc ├── Exterior_binary_tree.cc ├── Find_element_appears_once.cc ├── Find_k_largest_BST.cc ├── Find_kth_element_in_two_sorted_arrays.cc ├── Find_longest_arithmetic_progression.cc ├── Find_missing_and_duplicate.cc ├── Find_missing_and_duplicate_XOR.cc ├── Finding_min_max.cc ├── GCD.cc ├── GCD1.cc ├── GCD1.h ├── GCD2.h ├── Gassing_up.cc ├── Gaussian_elimination.cc ├── Gaussian_primes.cc ├── Generate_spiral_matrix.cc ├── Generating_a_b_sqrt2.cc ├── Hash_dictionary.cc ├── Height_determination.cc ├── House_majority.cc ├── Huffman_encoding.cc ├── Image_compression.cc ├── Inorder_traversal_with_parent.cc ├── Interconverting_string_integer.cc ├── Intersect_rectangle.cc ├── Intersect_sorted_arrays.cc ├── Intersect_sorted_arrays1.h ├── Intersect_sorted_arrays2.h ├── Intersect_sorted_arrays3.h ├── LRUCache.cc ├── Largest_rectangle_under_skyline.cc ├── Largest_rectangle_under_skyline.h ├── Lead_changes.cc ├── Levenshtein_distance.cc ├── Line_most_points.cc ├── Linked_list_prototype.h ├── Load_balancing.cc ├── Longest_increasing_subarray.cc ├── Longest_nondecreasing_subsequence.cc ├── Longest_nondecreasing_subsequence_n2.h ├── Longest_nondecreasing_subsequence_nlogn.h ├── Longest_subarray_k.cc ├── Longest_subarray_k_improved.cc ├── Lowest_common_ancestor.cc ├── Lowest_common_ancestor_hash.cc ├── Lowest_common_ancestor_no_parent.cc ├── Makefile ├── Matrix_rotation.cc ├── Matrix_rotation_constant.cc ├── Matrix_rotation_naive.cc ├── Matrix_search.cc ├── Max-sum_subarray.cc ├── Max_concatenation_numbers.cc ├── Max_difference_k_pairs.cc ├── Max_difference_unlimited_pairs.cc ├── Max_submatrix_rectangle.cc ├── Max_submatrix_rectangle_brute_force.h ├── Max_submatrix_rectangle_improved.cc ├── Max_submatrix_square.cc ├── Maximum_container.cc ├── Maximum_minimum_difference_k.cc ├── Maximum_sliding_window.cc ├── Maximum_sliding_window_template.cc ├── Maximum_subarray_in_circular_array.cc ├── Maximum_subarray_in_circular_array_constant_space.cc ├── Median_sorted_circular_linked_list.cc ├── Merge_sorted_arrays.cc ├── Merge_sorted_arrays.h ├── Merge_sorted_lists.cc ├── Merge_sorted_lists.h ├── Merge_two_BSTs.cc ├── Minimum_distance_3_sorted_arrays.cc ├── Minimum_subarray_difference.cc ├── Minimum_waiting_time.cc ├── Missing_element.cc ├── Morris_traversal.cc ├── Multibet_card_color_game.cc ├── MultiplyShiftAdd.cc ├── Nearest_repetition.cc ├── Nearest_restaurant.cc ├── Next_permutation.cc ├── Number_ways.cc ├── Number_ways_obstacles.cc ├── Offline_minimum.cc ├── Offline_sampling.cc ├── Offline_sampling.h ├── Online_median.cc ├── Online_sampling.cc ├── Overlapping_days.cc ├── Overlapping_lists.cc ├── Overlapping_lists_no_cycle.cc ├── Overlapping_lists_no_cycle.h ├── Painting_iterative.cc ├── Painting_recursive.cc ├── Palindrome_linked_list.cc ├── Parity.cc ├── Parity1.cc ├── Parity1.h ├── Parity2.h ├── Parity3.h ├── Parity4.h ├── Partition_2_same_average.cc ├── Permutation_array.cc ├── Permutation_array1.h ├── Permutation_array2.h ├── Phone_mnemonic.cc ├── Picking_up_coins.cc ├── Picking_up_coins_dont_lose.cc ├── Planning_fishing.cc ├── Point.h ├── Points_covering_intervals.cc ├── Points_covering_intervals_alternative.cc ├── Postings_list_prototype.h ├── Power_set.cc ├── Power_set_alternative.cc ├── Pretty_printing.cc ├── Prime_sieve.cc ├── Queue_from_stacks.cc ├── Queue_using_two_integers.cc ├── Queue_with_max.cc ├── Queue_with_max_alternative.cc ├── Queue_with_max_alternative.h ├── RPN.cc ├── Rays_covering_arcs.cc ├── Rearrange.cc ├── Rebuild_BST_postorder.cc ├── Rebuild_BST_postorder_better.cc ├── Rebuild_BST_preorder.cc ├── Rebuild_BST_preorder_better.cc ├── Reconstruct_binary_tree_post_in_orders.cc ├── Reconstruct_binary_tree_pre_in_orders.cc ├── Reconstruct_preorder_with_null.cc ├── Reconstruct_preorder_with_null.h ├── Regular_expression.cc ├── Remove_kth_last_list.cc ├── Rendering_calendar.cc ├── Replace_and_remove.cc ├── Reservoir_sampling.cc ├── Reverse_bits.cc ├── Reverse_linked_list_iterative.cc ├── Reverse_linked_list_iterative.h ├── Reverse_linked_list_recursive.cc ├── Reverse_words.cc ├── Road_network.cc ├── Rotate_array.cc ├── Rotate_array.h ├── Rotate_array_permutation.h ├── Run_length_compression.cc ├── Score_combination.cc ├── Score_combination_alternative.cc ├── Score_permutation.cc ├── Search_BST_first_larger_k.cc ├── Search_BST_for_first_occurrence_iterative.cc ├── Search_BST_for_first_occurrence_recursive.cc ├── Search_a_pair_sorted_array.cc ├── Search_frequent_items.cc ├── Search_majority.cc ├── Search_maze.cc ├── Search_min_first_BST.cc ├── Search_postings_list_iterative.cc ├── Search_postings_list_recursive.cc ├── Semaphore.cc ├── SemaphoreGaurav.cc ├── Shortest_path_fewest_edges.cc ├── Shortest_unique_prefix.cc ├── Sliding_window.cc ├── Smallest_subarray_covering_set.cc ├── Smallest_subarray_covering_set.h ├── Smallest_subarray_covering_set_stream.h ├── Sorted_list_to_BST.cc ├── Spiral_matrix.cc ├── Spiral_matrix_clockwise.cc ├── Spreadsheet_encoding.cc ├── Square_root.cc ├── Stable_assignment.cc ├── Stack_queue_using_heap.cc ├── Stack_sorting.cc ├── Stack_with_max.cc ├── Stack_with_max.h ├── Stack_with_max_improved.cc ├── String_in_matrix.cc ├── String_matching_wildcard.cc ├── Subseq_cover.cc ├── Successor.cc ├── Sudoku_solve.cc ├── Symmetric_binary_tree.cc ├── Tail.cc ├── Tail_coin.cc ├── Task_assignment.cc ├── Team_photo_1.cc ├── Team_photo_2.cc ├── Theory_of_equality.cc ├── Three_jugs.cc ├── Ties_election.cc ├── Tournament_tree.cc ├── Transform_string_to_other.cc ├── Transitive_closure.cc ├── Tree_diameter.cc ├── Uniform_random_number_generation.cc ├── Union_intervals.cc ├── Update_BST.cc ├── View_from_above.cc ├── View_sunset.cc ├── Wiring_circuit_board.cc ├── Word_breaking.cc ├── Word_breaking_alternative.cc ├── Zipping_list.cc ├── a.out.dSYM │ └── Contents │ │ └── Info.plist ├── add-binary.cc ├── add-two-number-list.cc ├── async_thread.cc ├── average-top-3-scores.cc ├── badmacro.cc ├── badrtti.cc ├── badrtti2.cc ├── binary-tree-level-order-bottom-up.cc ├── binary-tree-postorder-traversal-iterative-alternative.cc ├── binary-tree-postorder-traversal-iterative.cc ├── binary-tree-preorder-traversal-iterative.cc ├── binary-tree-zigzag-level-order-traversal.cc ├── bonus-improved.cc ├── bonus.cc ├── buy-and-sell-stock-twice.cc ├── buy-and-sell-stock.cc ├── c++11random.cc ├── checksolutions.sh ├── climb-stairs.cc ├── clone-graph.cc ├── closest-int-same-bits-alternative.cc ├── closest_int_same_bits_alternative.cc ├── coin_change.cc ├── collatz.cc ├── combinations-unique.cc ├── combinations.cc ├── compute_random_permutation.cc ├── container-with-most-water.cc ├── count_bits.cc ├── cpplint.py ├── cyclic-right-shift.cc ├── defaultconstructor.cc ├── delete_list.cc ├── distinct-sorted-list.cc ├── drawing_skylines_alternative.cc ├── dutch_national_flag_slow_inplace.cc ├── dutch_national_flag_two_passes.cc ├── even_odd_array.cc ├── execute-shell.h ├── fibonacci-iterative.cc ├── fibonacci.cc ├── first-missing-positive.cc ├── format.sh ├── generate-parentheses.cc ├── generating-a-b-sqrt2-improved.cc ├── generating-a-b-sqrt2-improved.h ├── generating-a-b-sqrt2.cc ├── generating-a-b-sqrt2.h ├── goodrtti.cc ├── gray-code-backtrack.cc ├── gray-code-backtrack.py ├── gray-code.cc ├── highest-affinity-pairs.cc ├── indirect_sort.cc ├── inlineexample.cc ├── insert-interval.cc ├── insert_list.cc ├── insertion-deletion-BST.cc ├── insertion-sort-list.cc ├── integer-to-roman.cc ├── interleaving-string.cc ├── is_binary_tree_a_BST.cc ├── is_binary_tree_a_BST_BFS.cc ├── is_binary_tree_a_BST_const_space.cc ├── is_palindromic.cc ├── job_assignment.cc ├── jump-game-min-steps.cc ├── jump-game.cc ├── justify-text.cc ├── k-balanced_binary_tree.cc ├── k-largest-elements-binary-heap.cc ├── k-th_element_streaming.cc ├── k-th_largest_element_large_n.cc ├── k-th_node_binary_tree.cc ├── k-th_permutation.cc ├── largearray.c ├── lazy-init.cc ├── length-of-last-word.cc ├── list-pivoting.cc ├── lock_ordering_bug.cc ├── lock_ordering_works.cc ├── longest-contained-range.cc ├── longest-subarray-with-distinct-entries.cc ├── longest-substring-without-repeating-characters.cc ├── longest-valid-parentheses.cc ├── longest_valid_parentheses_const_space.cc ├── look-and-say.cc ├── magic-maze-game.h ├── magic_maze_game.h ├── mapupdate1.cc ├── mapupdate2.cc ├── mapupdate3.cc ├── mapupdate4.cc ├── mapupdate5.cc ├── matrix-rotation-flip.cc ├── maze-game-main.cc ├── maze-game.h ├── maze_game.h ├── maze_game_main.cc ├── merge-two-sorted-arrays-in-place.cc ├── merge_contacts.cc ├── minmaxtemplate.cc ├── minmaxtemplatemove.cc ├── multiply_shift_add.cc ├── n-queens-count.cc ├── n-queens-permutation.cc ├── n-queens.cc ├── nnChomp.pseudo ├── nonconstructible-change.cc ├── nonuniform_random_number_generation.cc ├── normalized_pathnames.cc ├── number-steps.cc ├── odd_even.cc ├── order_statistic.cc ├── ordinary-maze-game.h ├── ordinary_maze_game.h ├── palindrome-number.cc ├── palindrome-partitioning-min-cuts.cc ├── palindrome-partitioning.cc ├── partition-array.cc ├── pascal-triangle-1.cc ├── pascal-triangle-2.cc ├── passbyvaluebug.cc ├── path-sum-binary-tree-all.cc ├── path-sum-binary-tree.cc ├── permutations-alternative.cc ├── permutations-unique.cc ├── permutations.cc ├── plus-one.cc ├── points_covering_intervals_sorting.cc ├── polymorphismproblems.cc ├── polymorphismproblemsfixed.cc ├── populating-next-right-pointers-any-binary-tree.cc ├── populating-next-right-pointers.cc ├── power-x-y.cc ├── ppp.sh ├── prefix-search.cc ├── prime-sieve-basic.cc ├── print_linked_list_reverse_order.cc ├── queue_with_max_intro.cc ├── rabin-karp.cc ├── range-lookup-BST.cc ├── reconstruct-almost-bst.cc ├── recover-binary-search-tree-constant-space.cc ├── remove-duplicates-from-sorted-array.cc ├── remove-duplicates-sorted-list.cc ├── remove-element.cc ├── remove-twice-duplicates-from-sorted-array.cc ├── reverse-integer.cc ├── reverse-list-in-k-group.cc ├── reverse_linked_list_from_s_to_f.cc ├── roman-to-integer.cc ├── rook-attack.cc ├── rw.cc ├── s1.cc ├── s2.cc ├── scramble-string.cc ├── search-a-range-sorted-array.cc ├── search-insert-position-sorted-array.cc ├── search-rotated-sorted-array-with-duplicates.cc ├── search-rotated-sorted-array.cc ├── search_BST.cc ├── search_list.cc ├── simple_web_server.cc ├── smartpointers.cc ├── snake-string.cc ├── solutions.tex ├── sort-list.cc ├── sort_k-increasing-decreasing_array.cc ├── spell.sh ├── square-root-int.cc ├── student_search.cc ├── student_sort.cc ├── substring-with-concatenation-of-all-words.cc ├── sudoku_check.cc ├── sum-root-to-leaf-binary-tree.cc ├── surrounded-regions.cc ├── swap_bits.cc ├── swap_bits.h ├── task_execution_web_server.cc ├── team_reachability.cc ├── test_toolkit │ ├── dummy.cc │ ├── grammatical-printer.h │ ├── json-writer-test.cc │ ├── json-writer.h │ ├── main_def.h │ ├── more_type_traits.h │ ├── performance-timer.h │ ├── signal-handler.h │ ├── test-options.h │ └── tree_utils.h ├── thread_per_task_webserver.cc ├── top_k.cc ├── tower_hanoi.cc ├── trapping-rain-water.cc ├── tree_traversal.cc ├── triangle.cc ├── two_thread_increment.cc ├── unique-binary-trees-all.cc ├── unique-binary-trees.cc ├── valid-IP-address.cc ├── valid-number.cc ├── valid-palindrome.cc ├── valid-parentheses.cc ├── valid_IP_address_recursive.cc ├── word-breaking-2.cc └── zigzag-conversion.cc ├── cpptest ├── AnagramsTest.cc ├── Anonymous_letterTest.cc ├── Balanced_binary_treeTest.cc ├── Convert_baseTest.cc ├── Gassing_upTest.cc ├── Matrix_searchTest.cc ├── Number_waysTest.cc ├── RPNTest.cc ├── Spreadsheet_encodingTest.cc ├── Sudoku_solveTest.cc ├── container-with-most-waterTest.cc ├── first-missing-positiveTest.cc ├── intersect_sorted_arrays3Test.cc ├── normalized_pathnamesTest.cc ├── palindrome-numberTest.cc ├── snake-stringTest.cc └── square-root-intTest.cc ├── epijudge ├── A.cpp ├── A.h ├── A.java ├── Atest.cpp ├── Atest.java ├── file.java ├── judgetest.py └── testutils.h └── java └── src ├── main └── java │ └── com │ └── epi │ ├── .clang-format │ ├── AddOperatorsInString.java │ ├── AddTwoNumberList.java │ ├── AddingCredits.java │ ├── Anagrams.java │ ├── AnonymousLetter.java │ ├── AnonymousLetterTest.java │ ├── ApproximateSort.java │ ├── Arbitrage.java │ ├── AsyncThread.java │ ├── AverageTop3Scores.java │ ├── BSTLowestCommonAncestor.java │ ├── BSTSortedOrder.java │ ├── BSTToSortedDoublyList.java │ ├── BadArrayListStore.java │ ├── BadArrayStore.java │ ├── BadAssert.java │ ├── BalancedBinaryTree.java │ ├── BalancedBinaryTreeTest.java │ ├── BasicStaticInitializer.java │ ├── BentleyBsearch.java │ ├── BigNumberMultiplication.java │ ├── BiggestProductNMinus1.java │ ├── BiggestProductNMinus1Math.java │ ├── BinarySearchAiEqI.java │ ├── BinarySearchCircularArray.java │ ├── BinarySearchCircularArrayWithDuplicates.java │ ├── BinarySearchFirstK.java │ ├── BinarySearchLargerK.java │ ├── BinarySearchTreePrototypeTemplate.java │ ├── BinarySearchUnknownLength.java │ ├── BinaryTreeLevelOrder.java │ ├── BinaryTreeLock.java │ ├── BinaryTreePostorderTraversalIterative.java │ ├── BinaryTreePostorderTraversalIterativeAlternative.java │ ├── BinaryTreePreorderTraversalIterative.java │ ├── BinaryTreePrototypeTemplate.java │ ├── BinaryTreeUtils.java │ ├── BinaryTreeWithParentPrototype.java │ ├── Bonus.java │ ├── BonusImproved.java │ ├── BuildBSTFromSortedArray.java │ ├── BuyAndSellStock.java │ ├── BuyAndSellStockTwice.java │ ├── CanStringBePalindrome.java │ ├── CanStringBePalindromeHash.java │ ├── CanStringBePalindromeSorting.java │ ├── CelebrityFinding.java │ ├── CheckingCycle.java │ ├── CheckingCycleAlternative.java │ ├── CircularQueue.java │ ├── CloneGraph.java │ ├── CloseSearch.java │ ├── ClosestIntSameBits.java │ ├── ClosestIntSameBitsAlternative.java │ ├── ClosestPairPoints.java │ ├── ClosestPalindrome.java │ ├── ClosestStars.java │ ├── ClosestToMedian.java │ ├── CoinChange.java │ ├── Collatz.java │ ├── CollatzConjecture.java │ ├── Combinations.java │ ├── CompareKthLargestInHeap.java │ ├── CompletionSearch.java │ ├── ComputeRandomPermutation.java │ ├── ComputingBinomialCoefficients.java │ ├── ComputingXPowN.java │ ├── ConnectLeavesBinaryTree.java │ ├── ContainerWithMostWater.java │ ├── ContainerWithMostWaterTest.java │ ├── ConvertBase.java │ ├── ConvertBaseTest.java │ ├── CopyingPostingsList.java │ ├── CountBits.java │ ├── CountInversions.java │ ├── CountOccurrencesInSentence.java │ ├── CyclicRightShift.java │ ├── DeleteList.java │ ├── DeletionList.java │ ├── DescendantAndAncestor.java │ ├── Division.java │ ├── Doors.java │ ├── DoublyLinkedListPrototypeTemplate.java │ ├── DrawingSkylines.java │ ├── DrawingSkylinesAlternative.java │ ├── DutchNationalFlag.java │ ├── DutchNationalFlagSlowInplace.java │ ├── DutchNationalFlagTwoPasses.java │ ├── EliasCoding.java │ ├── EliminateDuplicate.java │ ├── EquivClasses.java │ ├── EvenOddArray.java │ ├── EvenOddMergeLinkedList.java │ ├── ExteriorBinaryTree.java │ ├── Fibonacci.java │ ├── FibonacciIterative.java │ ├── FindElementAppearsOnce.java │ ├── FindKLargestBST.java │ ├── FindKthElementInTwoSortedArrays.java │ ├── FindMissingAndDuplicate.java │ ├── FindMissingAndDuplicateXOR.java │ ├── FindMissingBetter.java │ ├── FindingMinMax.java │ ├── FirstMissingPositive.java │ ├── FirstMissingPositiveTest.java │ ├── GCD.java │ ├── GCD1.java │ ├── GCD2.java │ ├── GassingUp.java │ ├── GassingUpTest.java │ ├── GaussianElimination.java │ ├── GaussianPrimes.java │ ├── GenerateParentheses.java │ ├── GeneratingABSqrt2.java │ ├── GeneratingABSqrt2Improved.java │ ├── GrayCode.java │ ├── GrayCodeBacktrack.java │ ├── HashDictionary.java │ ├── HeightDetermination.java │ ├── HighestAffinityPairs.java │ ├── HouseMajority.java │ ├── HuffmanEncoding.java │ ├── ImageCompression.java │ ├── IndirectSort.java │ ├── InorderTraversalNoStack.java │ ├── InorderTraversalWithParent.java │ ├── InsertInterval.java │ ├── InsertList.java │ ├── InsertionDeletionBST.java │ ├── InsertionSortList.java │ ├── InterconvertingStringInteger.java │ ├── InterleavingString.java │ ├── IntersectRectangle.java │ ├── IntersectSortedArrays.java │ ├── IntersectSortedArrays1.java │ ├── IntersectSortedArrays2.java │ ├── IntersectSortedArrays3.java │ ├── IntersectSortedArrays3Test.java │ ├── IsBinaryTreeABST.java │ ├── IsBinaryTreeABSTBFS.java │ ├── IsBinaryTreeABSTConstSpace.java │ ├── IsPalindromic.java │ ├── JobAssignment.java │ ├── JumpGame.java │ ├── JustifyText.java │ ├── KBalancedBinaryTree.java │ ├── KLargestElementsBinaryHeap.java │ ├── KThNodeBinaryTree.java │ ├── KthElementStreaming.java │ ├── KthLargestElementLargeN.java │ ├── LRUCache.java │ ├── LargeArray.java │ ├── LargestRectangleUnderSkyline.java │ ├── LazyInit.java │ ├── LevenshteinDistance.java │ ├── LineMostPoints.java │ ├── LinkedListPrototypeTemplate.java │ ├── ListPivoting.java │ ├── LoadBalancing.java │ ├── LockOrderingBug.java │ ├── LockOrderingWorks.java │ ├── LogFileAnalysis.java │ ├── LogFileAnalysisTest.java │ ├── LongestContainedRange.java │ ├── LongestIncreasingSubarray.java │ ├── LongestNondecreasingSubsequence.java │ ├── LongestNondecreasingSubsequenceN2.java │ ├── LongestNondecreasingSubsequenceNlogn.java │ ├── LongestSubarrayK.java │ ├── LongestSubarrayKImproved.java │ ├── LongestSubarrayWithDistinctEntries.java │ ├── LongestValidParentheses.java │ ├── LongestValidParenthesesConstSpace.java │ ├── LookAndSay.java │ ├── LowestCommonAncestor.java │ ├── LowestCommonAncestorHash.java │ ├── LowestCommonAncestorNoParent.java │ ├── MagicMazeGame.java │ ├── MatrixRotation.java │ ├── MatrixRotationConstant.java │ ├── MatrixRotationNaive.java │ ├── MatrixSearch.java │ ├── MatrixSearchTest.java │ ├── MaxDifferenceKPairs.java │ ├── MaxDifferenceUnlimitedPairs.java │ ├── MaxSubmatrixRectangle.java │ ├── MaxSubmatrixRectangleBruteForce.java │ ├── MaxSubmatrixRectangleImproved.java │ ├── MaxSubmatrixSquare.java │ ├── MaxSumSubarray.java │ ├── MaximumSubarrayInCircularArray.java │ ├── MaximumSubarrayInCircularArrayConstantSpace.java │ ├── MazeGame.java │ ├── MazeGameMain.java │ ├── MedianSortedCircularLinkedList.java │ ├── MergeContacts.java │ ├── MergeSortedArrays.java │ ├── MergeSortedLists.java │ ├── MergeTwoBSTs.java │ ├── MergeTwoSortedArraysInPlace.java │ ├── MinimumDistance3SortedArrays.java │ ├── MinimumSubarrayDifference.java │ ├── MinimumWaitingTime.java │ ├── MissingElement.java │ ├── MultibetCardColorGame.java │ ├── MultiplyShiftAdd.java │ ├── NQueens.java │ ├── NearestRepetition.java │ ├── NearestRestaurant.java │ ├── NextPermutation.java │ ├── NonUniformRandomNumberGeneration.java │ ├── NonconstructibleChange.java │ ├── NormalizedPathnames.java │ ├── NormalizedPathnamesTest.java │ ├── NumberSteps.java │ ├── NumberWays.java │ ├── NumberWaysObstacles.java │ ├── NumberWaysTest.java │ ├── OddEven.java │ ├── OfflineMinimum.java │ ├── OfflineSampling.java │ ├── OnlineMedian.java │ ├── OnlineSampling.java │ ├── Operators.java │ ├── OrderStatistic.java │ ├── OrdinaryMazeGame.java │ ├── OverlappingLists.java │ ├── OverlappingListsNoCycle.java │ ├── PaintingIterative.java │ ├── PaintingRecursive.java │ ├── PalindromeLinkedList.java │ ├── PalindromeNumber.java │ ├── PalindromeNumberTest.java │ ├── PalindromePartitioning.java │ ├── PalindromePartitioningMinCuts.java │ ├── Parity.java │ ├── Parity1.java │ ├── Parity2.java │ ├── Parity3.java │ ├── Parity4.java │ ├── PartitionArray.java │ ├── PascalTriangle1.java │ ├── PathSumBinaryTree.java │ ├── PermutationArray.java │ ├── PermutationArray1.java │ ├── PermutationArray2.java │ ├── Permutations.java │ ├── PermutationsAlternative.java │ ├── PhoneMnemonic.java │ ├── PickingUpCoins.java │ ├── PickingUpCoinsDontLose.java │ ├── PlanningFishing.java │ ├── PlusOne.java │ ├── PointsCoveringIntervals.java │ ├── PointsCoveringIntervalsAlternative.java │ ├── PointsCoveringIntervalsSorting.java │ ├── PopulatingNextRightPointers.java │ ├── PostingListNode.java │ ├── PowerSet.java │ ├── PowerSetAlternative.java │ ├── PowerXY.java │ ├── PrettyPrinting.java │ ├── PrimeSieve.java │ ├── PrimeSieveBasic.java │ ├── PrintLinkedListReverseOrder.java │ ├── ProducerConsumer.java │ ├── QueueFromStacks.java │ ├── QueueUsingTwoIntegers.java │ ├── QueueWithMax.java │ ├── QueueWithMaxAlternative.java │ ├── QueueWithMaxIntro.java │ ├── RPN.java │ ├── RPNTest.java │ ├── RW.java │ ├── RabinKarp.java │ ├── RangeLookupBST.java │ ├── Rearrange.java │ ├── RebuildBSTPostorder.java │ ├── RebuildBSTPreorder.java │ ├── RebuildBSTPreorderBetter.java │ ├── ReconstructAlmostBst.java │ ├── ReconstructBinaryTreePostInorders.java │ ├── ReconstructBinaryTreePreInorders.java │ ├── ReconstructPreorderWithNull.java │ ├── RegularExpression.java │ ├── RemoveDuplicatesFromSortedArray.java │ ├── RemoveDuplicatesSortedList.java │ ├── RemoveElement.java │ ├── RemoveKthLastList.java │ ├── RenderingCalendar.java │ ├── ReplaceAndRemove.java │ ├── ReservoirSampling.java │ ├── ReverseBits.java │ ├── ReverseInteger.java │ ├── ReverseLinkedListFromSToF.java │ ├── ReverseLinkedListIterative.java │ ├── ReverseLinkedListRecursive.java │ ├── ReverseListInKGroup.java │ ├── ReverseWords.java │ ├── RoadNetwork.java │ ├── RomanToInteger.java │ ├── RookAttack.java │ ├── RotateArray.java │ ├── RotateArrayPermutation.java │ ├── RotateArrayTest.java │ ├── RunLengthCompression.java │ ├── S1.java │ ├── S1Alternative.java │ ├── S2.java │ ├── S2Alternative.java │ ├── ScoreCombination.java │ ├── ScorePermutation.java │ ├── SearchAPairSortedArray.java │ ├── SearchBST.java │ ├── SearchBSTFirstLargerK.java │ ├── SearchBSTForFirstOccurrenceIterative.java │ ├── SearchBSTForFirstOccurrenceRecursive.java │ ├── SearchFrequentItems.java │ ├── SearchList.java │ ├── SearchMajority.java │ ├── SearchMaze.java │ ├── SearchMinFirstBST.java │ ├── SearchPostingsListIterative.java │ ├── SearchPostingsListRecursive.java │ ├── Semaphore.java │ ├── ShortestPathFewestEdges.java │ ├── ShortestUniquePrefix.java │ ├── SimpleWebServer.java │ ├── SlidingWindow.java │ ├── SmallestSubarrayCoveringSet.java │ ├── SmallestSubarrayCoveringSetStream.java │ ├── SnakeString.java │ ├── SnakeStringTest.java │ ├── SortKIncreasingDecreasingArray.java │ ├── SortList.java │ ├── SortedListToBST.java │ ├── SpiralMatrix.java │ ├── SpiralMatrixClockwise.java │ ├── SpreadsheetEncoding.java │ ├── SpreadsheetEncodingTest.java │ ├── SquareRoot.java │ ├── SquareRootInt.java │ ├── SquareRootIntTest.java │ ├── StableAssignment.java │ ├── StackQueueUsingHeap.java │ ├── StackSorting.java │ ├── StackWithMax.java │ ├── StackWithMaxImproved.java │ ├── StaticInitializer.java │ ├── StringConcatenation.java │ ├── StringConcatenationStringBuilder.java │ ├── StringInMatrix.java │ ├── StudentSearch.java │ ├── StudentSort.java │ ├── SubseqCover.java │ ├── SubstringWithConcatenationOfAllWords.java │ ├── Successor.java │ ├── SudokuCheck.java │ ├── SudokuSolve.java │ ├── SudokuSolveTest.java │ ├── SumRootToLeafBinaryTree.java │ ├── SurroundedRegions.java │ ├── SwapBits.java │ ├── SymmetricBinaryTree.java │ ├── TODO.java │ ├── Tail.java │ ├── TailCoin.java │ ├── TaskAssignment.java │ ├── TaskExecutionWebServer.java │ ├── TeamPhoto1.java │ ├── TeamPhoto2.java │ ├── TeamReachability.java │ ├── TheoryOfEquality.java │ ├── ThreadPerTaskWebserver.java │ ├── ThreeJugs.java │ ├── ThreeSum.java │ ├── TiesElection.java │ ├── TopK.java │ ├── TournamentTree.java │ ├── TowerHanoi.java │ ├── TransformStringToOther.java │ ├── TransitiveClosure.java │ ├── TrappingRainWater.java │ ├── TreeDiameter.java │ ├── TreeTraversal.java │ ├── Triangle.java │ ├── TwoExists.java │ ├── TwoForAll.java │ ├── TwoSum.java │ ├── TwoThreadIncrement.java │ ├── UniformRandomNumberGeneration.java │ ├── UnionIntervals.java │ ├── UniqueBinaryTreesAll.java │ ├── UpdateBST.java │ ├── ValidIPAddress.java │ ├── ValidIPAddressRecursive.java │ ├── ValidPalindrome.java │ ├── ValidParentheses.java │ ├── ViewFromAbove.java │ ├── ViewSunset.java │ ├── WiringCircuitBoard.java │ ├── WordBreaking.java │ ├── ZeroOneKnapsack.java │ ├── ZeroSumSubset.java │ ├── ZippingList.java │ ├── format.sh │ └── utils │ ├── AbstractPairWriter.java │ ├── AbstractTestOptions.java │ ├── AbstractTestStream.java │ ├── JsonPairWriter.java │ ├── JsonTestOptions.java │ ├── JsonTestStream.java │ ├── JsonUniversalObjectWriter.java │ ├── PerformanceMeasure.java │ ├── StopWatch.java │ ├── TestType.java │ ├── TreeUtils.java │ └── Utils.java └── test └── test └── java └── com └── epi └── TestAll.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.o 3 | a.out 4 | 5 | # Mobile Tools for Java (J2ME) 6 | .mtj.tmp/ 7 | 8 | # Package Files # 9 | *.jar 10 | *.war 11 | *.ear 12 | 13 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 14 | hs_err_pid* 15 | 16 | #JetBrains IDE folder 17 | target/ 18 | cpp/.idea 19 | java/.idea 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Adnan Aziz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # epicode 2 | Please visit http://elementsofprogramminginterviews.com/solutions/ to get a mapping from book problems to programs. 3 | -------------------------------------------------------------------------------- /cpp/2_sum.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_TWOSUM_H_ 4 | #define SOLUTIONS_TWOSUM_H_ 5 | 6 | namespace TwoSum { 7 | 8 | #include 9 | 10 | using std::vector; 11 | 12 | // @include 13 | bool HasTwoSum(const vector& A, int t) { 14 | int i = 0, j = A.size() - 1; 15 | while (i <= j) { 16 | if (A[i] + A[j] == t) { 17 | return true; 18 | } else if (A[i] + A[j] < t) { 19 | ++i; 20 | } else { // A[i] + A[j] > t. 21 | --j; 22 | } 23 | } 24 | return false; 25 | } 26 | // @exclude 27 | 28 | } // namespace TwoSum 29 | 30 | #endif // SOLUTIONS_TWOSUM_H_ 31 | -------------------------------------------------------------------------------- /cpp/BST_parent_prototype.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_BST_PARENT_PROTOTYPE_H_ 4 | #define SOLUTIONS_BST_PARENT_PROTOTYPE_H_ 5 | 6 | #include 7 | #include 8 | 9 | using std::unique_ptr; 10 | 11 | // @include 12 | template 13 | struct BSTNode { 14 | T data; 15 | unique_ptr> left, right; 16 | BSTNode* parent; 17 | }; 18 | // @exclude 19 | #endif // SOLUTIONS_BST_PARENT_PROTOTYPE_H_ 20 | -------------------------------------------------------------------------------- /cpp/BST_prototype.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_BST_PROTOTYPE_H_ 4 | #define SOLUTIONS_BST_PROTOTYPE_H_ 5 | 6 | #include 7 | 8 | using std::unique_ptr; 9 | 10 | // @include 11 | template 12 | struct BSTNode { 13 | T data; 14 | unique_ptr> left, right; 15 | }; 16 | // @exclude 17 | #endif // SOLUTIONS_BST_PROTOTYPE_H_ 18 | -------------------------------------------------------------------------------- /cpp/BST_prototype_shared_ptr.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_BST_PROTOTYPE_SHARED_PTR_H_ 4 | #define SOLUTIONS_BST_PROTOTYPE_SHARED_PTR_H_ 5 | 6 | #include 7 | 8 | using std::shared_ptr; 9 | 10 | // @include 11 | template 12 | struct BSTNode { 13 | T data; 14 | shared_ptr> left, right; 15 | }; 16 | // @exclude 17 | #endif // SOLUTIONS_BST_PROTOTYPE_SHARED_PTR_H_ 18 | -------------------------------------------------------------------------------- /cpp/Bentleybsearch.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | 6 | using std::vector; 7 | 8 | // @include 9 | int bsearch(int t, const vector& A) { 10 | int L = 0, U = A.size() - 1; 11 | while (L <= U) { 12 | int M = (L + U) / 2; 13 | if (A[M] < t) { 14 | L = M + 1; 15 | } else if (A[M] == t) { 16 | return M; 17 | } else { 18 | U = M - 1; 19 | } 20 | } 21 | return -1; 22 | } 23 | // @exclude 24 | 25 | static void SimpleTest() { 26 | vector A = {1, 2, 3}; 27 | assert(0 == bsearch(1, A)); 28 | assert(1 == bsearch(2, A)); 29 | assert(2 == bsearch(3, A)); 30 | A = {2, 2, 2}; 31 | assert(0 <= bsearch(2, A) && bsearch(2, A) <= 2); 32 | assert(-1 == bsearch(3, A)); 33 | assert(-1 == bsearch(0, A)); 34 | } 35 | 36 | int main(int argc, char* argv[]) { 37 | SimpleTest(); 38 | vector A; 39 | A.emplace_back(1); 40 | A.emplace_back(2); 41 | A.emplace_back(2); 42 | A.emplace_back(2); 43 | A.emplace_back(2); 44 | A.emplace_back(3); 45 | A.emplace_back(3); 46 | A.emplace_back(3); 47 | A.emplace_back(5); 48 | A.emplace_back(6); 49 | A.emplace_back(10); 50 | A.emplace_back(100); 51 | assert(0 == bsearch(1, A)); 52 | assert(1 <= bsearch(2, A) && bsearch(2, A) <= 4); 53 | assert(5 <= bsearch(3, A)); 54 | assert(-1 == bsearch(4, A)); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /cpp/Binary_tree_prototype.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_BINARY_TREE_PROTOTYPE_H_ 4 | #define SOLUTIONS_BINARY_TREE_PROTOTYPE_H_ 5 | 6 | #include 7 | 8 | using std::unique_ptr; 9 | 10 | // @include 11 | template 12 | struct BinaryTreeNode { 13 | T data; 14 | unique_ptr> left, right; 15 | }; 16 | // @exclude 17 | #endif // SOLUTIONS_BINARY_TREE_PROTOTYPE_H_ 18 | -------------------------------------------------------------------------------- /cpp/Binary_tree_with_parent_prototype.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_BINARY_TREE_WITH_PARENT_PROTOTYPE_H_ 4 | #define SOLUTIONS_BINARY_TREE_WITH_PARENT_PROTOTYPE_H_ 5 | 6 | #include 7 | 8 | using std::unique_ptr; 9 | 10 | // @include 11 | template 12 | struct BinaryTreeNode { 13 | T data; 14 | unique_ptr> left, right; 15 | BinaryTreeNode* parent; 16 | }; 17 | // @exclude 18 | #endif // SOLUTIONS_BINARY_TREE_WITH_PARENT_PROTOTYPE_H_ 19 | -------------------------------------------------------------------------------- /cpp/Can_string_be_palindrome.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "./Can_string_be_palindrome_hash.h" 9 | #include "./Can_string_be_palindrome_sorting.h" 10 | 11 | using std::boolalpha; 12 | using std::cout; 13 | using std::default_random_engine; 14 | using std::endl; 15 | using std::random_device; 16 | using std::string; 17 | using std::uniform_int_distribution; 18 | 19 | string RandString(int len) { 20 | string ret; 21 | default_random_engine gen((random_device())()); 22 | while (len--) { 23 | uniform_int_distribution dis('a', 'z'); 24 | ret += dis(gen); 25 | } 26 | return ret; 27 | } 28 | 29 | int main(int argc, char *argv[]) { 30 | default_random_engine gen((random_device())()); 31 | for (int times = 0; times < 1000; ++times) { 32 | string s; 33 | if (argc == 2) { 34 | s = argv[1]; 35 | } else { 36 | uniform_int_distribution dis(1, 10); 37 | s = RandString(dis(gen)); 38 | } 39 | cout << s << endl; 40 | assert(CanStringBeAPalindromeHash::CanFormPalindrome(s) == 41 | CanStringBeAPalindromeSorting::CanFormPalindrome(&s)); 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /cpp/Can_string_be_palindrome_hash.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_CAN_STRING_BE_PALINDROME_HASH_H_ 4 | #define SOLUTIONS_CAN_STRING_BE_PALINDROME_HASH_H_ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using std::string; 11 | using std::unordered_map; 12 | 13 | namespace CanStringBeAPalindromeHash { 14 | 15 | // @include 16 | bool CanFormPalindrome(const string& s) { 17 | unordered_map char_frequencies; 18 | // Compute the frequency of each char in s. 19 | for (char c : s) { 20 | ++char_frequencies[c]; 21 | } 22 | 23 | // A string can be permuted as a palindrome if and only if the number of 24 | // chars whose frequencies is odd is at most 1. 25 | int odd_frequency_count = 0; 26 | return none_of(begin(char_frequencies), end(char_frequencies), 27 | [&odd_frequency_count](const auto& p) { 28 | return (p.second % 2) && ++odd_frequency_count > 1; 29 | }); 30 | } 31 | // @exclude 32 | 33 | } // namespace CanStringBeAPalindromeHash 34 | 35 | #endif // SOLUTIONS_CAN_STRING_BE_PALINDROME_HASH_H_ 36 | -------------------------------------------------------------------------------- /cpp/Can_string_be_palindrome_sorting.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_CAN_STRING_BE_PALINDROME_SORTING_H_ 4 | #define SOLUTIONS_CAN_STRING_BE_PALINDROME_SORTING_H_ 5 | 6 | #include 7 | #include 8 | 9 | using std::string; 10 | 11 | namespace CanStringBeAPalindromeSorting { 12 | 13 | // @include 14 | bool CanFormPalindrome(string* s) { 15 | sort(s->begin(), s->end()); 16 | int odd_count = 0, num_curr_char = 1; 17 | 18 | for (int i = 1; i < s->size() && odd_count <= 1; ++i) { 19 | if ((*s)[i] != (*s)[i - 1]) { 20 | if (num_curr_char % 2) { 21 | ++odd_count; 22 | } 23 | num_curr_char = 1; 24 | } else { 25 | ++num_curr_char; 26 | } 27 | } 28 | if (num_curr_char % 2) { 29 | ++odd_count; 30 | } 31 | 32 | // A string can be permuted as a palindrome if the number of odd time 33 | // chars <= 1. 34 | return odd_count <= 1; 35 | } 36 | // @exclude 37 | 38 | } // namespace CanStringBeAPalindromeSorting 39 | 40 | #endif // SOLUTIONS_CAN_STRING_BE_PALINDROME_SORTING_H_ 41 | -------------------------------------------------------------------------------- /cpp/Checking_cycle.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_CHECKING_CYCLE_H_ 4 | #define SOLUTIONS_CHECKING_CYCLE_H_ 5 | 6 | #include 7 | 8 | #include "./Linked_list_prototype.h" 9 | 10 | // @include 11 | shared_ptr> HasCycle(const shared_ptr>& head) { 12 | shared_ptr> fast = head, slow = head; 13 | 14 | while (fast && fast->next) { 15 | slow = slow->next, fast = fast->next->next; 16 | if (slow == fast) { 17 | // There is a cycle, so now let's calculate the cycle length. 18 | int cycle_len = 0; 19 | do { 20 | ++cycle_len; 21 | fast = fast->next; 22 | } while (slow != fast); 23 | 24 | // Finds the start of the cycle. 25 | auto cycle_len_advanced_iter = head; 26 | while (cycle_len--) { 27 | cycle_len_advanced_iter = cycle_len_advanced_iter->next; 28 | } 29 | 30 | auto iter = head; 31 | // Both iterators advance in tandem. 32 | while (iter != cycle_len_advanced_iter) { 33 | iter = iter->next; 34 | cycle_len_advanced_iter = cycle_len_advanced_iter->next; 35 | } 36 | return iter; // iter is the start of cycle. 37 | } 38 | } 39 | return nullptr; // No cycle. 40 | } 41 | // @exclude 42 | #endif // SOLUTIONS_SWAP_BITS_H_ 43 | -------------------------------------------------------------------------------- /cpp/Deletion_list.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "./Linked_list_prototype.h" 8 | 9 | using std::cout; 10 | using std::endl; 11 | using std::make_shared; 12 | using std::shared_ptr; 13 | 14 | // @include 15 | // Assumes node_to_delete is not tail. 16 | void DeletionFromList(const shared_ptr>& node_to_delete) { 17 | node_to_delete->data = node_to_delete->next->data; 18 | node_to_delete->next = node_to_delete->next->next; 19 | } 20 | // @exclude 21 | 22 | int main(int argc, char* argv[]) { 23 | shared_ptr> L; 24 | L = make_shared>(ListNode{ 25 | 1, make_shared>(ListNode{ 26 | 2, make_shared>(ListNode{3, nullptr})})}); 27 | DeletionFromList(L); 28 | assert(L->data == 2 && L->next->data == 3); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /cpp/Division_no_operator.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | // @include 10 | int division_no_operator(int x, int y) { 11 | int left = 0, right = x; 12 | while (left <= right) { 13 | int mid = left + ((right - left) / 2); 14 | if (mid * y < x) { 15 | left = mid + 1; 16 | } else if (mid * y == x) { 17 | return mid; 18 | } else { 19 | right = mid - 1; 20 | } 21 | } 22 | return left; 23 | } 24 | // @exclude 25 | 26 | int main(int argc, char *argv[]) { 27 | if (argc == 3) { 28 | int x = atoi(argv[1]), y = atoi(argv[2]); 29 | int res = division_no_operator(x, y); 30 | cout << x << '/' << y << '=' << res << endl; 31 | assert(ceil(static_cast(x) / y) == res); 32 | } else { 33 | // random test, only works if the product not greater than 2^32 - 1 34 | srand(time(NULL)); 35 | for (int i = 0; i < 10000; ++i) { 36 | int x = rand() % 65536, y = rand() % 65536; 37 | int res = division_no_operator(x, y); 38 | cout << x << '/' << y << '=' << res << endl; 39 | assert(ceil(static_cast(x) / y) == res); 40 | } 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /cpp/Doors.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using std::default_random_engine; 9 | using std::deque; 10 | using std::random_device; 11 | using std::uniform_int_distribution; 12 | 13 | // @include 14 | bool IsDoorOpen(int i) { 15 | double sqrt_i = sqrt(i); 16 | int floor_sqrt_i = floor(sqrt_i); 17 | return floor_sqrt_i * floor_sqrt_i == i; 18 | } 19 | // @exclude 20 | 21 | void CheckAnswer(int n) { 22 | deque doors(n + 1, false); // false means closed door. 23 | for (int i = 1; i <= n; ++i) { 24 | int start = 0; 25 | while (start + i <= n) { 26 | start += i; 27 | doors[start] = doors[start] ? false : true; 28 | } 29 | } 30 | 31 | for (int i = 1; i <= n; ++i) { 32 | assert(IsDoorOpen(i) == doors[i]); 33 | } 34 | } 35 | 36 | int main(int argc, char* argv[]) { 37 | default_random_engine gen((random_device())()); 38 | int n; 39 | if (argc == 2) { 40 | n = atoi(argv[1]); 41 | } else { 42 | uniform_int_distribution dis(1, 1000); 43 | n = dis(gen); 44 | } 45 | CheckAnswer(n); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /cpp/Doubly_linked_list_prototype.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_DOUBLY_LINKED_LIST_PROTOTYPE_H_ 4 | #define SOLUTIONS_DOUBLY_LINKED_LIST_PROTOTYPE_H_ 5 | 6 | #include 7 | 8 | using std::shared_ptr; 9 | 10 | // @include 11 | template 12 | struct ListNode { 13 | T data; 14 | shared_ptr> prev, next; 15 | }; 16 | // @exclude 17 | #endif // SOLUTIONS_DOUBLY_LINKED_LIST_PROTOTYPE_H_ 18 | -------------------------------------------------------------------------------- /cpp/GCD.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "./GCD1.h" 9 | #include "./GCD2.h" 10 | 11 | using std::cout; 12 | using std::default_random_engine; 13 | using std::endl; 14 | using std::numeric_limits; 15 | using std::random_device; 16 | using std::uniform_int_distribution; 17 | 18 | int main(int argc, char *argv[]) { 19 | long long x = 18, y = 12; 20 | assert(GCD1::GCD(x, y) == 6); 21 | if (argc == 3) { 22 | x = atoll(argv[1]), y = atoll(argv[2]); 23 | cout << GCD1::GCD(x, y) << endl; 24 | assert(GCD1::GCD(x, y) == GCD2::GCD(x, y)); 25 | } else { 26 | default_random_engine gen((random_device())()); 27 | for (int times = 0; times < 1000; ++times) { 28 | uniform_int_distribution dis( 29 | 1, numeric_limits::max()); 30 | x = dis(gen), y = dis(gen); 31 | assert(GCD1::GCD(x, y) == GCD2::GCD(x, y)); 32 | } 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /cpp/GCD1.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_GCD1_H_ 4 | #define SOLUTIONS_GCD1_H_ 5 | 6 | namespace GCD1 { 7 | 8 | // @include 9 | long long GCD(long long x, long long y) { 10 | if (x == y) { 11 | return x; 12 | } else if (!(x & 1) && !(y & 1)) { // x and y are even. 13 | return GCD(x >> 1, y >> 1) << 1; 14 | } else if (!(x & 1) && y & 1) { // x is even, and y is odd. 15 | return GCD(x >> 1, y); 16 | } else if (x & 1 && !(y & 1)) { // x is odd, and y is even. 17 | return GCD(x, y >> 1); 18 | } else if (x > y) { // Both x and y are odd, and x > y. 19 | return GCD(x - y, y); 20 | } 21 | return GCD(x, y - x); // Both x and y are odd, and x <= y. 22 | } 23 | // @exclude 24 | 25 | } // namespace GCD1 26 | 27 | #endif // SOLUTIONS_GCD1_H_ 28 | -------------------------------------------------------------------------------- /cpp/GCD2.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_GCD2_H_ 4 | #define SOLUTIONS_GCD2_H_ 5 | 6 | namespace GCD2 { 7 | 8 | // @include 9 | long long GCD(long long x, long long y) { return y == 0 ? x : GCD(y, x % y); } 10 | // @exclude 11 | 12 | } // namespace GCD2 13 | 14 | #endif // SOLUTIONS_GCD2_H_ 15 | -------------------------------------------------------------------------------- /cpp/Generate_spiral_matrix.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | // @include 9 | vector> generate_spiral_matrix(int n) { 10 | vector> A(n, vector(n, 0)); 11 | int shift[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; 12 | int dir = 0, x = 0, y = 0; 13 | for (int i = 1; i <= n * n; ++i) { 14 | A[x][y] = i; 15 | int nx = x + shift[dir][0], ny = y + shift[dir][1]; 16 | if (nx < 0 || nx >= n || ny < 0 || ny >= n || A[nx][ny]) { 17 | dir = (dir + 1) % 4; 18 | nx = x + shift[dir][0], ny = y + shift[dir][1]; 19 | } 20 | x = nx, y = ny; 21 | } 22 | return A; 23 | } 24 | // @exclude 25 | 26 | int main(int argc, char *argv[]) { 27 | srand(time(NULL)); 28 | int n; 29 | if (argc == 2) { 30 | n = atoi(argv[1]); 31 | } else { 32 | n = 1 + rand() % 100; 33 | } 34 | vector> A(generate_spiral_matrix(n)); 35 | for (int i = 0; i < A.size(); ++i) { 36 | for (int j = 0; j < A[i].size(); ++j) { 37 | cout << A[i][j] << ' '; 38 | } 39 | cout << endl; 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /cpp/Intersect_sorted_arrays1.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_INTERSECT_SORTED_ARRAYS1_H_ 4 | #define SOLUTIONS_INTERSECT_SORTED_ARRAYS1_H_ 5 | 6 | #include 7 | 8 | using std::vector; 9 | 10 | namespace IntersectTwoSortedArrays1 { 11 | 12 | // @include 13 | vector IntersectTwoSortedArrays(const vector& A, 14 | const vector& B) { 15 | vector insersection_A_B; 16 | for (int i = 0; i < A.size(); ++i) { 17 | if (i == 0 || A[i] != A[i - 1]) { 18 | for (int b : B) { 19 | if (A[i] == b) { 20 | insersection_A_B.emplace_back(A[i]); 21 | break; 22 | } 23 | } 24 | } 25 | } 26 | return insersection_A_B; 27 | } 28 | // @exclude 29 | 30 | } // namespace IntersectTwoSortedArrays1 31 | 32 | #endif // SOLUTIONS_INTERSECT_SORTED_ARRAYS1_H_ 33 | -------------------------------------------------------------------------------- /cpp/Intersect_sorted_arrays2.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_INTERSECT_SORTED_ARRAYS2_H_ 4 | #define SOLUTIONS_INTERSECT_SORTED_ARRAYS2_H_ 5 | 6 | #include 7 | #include 8 | 9 | using std::vector; 10 | 11 | namespace IntersectTwoSortedArrays2 { 12 | 13 | // @include 14 | vector IntersectTwoSortedArrays(const vector& A, 15 | const vector& B) { 16 | vector intersection_A_B; 17 | for (int i = 0; i < A.size(); ++i) { 18 | if ((i == 0 || A[i] != A[i - 1]) && 19 | binary_search(B.cbegin(), B.cend(), A[i])) { 20 | intersection_A_B.emplace_back(A[i]); 21 | } 22 | } 23 | return intersection_A_B; 24 | } 25 | // @exclude 26 | 27 | } // namespace IntersectTwoSortedArrays2 28 | 29 | #endif // SOLUTIONS_INTERSECT_SORTED_ARRAYS2_H_ 30 | -------------------------------------------------------------------------------- /cpp/Intersect_sorted_arrays3.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_INTERSECT_SORTED_ARRAYS3_H_ 4 | #define SOLUTIONS_INTERSECT_SORTED_ARRAYS3_H_ 5 | 6 | #include 7 | 8 | using std::vector; 9 | 10 | namespace IntersectTwoSortedArrays3 { 11 | 12 | // @include 13 | vector IntersectTwoSortedArrays(const vector& A, 14 | const vector& B) { 15 | vector intersection_A_B; 16 | int i = 0, j = 0; 17 | while (i < A.size() && j < B.size()) { 18 | if (A[i] == B[j] && (i == 0 || A[i] != A[i - 1])) { 19 | intersection_A_B.emplace_back(A[i]); 20 | ++i, ++j; 21 | } else if (A[i] < B[j]) { 22 | ++i; 23 | } else { // A[i] > B[j]. 24 | ++j; 25 | } 26 | } 27 | return intersection_A_B; 28 | } 29 | // @exclude 30 | 31 | } // namespace IntersectTwoSortedArrays3 32 | 33 | #endif // SOLUTIONS_INTERSECT_SORTED_ARRAYS3_H_ 34 | -------------------------------------------------------------------------------- /cpp/Linked_list_prototype.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_LINKED_LIST_PROTOTYPE_H_ 4 | #define SOLUTIONS_LINKED_LIST_PROTOTYPE_H_ 5 | 6 | #include 7 | 8 | using std::shared_ptr; 9 | 10 | // @include 11 | template 12 | struct ListNode { 13 | T data; 14 | shared_ptr> next; 15 | }; 16 | // @exclude 17 | #endif // SOLUTIONS_LINKED_LIST_PROTOTYPE_H_ 18 | -------------------------------------------------------------------------------- /cpp/Longest_nondecreasing_subsequence.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "./Longest_nondecreasing_subsequence_n2.h" 10 | #include "./Longest_nondecreasing_subsequence_nlogn.h" 11 | 12 | using std::cout; 13 | using std::default_random_engine; 14 | using std::endl; 15 | using std::random_device; 16 | using std::uniform_int_distribution; 17 | using std::vector; 18 | 19 | int main(int argc, char *argv[]) { 20 | default_random_engine gen((random_device())()); 21 | for (int times = 0; times < 1000; ++times) { 22 | int n; 23 | if (argc == 2) { 24 | n = atoi(argv[1]); 25 | } else { 26 | uniform_int_distribution dis(1, 10000); 27 | n = dis(gen); 28 | } 29 | vector A; 30 | for (int i = 0; i < n; ++i) { 31 | uniform_int_distribution dis(0, 99999999); 32 | A.emplace_back(dis(gen)); 33 | } 34 | cout << "n = " << n << endl; 35 | int ret_length = LNS_nlogn::LongestNondecreasingSubsequenceLength(A); 36 | int another_length = LNS_n2::LongestNondecreasingSubsequenceLength(A); 37 | assert(ret_length == another_length); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /cpp/Longest_nondecreasing_subsequence_n2.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_LONGEST_NONDECREASING_SUBSEQUENCE_N2_H_ 4 | #define SOLUTIONS_LONGEST_NONDECREASING_SUBSEQUENCE_N2_H_ 5 | 6 | #include 7 | #include 8 | 9 | using std::max; 10 | using std::max_element; 11 | using std::vector; 12 | 13 | namespace LNS_n2 { 14 | 15 | // @include 16 | int LongestNondecreasingSubsequenceLength(const vector& A) { 17 | // max_length[i] holds the length of the longest nondecreasing subsequence 18 | // of A[0 : i]. 19 | vector max_length(A.size(), 1); 20 | for (int i = 1; i < A.size(); ++i) { 21 | for (int j = 0; j < i; ++j) { 22 | if (A[i] >= A[j]) { 23 | max_length[i] = max(max_length[i], max_length[j] + 1); 24 | } 25 | } 26 | } 27 | return *max_element(max_length.begin(), max_length.end()); 28 | } 29 | // @exclude 30 | 31 | } // LNS_n2 32 | 33 | #endif // SOLUTIONS_LONGEST_NONDECREASING_SUBSEQUENCE_N2_H_ 34 | -------------------------------------------------------------------------------- /cpp/Longest_nondecreasing_subsequence_nlogn.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_LONGEST_NONDECREASING_SUBSEQUENCE_NLOGN_H_ 4 | #define SOLUTIONS_LONGEST_NONDECREASING_SUBSEQUENCE_NLOGN_H_ 5 | 6 | #include 7 | #include 8 | 9 | using std::vector; 10 | 11 | namespace LNS_nlogn { 12 | 13 | // @include 14 | int LongestNondecreasingSubsequenceLength(const vector& A) { 15 | vector tail_values; 16 | for (int a : A) { 17 | auto it = upper_bound(tail_values.begin(), tail_values.end(), a); 18 | if (it == tail_values.end()) { 19 | tail_values.emplace_back(a); 20 | } else { 21 | *it = a; 22 | } 23 | } 24 | return tail_values.size(); 25 | } 26 | // @exclude 27 | 28 | } // LNS_nlogn 29 | 30 | #endif // SOLUTIONS_LONGEST_NONDECREASING_SUBSEQUENCE_NLOGN_H_ 31 | -------------------------------------------------------------------------------- /cpp/Makefile: -------------------------------------------------------------------------------- 1 | lastModifiedcppFile = $(shell ls -rt *\.c* | tail -1) 2 | clang: $(lastModifiedcppFile) 3 | $(MAKE) compile && ./a.out 4 | 5 | compile: $(lastModifiedcppFile) 6 | clang++ -Weverything -Wno-c++98-compat -Wno-missing-prototypes $(lastModifiedcppFile) -stdlib=libc++ -std=c++14 -O3 7 | 8 | lint: $(lastModifiedcppFile) 9 | python cpplint.py $(lastModifiedcppFile) 10 | 11 | cpp: $(lastModifiedcppFile) 12 | g++ -Wall -std=c++11 $(lastModifiedcppFile) -lm 13 | 14 | lastModifiedjavaFile = $(shell ls -rt *.java | tail -1) 15 | java: $(lastModifiedjavaFile) 16 | javac $(lastModifiedjavaFile) 17 | -------------------------------------------------------------------------------- /cpp/Max_concatenation_numbers.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | string rand_string(int len) { 11 | string ret; 12 | int x = rand() % 10; 13 | ret += '0' + x; 14 | if (x) { 15 | while (--len) { 16 | ret += '0' + rand() % 10; 17 | } 18 | } 19 | return ret; 20 | } 21 | 22 | // @include 23 | bool comp(const string &a, const string &b) { return a + b > b + a; } 24 | 25 | string max_concatenation(vector &A) { 26 | sort(A.begin(), A.end(), comp); 27 | string ret; 28 | for (int i = 0; i < A.size(); ++i) { 29 | ret += A[i]; 30 | } 31 | return ret; 32 | } 33 | // @exclude 34 | 35 | int main(int argc, char *argv[]) { 36 | int n; 37 | if (argc == 2) { 38 | n = atoi(argv[1]); 39 | } else { 40 | n = 1 + rand() % 100000; 41 | } 42 | vector A; 43 | for (int i = 0; i < n; ++i) { 44 | A.push_back(rand_string(1 + rand() % 4)); 45 | } 46 | for (int i = 0; i < n; ++i) { 47 | cout << A[i] << ' '; 48 | } 49 | cout << endl; 50 | string x(max_concatenation(A)); 51 | cout << x << endl; 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /cpp/Max_submatrix_rectangle_brute_force.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_MAX_SUBMATRIX_RECTANGLE_BRUTE_FORCE_H_ 4 | #define SOLUTIONS_MAX_SUBMATRIX_RECTANGLE_BRUTE_FORCE_H_ 5 | 6 | #include 7 | #include 8 | 9 | using std::deque; 10 | using std::vector; 11 | 12 | // O(m^3 n^3) time solution. 13 | int MaxRectangleSubmatrixBruteForce(const vector> &A) { 14 | int max = 0; 15 | for (int a = 0; a < A.size(); ++a) { 16 | for (int b = 0; b < A[a].size(); ++b) { 17 | for (int c = a; c < A.size(); ++c) { 18 | for (int d = b; d < A[c].size(); ++d) { 19 | bool all_1 = true; 20 | int count = 0; 21 | for (int i = a; i <= c; ++i) { 22 | for (int j = b; j <= d; ++j) { 23 | if (A[i][j] == false) { 24 | all_1 = false; 25 | count = 0; 26 | break; 27 | } else { 28 | ++count; 29 | } 30 | } 31 | if (all_1 == false) { 32 | break; 33 | } 34 | } 35 | if (all_1 == true && count > max) { 36 | max = count; 37 | } 38 | } 39 | } 40 | } 41 | } 42 | return max; 43 | } 44 | #endif // SOLUTIONS_MAX_SUBMATRIX_RECTANGLE_BRUTE_FORCE_H_ 45 | -------------------------------------------------------------------------------- /cpp/Maximum_container.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | // @include 10 | int max_container_area(const vector &A) { 11 | int largest = 0; 12 | int l = 0, r = A.size() - 1; 13 | while (l < r) { 14 | int l_h = A[l], r_h = A[r]; 15 | int area = min(l_h, r_h) * (r - l); 16 | if (area > largest) { 17 | largest = area; 18 | } 19 | if (l_h <= r_h) { 20 | while (l < r && A[l] <= l_h) { 21 | ++l; 22 | } 23 | } 24 | if (l_h >= r_h) { 25 | while (l < r && A[r] <= r_h) { 26 | --r; 27 | } 28 | } 29 | } 30 | cout << largest << endl; 31 | return largest; 32 | } 33 | // @exclude 34 | 35 | int check_answer(const vector &A) { 36 | int largest = 0; 37 | for (int i = 0; i < A.size(); ++i) { 38 | int area = 0; 39 | for (int j = i + 1; j < A.size(); ++j) { 40 | area = min(A[i], A[j]) * (j - i); 41 | largest = max(largest, area); 42 | } 43 | } 44 | return largest; 45 | } 46 | 47 | int main(int argc, char *argv[]) { 48 | int n; 49 | srand(time(NULL)); 50 | if (argc == 2) { 51 | n = atoi(argv[1]); 52 | } else { 53 | n = 1 + rand() % 100000; 54 | } 55 | vector A; 56 | for (int i = 0; i < n; ++i) { 57 | A.push_back(rand() % 10000); 58 | } 59 | assert(check_answer(A) == max_container_area(A)); 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /cpp/Merge_sorted_lists.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_MERGE_SORTED_LISTS_H_ 4 | #define SOLUTIONS_MERGE_SORTED_LISTS_H_ 5 | 6 | #include "./Linked_list_prototype.h" 7 | 8 | void AppendNode(shared_ptr> *, shared_ptr> *); 9 | 10 | // @include 11 | shared_ptr> MergeTwoSortedLists(shared_ptr> L1, 12 | shared_ptr> L2) { 13 | // Creates a placeholder for the result. 14 | shared_ptr> dummy_head(new ListNode); 15 | auto tail = dummy_head; 16 | 17 | while (L1 && L2) { 18 | AppendNode(L1->data <= L2->data ? &L1 : &L2, &tail); 19 | } 20 | 21 | // Appends the remaining nodes of L1 or L2. 22 | tail->next = L1 ? L1 : L2; 23 | return dummy_head->next; 24 | } 25 | 26 | void AppendNode(shared_ptr> *node, 27 | shared_ptr> *tail) { 28 | (*tail)->next = *node; 29 | *tail = *node; // Updates tail. 30 | *node = (*node)->next; 31 | } 32 | // @exclude 33 | #endif // SOLUTIONS_MERGE_SORTED_LISTS_H_ 34 | -------------------------------------------------------------------------------- /cpp/Offline_sampling.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "./Offline_sampling.h" 10 | 11 | using std::cout; 12 | using std::default_random_engine; 13 | using std::endl; 14 | using std::random_device; 15 | using std::swap; 16 | using std::uniform_int_distribution; 17 | using std::vector; 18 | 19 | int main(int argc, char* argv[]) { 20 | int n, k; 21 | default_random_engine gen((random_device())()); 22 | if (argc == 2) { 23 | n = atoi(argv[1]); 24 | uniform_int_distribution dis(1, n); 25 | k = dis(gen); 26 | } else if (argc == 3) { 27 | n = atoi(argv[1]); 28 | k = atoi(argv[2]); 29 | } else { 30 | uniform_int_distribution n_dis(1, 1000000); 31 | n = n_dis(gen); 32 | uniform_int_distribution k_dis(1, n); 33 | k = k_dis(gen); 34 | } 35 | vector A(n); 36 | iota(A.begin(), A.end(), 0); 37 | cout << n << ' ' << k << endl; 38 | RandomSampling(k, &A); 39 | for (int i = 0; i < A.size(); i++) { 40 | cout << i << ":" << A[i] << " "; 41 | } 42 | cout << endl; 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /cpp/Offline_sampling.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_OFFLINE_SAMPLING_H_ 4 | #define SOLUTIONS_OFFLINE_SAMPLING_H_ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using std::default_random_engine; 13 | using std::random_device; 14 | using std::swap; 15 | using std::uniform_int_distribution; 16 | using std::vector; 17 | 18 | // @include 19 | void RandomSampling(int k, vector* A_ptr) { 20 | vector& A = *A_ptr; 21 | default_random_engine seed((random_device())()); // Random num generator. 22 | for (int i = 0; i < k; ++i) { 23 | // Generate a random index in [i, A.size() - 1]. 24 | swap(A[i], A[uniform_int_distribution{ 25 | i, static_cast(A.size()) - 1}(seed)]); 26 | } 27 | } 28 | // @exclude 29 | #endif // SOLUTIONS_OFFLINE_SAMPLING_H_ 30 | -------------------------------------------------------------------------------- /cpp/Overlapping_lists_no_cycle.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "./Linked_list_prototype.h" 8 | #include "./Overlapping_lists_no_cycle.h" 9 | 10 | using std::cout; 11 | using std::endl; 12 | using std::make_shared; 13 | using std::shared_ptr; 14 | 15 | int main(int argc, char* argv[]) { 16 | shared_ptr> L1, L2; 17 | // L1: 1->2->3->null 18 | L1 = make_shared>(ListNode{ 19 | 1, make_shared>(ListNode{ 20 | 2, make_shared>(ListNode{3, nullptr})})}); 21 | L2 = L1->next->next; 22 | assert(OverlappingNoCycleLists(L1, L2)->data == 3); 23 | // L2: 4->5->null 24 | L2 = make_shared>(ListNode{ 25 | 4, make_shared>(ListNode{5, nullptr})}); 26 | assert(!OverlappingNoCycleLists(L1, L2)); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /cpp/Overlapping_lists_no_cycle.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_OVERLAPPING_LISTS_NO_CYCLE_H_ 4 | #define SOLUTIONS_OVERLAPPING_LISTS_NO_CYCLE_H_ 5 | 6 | #include "./Linked_list_prototype.h" 7 | 8 | int Length(shared_ptr> L); 9 | void AdvanceListByK(int k, shared_ptr>* L); 10 | 11 | // @include 12 | shared_ptr> OverlappingNoCycleLists( 13 | shared_ptr> L1, shared_ptr> L2) { 14 | int L1_len = Length(L1), L2_len = Length(L2); 15 | 16 | // Advances the longer list to get equal length lists. 17 | AdvanceListByK(abs(L1_len - L2_len), L1_len > L2_len ? &L1 : &L2); 18 | 19 | while (L1 && L2 && L1 != L2) { 20 | L1 = L1->next, L2 = L2->next; 21 | } 22 | return L1; // nullptr implies there is no overlap between L1 and L2. 23 | } 24 | 25 | int Length(shared_ptr> L) { 26 | int length = 0; 27 | while (L) { 28 | ++length, L = L->next; 29 | } 30 | return length; 31 | } 32 | 33 | // Advances L by k steps. 34 | void AdvanceListByK(int k, shared_ptr>* L) { 35 | while (k--) { 36 | *L = (*L)->next; 37 | } 38 | } 39 | // @exclude 40 | #endif // SOLUTIONS_OVERLAPPING_LISTS_NO_CYCLE_H_ 41 | -------------------------------------------------------------------------------- /cpp/Parity.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "./Parity1.h" 9 | #include "./Parity2.h" 10 | #include "./Parity3.h" 11 | #include "./Parity4.h" 12 | 13 | using std::cout; 14 | using std::default_random_engine; 15 | using std::endl; 16 | using std::numeric_limits; 17 | using std::random_device; 18 | using std::uniform_int_distribution; 19 | 20 | int main(int argc, char* argv[]) { 21 | Parity3::BuildTable(); 22 | if (argc == 2) { 23 | long x = atol(argv[1]); 24 | cout << "x = " << x << ", parity = " << Parity1::Parity(x) 25 | << ", parity = " << Parity3::Parity(x) << endl; 26 | assert(Parity1::Parity(x) == Parity3::Parity(x)); 27 | assert(Parity2::Parity(x) == Parity3::Parity(x)); 28 | assert(Parity3::Parity(x) == Parity4::Parity(x)); 29 | cout << "x = " << x << ", parity = " << Parity3::Parity(x) << endl; 30 | } else { 31 | default_random_engine gen((random_device())()); 32 | for (int times = 0; times < 1000; ++times) { 33 | uniform_int_distribution dis(0, numeric_limits::max()); 34 | long x = dis(gen); 35 | assert(Parity1::Parity(x) == Parity3::Parity(x)); 36 | assert(Parity2::Parity(x) == Parity3::Parity(x)); 37 | assert(Parity4::Parity(x) == Parity3::Parity(x)); 38 | cout << "x = " << x << ", parity = " << Parity3::Parity(x) << endl; 39 | } 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /cpp/Parity1.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_PARITY1_H_ 4 | #define SOLUTIONS_PARITY1_H_ 5 | 6 | namespace Parity1 { 7 | 8 | // @include 9 | short Parity(unsigned long x) { 10 | short result = 0; 11 | while (x) { 12 | result ^= (x & 1); 13 | x >>= 1; 14 | } 15 | return result; 16 | } 17 | // @exclude 18 | 19 | } // namespace Parity1 20 | 21 | #endif // SOLUTIONS_PARITY1_H_ 22 | -------------------------------------------------------------------------------- /cpp/Parity2.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_PARITY2_H_ 4 | #define SOLUTIONS_PARITY2_H_ 5 | 6 | namespace Parity2 { 7 | 8 | // @include 9 | short Parity(unsigned long x) { 10 | short result = 0; 11 | while (x) { 12 | result ^= 1; 13 | x &= (x - 1); // Drops the lowest set bit of x. 14 | } 15 | return result; 16 | } 17 | // @exclude 18 | 19 | } // namespace Parity2 20 | 21 | #endif // SOLUTIONS_PARITY2_H_ 22 | -------------------------------------------------------------------------------- /cpp/Parity3.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_PARITY3_H_ 4 | #define SOLUTIONS_PARITY3_H_ 5 | 6 | #include 7 | 8 | using std::array; 9 | 10 | namespace Parity3 { 11 | 12 | array BuildTable() { 13 | array result; 14 | for (int i = 0; i < (1 << 16); ++i) { 15 | result[i] = Parity1::Parity(i); 16 | } 17 | return result; 18 | } 19 | 20 | static array precomputed_parity = BuildTable(); 21 | 22 | // @include 23 | short Parity(unsigned long x) { 24 | const int kWordSize = 16; 25 | const int kBitMask = 0xFFFF; 26 | return precomputed_parity[x >> (3 * kWordSize)] ^ 27 | precomputed_parity[(x >> (2 * kWordSize)) & kBitMask] ^ 28 | precomputed_parity[(x >> kWordSize) & kBitMask] ^ 29 | precomputed_parity[x & kBitMask]; 30 | } 31 | // @exclude 32 | 33 | } // namespace Parity3 34 | 35 | #endif // SOLUTIONS_PARITY3_H_ 36 | -------------------------------------------------------------------------------- /cpp/Parity4.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_PARITY4_H_ 4 | #define SOLUTIONS_PARITY4_H_ 5 | 6 | namespace Parity4 { 7 | 8 | short FourBitParityLookup(int x); 9 | 10 | // @include 11 | short Parity(unsigned long x) { 12 | x ^= x >> 32; 13 | x ^= x >> 16; 14 | x ^= x >> 8; 15 | x ^= x >> 4; 16 | x ^= x >> 2; 17 | x ^= x >> 1; 18 | return x & 0x1; 19 | } 20 | // @exclude 21 | 22 | } // namespace Parity4 23 | 24 | #endif // SOLUTIONS_PARITY4_H_ 25 | -------------------------------------------------------------------------------- /cpp/Permutation_array1.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_PERMUTATION_ARRAY1_H_ 4 | #define SOLUTIONS_PERMUTATION_ARRAY1_H_ 5 | 6 | #include 7 | #include 8 | 9 | using std::swap; 10 | using std::vector; 11 | 12 | namespace ApplyPermutation1 { 13 | 14 | // @include 15 | void ApplyPermutation(vector* perm_ptr, vector* A_ptr) { 16 | vector &perm = *perm_ptr, &A = *A_ptr; 17 | for (int i = 0; i < A.size(); ++i) { 18 | // Check if the element at index i has not been moved by checking if 19 | // perm[i] is nonnegative. 20 | int next = i; 21 | while (perm[next] >= 0) { 22 | swap(A[i], A[perm[next]]); 23 | int temp = perm[next]; 24 | // Subtracts perm.size() from an entry in perm to make it negative, 25 | // which indicates the corresponding move has been performed. 26 | perm[next] -= perm.size(); 27 | next = temp; 28 | } 29 | } 30 | 31 | // Restore perm. 32 | for_each(begin(perm), end(perm), [&perm](int& x) { x += perm.size(); }); 33 | } 34 | // @exclude 35 | 36 | } // ApplyPermutation1 37 | 38 | #endif // SOLUTIONS_PERMUTATION_ARRAY1_H_ 39 | -------------------------------------------------------------------------------- /cpp/Permutation_array2.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_PERMUTATION_ARRAY2_H_ 4 | #define SOLUTIONS_PERMUTATION_ARRAY2_H_ 5 | 6 | #include 7 | 8 | using std::vector; 9 | 10 | namespace ApplyPermutation2 { 11 | 12 | void CyclicPermutation(int, const vector&, vector*); 13 | 14 | // @include 15 | void ApplyPermutation(const vector& perm, vector* A_ptr) { 16 | vector& A = *A_ptr; 17 | for (int i = 0; i < A.size(); ++i) { 18 | // Traverses the cycle to see if i is the minimum element. 19 | bool is_min = true; 20 | int j = perm[i]; 21 | while (j != i) { 22 | if (j < i) { 23 | is_min = false; 24 | break; 25 | } 26 | j = perm[j]; 27 | } 28 | 29 | if (is_min) { 30 | CyclicPermutation(i, perm, &A); 31 | } 32 | } 33 | } 34 | 35 | void CyclicPermutation(int start, const vector& perm, 36 | vector* A_ptr) { 37 | vector& A = *A_ptr; 38 | int i = start; 39 | int temp = A[start]; 40 | do { 41 | int next_i = perm[i]; 42 | int next_temp = A[next_i]; 43 | A[next_i] = temp; 44 | i = next_i, temp = next_temp; 45 | } while (i != start); 46 | } 47 | // @exclude 48 | 49 | } // namespace ApplyPermutation2 50 | 51 | #endif // SOLUTIONS_PERMUTATION_ARRAY2_H_ 52 | -------------------------------------------------------------------------------- /cpp/Planning_fishing.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using std::cout; 9 | using std::default_random_engine; 10 | using std::endl; 11 | using std::max; 12 | using std::random_device; 13 | using std::uniform_int_distribution; 14 | using std::vector; 15 | 16 | // @include 17 | int MaximizeFishing(vector> A) { 18 | for (int i = 0; i < A.size(); ++i) { 19 | for (int j = 0; j < A[i].size(); ++j) { 20 | A[i][j] += max(i < 1 ? 0 : A[i - 1][j], j < 1 ? 0 : A[i][j - 1]); 21 | } 22 | } 23 | return A.back().back(); 24 | } 25 | // @exclude 26 | 27 | int main(int argc, char* argv[]) { 28 | default_random_engine gen((random_device())()); 29 | int n, m; 30 | if (argc == 3) { 31 | n = atoi(argv[1]), m = atoi(argv[2]); 32 | } else { 33 | uniform_int_distribution dis(1, 100); 34 | n = dis(gen), m = dis(gen); 35 | } 36 | vector> A(n, vector(m)); 37 | for (size_t i = 0; i < n; ++i) { 38 | for (size_t j = 0; j < m; ++j) { 39 | uniform_int_distribution dis(0, 999); 40 | A[i][j] = dis(gen); 41 | } 42 | } 43 | for (size_t i = 0; i < n; ++i) { 44 | for (size_t j = 0; j < m; ++j) { 45 | cout << A[i][j] << ' '; 46 | } 47 | cout << endl; 48 | } 49 | cout << MaximizeFishing(A) << endl; 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /cpp/Point.h: -------------------------------------------------------------------------------- 1 | using std::hash; 2 | 3 | class Point { 4 | public: 5 | int x; 6 | int y; 7 | Point(int a, int b) { 8 | x = a; 9 | y = b; 10 | } 11 | 12 | bool operator==(const Point& that) const { 13 | return x == that.x && y == that.y; 14 | } 15 | }; 16 | 17 | struct HashPoint { 18 | size_t operator()(const Point& p) const { 19 | size_t hash_code = 0; 20 | hash_code ^= hash()(p.x); 21 | hash_code ^= hash()(p.y); 22 | return hash_code; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /cpp/Postings_list_prototype.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_POSTINGS_LIST_PROTOTYPE_H_ 4 | #define SOLUTIONS_POSTINGS_LIST_PROTOTYPE_H_ 5 | 6 | #include 7 | 8 | using std::shared_ptr; 9 | 10 | // @include 11 | class PostingListNode { 12 | public: 13 | int order; 14 | shared_ptr next, jump; 15 | }; 16 | // @exclude 17 | #endif // SOLUTIONS_POSTINGS_LIST_PROTOTYPE_H_ 18 | -------------------------------------------------------------------------------- /cpp/Remove_kth_last_list.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "./Linked_list_prototype.h" 8 | 9 | using std::cout; 10 | using std::endl; 11 | using std::make_shared; 12 | using std::shared_ptr; 13 | 14 | // @include 15 | // Assumes L has at least k nodes, deletes the k-th last node in L. 16 | shared_ptr> RemoveKthLast(const shared_ptr>& L, 17 | int k) { 18 | auto dummy_head = make_shared>(ListNode{0, L}); 19 | auto first = dummy_head->next; 20 | while (k--) { 21 | first = first->next; 22 | } 23 | 24 | auto second = dummy_head; 25 | while (first) { 26 | second = second->next, first = first->next; 27 | } 28 | // second points to the (k + 1)-th last node, deletes its successor. 29 | second->next = second->next->next; 30 | return dummy_head->next; 31 | } 32 | // @exclude 33 | 34 | int main(int argc, char* argv[]) { 35 | shared_ptr> L; 36 | L = make_shared>(ListNode{ 37 | 1, make_shared>(ListNode{ 38 | 2, make_shared>(ListNode{3, nullptr})})}); 39 | L = RemoveKthLast(L, 2); 40 | assert(L->data == 1 && L->next->data == 3); 41 | L = RemoveKthLast(L, 2); 42 | assert(L->data == 3 && L->next == nullptr); 43 | L = RemoveKthLast(L, 1); 44 | assert(L == nullptr); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /cpp/Reverse_linked_list_iterative.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_REVERSE_LINKED_LIST_ITERATIVE_H_ 4 | #define SOLUTIONS_REVERSE_LINKED_LIST_ITERATIVE_H_ 5 | 6 | #include 7 | 8 | #include "./Linked_list_prototype.h" 9 | 10 | using std::shared_ptr; 11 | 12 | // @include 13 | shared_ptr> ReverseLinkedList( 14 | const shared_ptr>& head) { 15 | shared_ptr> prev = nullptr, curr = head; 16 | while (curr) { 17 | auto next = curr->next; 18 | curr->next = prev; 19 | prev = curr; 20 | curr = next; 21 | } 22 | return prev; 23 | } 24 | // @exclude 25 | #endif // SOLUTIONS_REVERSE_LINKED_LIST_ITERATIVE_H_ 26 | -------------------------------------------------------------------------------- /cpp/Rotate_array.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_ROTATE_ARRAY_H_ 4 | #define SOLUTIONS_ROTATE_ARRAY_H_ 5 | 6 | #include 7 | #include 8 | 9 | using std::vector; 10 | 11 | namespace rotate_array2 { 12 | 13 | // @include 14 | void RotateArray(int i, vector* A) { 15 | i %= A->size(); 16 | reverse(A->begin(), A->end()); 17 | reverse(A->begin(), A->begin() + i); 18 | reverse(A->begin() + i, A->end()); 19 | } 20 | // @exclude 21 | 22 | } // rotate_array2 23 | #endif // SOLUTIONS_ROTATE_ARRAY_H_ 24 | -------------------------------------------------------------------------------- /cpp/Rotate_array_permutation.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_ROTATE_ARRAY_PERMUTATION_H_ 4 | #define SOLUTIONS_ROTATE_ARRAY_PERMUTATION_H_ 5 | 6 | #include 7 | #include 8 | 9 | #include "./GCD2.h" 10 | 11 | using std::swap; 12 | using std::vector; 13 | using GCD2::GCD; 14 | 15 | namespace rotate_array1 { 16 | 17 | void ApplyCyclicPermutation(int, int, int, vector*); 18 | 19 | // @include 20 | void RotateArray(int rotate_amount, vector* A_ptr) { 21 | rotate_amount %= A_ptr->size(); 22 | if (!rotate_amount) { 23 | return; 24 | } 25 | 26 | int num_cycles = GCD(A_ptr->size(), rotate_amount); 27 | int cycle_length = A_ptr->size() / num_cycles; 28 | 29 | for (int c = 0; c < num_cycles; ++c) { 30 | ApplyCyclicPermutation(rotate_amount, c, cycle_length, A_ptr); 31 | } 32 | } 33 | 34 | void ApplyCyclicPermutation(int rotate_amount, int offset, int cycle_length, 35 | vector* A_ptr) { 36 | vector& A = *A_ptr; 37 | int temp = A[offset]; 38 | for (int i = 1; i < cycle_length; ++i) { 39 | swap(A[(offset + i * rotate_amount) % A.size()], temp); 40 | } 41 | A[offset] = temp; 42 | } 43 | // @exclude 44 | 45 | } // rotate_array1 46 | #endif // SOLUTIONS_ROTATE_ARRAY_PERMUTATION_H_ 47 | -------------------------------------------------------------------------------- /cpp/Run_length_compression.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::endl; 11 | using std::string; 12 | using std::to_string; 13 | 14 | // @include 15 | string Decoding(const string &s) { 16 | int count = 0; 17 | string result; 18 | for (const char &c : s) { 19 | if (isdigit(c)) { 20 | count = count * 10 + c - '0'; 21 | } else { // c is a letter of alphabet. 22 | result.append(count, c); // Appends count copies of c to result. 23 | count = 0; 24 | } 25 | } 26 | return result; 27 | } 28 | 29 | string Encoding(const string &s) { 30 | string result; 31 | for (int i = 1, count = 1; i <= s.size(); ++i) { 32 | if (i == s.size() || s[i] != s[i - 1]) { 33 | // Found new character so write the count of previous character. 34 | result += to_string(count) + s[i - 1]; 35 | count = 1; 36 | } else { // s[i] == s[i - 1]. 37 | ++count; 38 | } 39 | } 40 | return result; 41 | } 42 | // @exclude 43 | 44 | int main(int argc, char *argv[]) { 45 | if (argc == 3) { 46 | cout << Encoding(argv[1]) << ' ' << Decoding(argv[2]) << endl; 47 | } 48 | assert(string("4a1b3c2a") == Encoding("aaaabcccaa")); 49 | assert(string("eeeffffee") == Decoding("3e4f2e")); 50 | assert(string("aaaaaaaaaaffffee") == Decoding("10a4f2e")); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /cpp/Spreadsheet_encoding.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using std::cout; 9 | using std::default_random_engine; 10 | using std::endl; 11 | using std::random_device; 12 | using std::string; 13 | using std::uniform_int_distribution; 14 | 15 | string RandString(int len) { 16 | default_random_engine gen((random_device())()); 17 | string result; 18 | uniform_int_distribution dis('A', 'Z'); 19 | while (len--) { 20 | result.push_back(dis(gen)); 21 | } 22 | return result; 23 | } 24 | 25 | // @include 26 | int SSDecodeColID(const string& col) { 27 | int result = 0; 28 | for (char c : col) { 29 | result = result * 26 + c - 'A' + 1; 30 | } 31 | return result; 32 | } 33 | // @exclude 34 | 35 | void SimpleTest() { 36 | assert(1 == SSDecodeColID("A")); 37 | assert(2 == SSDecodeColID("B")); 38 | assert(26 == SSDecodeColID("Z")); 39 | assert(27 == SSDecodeColID("AA")); 40 | } 41 | 42 | int main(int argc, char* argv[]) { 43 | SimpleTest(); 44 | default_random_engine gen((random_device())()); 45 | if (argc == 2) { 46 | cout << argv[1] << " " << SSDecodeColID(argv[1]) << endl; 47 | } else { 48 | uniform_int_distribution len_dis(1, 5); 49 | string s(RandString(len_dis(gen))); 50 | cout << s << " " << SSDecodeColID(s) << endl; 51 | } 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /cpp/Stack_with_max.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "./Stack_with_max.h" 8 | 9 | using std::cout; 10 | using std::endl; 11 | using std::exception; 12 | 13 | int main(int argc, char* argv[]) { 14 | Stack s; 15 | s.Push(1); 16 | s.Push(2); 17 | assert(s.Max() == 2); 18 | cout << s.Max() << endl; // 2 19 | cout << s.Pop() << endl; // 2 20 | assert(s.Max() == 1); 21 | cout << s.Max() << endl; // 1 22 | s.Push(3); 23 | s.Push(2); 24 | assert(s.Max() == 3); 25 | cout << s.Max() << endl; // 3 26 | s.Pop(); 27 | assert(s.Max() == 3); 28 | cout << s.Max() << endl; // 3 29 | s.Pop(); 30 | assert(s.Max() == 1); 31 | cout << s.Max() << endl; // 1 32 | s.Pop(); 33 | try { 34 | s.Max(); 35 | s.Pop(); 36 | s.Pop(); 37 | s.Pop(); 38 | s.Pop(); 39 | } catch (const exception& e) { 40 | cout << e.what() << endl; 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /cpp/Stack_with_max.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_STACK_WITH_MAX_H_ 4 | #define SOLUTIONS_STACK_WITH_MAX_H_ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using std::length_error; 12 | using std::max; 13 | using std::stack; 14 | 15 | // @include 16 | class Stack { 17 | public: 18 | bool Empty() const { return element_with_cached_max_.empty(); } 19 | 20 | int Max() const { 21 | if (Empty()) { 22 | throw length_error("Max(): empty stack"); 23 | } 24 | return element_with_cached_max_.top().max; 25 | } 26 | 27 | int Pop() { 28 | if (Empty()) { 29 | throw length_error("Pop(): empty stack"); 30 | } 31 | int pop_element = element_with_cached_max_.top().element; 32 | element_with_cached_max_.pop(); 33 | return pop_element; 34 | } 35 | 36 | void Push(int x) { 37 | element_with_cached_max_.emplace( 38 | ElementWithCachedMax{x, max(x, Empty() ? x : Max())}); 39 | } 40 | 41 | private: 42 | struct ElementWithCachedMax { 43 | int element, max; 44 | }; 45 | stack element_with_cached_max_; 46 | }; 47 | // @exclude 48 | #endif // SOLUTIONS_STACK_WITH_MAX_H_ 49 | -------------------------------------------------------------------------------- /cpp/Tail_coin.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | 6 | using std::cout; 7 | using std::default_random_engine; 8 | using std::endl; 9 | using std::random_device; 10 | using std::uniform_int_distribution; 11 | using std::uniform_real_distribution; 12 | 13 | // @include 14 | // Return the number of failed trials. 15 | int simulate_biased_coin(int n, int trials) { 16 | default_random_engine gen((random_device())()); // random num generator. 17 | // Generate random double in [0.0, 1.0]. 18 | uniform_real_distribution dis(0.0, 1.0); 19 | const double kBias = 0.4; 20 | int fails = 0; 21 | for (int i = 0; i < trials; ++i) { 22 | int biased_num = 0; 23 | for (int j = 0; j < n; ++j) { 24 | biased_num += (dis(gen) >= kBias); 25 | } 26 | 27 | if (biased_num < (n / 2)) { 28 | ++fails; 29 | } 30 | } 31 | return fails; 32 | } 33 | // @exclude 34 | 35 | int main(int argc, char* argv[]) { 36 | int n, trials; 37 | default_random_engine gen((random_device())()); 38 | if (argc == 3) { 39 | n = atoi(argv[1]); 40 | trials = atoi(argv[2]); 41 | } else { 42 | uniform_int_distribution dis(1, 1000); 43 | n = dis(gen); 44 | trials = dis(gen); 45 | } 46 | int fails = simulate_biased_coin(n, trials); 47 | cout << "fails = " << fails << endl; 48 | cout << "ratio = " << static_cast(fails) / trials << endl; 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /cpp/a.out.dSYM/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.apple.xcode.dsym.a.out 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundlePackageType 12 | dSYM 13 | CFBundleSignature 14 | ???? 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleVersion 18 | 1 19 | 20 | 21 | -------------------------------------------------------------------------------- /cpp/add-binary.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::default_random_engine; 11 | using std::endl; 12 | using std::random_device; 13 | using std::string; 14 | using std::uniform_int_distribution; 15 | 16 | // @include 17 | string add_binary(string a, string b) { 18 | string sum; 19 | reverse(a.begin(), a.end()), reverse(b.begin(), b.end()); 20 | bool have_carry = false; 21 | for (size_t i = 0; i < a.size() || i < b.size(); ++i) { 22 | int val_a = i < a.size() ? a[i] - '0' : 0, 23 | val_b = i < b.size() ? b[i] - '0' : 0; 24 | int val = val_a + val_b + have_carry; 25 | have_carry = val >= 2; 26 | sum += (val == 1 || val == 3) ? '1' : '0'; 27 | } 28 | if (have_carry) { 29 | sum += '1'; 30 | } 31 | reverse(sum.begin(), sum.end()); 32 | return sum; 33 | } 34 | // @exclude 35 | 36 | int main(int argc, char** argv) { 37 | if (argc == 3) { 38 | cout << "a = " << argv[1] << ", b = " << argv[2] << endl; 39 | cout << add_binary(argv[1], argv[2]) << endl; 40 | } 41 | assert(!add_binary("0", "0").compare("0")); 42 | assert(!add_binary("11", "1").compare("100")); 43 | assert(!add_binary("1", "0").compare("1")); 44 | assert(!add_binary("111", "1").compare("1000")); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /cpp/badmacro.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | //@include 4 | // Avoid overhead of a function call. 5 | #define isvowel(c) (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') 6 | //@exclude 7 | 8 | int main(int argc, char** argv) { 9 | char c = 'a'; 10 | assert(isvowel(c)); 11 | } 12 | -------------------------------------------------------------------------------- /cpp/badrtti.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | 8 | //@include 9 | class A { 10 | public: 11 | virtual void foo() { cout << "A's foo" << endl; } 12 | }; 13 | 14 | class B : public A { 15 | public: 16 | void foo() override { cout << "B's foo" << endl; } 17 | virtual void bar() { cout << "B's bar" << endl; } 18 | }; 19 | 20 | class C : public B { 21 | public: 22 | void bar() override { cout << "C's bar" << endl; } 23 | void widget() { cout << "C's widget" << endl; } 24 | }; 25 | 26 | void bad(A* x) { 27 | if (typeid(*x) == typeid(A)) { 28 | x->foo(); 29 | } else if (typeid(*x) == typeid(B)) { 30 | ((B*)x)->foo(); 31 | ((B*)x)->bar(); 32 | } else if (typeid(*x) == typeid(C)) { 33 | ((C*)x)->foo(); 34 | ((C*)x)->bar(); 35 | ((C*)x)->widget(); 36 | } 37 | } 38 | 39 | //@exclude 40 | 41 | A* randomBuilder() { 42 | // int r = random()%3; 43 | int r = 2; 44 | if (r == 0) { 45 | return new A(); 46 | } else if (r == 1) { 47 | cout << "returning a B" << endl; 48 | return new B(); 49 | } else if (r == 2) { 50 | return new C(); 51 | } else { 52 | return new C(); 53 | } 54 | } 55 | 56 | // @include 57 | int main() { 58 | // Randomly returns a pointer to an A, B, or C type object. 59 | A* x = randomBuilder(); 60 | bad(x); 61 | } 62 | // @exclude 63 | -------------------------------------------------------------------------------- /cpp/badrtti2.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | 8 | class A { 9 | public: 10 | virtual void foo() { cout << "A's foo" << endl; } 11 | }; 12 | 13 | class B : public A { 14 | public: 15 | void foo() override { cout << "B's foo" << endl; } 16 | virtual void bar() { cout << "B's bar" << endl; } 17 | }; 18 | 19 | class C : public B { 20 | public: 21 | void bar() override { cout << "C's bar" << endl; } 22 | void widget() { cout << "C's widget" << endl; } 23 | }; 24 | 25 | //@include 26 | class D : public B { 27 | public: 28 | void bar() override { cout << "D's bar" << endl; } 29 | }; 30 | 31 | void bad(A* x) { 32 | if (typeid(*x) == typeid(A)) { 33 | x->foo(); 34 | } else if (typeid(*x) == typeid(B) || typeid(*x) == typeid(D)) { 35 | ((B*)x)->foo(); 36 | ((B*)x)->bar(); 37 | } else if (typeid(*x) == typeid(C)) { 38 | ((C*)x)->foo(); 39 | ((C*)x)->bar(); 40 | ((C*)x)->widget(); 41 | } 42 | } 43 | //@exclude 44 | 45 | A* randomBuilder() { 46 | // int r = random()%3; 47 | int r = 3; 48 | if (r == 0) { 49 | return new A(); 50 | } else if (r == 1) { 51 | cout << "returning a B" << endl; 52 | return new B(); 53 | } else if (r == 2) { 54 | return new C(); 55 | } else { 56 | return new D(); 57 | } 58 | } 59 | 60 | int main(int argc, char** argv) { 61 | // Randomly returns a pointer to an A, B, or C type object. 62 | A* x = randomBuilder(); 63 | bad(x); 64 | } 65 | -------------------------------------------------------------------------------- /cpp/checksolutions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | longRunningTests["AddOperators"]="1" 4 | 5 | for javasource in *.java 6 | do 7 | # string substitution syntax from 8 | # http://tldp.org/LDP/abs/html/string-manipulation.html 9 | echo "Processing $javasource" 10 | javac ${javasource%.java}.java > /dev/null 11 | java -ea ${javasource%.java} > /dev/null 12 | if [ "$?" -ne "0" ]; then 13 | echo "TEST FAILURE $javasource" 14 | # exit -1; 15 | fi 16 | done 17 | -------------------------------------------------------------------------------- /cpp/climb-stairs.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::default_random_engine; 11 | using std::endl; 12 | using std::random_device; 13 | using std::stoi; 14 | using std::uniform_int_distribution; 15 | 16 | // @include 17 | int climb_stairs(int n) { 18 | if (n <= 1) { 19 | return 1; 20 | } 21 | 22 | int pre_2 = 1, pre_1 = 1; 23 | for (int i = 2; i <= n; ++i) { 24 | int temp = pre_2 + pre_1; 25 | pre_2 = pre_1; 26 | pre_1 = temp; 27 | } 28 | return pre_1; 29 | } 30 | // @exclude 31 | 32 | int main(int argc, char** argv) { 33 | default_random_engine gen((random_device())()); 34 | int n; 35 | if (argc == 2) { 36 | n = stoi(argv[1]); 37 | } else { 38 | uniform_int_distribution dis(1, 100); 39 | n = dis(gen); 40 | } 41 | cout << climb_stairs(n) << endl; 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /cpp/coin_change.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | 6 | using std::array; 7 | 8 | // @include 9 | int ChangeMaking(int cents) { 10 | const array kCoins = {100, 50, 25, 10, 5, 1}; 11 | int num_coins = 0; 12 | for (int i = 0; i < kCoins.size(); i++) { 13 | num_coins += cents / kCoins[i]; 14 | cents %= kCoins[i]; 15 | } 16 | return num_coins; 17 | } 18 | // @exclude 19 | 20 | int main(int argc, char* argv[]) { 21 | assert(ChangeMaking(100) == 1); 22 | assert(ChangeMaking(101) == 2); 23 | assert(ChangeMaking(68) == 6); 24 | assert(ChangeMaking(13142) == 136); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /cpp/compute_random_permutation.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "./Offline_sampling.h" 10 | 11 | using std::cout; 12 | using std::default_random_engine; 13 | using std::endl; 14 | using std::random_device; 15 | using std::uniform_int_distribution; 16 | using std::vector; 17 | 18 | // @include 19 | vector ComputeRandomPermutation(int n) { 20 | vector permutation(n); 21 | // Initializes permutation to 0, 1, 2, ..., n - 1. 22 | iota(permutation.begin(), permutation.end(), 0); 23 | RandomSampling(permutation.size(), &permutation); 24 | return permutation; 25 | } 26 | // @exclude 27 | 28 | int main(int argc, char* argv[]) { 29 | int n; 30 | default_random_engine gen((random_device())()); 31 | if (argc == 2) { 32 | n = atoi(argv[1]); 33 | } else { 34 | uniform_int_distribution n_dis(1, 1000000); 35 | n = n_dis(gen); 36 | } 37 | cout << n << endl; 38 | auto result = ComputeRandomPermutation(n); 39 | sort(result.begin(), result.end()); 40 | for (int i = 0; i < n; ++i) { 41 | assert(result[i] == i); 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /cpp/count_bits.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using std::bitset; 11 | using std::cout; 12 | using std::default_random_engine; 13 | using std::endl; 14 | using std::numeric_limits; 15 | using std::random_device; 16 | using std::stoul; 17 | using std::uniform_int_distribution; 18 | 19 | // @include 20 | short CountBits(unsigned int x) { 21 | short num_bits = 0; 22 | while (x) { 23 | num_bits += x & 1; 24 | x >>= 1; 25 | } 26 | return num_bits; 27 | } 28 | // @exclude 29 | 30 | int main(int argc, char* argv[]) { 31 | if (argc == 2) { 32 | int x = stoul(argv[1]); 33 | cout << "x = " << x << ", = " << CountBits(x) << endl; 34 | } else { 35 | default_random_engine gen((random_device())()); 36 | for (int times = 0; times < 1000; ++times) { 37 | uniform_int_distribution dis(0, numeric_limits::max()); 38 | int x = dis(gen); 39 | cout << "x = " << x << ", = " << CountBits(x) << endl; 40 | bitset<32> checker(x); 41 | assert(CountBits(x) == checker.count()); 42 | } 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /cpp/defaultconstructor.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Foo { 4 | public: 5 | int readA() { return a; } 6 | Foo() : a(123) {} 7 | 8 | private: 9 | int a; 10 | }; 11 | 12 | int main() { 13 | //@include 14 | Foo x; // x is initialized by the default constructor 15 | //@exclude 16 | assert(x.readA() == 123); 17 | } 18 | -------------------------------------------------------------------------------- /cpp/delete_list.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "./Linked_list_prototype.h" 8 | 9 | using std::make_shared; 10 | using std::shared_ptr; 11 | using std::vector; 12 | 13 | // @include 14 | // Delete the node past this one. Assume node is not a tail. 15 | void DeleteAfter(const shared_ptr>& node) { 16 | node->next = node->next->next; 17 | } 18 | // @exclude 19 | 20 | void CheckAnswer(shared_ptr> L, const vector& vals) { 21 | for (int i = 0; i < vals.size(); ++i) { 22 | assert(L->data == vals[i]); 23 | L = L->next; 24 | } 25 | assert(!L); 26 | } 27 | 28 | int main(int argc, char* argv[]) { 29 | shared_ptr> L; 30 | L = make_shared>(ListNode{ 31 | 2, make_shared>(ListNode{ 32 | 4, make_shared>(ListNode{3, nullptr})})}); 33 | DeleteAfter(L); 34 | CheckAnswer(L, {2, 3}); 35 | DeleteAfter(L); 36 | CheckAnswer(L, {2}); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /cpp/execute-shell.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_EXECUTE_SHELL_H_ 4 | #define SOLUTIONS_EXECUTE_SHELL_H_ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using std::string; 11 | 12 | string execute_shell(const string& cmd) { 13 | FILE* pipe = popen(cmd.c_str(), "r"); 14 | if (!pipe) { 15 | return "ERROR"; 16 | } 17 | char buffer[128]; 18 | string result; 19 | while (!feof(pipe)) { 20 | if (!fgets(buffer, 128, pipe)) { 21 | result += buffer; 22 | } 23 | } 24 | pclose(pipe); 25 | return result; 26 | } 27 | #endif // SOLUTIONS_EXECUTE_SHELL_H_ 28 | -------------------------------------------------------------------------------- /cpp/fibonacci-iterative.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using std::cout; 9 | using std::default_random_engine; 10 | using std::endl; 11 | using std::unordered_map; 12 | using std::random_device; 13 | using std::uniform_int_distribution; 14 | 15 | // @include 16 | int Fibonacci(int n) { 17 | if (n <= 1) { 18 | return n; 19 | } 20 | 21 | int f_minus_2 = 0, f_minus_1 = 1; 22 | for (int i = 2; i <= n; ++i) { 23 | int f = f_minus_2 + f_minus_1; 24 | f_minus_2 = f_minus_1; 25 | f_minus_1 = f; 26 | } 27 | return f_minus_1; 28 | } 29 | // @exclude 30 | 31 | void SmallTest() { 32 | assert(Fibonacci(10) == 55); 33 | assert(Fibonacci(0) == 0); 34 | assert(Fibonacci(1) == 1); 35 | assert(Fibonacci(16) == 987); 36 | assert(Fibonacci(40) == 102334155); 37 | } 38 | 39 | int main(int argc, char* argv[]) { 40 | SmallTest(); 41 | int n; 42 | if (argc == 2) { 43 | n = atoi(argv[1]); 44 | } else { 45 | default_random_engine gen((random_device())()); 46 | uniform_int_distribution n_dis(0, 40); 47 | n = n_dis(gen); 48 | } 49 | cout << "F(" << n << ") = " << Fibonacci(n) << endl; 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /cpp/fibonacci.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using std::cout; 9 | using std::default_random_engine; 10 | using std::endl; 11 | using std::unordered_map; 12 | using std::random_device; 13 | using std::uniform_int_distribution; 14 | 15 | // @include 16 | unordered_map cache; 17 | 18 | int Fibonacci(int n) { 19 | if (n <= 1) { 20 | return n; 21 | } else if (!cache.count(n)) { 22 | cache[n] = Fibonacci(n - 1) + Fibonacci(n - 2); 23 | } 24 | return cache[n]; 25 | } 26 | // @exclude 27 | 28 | void SmallTest() { 29 | assert(Fibonacci(10) == 55); 30 | assert(Fibonacci(0) == 0); 31 | assert(Fibonacci(1) == 1); 32 | assert(Fibonacci(16) == 987); 33 | assert(Fibonacci(40) == 102334155); 34 | } 35 | 36 | int main(int argc, char* argv[]) { 37 | SmallTest(); 38 | int n; 39 | if (argc == 2) { 40 | n = atoi(argv[1]); 41 | } else { 42 | default_random_engine gen((random_device())()); 43 | uniform_int_distribution n_dis(0, 40); 44 | n = n_dis(gen); 45 | } 46 | cout << "F(" << n << ") = " << Fibonacci(n) << endl; 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /cpp/format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script reformats source files using the clang-format utility. 4 | # Set the list of source directories on the "for" line below. 5 | # 6 | # The file .clang-format in this directory specifies the formatting parameters. 7 | # 8 | # Files are changed in-place, so make sure you don't have anything open in an 9 | # editor, and you may want to commit before formatting in case of awryness. 10 | # 11 | # Note that clang-format is not included with OS X or Xcode; you must 12 | # install it yourself. There are multiple ways to do this: 13 | # 14 | # - If you use Xcode, install the ClangFormat-Xcode plugin. See instructions at 15 | # . 16 | # After installation, the executable can be found at 17 | # $HOME/Library/Application Support/Alcatraz/Plug-ins/ClangFormat/bin/clang-format. 18 | # 19 | # - Download an LLVM release from . 20 | # For OS X, use the pre-built binaries for "Darwin". 21 | # 22 | # - Build the LLVM tools from source. See the documentation at . 23 | 24 | # Change this if your clang-format executable is somewhere else 25 | 26 | for DIRECTORY in . 27 | do 28 | echo "Formatting code under $DIRECTORY/" 29 | find "$DIRECTORY" \( -name '*.h' -or -name '*.cc' \) -print0 | xargs -0 "clang-format" -i 30 | done 31 | -------------------------------------------------------------------------------- /cpp/generating-a-b-sqrt2-improved.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_GENERATING_A_B_SQRT2_IMPROVED_H_ 4 | #define SOLUTIONS_GENERATING_A_B_SQRT2_IMPROVED_H_ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "./generating-a-b-sqrt2.h" 11 | 12 | using std::min; 13 | using std::set; 14 | using std::vector; 15 | using GeneratingABSqrt2::ABSqrt2; 16 | 17 | namespace GeneratingABSqrt2Improved { 18 | 19 | // @include 20 | vector GenerateFirstKABSqrt2(int k) { 21 | // Will store the first k numbers of the form a + b sqrt(2). 22 | vector result; 23 | result.emplace_back(0, 0); 24 | int i = 0, j = 0; 25 | for (int n = 1; n < k; ++n) { 26 | ABSqrt2 result_i_plus_1(result[i].a + 1, result[i].b); 27 | ABSqrt2 result_j_plus_sqrt2(result[j].a, result[j].b + 1); 28 | result.emplace_back(min(result_i_plus_1, result_j_plus_sqrt2)); 29 | if (result_i_plus_1.val == result.back().val) { 30 | ++i; 31 | } 32 | if (result_j_plus_sqrt2.val == result.back().val) { 33 | ++j; 34 | } 35 | } 36 | return result; 37 | } 38 | // @exclude 39 | 40 | } // namespace GeneratingABSqrt2Improved 41 | 42 | #endif // SOLUTIONS_GENERATING_A_B_SQRT2_IMPROVED_H_ 43 | -------------------------------------------------------------------------------- /cpp/generating-a-b-sqrt2.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_GENERATING_A_B_SQRT2_H_ 4 | #define SOLUTIONS_GENERATING_A_B_SQRT2_H_ 5 | 6 | #include 7 | #include 8 | 9 | using std::set; 10 | using std::vector; 11 | 12 | namespace GeneratingABSqrt2 { 13 | 14 | // These numbers have very interesting property, and people called it ugly 15 | // numbers. It is also called Quadratic integer rings. 16 | // @include 17 | struct ABSqrt2 { 18 | ABSqrt2(int a, int b) : a(a), b(b), val(a + b * sqrt(2)) {} 19 | 20 | bool operator<(const ABSqrt2& that) const { return val < that.val; } 21 | 22 | int a, b; 23 | double val; 24 | }; 25 | 26 | vector GenerateFirstKABSqrt2(int k) { 27 | set candidates; 28 | // Initial for 0 + 0 * sqrt(2). 29 | candidates.emplace(0, 0); 30 | 31 | vector result; 32 | while (result.size() < k) { 33 | auto next_smallest = candidates.cbegin(); 34 | result.emplace_back(*next_smallest); 35 | 36 | // Adds the next two numbers derived from next_smallest. 37 | candidates.emplace(next_smallest->a + 1, next_smallest->b); 38 | candidates.emplace(next_smallest->a, next_smallest->b + 1); 39 | candidates.erase(next_smallest); 40 | } 41 | return result; 42 | } 43 | // @exclude 44 | 45 | } // namespace GeneratingABSqrt2 46 | 47 | #endif // SOLUTIONS_GENERATING_A_B_SQRT2_H_ 48 | -------------------------------------------------------------------------------- /cpp/goodrtti.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | 8 | class A { 9 | public: 10 | virtual void foo() { cout << "A's foo" << endl; } 11 | }; 12 | 13 | class B : public A { 14 | public: 15 | void foo() override { cout << "B's foo" << endl; } 16 | virtual void bar() { cout << "B's bar" << endl; } 17 | }; 18 | 19 | class C : public B { 20 | public: 21 | void bar() override { cout << "C's bar" << endl; } 22 | void widget() { cout << "C's widget" << endl; } 23 | }; 24 | 25 | class D : public B { 26 | public: 27 | void bar() override { cout << "D's bar" << endl; } 28 | }; 29 | 30 | //@include 31 | void good(A* x) { 32 | x->foo(); 33 | // Objects of type D can be cast to a B, so the call below is to D's bar(). 34 | B* p = dynamic_cast(x); 35 | if (p) { 36 | p->bar(); 37 | } 38 | C* q = dynamic_cast(x); 39 | if (q) { 40 | q->widget(); 41 | } 42 | } 43 | //@exclude 44 | 45 | A* randomBuilder() { 46 | // int r = random()%3; 47 | int r = 3; 48 | if (r == 0) { 49 | return new A(); 50 | } else if (r == 1) { 51 | cout << "returning a B" << endl; 52 | return new B(); 53 | } else if (r == 2) { 54 | return new C(); 55 | } else { 56 | return new D(); 57 | } 58 | } 59 | 60 | int main(int argc, char** argv) { 61 | /* 62 | ... 63 | */ 64 | // Randomly returns a pointer to an A, B, or C type object. 65 | A* x = randomBuilder(); 66 | good(x); 67 | } 68 | -------------------------------------------------------------------------------- /cpp/inlineexample.cc: -------------------------------------------------------------------------------- 1 | //@include 2 | inline bool isvowel(char c) { 3 | return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'); 4 | } 5 | //@exclude 6 | 7 | int main(int argc, char** argv) { isvowel('a'); } 8 | -------------------------------------------------------------------------------- /cpp/insert_list.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "./Linked_list_prototype.h" 8 | 9 | using std::make_shared; 10 | using std::shared_ptr; 11 | using std::vector; 12 | 13 | // @include 14 | // Insert new_node after node. 15 | void InsertAfter(const shared_ptr>& node, 16 | const shared_ptr>& new_node) { 17 | new_node->next = node->next; 18 | node->next = new_node; 19 | } 20 | // @exclude 21 | 22 | void CheckAnswer(shared_ptr> L, const vector& vals) { 23 | for (int i = 0; i < vals.size(); ++i) { 24 | assert(L->data == vals[i]); 25 | L = L->next; 26 | } 27 | assert(!L); 28 | } 29 | 30 | int main(int argc, char* argv[]) { 31 | shared_ptr> L; 32 | L = make_shared>(ListNode{ 33 | 2, make_shared>(ListNode{ 34 | 4, make_shared>(ListNode{3, nullptr})})}); 35 | InsertAfter(L, make_shared>(ListNode{1, nullptr})); 36 | CheckAnswer(L, {2, 1, 4, 3}); 37 | InsertAfter(L->next->next, 38 | make_shared>(ListNode{10, nullptr})); 39 | CheckAnswer(L, {2, 1, 4, 10, 3}); 40 | InsertAfter(L->next->next->next->next, 41 | make_shared>(ListNode{-1, nullptr})); 42 | CheckAnswer(L, {2, 1, 4, 10, 3, -1}); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /cpp/is_palindromic.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using std::default_random_engine; 8 | using std::random_device; 9 | using std::string; 10 | using std::uniform_int_distribution; 11 | 12 | // @include 13 | bool IsPalindromic(const string& s) { 14 | for (int i = 0, j = s.size() - 1; i < j; ++i, --j) { 15 | if (s[i] != s[j]) { 16 | return false; 17 | } 18 | } 19 | return true; 20 | } 21 | // @exclude 22 | 23 | bool CheckAnswer(const string& s) { 24 | string copy(s); 25 | reverse(copy.begin(), copy.end()); 26 | return s == copy; 27 | } 28 | 29 | string RandString(int len) { 30 | default_random_engine gen((random_device())()); 31 | string ret; 32 | while (len--) { 33 | uniform_int_distribution dis('a', 'z'); 34 | ret += dis(gen); 35 | } 36 | return ret; 37 | } 38 | 39 | int main(int argc, char** argv) { 40 | default_random_engine gen((random_device())()); 41 | for (int times = 0; times < 10000; ++times) { 42 | uniform_int_distribution dis(1, 1000); 43 | string s = RandString(dis(gen)); 44 | assert(IsPalindromic(s) == CheckAnswer(s)); 45 | } 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /cpp/jump-game-min-steps.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using std::cout; 11 | using std::default_random_engine; 12 | using std::endl; 13 | using std::max; 14 | using std::random_device; 15 | using std::stoul; 16 | using std::uniform_int_distribution; 17 | using std::vector; 18 | 19 | // @include 20 | int jump(const vector& A) { 21 | int step = 0, last_reach = 0, reach = 0; 22 | for (int i = 0; i < A.size(); ++i) { 23 | if (i > last_reach) { 24 | last_reach = reach, ++step; 25 | } 26 | reach = max(reach, i + A[i]); 27 | } 28 | return step; 29 | } 30 | // @exclude 31 | 32 | void small_test() { 33 | vector A1 = {2, 3, 1, 1, 4}; 34 | assert(2 == jump(A1)); 35 | vector A2 = {3, 1, 4, 1, 1, 1}; 36 | assert(2 == jump(A2)); 37 | } 38 | 39 | int main(int argc, char** argv) { 40 | small_test(); 41 | return 0; 42 | default_random_engine gen((random_device())()); 43 | size_t n; 44 | if (argc == 2) { 45 | n = stoul(argv[1]); 46 | } else { 47 | uniform_int_distribution dis(1, 1000); 48 | n = dis(gen); 49 | } 50 | uniform_int_distribution A_dis(1, 10); 51 | vector A; 52 | generate_n(back_inserter(A), n, [&] { return A_dis(gen); }); 53 | cout << jump(A) << endl; 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /cpp/lazy-init.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | 9 | // @include 10 | template 11 | class Array { 12 | public: 13 | bool read(size_t i, ValueType* v) const { 14 | if (isValid(i)) { 15 | *v = A_[i]; 16 | return true; 17 | } 18 | return false; 19 | } 20 | 21 | void write(size_t i, const ValueType& v) { 22 | if (!isValid(i)) { 23 | S_[t_] = i; 24 | P_[i] = t_++; 25 | } 26 | A_[i] = v; 27 | } 28 | 29 | private: 30 | bool isValid(size_t i) const { 31 | return (0 <= P_[i] && P_[i] < t_ && S_[P_[i]] == i); 32 | } 33 | 34 | ValueType A_[N]; 35 | int P_[N], S_[N], t_ = 0; 36 | }; 37 | // @exclude 38 | 39 | int main(int argc, char* argv[]) { 40 | Array A; 41 | int x; 42 | assert(A.read(0, &x) == false); 43 | assert(A.read(1, &x) == false); 44 | A.write(1, 5); 45 | assert(A.read(1, &x) == true && x == 5); 46 | assert(A.read(2, &x) == false); 47 | A.write(2, 27); 48 | assert(A.read(2, &x) == true && x == 27); 49 | assert(A.read(7, &x) == false); 50 | A.write(7, -19); 51 | assert(A.read(7, &x) == true && x == -19); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /cpp/magic-maze-game.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_MAGIC_MAZE_GAME_H_ 4 | #define SOLUTIONS_MAGIC_MAZE_GAME_H_ 5 | 6 | #include "./maze-game.h" 7 | 8 | class MagicRoom : public Room { 9 | public: 10 | virtual ~MagicRoom() override = default; 11 | 12 | void Connect(const Room* that) override {} 13 | }; 14 | 15 | // @include 16 | class MagicMazeGameCreator : public MazeGameCreator { 17 | // @exclude 18 | public: 19 | virtual ~MagicMazeGameCreator() override = default; 20 | // @include 21 | Room* MakeRoom() override { return new MagicRoom(); } 22 | }; 23 | // @exclude 24 | 25 | #endif // SOLUTIONS_MAGIC_MAZE_GAME_H_ 26 | -------------------------------------------------------------------------------- /cpp/magic_maze_game.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_MAGIC_MAZE_GAME_H_ 4 | #define SOLUTIONS_MAGIC_MAZE_GAME_H_ 5 | 6 | #include "./maze_game.h" 7 | 8 | class MagicRoom : public Room { 9 | public: 10 | virtual ~MagicRoom() override = default; 11 | 12 | void Connect(const Room* that) override {} 13 | }; 14 | 15 | // @include 16 | class MagicMazeGameCreator : public MazeGameCreator { 17 | // @exclude 18 | public: 19 | virtual ~MagicMazeGameCreator() override = default; 20 | // @include 21 | Room* MakeRoom() override { return new MagicRoom(); } 22 | }; 23 | // @exclude 24 | 25 | #endif // SOLUTIONS_MAGIC_MAZE_GAME_H_ 26 | -------------------------------------------------------------------------------- /cpp/mapupdate1.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "Point.h" 6 | 7 | using std::cout; 8 | using std::hash; 9 | using std::string; 10 | using std::endl; 11 | using std::unordered_map; 12 | 13 | int main(int argc, char** argv) { 14 | // @include 15 | // Attempt 1 16 | unordered_map table; 17 | Point p{1, 2}; 18 | table[p] = "Minkowski"; 19 | p.x = 3; 20 | // @exclude 21 | } 22 | -------------------------------------------------------------------------------- /cpp/mapupdate2.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "Point.h" 6 | 7 | using std::cout; 8 | using std::hash; 9 | using std::string; 10 | using std::endl; 11 | using std::unordered_map; 12 | 13 | int main(int argc, char** argv) { 14 | // @include 15 | // Attempt 2 16 | unordered_map table; 17 | Point p{1, 2}; 18 | table[p] = "Minkowski"; 19 | auto iter = table.find(p); 20 | iter->first.x = 3; 21 | // @exclude 22 | } 23 | -------------------------------------------------------------------------------- /cpp/mapupdate3.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::cout; 6 | using std::hash; 7 | using std::string; 8 | using std::endl; 9 | using std::unordered_map; 10 | 11 | #include "Point.h" 12 | 13 | using std::unordered_map; 14 | 15 | int main(int argc, char** argv) { 16 | // @include 17 | Point p(1, 2); 18 | unordered_map table; 19 | table[p] = "Minkowski"; 20 | auto val = table[p]; 21 | table.erase(p); 22 | p.x = 4; 23 | table[p] = val; 24 | // @exclude 25 | } 26 | -------------------------------------------------------------------------------- /cpp/mapupdate4.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::cout; 6 | using std::hash; 7 | using std::string; 8 | using std::endl; 9 | using std::unordered_map; 10 | 11 | #include "Point.h" 12 | 13 | using std::unordered_map; 14 | 15 | int main(int argc, char** argv) { 16 | // @include 17 | Point p(1, 2); 18 | unordered_map table; 19 | table[p] = "Minkowski"; 20 | auto it = table.find(p); 21 | p.x = 4; 22 | std::swap(table[p], it->second); 23 | table.erase(it); 24 | // @exclude 25 | } 26 | -------------------------------------------------------------------------------- /cpp/mapupdate5.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::cout; 6 | using std::hash; 7 | using std::string; 8 | using std::endl; 9 | using std::unordered_map; 10 | 11 | #include "Point.h" 12 | 13 | using std::unordered_map; 14 | 15 | int main(int argc, char** argv) { 16 | // @include 17 | Point p(1, 2); 18 | unordered_map table; 19 | table[p] = "Minkowski"; 20 | auto it = table.find(p); 21 | p.x = 4; 22 | table[p] = std::move(it->second); 23 | table.erase(it); 24 | // @exclude 25 | } 26 | -------------------------------------------------------------------------------- /cpp/maze-game-main.cc: -------------------------------------------------------------------------------- 1 | #include "./magic-maze-game.h" 2 | #include "./maze-game.h" 3 | #include "./ordinary-maze-game.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | // @include 7 | MazeGame* ordinaryMazeGame = 8 | (new OrdinaryMazeGameCreator())->FactoryMethod(); 9 | MazeGame* magicMazeGame = (new MagicMazeGameCreator())->FactoryMethod(); 10 | // @exclude 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /cpp/maze-game.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_MAZE_GAME_H_ 4 | #define SOLUTIONS_MAZE_GAME_H_ 5 | 6 | #include 7 | #include 8 | 9 | using std::vector; 10 | using std::cout; 11 | 12 | class Room { 13 | public: 14 | virtual ~Room() = default; 15 | 16 | virtual void Connect(const Room* that) = 0; 17 | }; 18 | 19 | class MazeGame { 20 | public: 21 | void AddRoom(const Room* that) { rooms.push_back(that); } 22 | 23 | private: 24 | vector rooms; 25 | }; 26 | 27 | // @include 28 | class MazeGameCreator { 29 | public: 30 | virtual Room* MakeRoom() = 0; 31 | // @exclude 32 | virtual ~MazeGameCreator() = default; 33 | // @include 34 | // This factory method is a template method for creating MazeGame objects. 35 | // MazeGameCreator's subclasses implement MakeRoom() as appropriate for 36 | // the type of room being created. 37 | MazeGame* FactoryMethod() { 38 | MazeGame* mazeGame = new MazeGame(); 39 | Room* room1 = MakeRoom(); 40 | Room* room2 = MakeRoom(); 41 | room1->Connect(room2); 42 | mazeGame->AddRoom(room1); 43 | mazeGame->AddRoom(room2); 44 | return mazeGame; 45 | } 46 | }; 47 | // @exclude 48 | 49 | #endif // SOLUTIONS_MAZE_GAME_H_ 50 | -------------------------------------------------------------------------------- /cpp/maze_game.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_MAZE_GAME_H_ 4 | #define SOLUTIONS_MAZE_GAME_H_ 5 | 6 | #include 7 | #include 8 | 9 | using std::vector; 10 | using std::cout; 11 | 12 | class Room { 13 | public: 14 | virtual ~Room() = default; 15 | 16 | virtual void Connect(const Room* that) = 0; 17 | }; 18 | 19 | class MazeGame { 20 | public: 21 | void AddRoom(const Room* that) { rooms.push_back(that); } 22 | 23 | private: 24 | vector rooms; 25 | }; 26 | 27 | // @include 28 | class MazeGameCreator { 29 | public: 30 | virtual Room* MakeRoom() = 0; 31 | // @exclude 32 | virtual ~MazeGameCreator() = default; 33 | // @include 34 | // This factory method is a template method for creating MazeGame objects. 35 | // MazeGameCreator's subclasses implement MakeRoom() as appropriate for 36 | // the type of room being created. 37 | MazeGame* FactoryMethod() { 38 | MazeGame* mazeGame = new MazeGame(); 39 | Room* room1 = MakeRoom(); 40 | Room* room2 = MakeRoom(); 41 | room1->Connect(room2); 42 | mazeGame->AddRoom(room1); 43 | mazeGame->AddRoom(room2); 44 | return mazeGame; 45 | } 46 | }; 47 | // @exclude 48 | 49 | #endif // SOLUTIONS_MAZE_GAME_H_ 50 | -------------------------------------------------------------------------------- /cpp/maze_game_main.cc: -------------------------------------------------------------------------------- 1 | #include "./magic_maze_game.h" 2 | #include "./maze_game.h" 3 | #include "./ordinary_maze_game.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | // @include 7 | MazeGame* ordinaryMazeGame = 8 | (new OrdinaryMazeGameCreator())->FactoryMethod(); 9 | MazeGame* magicMazeGame = (new MagicMazeGameCreator())->FactoryMethod(); 10 | // @exclude 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /cpp/minmaxtemplate.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // @include 4 | template 5 | void minmax(T& x, T& y) { 6 | if (x > y) { 7 | T tmp = x; 8 | x = y; 9 | y = tmp; 10 | } 11 | } 12 | // @exclude 13 | 14 | int main(int argc, char** argv) { 15 | int x = 20; 16 | int y = 10; 17 | minmax(x, y); 18 | assert(x == 10 && y == 20); 19 | } 20 | -------------------------------------------------------------------------------- /cpp/minmaxtemplatemove.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // @include 5 | template 6 | void minmax(T& x, T& y) { 7 | if (x > y) { 8 | T tmp = std::move(x); 9 | x = std::move(y); 10 | y = std::move(tmp); 11 | // Alternative: call std::swap(x, y) 12 | } 13 | } 14 | // @exclude 15 | 16 | int main(int argc, char** argv) { 17 | int x = 20; 18 | int y = 10; 19 | std::cout << x << std::endl; 20 | std::cout << y << std::endl; 21 | minmax(x, y); 22 | std::cout << x << std::endl; 23 | std::cout << y << std::endl; 24 | assert(x == 10 && y == 20); 25 | } 26 | -------------------------------------------------------------------------------- /cpp/nnChomp.pseudo: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | // @include 4 | WinChomp(): 5 | You choose square (1,1); 6 | Until you win: 7 | Wait for your opponent to choose square (i,j); 8 | You choose square (j,i); 9 | // @exclude 10 | -------------------------------------------------------------------------------- /cpp/ordinary-maze-game.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_ORDINARY_MAZE_GAME_H_ 4 | #define SOLUTIONS_ORDINARY_MAZE_GAME_H_ 5 | 6 | #include "./maze-game.h" 7 | 8 | class OrdinaryRoom : public Room { 9 | public: 10 | virtual ~OrdinaryRoom() override = default; 11 | 12 | void Connect(const Room* that) override {} 13 | }; 14 | 15 | // @include 16 | class OrdinaryMazeGameCreator : public MazeGameCreator { 17 | // @exclude 18 | public: 19 | virtual ~OrdinaryMazeGameCreator() override = default; 20 | // @include 21 | Room* MakeRoom() override { return new OrdinaryRoom(); } 22 | }; 23 | // @exclude 24 | 25 | #endif // SOLUTIONS_ORDINARY_MAZE_GAME_H_ 26 | -------------------------------------------------------------------------------- /cpp/ordinary_maze_game.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_ORDINARY_MAZE_GAME_H_ 4 | #define SOLUTIONS_ORDINARY_MAZE_GAME_H_ 5 | 6 | #include "./maze_game.h" 7 | 8 | class OrdinaryRoom : public Room { 9 | public: 10 | virtual ~OrdinaryRoom() override = default; 11 | 12 | void Connect(const Room* that) override {} 13 | }; 14 | 15 | // @include 16 | class OrdinaryMazeGameCreator : public MazeGameCreator { 17 | // @exclude 18 | public: 19 | virtual ~OrdinaryMazeGameCreator() override = default; 20 | // @include 21 | Room* MakeRoom() override { return new OrdinaryRoom(); } 22 | }; 23 | // @exclude 24 | 25 | #endif // SOLUTIONS_ORDINARY_MAZE_GAME_H_ 26 | -------------------------------------------------------------------------------- /cpp/passbyvaluebug.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::array; 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main(int argc, char** argv) { 10 | //@include 11 | class Buffer { 12 | public: 13 | Buffer(int size, int* buffer) : size(size), buffer(buffer) {} 14 | 15 | int size; 16 | int* buffer; 17 | }; 18 | 19 | const int kBufSize = 2; 20 | int* buffer = new int[kBufSize]{1, 2}; 21 | 22 | Buffer b1 = Buffer(kBufSize, buffer); 23 | cout << b1.buffer[0] << endl; 24 | 25 | Buffer b2 = b1; 26 | b2.buffer[0] = -2; 27 | cout << b1.buffer[0] << endl; 28 | //@exclude 29 | assert(b1.buffer[0] == b2.buffer[0]); 30 | } 31 | -------------------------------------------------------------------------------- /cpp/polymorphismproblems.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::string; 5 | using std::cout; 6 | using std::endl; 7 | 8 | //@include 9 | class Base { 10 | public: 11 | virtual string msg() { return "I am base"; } 12 | }; 13 | 14 | class Child : public Base { 15 | public: 16 | virtual string msg() { return "I am child"; } 17 | }; 18 | 19 | void cast(Base x) { cout << x.msg() << endl; } 20 | 21 | int main() { 22 | Base f; 23 | Child b; 24 | cast(f); 25 | cast(b); 26 | } 27 | //@exclude 28 | -------------------------------------------------------------------------------- /cpp/polymorphismproblemsfixed.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::string; 5 | using std::cout; 6 | using std::endl; 7 | 8 | class Base { 9 | public: 10 | virtual string msg() { return "I am base"; } 11 | }; 12 | 13 | class Child : public Base { 14 | public: 15 | virtual string msg() { return "I am child"; } 16 | }; 17 | 18 | //@include 19 | void cast(Base& x) { cout << x.msg() << endl; } 20 | //@exclude 21 | 22 | int main(int argc, char** argv) { 23 | Base f; 24 | Child b; 25 | cast(f); 26 | cast(b); 27 | } 28 | -------------------------------------------------------------------------------- /cpp/ppp.sh: -------------------------------------------------------------------------------- 1 | javac -cp /usr/share/java/junit.jar:. PPP.java PPPTest.java 2 | java -cp /usr/share/java/junit.jar:. org.junit.runner.JUnitCore PPPTest 3 | 4 | -------------------------------------------------------------------------------- /cpp/print_linked_list_reverse_order.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "./Linked_list_prototype.h" 9 | 10 | using std::cout; 11 | using std::endl; 12 | using std::make_shared; 13 | using std::shared_ptr; 14 | using std::stack; 15 | 16 | // @include 17 | void PrintLinkedListInReverse(shared_ptr> head) { 18 | stack nodes; 19 | while (head) { 20 | nodes.push(head->data); 21 | head = head->next; 22 | } 23 | while (!nodes.empty()) { 24 | cout << nodes.top() << endl; 25 | nodes.pop(); 26 | } 27 | } 28 | // @exclude 29 | 30 | int main(int argc, char* argv[]) { 31 | PrintLinkedListInReverse(make_shared>(ListNode{ 32 | 1, make_shared>(ListNode{ 33 | 2, make_shared>(ListNode{3, nullptr})})})); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /cpp/roman-to-integer.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::endl; 11 | using std::string; 12 | using std::unordered_map; 13 | 14 | // @include 15 | int RomanToInteger(const string& s) { 16 | unordered_map T = {{'I', 1}, {'V', 5}, {'X', 10}, {'L', 50}, 17 | {'C', 100}, {'D', 500}, {'M', 1000}}; 18 | 19 | int sum = T[s.back()]; 20 | for (int i = s.length() - 2; i >= 0; --i) { 21 | if (T[s[i]] < T[s[i + 1]]) { 22 | sum -= T[s[i]]; 23 | } else { 24 | sum += T[s[i]]; 25 | } 26 | } 27 | return sum; 28 | } 29 | // @exclude 30 | 31 | int main(int argc, char** argv) { 32 | assert(7 == RomanToInteger("VII")); 33 | assert(184 == RomanToInteger("CLXXXIV")); 34 | assert(9 == RomanToInteger("IX")); 35 | assert(40 == RomanToInteger("XL")); 36 | assert(60 == RomanToInteger("LX")); 37 | assert(1500 == RomanToInteger("MD")); 38 | assert(400 == RomanToInteger("CD")); 39 | assert(1900 == RomanToInteger("MCM")); 40 | assert(9919 == RomanToInteger("MMMMMMMMMCMXIX")); 41 | if (argc == 2) { 42 | cout << argv[1] << " equals to " << RomanToInteger(argv[1]) << endl; 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /cpp/search_list.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | 6 | #include "./Linked_list_prototype.h" 7 | 8 | using std::make_shared; 9 | using std::shared_ptr; 10 | 11 | // @include 12 | shared_ptr> SearchList(shared_ptr> L, int key) { 13 | while (L && L->data != key) { 14 | L = L->next; 15 | } 16 | // If key was not present in the list, L will have become null. 17 | return L; 18 | } 19 | // @exclude 20 | 21 | int main(int argc, char* argv[]) { 22 | shared_ptr> L; 23 | L = make_shared>(ListNode{ 24 | 2, make_shared>(ListNode{ 25 | 4, make_shared>(ListNode{3, nullptr})})}); 26 | assert(L == SearchList(L, 2)); 27 | assert(L->next == SearchList(L, 4)); 28 | assert(L->next->next == SearchList(L, 3)); 29 | assert(nullptr == SearchList(L, 100)); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /cpp/simple_web_server.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | using boost::system::error_code; 9 | namespace asio = boost::asio; 10 | using asio::ip::tcp; 11 | 12 | void ProcessReq(tcp::socket& sock) { 13 | asio::streambuf sb; 14 | while (true) { 15 | error_code e; 16 | size_t n = asio::read_until(sock, sb, '\n', e); 17 | if (e == asio::error::eof) { 18 | cout << endl << "connection closed" << endl; 19 | break; 20 | } 21 | asio::write(sock, sb.data()); 22 | cout << &sb; 23 | } 24 | } 25 | 26 | // @include 27 | const unsigned short SERVERPORT = 8080; 28 | 29 | int main(int argc, char* argv[]) { 30 | asio::io_service io_service; 31 | tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), SERVERPORT)); 32 | while (true) { 33 | tcp::socket sock(io_service); 34 | acceptor.accept(sock); 35 | ProcessReq(sock); 36 | } 37 | return 0; 38 | } 39 | // @exclude 40 | -------------------------------------------------------------------------------- /cpp/smartpointers.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::make_shared; 4 | using std::shared_ptr; 5 | 6 | int main(int argc, char** argv) { 7 | struct Cycle2; 8 | 9 | // @include 10 | struct Cycle1 { 11 | shared_ptr next; 12 | }; 13 | 14 | struct Cycle2 { 15 | shared_ptr next; 16 | }; 17 | 18 | auto head = make_shared(); // head's reference count is now 1. 19 | auto tail = make_shared(); // tail's reference count is now 1. 20 | head->next = tail; // tail's reference count is now 2. 21 | tail->next = head; // head's reference count is now 2. 22 | // On destruction of head and tail, the reference counts go to 1 and stay 23 | // there. 24 | // @exclude 25 | } 26 | -------------------------------------------------------------------------------- /cpp/spell.sh: -------------------------------------------------------------------------------- 1 | #!/bin/tcsh 2 | foreach f (`ls *.cpp *.cc *.h`) 3 | echo $f 4 | cat $f | aspell --mode=ccpp --personal=./c++.aspell.en.pws list | sort | uniq -c 5 | # cat epi.tex | aspell --mode=tex --personal=./epi.aspell.en.pws list | sort | uniq -c 6 | end 7 | # use something like this to examine report: 8 | # cat solutions.spell_report | awk '{print $2}' | sort | uniq -c | sort -nr |less 9 | -------------------------------------------------------------------------------- /cpp/student_search.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using std::binary_search; 10 | using std::function; 11 | using std::sort; 12 | using std::string; 13 | using std::vector; 14 | 15 | // @include 16 | struct Student { 17 | string name; 18 | double grade_point_average; 19 | }; 20 | 21 | const static function CompGPA = []( 22 | const Student& a, const Student& b) { 23 | if (a.grade_point_average != b.grade_point_average) { 24 | return a.grade_point_average > b.grade_point_average; 25 | } 26 | return a.name < b.name; 27 | }; 28 | 29 | bool SearchStudent( 30 | const vector& students, const Student& target, 31 | const function& comp_GPA) { 32 | return binary_search(students.begin(), students.end(), target, comp_GPA); 33 | } 34 | // @exclude 35 | 36 | int main(int argc, char* argv[]) { 37 | vector students = {{"A", 4.0}, {"C", 3.0}, {"B", 2.0}, {"D", 3.2}}; 38 | sort(students.begin(), students.end(), CompGPA); 39 | assert(SearchStudent(students, {"A", 4.0}, CompGPA)); 40 | assert(!SearchStudent(students, {"A", 3.0}, CompGPA)); 41 | assert(!SearchStudent(students, {"B", 3.0}, CompGPA)); 42 | assert(SearchStudent(students, {"D", 3.2}, CompGPA)); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /cpp/student_sort.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using std::sort; 9 | using std::string; 10 | using std::vector; 11 | 12 | // @include 13 | struct Student { 14 | bool operator<(const Student& that) const { return name < that.name; } 15 | 16 | string name; 17 | double grade_point_average; 18 | }; 19 | 20 | void SortByGPA(vector* students) { 21 | sort(students->begin(), students->end(), 22 | [](const Student& a, const Student& b) { 23 | return a.grade_point_average >= b.grade_point_average; 24 | }); 25 | } 26 | 27 | void SortByName(vector* students) { 28 | // Rely on the operator< defined in Student. 29 | sort(students->begin(), students->end()); 30 | } 31 | // @exclude 32 | 33 | int main(int argc, char* argv[]) { 34 | vector students = {{"A", 4.0}, {"C", 3.0}, {"B", 2.0}, {"D", 3.2}}; 35 | SortByName(&students); 36 | assert(is_sorted(students.begin(), students.end())); 37 | SortByGPA(&students); 38 | assert(is_sorted(students.begin(), students.end(), 39 | [](const Student& a, const Student& b) { 40 | return a.grade_point_average >= b.grade_point_average; 41 | })); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /cpp/swap_bits.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "./swap_bits.h" 9 | 10 | using std::cout; 11 | using std::default_random_engine; 12 | using std::endl; 13 | using std::numeric_limits; 14 | using std::random_device; 15 | using std::uniform_int_distribution; 16 | 17 | void SimpleTest() { 18 | assert(SwapBits(47, 1, 4) == 61); 19 | assert(SwapBits(28, 0, 2) == 25); 20 | } 21 | 22 | int main(int argc, char *argv[]) { 23 | SimpleTest(); 24 | default_random_engine gen((random_device())()); 25 | long x; 26 | int i, j; 27 | if (argc == 4) { 28 | x = atol(argv[1]), i = atoi(argv[2]), j = atoi(argv[3]); 29 | } else { 30 | uniform_int_distribution dis(0, numeric_limits::max()); 31 | x = dis(gen); 32 | uniform_int_distribution digit_dis(0, 63); 33 | i = digit_dis(gen), j = digit_dis(gen); 34 | } 35 | cout << "x = " << x << ", i = " << i << ", j = " << j << endl; 36 | cout << SwapBits(x, i, j) << endl; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /cpp/swap_bits.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_SWAP_BITS_H_ 4 | #define SOLUTIONS_SWAP_BITS_H_ 5 | 6 | // @include 7 | long SwapBits(long x, int i, int j) { 8 | // Extract the i-th and j-th bits, and see if they differ. 9 | if (((x >> i) & 1) != ((x >> j) & 1)) { 10 | // i-th and j-th bits differ. We will swap them by flipping their values. 11 | // Select the bits to flip with bitMask. Since x^1 = 0 when x = 1 and 1 12 | // when x = 0, we can perform the flip XOR. 13 | unsigned long bit_mask = (1L << i) | (1L << j); 14 | x ^= bit_mask; 15 | } 16 | return x; 17 | } 18 | // @exclude 19 | #endif // SOLUTIONS_SWAP_BITS_H_ 20 | -------------------------------------------------------------------------------- /cpp/test_toolkit/dummy.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Created by metopa on 04.04.2016. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /cpp/test_toolkit/grammatical-printer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef SOLUTIONS_GRAMMATICAL_PRINTER_H 4 | #define SOLUTIONS_GRAMMATICAL_PRINTER_H 5 | 6 | //FIXME Better name 7 | 8 | template 9 | class GrammaticalPrinter { 10 | public: 11 | GrammaticalPrinter( const Value& value, const String1& singular, const String2& plural ) : 12 | value_( value ), singular_( singular ), plural_( plural ) { } 13 | 14 | friend ostream& operator <<( ostream& out, const GrammaticalPrinter& p ) { 15 | if ( p.value_ == 1 ) 16 | return out << p.value_ << p.singular_; 17 | else 18 | return out << p.value_ << p.plural_; 19 | } 20 | private: 21 | const Value& value_; 22 | const String1& singular_; 23 | const String2& plural_; 24 | }; 25 | 26 | template 27 | GrammaticalPrinter 28 | grammaticalPrinter( const Value& value, const String1& singular, const String2& plural ) { 29 | return GrammaticalPrinter( value, singular, plural ); 30 | } 31 | 32 | #endif //SOLUTIONS_GRAMMATICAL_PRINTER_H 33 | -------------------------------------------------------------------------------- /cpp/test_toolkit/json-writer-test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "json-writer.h" 10 | 11 | using namespace std; 12 | 13 | int main() { 14 | stringstream ss; 15 | 16 | printer::print(ss, -10); 17 | assert(ss.str() == "-10"); 18 | ss.str(""); 19 | 20 | printer::print(ss, 10.25); 21 | assert(ss.str() == "10.25"); 22 | ss.str(""); 23 | 24 | printer::print(ss, "Escaped string \\ \" \t \n"); 25 | assert(ss.str() == "\"Escaped string \\\\ \\\" \\t \\n\""); 26 | ss.str(""); 27 | 28 | vector> v; 29 | v.push_back({1, 2, 3}); 30 | v.push_back({}); 31 | printer::print(ss, v); 32 | 33 | assert(ss.str() == "[[1, 2, 3], []]"); 34 | ss.str(""); 35 | 36 | map> m; 37 | m["a"] = {false}; 38 | m["b\n"] = {true, false}; 39 | m["b"] = {}; 40 | printer::print(ss, m); 41 | assert(ss.str() == "[{\"a\": [false]}, {\"b\": []}, {\"b\\n\": [false, true]}]"); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /cpp/test_toolkit/main_def.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Elements of Programming Interviews. All rights reserved. 2 | 3 | #ifndef MAIN_FUNC 4 | #ifdef EPI_TEST_TOOLKIT 5 | #define EPI_MERGE_(a,b) a##b 6 | #define EPI_LABEL_(a) EPI_MERGE_(_main_, a) 7 | #define MAIN_FUNC EPI_LABEL_(__COUNTER__) 8 | #else 9 | #define MAIN_FUNC main 10 | #endif 11 | #endif 12 | -------------------------------------------------------------------------------- /cpp/test_toolkit/signal-handler.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by metopa on 22.02.2016. 3 | // 4 | 5 | #ifndef SOLUTIONS_SIGNALHANDLER_H 6 | #define SOLUTIONS_SIGNALHANDLER_H 7 | 8 | #include 9 | #include 10 | 11 | typedef void (*sig_handler_func)(int); 12 | 13 | template 14 | class SignalHandler { 15 | public: 16 | SignalHandler(T *functor) { 17 | functor_ = functor; 18 | old_callback_ = std::signal(SigNum, Callback); 19 | } 20 | ~SignalHandler() { 21 | functor_ = nullptr; 22 | std::signal(SigNum, old_callback_); 23 | } 24 | private: 25 | static void Callback(int signum) { 26 | if (functor_) 27 | (*functor_)(signum); 28 | } 29 | static T *functor_; 30 | sig_handler_func old_callback_; 31 | }; 32 | 33 | template T *SignalHandler::functor_ = nullptr; 34 | 35 | template 36 | SignalHandler SetSignalHandler(T *functor) { 37 | return SignalHandler(functor); 38 | }; 39 | 40 | 41 | #endif //SOLUTIONS_SIGNALHANDLER_H 42 | -------------------------------------------------------------------------------- /cpp/test_toolkit/tree_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef SOLUTIONS_TREE_UTILS_H 2 | #define SOLUTIONS_TREE_UTILS_H 3 | 4 | #include 5 | 6 | #include "../Binary_tree_prototype.h" 7 | 8 | template 9 | unique_ptr> CreateNode(const T& value) { 10 | return unique_ptr>(new BinaryTreeNode{value}); 11 | } 12 | 13 | template 14 | void TreeInsert(unique_ptr>& node, T value) { 15 | if (!node) { 16 | node.reset(new BinaryTreeNode()); 17 | node->data = value; 18 | } 19 | else { 20 | if (value <= node->data) 21 | TreeInsert(node->left, value); 22 | else 23 | TreeInsert(node->right, value); 24 | } 25 | } 26 | 27 | template 28 | unique_ptr> BuildTree(const vector values) { 29 | unique_ptr> head; 30 | for (auto& x : values) 31 | TreeInsert(head, x); 32 | 33 | return move(head); 34 | } 35 | 36 | #endif //SOLUTIONS_TREE_UTILS_H 37 | -------------------------------------------------------------------------------- /cpp/thread_per_task_webserver.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using std::shared_ptr; 9 | using std::cout; 10 | using std::endl; 11 | using std::thread; 12 | using boost::system::error_code; 13 | namespace asio = boost::asio; 14 | using asio::ip::tcp; 15 | 16 | void ProcessReq(shared_ptr sock) { 17 | asio::streambuf sb; 18 | while (true) { 19 | error_code e; 20 | size_t n = asio::read_until(*sock, sb, '\n', e); 21 | if (e == asio::error::eof) { 22 | cout << endl << "connection closed" << endl; 23 | break; 24 | } 25 | asio::write(*sock, sb.data()); 26 | cout << &sb; 27 | } 28 | } 29 | 30 | // @include 31 | const unsigned short SERVERPORT = 8080; 32 | 33 | int main(int argc, char* argv[]) { 34 | asio::io_service io_service; 35 | tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), SERVERPORT)); 36 | while (true) { 37 | shared_ptr sock(new tcp::socket(io_service)); 38 | acceptor.accept(*sock); 39 | thread(ProcessReq, sock).detach(); 40 | } 41 | return 0; 42 | } 43 | // @exclude 44 | -------------------------------------------------------------------------------- /cpp/triangle.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using std::cout; 9 | using std::endl; 10 | using std::min; 11 | using std::vector; 12 | 13 | // @include 14 | int MinimumPathWeight(const vector>& triangle) { 15 | if (triangle.empty()) { 16 | return 0; 17 | } 18 | 19 | // As we iterate, prev_row stores the minimum path sum to each entry in 20 | // triangle[i - 1]. 21 | vector prev_row(triangle.front()); 22 | for (int i = 1; i < triangle.size(); ++i) { 23 | // Stores the minimum path sum to each entry in triangle[i]. 24 | vector curr_row(triangle[i]); 25 | curr_row.front() += prev_row.front(); // For the first element. 26 | for (int j = 1; j < curr_row.size() - 1; ++j) { 27 | curr_row[j] += min(prev_row[j - 1], prev_row[j]); 28 | } 29 | curr_row.back() += prev_row.back(); // For the last element. 30 | 31 | // Uses swap to assign curr_row's content to prev_row in O(1) time. 32 | prev_row.swap(curr_row); 33 | } 34 | return *min_element(prev_row.cbegin(), prev_row.cend()); 35 | } 36 | // @exclude 37 | 38 | int main(int argc, char** argv) { 39 | vector> A = {{2}, {3, 4}, {6, 5, 7}, {4, 1, 8, 3}}; 40 | assert(11 == MinimumPathWeight(A)); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /cpp/two_thread_increment.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | using std::stoi; 10 | using std::thread; 11 | 12 | // @include 13 | static int counter = 0; 14 | 15 | void IncrementThread(int N) { 16 | for (int i = 0; i < N; ++i) { 17 | ++counter; 18 | } 19 | } 20 | 21 | void TwoThreadIncrementDriver(int N) { 22 | thread T1(IncrementThread, N); 23 | thread T2(IncrementThread, N); 24 | T1.join(); 25 | T2.join(); 26 | 27 | cout << counter << endl; 28 | } 29 | // @exclude 30 | 31 | int main(int argc, char* argv[]) { 32 | int N = argc == 2 ? stoi(argv[1]) : 1000000000; 33 | TwoThreadIncrementDriver(N); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /cpp/unique-binary-trees.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using std::cout; 11 | using std::default_random_engine; 12 | using std::endl; 13 | using std::random_device; 14 | using std::string; 15 | using std::stoi; 16 | using std::uniform_int_distribution; 17 | using std::vector; 18 | 19 | // @include 20 | int num_unique_binary_trees(int n) { 21 | vector num(n + 1, 0); 22 | num[0] = 1; 23 | for (int i = 1; i <= n; ++i) { 24 | for (int j = 0; j < i; ++j) { 25 | num[i] += num[j] * num[i - j - 1]; 26 | } 27 | } 28 | return num.back(); 29 | } 30 | // @exclude 31 | 32 | int main(int argc, char** argv) { 33 | assert(16796 == num_unique_binary_trees(10)); 34 | assert(4862 == num_unique_binary_trees(9)); 35 | assert(2 == num_unique_binary_trees(2)); 36 | assert(5 == num_unique_binary_trees(3)); 37 | default_random_engine gen((random_device())()); 38 | int n; 39 | if (argc == 2) { 40 | n = stoi(argv[1]); 41 | } else { 42 | uniform_int_distribution dis(1, 15); 43 | n = dis(gen); 44 | } 45 | cout << "n = " << n << endl; 46 | cout << num_unique_binary_trees(n) << endl; 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /cpp/valid-palindrome.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using std::cout; 9 | using std::endl; 10 | using std::string; 11 | 12 | // @include 13 | bool IsPalindrome(const string& s) { 14 | // i moves forward, and j moves backward. 15 | int i = 0, j = s.size() - 1; 16 | while (i < j) { 17 | // i and j both skip non-alphanumeric characters. 18 | while (!isalnum(s[i]) && i < j) { 19 | ++i; 20 | } 21 | while (!isalnum(s[j]) && i < j) { 22 | --j; 23 | } 24 | if (tolower(s[i++]) != tolower(s[j--])) { 25 | return false; 26 | } 27 | } 28 | return true; 29 | } 30 | // @exclude 31 | 32 | int main(int argc, char** argv) { 33 | assert(IsPalindrome("A man, a plan, a canal: Panama")); 34 | assert(!IsPalindrome("race a car")); 35 | assert(IsPalindrome("Able was I, ere I saw Elba!")); 36 | assert(!IsPalindrome("Ray a Ray")); 37 | assert(IsPalindrome("")); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /cpp/valid-parentheses.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Elements of Programming Interviews. All rights reserved. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using std::boolalpha; 9 | using std::cout; 10 | using std::endl; 11 | using std::stack; 12 | using std::string; 13 | 14 | // @include 15 | bool IsWellFormed(const string& s) { 16 | stack left_chars; 17 | for (int i = 0; i < s.size(); ++i) { 18 | if (s[i] == '(' || s[i] == '{' || s[i] == '[') { 19 | left_chars.emplace(s[i]); 20 | } else { 21 | if (left_chars.empty()) { 22 | return false; // Unmatched right char. 23 | } 24 | if ((s[i] == ')' && left_chars.top() != '(') || 25 | (s[i] == '}' && left_chars.top() != '{') || 26 | (s[i] == ']' && left_chars.top() != '[')) { 27 | return false; // Mismatched chars. 28 | } 29 | left_chars.pop(); 30 | } 31 | } 32 | return left_chars.empty(); 33 | } 34 | // @exclude 35 | 36 | void small_test() { 37 | assert(IsWellFormed("()")); 38 | assert(IsWellFormed("()[]{}")); 39 | assert(IsWellFormed("[()[]]{}")); 40 | assert(IsWellFormed("(()[]{()[]{}{}})")); 41 | assert(!IsWellFormed("([)]")); 42 | assert(!IsWellFormed("[")); 43 | assert(!IsWellFormed("(()[]{()[]{})({}})")); 44 | } 45 | 46 | int main(int argc, char** argv) { 47 | small_test(); 48 | if (argc == 2) { 49 | cout << boolalpha << IsWellFormed(argv[1]) << endl; 50 | } 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /cpptest/Number_waysTest.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Elements of Programming Interviews. All rights reserved. 2 | #include "test_toolkit/test-options.h" 3 | // @pg_ignore:1 4 | #include "Number_ways.cc" 5 | // @pg_include:Number_ways.cc 6 | 7 | void UnitTest(TestSentry::Ptr& sentry, const char* description, 8 | int n, int m) { 9 | int expected = ComputeNumberOfWaysSpaceEfficient(n, m); 10 | TestStream::Ptr stream = sentry->GetTestStream(TestType::NORMAL, description); 11 | stream->GetInputWriter()->WritePair("n", n).WritePair("m", m); 12 | stream->RegisterExpectedOutput(expected); 13 | try { 14 | int result = NumberOfWays(n, m); 15 | stream->RegisterUserOutput(result, result == expected); 16 | } 17 | catch (...) { 18 | stream->RegisterUnhandledException(); 19 | } 20 | } 21 | 22 | void DirectedTests(const TestOptions& options) { 23 | TestSentry::Ptr sentry = options.GetTestSentry(0, "Number of ways"); 24 | 25 | UnitTest(sentry, "Trivial test", 1, 1); 26 | UnitTest(sentry, "n == m test #1", 5, 5); 27 | UnitTest(sentry, "n == m test #2", 10, 10); 28 | UnitTest(sentry, "n < m test #1", 1, 5); 29 | UnitTest(sentry, "n < m test #2", 3, 5); 30 | UnitTest(sentry, "n > m test #1", 6, 1); 31 | UnitTest(sentry, "n > m test #2", 6, 3); 32 | } 33 | 34 | int main(int argc, char* argv[]) { 35 | DirectedTests(TestOptions(&cout)); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /cpptest/Spreadsheet_encodingTest.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Elements of Programming Interviews. All rights reserved. 2 | #include "test_toolkit/test-options.h" 3 | // @pg_ignore:1 4 | #include "Spreadsheet_encoding.cc" 5 | // @pg_include:Spreadsheet_encoding.cc 6 | 7 | void UnitTest(TestSentry::Ptr& sentry, const char* description, 8 | const string& input, int expected) { 9 | TestStream::Ptr stream = sentry->GetTestStream(TestType::NORMAL, description); 10 | stream->RegisterInput(input); 11 | stream->RegisterExpectedOutput(expected); 12 | try { 13 | int result = SSDecodeColID(input); 14 | stream->RegisterUserOutput(result, result == expected); 15 | } 16 | catch (...) { 17 | stream->RegisterUnhandledException(); 18 | } 19 | } 20 | 21 | void DirectedTests(const TestOptions& options) { 22 | TestSentry::Ptr sentry = options.GetTestSentry(5, "Spreadsheet encoding"); 23 | 24 | UnitTest(sentry, "First number test", "A", 1); 25 | UnitTest(sentry, "Second number test", "B", 2); 26 | UnitTest(sentry, "Z-AA transition test", "Z", 26); 27 | UnitTest(sentry, "Z-AA transition test", "AA", 27); 28 | UnitTest(sentry, "AZ-BA transition test", "AZ", 52); 29 | UnitTest(sentry, "AZ-BA transition test", "BA", 53); 30 | UnitTest(sentry, "Small test", "CPP", 2460); 31 | UnitTest(sentry, "Huge test", "TESTS", 9240783); 32 | } 33 | 34 | int main(int argc, char* argv[]) { 35 | DirectedTests(TestOptions(&cout)); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /epijudge/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "A.h" 3 | 4 | using namespace std; 5 | 6 | int sum(int a, int b) { 7 | // @exclude-judge 8 | return a + b; 9 | // @include-judge 10 | } 11 | 12 | int main(int argc, char** argv) { 13 | cout << sum(1,1) << endl; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /epijudge/A.h: -------------------------------------------------------------------------------- 1 | #ifndef A_H_ 2 | #define A_H_ 3 | 4 | #include 5 | 6 | using std::unique_ptr; 7 | 8 | // @include 9 | template 10 | struct BSTNode { 11 | T data; 12 | unique_ptr> left, right; 13 | }; 14 | // @exclude 15 | #endif // A_H_ 16 | 17 | -------------------------------------------------------------------------------- /epijudge/A.java: -------------------------------------------------------------------------------- 1 | 2 | // This is the EPI program 3 | 4 | import java.util.*; 5 | 6 | class A { 7 | static int sum(int a, int b) { 8 | return a + b; 9 | } 10 | 11 | public static void main(String[] args) { 12 | System.out.println(sum(1,1)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /epijudge/Atest.cpp: -------------------------------------------------------------------------------- 1 | // this is the test harness, everthing we need to test the code under test 2 | // goes here. it has its own main(). we build a single stand alone executable 3 | // using g++ Atest.cpp 4 | 5 | #include 6 | #include "testutils.h" 7 | #include "A.h" 8 | 9 | using namespace std; 10 | 11 | extern int sum(int a, int b); 12 | 13 | // potential name conflict with A.cpp, but we can change the names, 14 | // and this issue is easy to detect. 15 | void test() { 16 | utils_check_equal(2, sum(1,1)); 17 | } 18 | 19 | int main(int argc, char** argv) { 20 | test(); 21 | return 0; 22 | } 23 | 24 | // now we include the code under test, with its main redefined to avoid a conflict 25 | #define main _main 26 | 27 | #include "A.cpp" 28 | -------------------------------------------------------------------------------- /epijudge/Atest.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | // can import test specific utilities 3 | 4 | class Atest { 5 | 6 | public static void main(String[] args) { 7 | if (2 != A.sum(1,1)) { 8 | System.out.println("Atrocity! 2 != 1 + 1"); 9 | } 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /epijudge/file.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | // can import test specific utilities 5 | 6 | class Atest { 7 | 8 | public static void main(String[] args) { 9 | if (2 != A.sum(1,1)) { 10 | System.out.println("Atrocity! 2 != 1 + 1"); 11 | } 12 | } 13 | 14 | } 15 | 16 | 17 | // This is the EPI program 18 | // it will not compile like this because of the import just before class A. 19 | // 20 | // approach 1: have slava's program that generates the JSON for the post move the imports 21 | // from the second program to the top 22 | // 23 | // approach 2: have the two programs sent by judge, and compilebox will compile both and 24 | // execute the test one (Atest in this case). this has the benefit of compile errors 25 | // matching line numbers in the users editor. 26 | // 27 | // if we use approach 2, then we should do the same for CPP 28 | 29 | import java.util.*; 30 | 31 | class A { 32 | // @fillme (this is used to add in the contributed program) 33 | // judge include 34 | static int sum(int a, int b) { 35 | // judge exclude 36 | return a + b; 37 | // judge include 38 | } 39 | // judge exclude 40 | 41 | 42 | public static void main(String[] args) { 43 | System.out.println(sum(1,1)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /epijudge/testutils.h: -------------------------------------------------------------------------------- 1 | 2 | bool utils_check_equal(int x, int y) { 3 | return x == y; 4 | } 5 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/BadArrayListStore.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class BadArrayListStore { 7 | public static void main(String[] args) { 8 | /* Intentionally commented out, otherwise mvn will not compile the project. 9 | // @include 10 | List numArrayList = new ArrayList(1); 11 | numArrayList.add(42); 12 | // @exclude 13 | */ 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/BadArrayStore.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class BadArrayStore { 4 | public static void main(String[] args) { 5 | // @include 6 | Object[] numArray = new Integer[2]; 7 | numArray[0] = 42; 8 | numArray[1] = "Hello World!"; 9 | // @exclude 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/BadAssert.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class BadAssert { 4 | public static void main(String[] args) { 5 | // @include 6 | assert((0.37 - 0.23) == 0.14); 7 | // @exclude 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/BasicStaticInitializer.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class BasicStaticInitializer { 7 | // @include 8 | private static final Map monthToOrdinal = new HashMap<>(); 9 | 10 | // Static initializer block. Executed once, when class is first acccessed. 11 | static { 12 | int ordinal = 0; 13 | String[] months = {"January", "February", "March", "April", 14 | "May", "June", "July", "August", 15 | "September", "October", "November", "December"}; 16 | for (String month : months) { 17 | monthToOrdinal.put(month, ordinal++); 18 | } 19 | } 20 | // @exclude 21 | } 22 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/BinarySearchTreePrototypeTemplate.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Objects; 4 | 5 | public class BinarySearchTreePrototypeTemplate { 6 | // @include 7 | public static class BSTNode { 8 | public T data; 9 | public BSTNode left, right; 10 | // @exclude 11 | 12 | public BSTNode() {} 13 | 14 | public BSTNode(T data) { this.data = data; } 15 | 16 | public BSTNode(T data, BSTNode left, BSTNode right) { 17 | this.data = data; 18 | this.left = left; 19 | this.right = right; 20 | } 21 | 22 | @Override 23 | public boolean equals(Object o) { 24 | if (this == o) { 25 | return true; 26 | } 27 | if (o == null || getClass() != o.getClass()) { 28 | return false; 29 | } 30 | 31 | BSTNode that = (BSTNode)o; 32 | 33 | if (data != null ? !data.equals(that.data) : that.data != null) { 34 | return false; 35 | } 36 | if (left != null ? !left.equals(that.left) : that.left != null) { 37 | return false; 38 | } 39 | if (right != null ? !right.equals(that.right) : that.right != null) { 40 | return false; 41 | } 42 | 43 | return true; 44 | } 45 | 46 | // clang-format off 47 | @Override 48 | public int hashCode() { return Objects.hash(data, left, right); } 49 | // clang-format on 50 | } 51 | // @include 52 | } 53 | // @exclude 54 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/BinaryTreeWithParentPrototype.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class BinaryTreeWithParentPrototype { 4 | public static class BinaryTree { 5 | public T data; 6 | public BinaryTree left, right; 7 | public BinaryTree parent; 8 | 9 | public BinaryTree() {} 10 | 11 | public BinaryTree(T data) { this.data = data; } 12 | 13 | public BinaryTree(T data, BinaryTree left, BinaryTree right) { 14 | this.data = data; 15 | this.left = left; 16 | this.right = right; 17 | } 18 | 19 | public BinaryTree(T data, BinaryTree left, BinaryTree right, 20 | BinaryTree parent) { 21 | this(data, left, right); 22 | this.parent = parent; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/CanStringBePalindrome.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.Random; 6 | 7 | public class CanStringBePalindrome { 8 | private static String randString(int len) { 9 | StringBuilder ret = new StringBuilder(); 10 | Random rnd = new Random(); 11 | 12 | while (len-- > 0) { 13 | ret.append((char)(rnd.nextInt(26) + 97)); 14 | } 15 | return ret.toString(); 16 | } 17 | 18 | public static void main(String[] args) { 19 | Random rnd = new Random(); 20 | for (int times = 0; times < 1000; ++times) { 21 | String s = null; 22 | if (args.length == 1) { 23 | s = args[0]; 24 | } else { 25 | s = randString(rnd.nextInt(10) + 1); 26 | } 27 | System.out.println(s); 28 | assert(CanStringBePalindromeHash.canFormPalindrome(s) 29 | == CanStringBePalindromeSorting.canFormPalindrome(s)); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/CanStringBePalindromeHash.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | public class CanStringBePalindromeHash { 9 | // @include 10 | public static boolean canFormPalindrome(String s) { 11 | Map charFrequencies = new HashMap<>(); 12 | // Compute the frequency of each char in s. 13 | for (int i = 0; i < s.length(); i++) { 14 | char c = s.charAt(i); 15 | if (!charFrequencies.containsKey(c)) { 16 | charFrequencies.put(c, 1); 17 | } else { 18 | charFrequencies.put(c, charFrequencies.get(c) + 1); 19 | } 20 | } 21 | 22 | // A string can be permuted as a palindrome if and only if the number of 23 | // chars whose frequencies is odd is at most 1. 24 | int oddCount = 0; 25 | for (Map.Entry p : charFrequencies.entrySet()) { 26 | if ((p.getValue() % 2) != 0 && ++oddCount > 1) { 27 | return false; 28 | } 29 | } 30 | return true; 31 | } 32 | // @exclude 33 | } 34 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/CanStringBePalindromeSorting.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.Arrays; 6 | 7 | public class CanStringBePalindromeSorting { 8 | // @include 9 | public static boolean canFormPalindrome(String s) { 10 | char[] a = s.toCharArray(); 11 | Arrays.sort(a); 12 | int oddCount = 0; 13 | int numCurrChar = 1; 14 | 15 | for (int i = 1; i < a.length && oddCount <= 1; ++i) { 16 | if (a[i] != a[i - 1]) { 17 | if ((numCurrChar % 2) != 0) { 18 | ++oddCount; 19 | } 20 | numCurrChar = 1; 21 | } else { 22 | ++numCurrChar; 23 | } 24 | } 25 | if ((numCurrChar & 1) != 0) { 26 | ++oddCount; 27 | } 28 | 29 | // A string can be permuted as a palindrome if the number of odd time 30 | // chars <= 1. 31 | return oddCount <= 1; 32 | } 33 | // @exclude 34 | } 35 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/CloseSearch.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Random; 6 | 7 | public class CloseSearch { 8 | // @include 9 | public static int closeSearch(List A, int k) { 10 | int idx = 0; 11 | while (idx < A.size() && A.get(idx) != k) { 12 | idx += StrictMath.abs(A.get(idx) - k); 13 | } 14 | return idx < A.size() ? idx : -1; // -1 means no result. 15 | } 16 | // @exclude 17 | 18 | public static void main(String[] args) { 19 | Random r = new Random(); 20 | for (int times = 0; times < 10000; ++times) { 21 | int n; 22 | if (args.length == 1) { 23 | n = Integer.parseInt(args[0]); 24 | } else { 25 | n = r.nextInt(10000) + 1; 26 | } 27 | List A = new ArrayList<>(); 28 | A.add(r.nextInt(10)); 29 | for (int i = 1; i < n; ++i) { 30 | int shift = r.nextInt(3) - 1; 31 | A.add(A.get(i - 1) + shift); 32 | } 33 | int k = r.nextInt(100); 34 | int ans = closeSearch(A, k); 35 | System.out.println(ans); 36 | if (ans != -1) { 37 | assert(A.get(ans) == k); 38 | } else { 39 | boolean found = false; 40 | for (Integer anA : A) { 41 | if (anA == k) { 42 | found = true; 43 | break; 44 | } 45 | } 46 | assert(!found); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/CoinChange.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class CoinChange { 4 | // @include 5 | public static int changeMaking(int cents) { 6 | final int[] COINS = {100, 50, 25, 10, 5, 1}; 7 | int numCoins = 0; 8 | for (int i = 0; i < COINS.length; i++) { 9 | numCoins += cents / COINS[i]; 10 | cents %= COINS[i]; 11 | } 12 | return numCoins; 13 | } 14 | // @exclude 15 | 16 | public static void main(String[] args) { 17 | assert(changeMaking(100) == 1); 18 | assert(changeMaking(101) == 2); 19 | assert(changeMaking(68) == 6); 20 | assert(changeMaking(13142) == 136); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/ComputeRandomPermutation.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.Random; 7 | 8 | public class ComputeRandomPermutation { 9 | // @include 10 | public static List computeRandomPermutation(int n) { 11 | List permutation = new ArrayList<>(n); 12 | for (int i = 0; i < n; ++i) { 13 | permutation.add(i); 14 | } 15 | OfflineSampling.randomSampling(permutation.size(), permutation); 16 | return permutation; 17 | } 18 | // @exclude 19 | 20 | public static void main(String[] args) { 21 | int n; 22 | Random gen = new Random(); 23 | if (args.length == 1) { 24 | n = Integer.parseInt(args[0]); 25 | } else { 26 | n = gen.nextInt(1000000) + 1; 27 | } 28 | 29 | System.out.println(n); 30 | List result = computeRandomPermutation(n); 31 | Collections.sort(result); 32 | for (int i = 0; i < n; ++i) { 33 | assert(i == result.get(i)); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/CountBits.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.BitSet; 4 | import java.util.Random; 5 | 6 | public class CountBits { 7 | // @include 8 | public static short countBits(int x) { 9 | short numBits = 0; 10 | while (x != 0) { 11 | numBits += (x & 1); 12 | // clang-format off 13 | x >>>= 1; 14 | // clang-format on 15 | } 16 | return numBits; 17 | } 18 | // @exclude 19 | 20 | public static void main(String[] args) { 21 | if (args.length == 1) { 22 | int x = Integer.parseInt(args[0]); 23 | System.out.println("x = " + x + ", = " + countBits(x)); 24 | } else { 25 | Random r = new Random(); 26 | for (int times = 0; times < 1000; ++times) { 27 | int x = r.nextInt(Integer.MAX_VALUE); 28 | System.out.println("x = " + x + ", = " + countBits(x)); 29 | BitSet checker = BitSet.valueOf(new long[] {x}); 30 | assert(countBits(x) == checker.cardinality()); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/DeleteList.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Random; 6 | 7 | public class DeleteList { 8 | // @include 9 | // Delete the node immediately following aNode. Assumes aNode is not a tail. 10 | public static void deleteList(ListNode aNode) { 11 | aNode.next = aNode.next.next; 12 | } 13 | // @exclude 14 | 15 | private static void checkAnswer(ListNode L, List vals) { 16 | for (int i = 0; i < vals.size(); ++i) { 17 | assert(L.data == vals.get(i)); 18 | L = L.next; 19 | } 20 | assert(L == null); 21 | } 22 | 23 | public static void main(String[] args) { 24 | ListNode L; 25 | L = new ListNode<>(2, new ListNode<>(4, new ListNode<>(3, null))); 26 | deleteList(L); 27 | checkAnswer(L, Arrays.asList(2, 3)); 28 | deleteList(L); 29 | checkAnswer(L, Arrays.asList(2)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/DeletionList.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | // @author Andrey Pavlov 3 | 4 | package com.epi; 5 | 6 | public class DeletionList { 7 | // @include 8 | // Assumes nodeToDelete is not tail. 9 | public static void deletionFromList(ListNode nodeToDelete) { 10 | nodeToDelete.data = nodeToDelete.next.data; 11 | nodeToDelete.next = nodeToDelete.next.next; 12 | } 13 | // @exclude 14 | 15 | public static void main(String[] args) { 16 | ListNode L 17 | = new ListNode<>(1, new ListNode<>(2, new ListNode<>(3, null))); 18 | deletionFromList(L); 19 | assert(L.data == 2 && L.next.data == 3); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/Doors.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Random; 4 | 5 | public class Doors { 6 | // @include 7 | static boolean isDoorOpen(int i) { 8 | double sqrtI = Math.sqrt(i); 9 | int floorSqrtI = (int)Math.floor(sqrtI); 10 | return floorSqrtI * floorSqrtI == i; 11 | } 12 | // @exclude 13 | 14 | static void checkAnswer(int n) { 15 | boolean[] doors = new boolean[n + 1]; // false means closed door. 16 | for (int i = 1; i <= n; ++i) { 17 | int start = 0; 18 | while (start + i <= n) { 19 | start += i; 20 | doors[start] = !doors[start]; 21 | } 22 | } 23 | 24 | for (int i = 1; i <= n; ++i) { 25 | assert isDoorOpen(i) == doors[i]; 26 | } 27 | } 28 | 29 | public static void main(String[] args) { 30 | Random gen = new Random(); 31 | int n; 32 | if (args.length == 1) { 33 | n = Integer.parseInt(args[0]); 34 | } else { 35 | n = gen.nextInt(1000) + 1; 36 | } 37 | checkAnswer(n); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/DoublyLinkedListPrototypeTemplate.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | // @include 6 | class DoublyLinkedListNode { 7 | public T data; 8 | public DoublyLinkedListNode prev, next; 9 | // @exclude 10 | 11 | DoublyLinkedListNode(T data, DoublyLinkedListNode prev, 12 | DoublyLinkedListNode next) { 13 | this.data = data; 14 | this.prev = prev; 15 | this.next = next; 16 | } 17 | // @include 18 | } 19 | // @exclude 20 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/Fibonacci.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.Random; 8 | 9 | public class Fibonacci { 10 | // @include 11 | private static Map cache = new HashMap<>(); 12 | 13 | public static int fibonacci(int n) { 14 | if (n <= 1) { 15 | return n; 16 | } else if (!cache.containsKey(n)) { 17 | cache.put(n, fibonacci(n - 2) + fibonacci(n - 1)); 18 | } 19 | return cache.get(n); 20 | } 21 | // @exclude 22 | 23 | private static void smallTest() { 24 | assert(fibonacci(10) == 55); 25 | assert(fibonacci(0) == 0); 26 | assert(fibonacci(1) == 1); 27 | assert(fibonacci(16) == 987); 28 | assert(fibonacci(40) == 102334155); 29 | } 30 | 31 | public static void main(String[] args) { 32 | smallTest(); 33 | int n; 34 | if (args.length == 1) { 35 | n = Integer.parseInt(args[0]); 36 | } else { 37 | Random gen = new Random(); 38 | n = gen.nextInt(41); 39 | } 40 | System.out.println("F(" + n + ") = " + fibonacci(n)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/FibonacciIterative.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.Random; 8 | 9 | public class FibonacciIterative { 10 | // @include 11 | public static int fibonacci(int n) { 12 | if (n <= 1) { 13 | return n; 14 | } 15 | 16 | int fMinus2 = 0; 17 | int fMinus1 = 1; 18 | for (int i = 2; i <= n; ++i) { 19 | int f = fMinus2 + fMinus1; 20 | fMinus2 = fMinus1; 21 | fMinus1 = f; 22 | } 23 | return fMinus1; 24 | } 25 | // @exclude 26 | 27 | private static void smallTest() { 28 | assert(fibonacci(10) == 55); 29 | assert(fibonacci(0) == 0); 30 | assert(fibonacci(1) == 1); 31 | assert(fibonacci(16) == 987); 32 | assert(fibonacci(40) == 102334155); 33 | } 34 | 35 | public static void main(String[] args) { 36 | smallTest(); 37 | int n; 38 | if (args.length == 1) { 39 | n = Integer.parseInt(args[0]); 40 | } else { 41 | Random gen = new Random(); 42 | n = gen.nextInt(41); 43 | } 44 | System.out.println("F(" + n + ") = " + fibonacci(n)); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/FindMissingBetter.java: -------------------------------------------------------------------------------- 1 | // - mixed x and num (which was undefined) 2 | // - precedence of & 3 | // used sb, forgot binary to int is not how string conversion works! 4 | import java.util.*; 5 | 6 | class FindMissingBetter { 7 | // @include 8 | public static int numberAppearingOnce(int[] nums) { 9 | int[] countsMod3 = new int[32]; 10 | for (int x : nums) { 11 | for (int i = 0; i < 32; i++) { 12 | if ((x & (1 << i)) != 0) { 13 | countsMod3[i] = (countsMod3[i] + 1) % 3; 14 | } 15 | } 16 | } 17 | int result = 0; 18 | for (int i = 31; i >= 0; i--) { 19 | result += countsMod3[i] * (1 << i); 20 | } 21 | return result; 22 | } 23 | // @exclude 24 | 25 | public static void main(String[] args) { 26 | System.out.println( 27 | numberAppearingOnce(new int[] {1, 7, 1, 3, 1, 3, 2, 4, 4, 4, 7, 3, 7})); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/GCD.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Random; 4 | 5 | public class GCD { 6 | public static void main(String[] args) { 7 | long x = 18, y = 12; 8 | assert(GCD1.GCD(x, y) == 6); 9 | if (args.length == 2) { 10 | x = Integer.parseInt(args[0]); 11 | y = Integer.parseInt(args[1]); 12 | System.out.println(GCD1.GCD(x, y)); 13 | assert(GCD1.GCD(x, y) == GCD2.GCD(x, y)); 14 | } else { 15 | Random r = new Random(); 16 | for (int times = 0; times < 1000; ++times) { 17 | x = r.nextInt(Integer.MAX_VALUE); 18 | y = r.nextInt(Integer.MAX_VALUE); 19 | assert(GCD1.GCD(x, y) == GCD2.GCD(x, y)); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/GCD2.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class GCD2 { 4 | // @include 5 | public static long GCD(long x, long y) { return y == 0 ? x : GCD(y, x % y); } 6 | // @exclude 7 | } 8 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/GeneratingABSqrt2Improved.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import com.epi.GeneratingABSqrt2.ABSqrt2; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Objects; 8 | import java.util.Random; 9 | import java.util.SortedSet; 10 | import java.util.TreeSet; 11 | 12 | public class GeneratingABSqrt2Improved { 13 | // @include 14 | public static List generateFirstKABSqrt2(int k) { 15 | // Will store the first k numbers of the form a + b sqrt(2). 16 | List result = new ArrayList<>(); 17 | result.add(new ABSqrt2(0, 0)); 18 | int i = 0, j = 0; 19 | for (int n = 1; n < k; ++n) { 20 | ABSqrt2 resultIPlus1 = new ABSqrt2(result.get(i).a + 1, result.get(i).b); 21 | ABSqrt2 resultJPlusSqrt2 22 | = new ABSqrt2(result.get(j).a, result.get(j).b + 1); 23 | result.add(resultIPlus1.val < resultJPlusSqrt2.val ? resultIPlus1 24 | : resultJPlusSqrt2); 25 | if (resultIPlus1.compareTo(result.get(result.size() - 1)) == 0) { 26 | ++i; 27 | } 28 | if (resultJPlusSqrt2.compareTo(result.get(result.size() - 1)) == 0) { 29 | ++j; 30 | } 31 | } 32 | return result; 33 | } 34 | // @exclude 35 | } 36 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/HashDictionary.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.Random; 6 | 7 | public class HashDictionary { 8 | private static String randString(int len) { 9 | StringBuilder ret = new StringBuilder(); 10 | Random rnd = new Random(); 11 | 12 | while (len-- > 0) { 13 | ret.append((char)(rnd.nextInt(26) + 97)); 14 | } 15 | return ret.toString(); 16 | } 17 | 18 | // @include 19 | public static int stringHash(String str, int modulus) { 20 | int kMult = 997; 21 | int val = 0; 22 | for (int i = 0; i < str.length(); i++) { 23 | char c = str.charAt(i); 24 | val = (val * kMult + c) % modulus; 25 | } 26 | return val; 27 | } 28 | // @exclude 29 | 30 | public static void main(String[] args) { 31 | String str = null; 32 | if (args.length == 1) { 33 | str = args[0]; 34 | } else { 35 | Random rnd = new Random(); 36 | str = randString(rnd.nextInt(20) + 1); 37 | } 38 | System.out.println("string = " + str); 39 | System.out.println(stringHash(str, 1 << 16)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/InsertList.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Random; 6 | 7 | public class InsertList { 8 | // @include 9 | // Insert newNode after node. 10 | public static void insertAfter(ListNode node, 11 | ListNode newNode) { 12 | newNode.next = node.next; 13 | node.next = newNode; 14 | } 15 | // @exclude 16 | 17 | private static void checkAnswer(ListNode L, List vals) { 18 | for (int i = 0; i < vals.size(); ++i) { 19 | assert(L.data == vals.get(i)); 20 | L = L.next; 21 | } 22 | assert(L == null); 23 | } 24 | 25 | public static void main(String[] args) { 26 | ListNode L; 27 | L = new ListNode<>(2, new ListNode<>(4, new ListNode<>(3, null))); 28 | insertAfter(L, new ListNode<>(1, null)); 29 | checkAnswer(L, Arrays.asList(2, 1, 4, 3)); 30 | insertAfter(L.next.next, new ListNode<>(10, null)); 31 | checkAnswer(L, Arrays.asList(2, 1, 4, 10, 3)); 32 | insertAfter(L.next.next.next.next, new ListNode<>(-1, null)); 33 | checkAnswer(L, Arrays.asList(2, 1, 4, 10, 3, -1)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/IntersectSortedArrays.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Random; 6 | 7 | public class IntersectSortedArrays { 8 | public static void main(String[] args) { 9 | int n = 100; 10 | int l = 1000; 11 | if (args.length > 0) { 12 | n = Integer.parseInt(args[0]); 13 | } 14 | if (args.length > 1) { 15 | l = Integer.parseInt(args[1]); 16 | } 17 | Random rnd = new Random(0); 18 | for (int i = 0; i < n; i++) { 19 | List a = new ArrayList<>(); 20 | List b = new ArrayList<>(); 21 | for (int j = 0; j < l; j++) { 22 | a.add(rnd.nextInt()); 23 | b.add(rnd.nextInt()); 24 | } 25 | List r1 = IntersectSortedArrays1.intersectTwoSortedArrays(a, b); 26 | List r2 = IntersectSortedArrays2.intersectTwoSortedArrays(a, b); 27 | List r3 = IntersectSortedArrays3.intersectTwoSortedArrays(a, b); 28 | assert r1.equals(r2); 29 | assert r2.equals(r3); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/IntersectSortedArrays1.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class IntersectSortedArrays1 { 9 | // @include 10 | public static List intersectTwoSortedArrays(List A, 11 | List B) { 12 | List intersectionAB = new ArrayList<>(); 13 | for (int i = 0; i < A.size(); ++i) { 14 | if (i == 0 || A.get(i) != A.get(i - 1)) { 15 | for (Integer b : B) { 16 | if (A.get(i).equals(b)) { 17 | intersectionAB.add(A.get(i)); 18 | break; 19 | } 20 | } 21 | } 22 | } 23 | return intersectionAB; 24 | } 25 | // @exclude 26 | } 27 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/IntersectSortedArrays2.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Collections; 7 | import java.util.List; 8 | 9 | public class IntersectSortedArrays2 { 10 | // @include 11 | public static List intersectTwoSortedArrays(List A, 12 | List B) { 13 | List intersectionAB = new ArrayList<>(); 14 | for (int i = 0; i < A.size(); ++i) { 15 | if ((i == 0 || A.get(i) != A.get(i - 1)) 16 | && Collections.binarySearch(B, A.get(i)) >= 0) { 17 | intersectionAB.add(A.get(i)); 18 | } 19 | } 20 | return intersectionAB; 21 | } 22 | // @exclude 23 | } 24 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/IsPalindromic.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.Random; 6 | 7 | public class IsPalindromic { 8 | // @include 9 | public static boolean isPalindromic(String s) { 10 | for (int i = 0, j = s.length() - 1; i < j; ++i, --j) { 11 | if (s.charAt(i) != s.charAt(j)) { 12 | return false; 13 | } 14 | } 15 | return true; 16 | } 17 | // @exclude 18 | 19 | private static boolean checkAnswer(String s) { 20 | String copy = new StringBuilder(s).reverse().toString(); 21 | return s.equals(copy); 22 | } 23 | 24 | private static String randString(int len) { 25 | Random r = new Random(); 26 | StringBuilder ret = new StringBuilder(len); 27 | while (len-- > 0) { 28 | ret.append((char)(r.nextInt(26) + 'a')); 29 | } 30 | return ret.toString(); 31 | } 32 | 33 | public static void main(String args[]) { 34 | Random r = new Random(); 35 | for (int times = 0; times < 10000; ++times) { 36 | String s = randString(r.nextInt(1000) + 1); 37 | assert(checkAnswer(s) == isPalindromic(s)); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/JumpGame.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import java.util.Random; 7 | 8 | public class JumpGame { 9 | // @include 10 | public static boolean canReachEnd(List maxAdvanceSteps) { 11 | int furthestReachSoFar = 0, lastIndex = maxAdvanceSteps.size() - 1; 12 | for (int i = 0; i <= furthestReachSoFar && furthestReachSoFar < lastIndex; 13 | ++i) { 14 | furthestReachSoFar 15 | = Math.max(furthestReachSoFar, i + maxAdvanceSteps.get(i)); 16 | } 17 | return furthestReachSoFar >= lastIndex; 18 | } 19 | // @exclude 20 | 21 | private static void smallTest() { 22 | assert(canReachEnd(Arrays.asList(2, 3, 1, 1, 4))); 23 | assert(!canReachEnd(Arrays.asList(3, 2, 1, 0, 4))); 24 | assert(!canReachEnd(Arrays.asList(3, 2, 1, -10, 4))); 25 | assert(canReachEnd(Arrays.asList(2, 3, -1, -1, 4))); 26 | assert(!canReachEnd(Arrays.asList(2, 2, -1, -1, 100))); 27 | } 28 | 29 | public static void main(String[] args) { 30 | smallTest(); 31 | Random r = new Random(); 32 | int n; 33 | if (args.length == 1) { 34 | n = Integer.parseInt(args[0]); 35 | } else { 36 | n = r.nextInt(1000) + 1; 37 | } 38 | List maxAdvanceSteps = new ArrayList<>(n); 39 | for (int i = 0; i < n; i++) { 40 | maxAdvanceSteps.add(r.nextInt(10) + 1); 41 | } 42 | System.out.println(canReachEnd(maxAdvanceSteps)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/LinkedListPrototypeTemplate.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | // @include 9 | class ListNode { 10 | public T data; 11 | public ListNode next; 12 | // @exclude 13 | 14 | ListNode(T data, ListNode next) { 15 | this.data = data; 16 | this.next = next; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | StringBuffer result = new StringBuffer(); 22 | Set> visited = new HashSet>(); 23 | ListNode iter = this; 24 | while (iter != null) { 25 | if (visited.contains(iter)) { 26 | result.append(" Loop back to " + data.toString()); 27 | break; 28 | } 29 | visited.add(iter); 30 | result.append(iter.data.toString() + (iter.next != null ? " -> " : " ")); 31 | } 32 | return result.toString(); 33 | } 34 | 35 | // @include 36 | } 37 | // @exclude 38 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/LockOrderingBug.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class LockOrderingBug { 4 | // @include 5 | public static class Account { 6 | private int balance; 7 | private int id; 8 | private static int globalId; 9 | 10 | Account(int balance) { 11 | this.balance = balance; 12 | this.id = ++globalId; 13 | } 14 | 15 | private boolean move(Account to, int amount) { 16 | synchronized (this) { 17 | synchronized (to) { 18 | if (amount > balance) { 19 | return false; 20 | } 21 | to.balance += amount; 22 | this.balance -= amount; 23 | System.out.println("returning true"); 24 | return true; 25 | } 26 | } 27 | } 28 | 29 | public static void transfer(final Account from, final Account to, 30 | final int amount) { 31 | Thread transfer = new Thread(new Runnable() { 32 | public void run() { from.move(to, amount); } 33 | }); 34 | transfer.start(); 35 | } 36 | } 37 | // @exclude 38 | 39 | public static void main(String[] args) throws Exception { 40 | Account from = new Account(200); 41 | Account to = new Account(100); 42 | System.out.println("Initial balances = " + from.balance + " " + to.balance); 43 | Account.transfer(from, to, 50); 44 | Thread.sleep(100); 45 | System.out.println("New balances = " + from.balance + " " + to.balance); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/LongestNondecreasingSubsequence.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Random; 8 | 9 | public class LongestNondecreasingSubsequence { 10 | public static void main(String[] args) { 11 | Random r = new Random(); 12 | for (int times = 0; times < 1000; ++times) { 13 | int n; 14 | if (args.length == 2) { 15 | n = Integer.parseInt(args[0]); 16 | } else { 17 | n = r.nextInt(1000) + 1; 18 | } 19 | List A = new ArrayList<>(); 20 | for (int i = 0; i < n; ++i) { 21 | A.add(r.nextInt(99999999)); 22 | } 23 | System.out.println(A); 24 | System.out.println("n = " + n); 25 | int retLength = LongestNondecreasingSubsequenceNlogn 26 | .longestNondecreasingSubsequenceLength(A); 27 | int anotherLength = LongestNondecreasingSubsequenceN2 28 | .longestNondecreasingSubsequenceLength(A); 29 | assert(retLength == anotherLength); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/LongestNondecreasingSubsequenceN2.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Arrays; 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | public class LongestNondecreasingSubsequenceN2 { 9 | // @include 10 | public static int longestNondecreasingSubsequenceLength(List A) { 11 | // maxLength[i] holds the length of the longest nondecreasing subsequence of 12 | // A[0 : i]. 13 | Integer[] maxLength = new Integer[A.size()]; 14 | Arrays.fill(maxLength, 1); 15 | for (int i = 1; i < A.size(); ++i) { 16 | for (int j = 0; j < i; ++j) { 17 | if (A.get(i) >= A.get(j)) { 18 | maxLength[i] = Math.max(maxLength[i], maxLength[j] + 1); 19 | } 20 | } 21 | } 22 | return Collections.max(Arrays.asList(maxLength)); 23 | } 24 | // @exclude 25 | } 26 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/LookAndSay.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Random; 4 | 5 | public class LookAndSay { 6 | // @include 7 | public static String lookAndSay(int n) { 8 | String s = "1"; 9 | for (int i = 1; i < n; ++i) { 10 | s = nextNumber(s); 11 | } 12 | return s; 13 | } 14 | 15 | private static String nextNumber(String s) { 16 | StringBuilder result = new StringBuilder(); 17 | for (int i = 0; i < s.length(); ++i) { 18 | int count = 1; 19 | while (i + 1 < s.length() && s.charAt(i) == s.charAt(i + 1)) { 20 | ++i; 21 | ++count; 22 | } 23 | result.append(count); 24 | result.append(s.charAt(i)); 25 | } 26 | return result.toString(); 27 | } 28 | // @exclude 29 | 30 | public static void main(String[] args) { 31 | Random r = new Random(); 32 | int n; 33 | if (args.length == 1) { 34 | n = Integer.parseInt(args[0]); 35 | } else { 36 | n = r.nextInt(20) + 1; 37 | } 38 | assert(lookAndSay(1).equals("1")); 39 | assert(lookAndSay(2).equals("11")); 40 | assert(lookAndSay(3).equals("21")); 41 | assert(lookAndSay(4).equals("1211")); 42 | assert(lookAndSay(5).equals("111221")); 43 | assert(lookAndSay(6).equals("312211")); 44 | assert(lookAndSay(7).equals("13112221")); 45 | assert(lookAndSay(8).equals("1113213211")); 46 | 47 | System.out.println("n = " + n); 48 | System.out.println(lookAndSay(n)); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/MagicMazeGame.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | // @include 4 | public class MagicMazeGame extends MazeGame { 5 | // The default constructor will call superclass constructor. 6 | @Override 7 | protected Room makeRoom() { 8 | return new MagicRoom(); 9 | } 10 | } 11 | //@exclude 12 | 13 | class MagicRoom implements Room { 14 | public void connect(Room that) {} 15 | } 16 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/MaxSubmatrixRectangleBruteForce.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class MaxSubmatrixRectangleBruteForce { 7 | // O(m^3 n^3) time solution. 8 | public static int maxRectangleSubmatrixBruteForce(List> A) { 9 | int max = 0; 10 | for (int a = 0; a < A.size(); ++a) { 11 | for (int b = 0; b < A.get(a).size(); ++b) { 12 | for (int c = a; c < A.size(); ++c) { 13 | for (int d = b; d < A.get(c).size(); ++d) { 14 | boolean all1 = true; 15 | int count = 0; 16 | for (int i = a; i <= c; ++i) { 17 | for (int j = b; j <= d; ++j) { 18 | if (!A.get(i).get(j)) { 19 | all1 = false; 20 | count = 0; 21 | break; 22 | } else { 23 | ++count; 24 | } 25 | } 26 | if (!all1) { 27 | break; 28 | } 29 | } 30 | if (all1 && count > max) { 31 | max = count; 32 | } 33 | } 34 | } 35 | } 36 | } 37 | return max; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/MazeGame.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | // @include 4 | public abstract class MazeGame { 5 | // Template method pattern - uses subclasses implemention of makeRoom() 6 | public MazeGame() { 7 | Room room1 = makeRoom(); 8 | Room room2 = makeRoom(); 9 | room1.connect(room2); 10 | this.addRoom(room1); 11 | this.addRoom(room2); 12 | } 13 | 14 | // Implementing classes provide this method. 15 | abstract protected Room makeRoom(); 16 | // @exclude 17 | private void addRoom(Room that) {} 18 | // @include 19 | } 20 | // @exclude 21 | 22 | interface Room { 23 | public void connect(Room that); 24 | } 25 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/MazeGameMain.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class MazeGameMain { 4 | public static void main(String[] args) { 5 | // @include 6 | MazeGame ordinaryGame = new OrdinaryMazeGame(); 7 | MazeGame magicGame = new MagicMazeGame(); 8 | //@exclude 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/MinimumWaitingTime.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | import java.util.Random; 8 | 9 | public class MinimumWaitingTime { 10 | // @include 11 | public static int minimumTotalWaitingTime(List serviceTimes) { 12 | // Sort the service times in increasing order. 13 | Collections.sort(serviceTimes); 14 | 15 | int totalWaitingTime = 0; 16 | for (int i = 0; i < serviceTimes.size(); ++i) { 17 | int numRemainingQueries = serviceTimes.size() - (i + 1); 18 | totalWaitingTime += serviceTimes.get(i) * numRemainingQueries; 19 | } 20 | return totalWaitingTime; 21 | } 22 | // @exclude 23 | 24 | private static void smallTest() { 25 | assert(10 == minimumTotalWaitingTime(Arrays.asList(5, 1, 2, 3))); 26 | } 27 | 28 | public static void main(String[] args) { 29 | smallTest(); 30 | Random r = new Random(); 31 | int n; 32 | if (args.length == 1) { 33 | n = Integer.parseInt(args[0]); 34 | } else { 35 | n = r.nextInt(100) + 1; 36 | } 37 | List waitingTime = new ArrayList<>(); 38 | for (int i = 0; i < n; ++i) { 39 | waitingTime.add(r.nextInt(1000)); 40 | } 41 | System.out.println(waitingTime); 42 | System.out.println(minimumTotalWaitingTime(waitingTime)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/NumberSteps.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Random; 4 | 5 | public class NumberSteps { 6 | // @include 7 | public static int numberOfWaysToTop(int top, int maximumStep) { 8 | return computeNumberOfWaysToH(top, maximumStep, new int[top + 1]); 9 | } 10 | 11 | private static int computeNumberOfWaysToH(int n, int maximumStep, 12 | int[] numberOfWaysToH) { 13 | if (n <= 1) { 14 | return 1; 15 | } 16 | if (numberOfWaysToH[n] == 0) { 17 | for (int i = 1; i <= maximumStep && n - i >= 0; ++i) { 18 | numberOfWaysToH[n] 19 | += computeNumberOfWaysToH(n - i, maximumStep, numberOfWaysToH); 20 | } 21 | } 22 | return numberOfWaysToH[n]; 23 | } 24 | // @exclude 25 | 26 | public static void main(String[] args) { 27 | assert(5 == numberOfWaysToTop(4, 2)); 28 | assert(1 == numberOfWaysToTop(1, 2)); 29 | assert(1 == numberOfWaysToTop(0, 3)); 30 | Random r = new Random(); 31 | int n, k; 32 | if (args.length == 2) { 33 | n = Integer.parseInt(args[0]); 34 | k = Integer.parseInt(args[1]); 35 | } else { 36 | n = r.nextInt(20) + 1; 37 | k = r.nextInt(n) + 1; 38 | } 39 | System.out.println("n = " + n + ", k = " + k); 40 | System.out.println(numberOfWaysToTop(n, k)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/OfflineSampling.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.Random; 7 | 8 | public class OfflineSampling { 9 | // @include 10 | public static void randomSampling(int k, List A) { 11 | Random gen = new Random(); 12 | for (int i = 0; i < k; ++i) { 13 | // Generate a random int in [i, A.size() - 1]. 14 | Collections.swap(A, i, i + gen.nextInt(A.size() - i)); 15 | } 16 | } 17 | // @exclude 18 | 19 | public static void main(String[] args) { 20 | int n, k; 21 | Random gen = new Random(); 22 | if (args.length == 1) { 23 | n = Integer.parseInt(args[0]); 24 | k = gen.nextInt(n) + 1; 25 | } else if (args.length == 2) { 26 | n = Integer.parseInt(args[0]); 27 | k = Integer.parseInt(args[1]); 28 | } else { 29 | n = gen.nextInt(1000000) + 1; 30 | k = gen.nextInt(n) + 1; 31 | } 32 | 33 | List A = new ArrayList<>(); 34 | for (int i = 0; i < n; ++i) { 35 | A.add(i); 36 | } 37 | System.out.println(n + " " + k); 38 | 39 | randomSampling(k, A); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/OrdinaryMazeGame.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | // @include 4 | public class OrdinaryMazeGame extends MazeGame { 5 | // The default constructor will call superclass constructor. 6 | @Override 7 | protected Room makeRoom() { 8 | return new OrdinaryRoom(); 9 | } 10 | } 11 | // @exclude 12 | 13 | class OrdinaryRoom implements Room { 14 | public void connect(Room that) {} 15 | } 16 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/Parity.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Random; 4 | 5 | public class Parity { 6 | public static void main(String[] args) { 7 | if (args.length == 1) { 8 | long x = Long.parseLong(args[0]); 9 | assert(Parity1.parity(x) == Parity3.parity(x)); 10 | assert(Parity2.parity(x) == Parity3.parity(x)); 11 | assert(Parity3.parity(x) == Parity4.parity(x)); 12 | System.out.println("x = " + x + ", parity = " + Parity3.parity(x)); 13 | } else { 14 | Random r = new Random(); 15 | for (int times = 0; times < 1000; ++times) { 16 | long x = r.nextInt(Integer.MAX_VALUE); 17 | assert(Parity1.parity(x) == Parity3.parity(x)); 18 | assert(Parity2.parity(x) == Parity3.parity(x)); 19 | assert(Parity4.parity(x) == Parity3.parity(x)); 20 | System.out.println("x = " + x + ", parity = " + Parity3.parity(x)); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/Parity2.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class Parity2 { 4 | // @include 5 | public static short parity(long x) { 6 | short result = 0; 7 | while (x != 0) { 8 | result ^= 1; 9 | x &= (x - 1); // Drops the lowest set bit of x. 10 | } 11 | return result; 12 | } 13 | // @exclude 14 | } 15 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/Parity3.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class Parity3 { 4 | private static short[] precomputedParity; 5 | 6 | static { 7 | precomputedParity = new short[1 << 16]; 8 | for (int i = 0; i < (1 << 16); ++i) { 9 | precomputedParity[i] = Parity1.parity(i); 10 | } 11 | } 12 | 13 | // @include 14 | public static short parity(long x) { 15 | final int WORD_SIZE = 16; 16 | final int BIT_MASK = 0xFFFF; 17 | // clang-format off 18 | return (short) ( 19 | precomputedParity[(int)((x >>> (3 * WORD_SIZE)) & BIT_MASK)] 20 | ^ precomputedParity[(int)((x >>> (2 * WORD_SIZE)) & BIT_MASK)] 21 | ^ precomputedParity[(int)((x >>> WORD_SIZE) & BIT_MASK)] 22 | ^ precomputedParity[(int)(x & BIT_MASK)]); 23 | // clang-format on 24 | } 25 | // @exclude 26 | } 27 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/Parity4.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class Parity4 { 4 | // @include 5 | public static short parity(long x) { 6 | x ^= x >>> 32; 7 | x ^= x >>> 16; 8 | x ^= x >>> 8; 9 | x ^= x >>> 4; 10 | x ^= x >>> 2; 11 | x ^= x >>> 1; 12 | return (short)(x & 0x1); 13 | } 14 | // @exclude 15 | } 16 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/PermutationArray.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.Random; 7 | 8 | public class PermutationArray { 9 | public static void main(String[] args) { 10 | Random gen = new Random(); 11 | int n; 12 | for (int times = 0; times < 1000; ++times) { 13 | if (args.length == 1) { 14 | n = Integer.parseInt(args[0]); 15 | } else { 16 | n = gen.nextInt(100) + 1; 17 | } 18 | List A = new ArrayList<>(n), perm = new ArrayList<>(n); 19 | for (int i = 0; i < n; ++i) { 20 | A.add(i); 21 | perm.add(i); 22 | } 23 | 24 | // Knuth shuffle 25 | Collections.shuffle(perm); 26 | System.out.println("perm = " + perm); 27 | 28 | List B = new ArrayList<>(A); 29 | PermutationArray1.applyPermutation(perm, B); 30 | System.out.println(B); 31 | 32 | List C = new ArrayList<>(A); 33 | PermutationArray2.applyPermutation(perm, C); 34 | System.out.println(C); 35 | 36 | // check answer by comparing the two permutations 37 | assert(B.equals(C)); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/PermutationArray1.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | public class PermutationArray1 { 9 | // @include 10 | public static void applyPermutation(List perm, List A) { 11 | for (int i = 0; i < A.size(); ++i) { 12 | // Check if the element at index i has not been moved by checking if 13 | // perm.get(i) is nonnegative. 14 | int next = i; 15 | while (perm.get(next) >= 0) { 16 | Collections.swap(A, i, perm.get(next)); 17 | int temp = perm.get(next); 18 | // Subtracts perm.size() from an entry in perm to make it negative, 19 | // which indicates the corresponding move has been performed. 20 | perm.set(next, perm.get(next) - perm.size()); 21 | next = temp; 22 | } 23 | } 24 | 25 | // Restore perm. 26 | for (int i = 0; i < perm.size(); i++) { 27 | perm.set(i, perm.get(i) + perm.size()); 28 | } 29 | } 30 | // @exclude 31 | } 32 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/PermutationArray2.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.List; 6 | 7 | public class PermutationArray2 { 8 | // @include 9 | public static void applyPermutation(List perm, List A) { 10 | for (int i = 0; i < A.size(); ++i) { 11 | // Traverses the cycle to see if i is the minimum element. 12 | boolean isMin = true; 13 | int j = perm.get(i); 14 | while (j != i) { 15 | if (j < i) { 16 | isMin = false; 17 | break; 18 | } 19 | j = perm.get(j); 20 | } 21 | 22 | if (isMin) { 23 | cyclicPermutation(i, perm, A); 24 | } 25 | } 26 | } 27 | 28 | private static void cyclicPermutation(int start, List perm, 29 | List A) { 30 | int i = start; 31 | int temp = A.get(start); 32 | do { 33 | int nextI = perm.get(i); 34 | int nextTemp = A.get(nextI); 35 | A.set(nextI, temp); 36 | i = nextI; 37 | temp = nextTemp; 38 | } while (i != start); 39 | } 40 | // @exclude 41 | } 42 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/PlanningFishing.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Arrays; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import java.util.Random; 7 | 8 | public class PlanningFishing { 9 | // @include 10 | public static int maximizeFishing(List> A) { 11 | for (int i = 0; i < A.size(); ++i) { 12 | for (int j = 0; j < A.get(i).size(); ++j) { 13 | A.get(i).set(j, A.get(i).get(j) 14 | + Math.max(i < 1 ? 0 : A.get(i - 1).get(j), 15 | j < 1 ? 0 : A.get(i).get(j - 1))); 16 | } 17 | } 18 | return A.get(A.size() - 1).get(A.get(0).size() - 1); 19 | } 20 | // @exclude 21 | 22 | public static void main(String[] args) { 23 | Random r = new Random(); 24 | int n, m; 25 | if (args.length == 2) { 26 | n = Integer.parseInt(args[0]); 27 | m = Integer.parseInt(args[1]); 28 | } else { 29 | n = r.nextInt(100) + 1; 30 | m = r.nextInt(100) + 1; 31 | } 32 | List> A = new ArrayList<>(n); 33 | for (int i = 0; i < n; ++i) { 34 | A.add(new ArrayList(m)); 35 | for (int j = 0; j < m; ++j) { 36 | A.get(i).add(r.nextInt(1000)); 37 | } 38 | } 39 | System.out.println(A); 40 | System.out.println(maximizeFishing(A)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/PostingListNode.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class PostingListNode { 4 | public int order; 5 | public PostingListNode next, jump; 6 | 7 | public PostingListNode(int order, PostingListNode next, 8 | PostingListNode jump) { 9 | this.order = order; 10 | this.next = next; 11 | this.jump = jump; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/PrintLinkedListReverseOrder.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.Deque; 6 | import java.util.LinkedList; 7 | 8 | public class PrintLinkedListReverseOrder { 9 | // @include 10 | public static void printLinkedListInReverse(ListNode head) { 11 | Deque nodes = new LinkedList<>(); 12 | while (head != null) { 13 | nodes.addFirst(head.data); 14 | head = head.next; 15 | } 16 | while (!nodes.isEmpty()) { 17 | System.out.println(nodes.poll()); 18 | } 19 | } 20 | // @exclude 21 | 22 | public static void main(String[] args) { 23 | printLinkedListInReverse( 24 | new ListNode<>(1, new ListNode<>(2, new ListNode<>(3, null)))); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/RemoveKthLastList.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | public class RemoveKthLastList { 6 | // @include 7 | // Assumes L has at least k nodes, deletes the k-th last node in L. 8 | public static ListNode removeKthLast(ListNode L, int k) { 9 | ListNode dummyHead = new ListNode<>(0, L); 10 | ListNode first = dummyHead.next; 11 | while (k-- > 0) { 12 | first = first.next; 13 | } 14 | 15 | ListNode second = dummyHead; 16 | while (first != null) { 17 | second = second.next; 18 | first = first.next; 19 | } 20 | // second points to the (k + 1)-th last node, deletes its successor. 21 | second.next = second.next.next; 22 | return dummyHead.next; 23 | } 24 | // @exclude 25 | 26 | public static void main(String[] args) { 27 | ListNode L 28 | = new ListNode<>(1, new ListNode<>(2, new ListNode<>(3, null))); 29 | L = removeKthLast(L, 2); 30 | assert(L.data == 1 && L.next.data == 3); 31 | L = removeKthLast(L, 2); 32 | assert(L.data == 3 && L.next == null); 33 | L = removeKthLast(L, 1); 34 | assert(L == null); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/ReverseInteger.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Random; 4 | 5 | public class ReverseInteger { 6 | // @include 7 | public static long reverse(int x) { 8 | long result = 0; 9 | long xRemaining = Math.abs(x); 10 | while (xRemaining != 0) { 11 | result = result * 10 + xRemaining % 10; 12 | xRemaining /= 10; 13 | } 14 | return x < 0 ? -result : result; 15 | } 16 | // @exclude 17 | 18 | private static long checkAns(int x) { 19 | String s = String.valueOf(x); 20 | char chars[] = s.toCharArray(); 21 | StringBuilder result = new StringBuilder(); 22 | if (chars[0] == '-') { 23 | result.append('-'); 24 | } 25 | for (int i = chars.length - 1; i >= 0; i--) { 26 | if (chars[i] != '-') { 27 | result.append(chars[i]); 28 | } 29 | } 30 | return Long.parseLong(result.toString()); 31 | } 32 | 33 | public static void main(String[] args) { 34 | Random r = new Random(); 35 | int n; 36 | if (args.length == 1) { 37 | n = Integer.parseInt(args[0]); 38 | System.out.println("n = " + n + ", reversed n = " + reverse(n)); 39 | assert(checkAns(n) == reverse(n)); 40 | } else { 41 | for (int times = 0; times < 1000; ++times) { 42 | n = r.nextInt(); 43 | System.out.println("n = " + n + ", reversed n = " + reverse(n)); 44 | assert(checkAns(n) == reverse(n)); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/ReverseLinkedListRecursive.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | public class ReverseLinkedListRecursive { 6 | // @include 7 | public static ListNode reverseLinkedList(ListNode head) { 8 | if (head == null || head.next == null) { 9 | return head; 10 | } 11 | 12 | ListNode newHead = reverseLinkedList(head.next); 13 | head.next.next = head; 14 | head.next = null; 15 | return newHead; 16 | } 17 | // @exclude 18 | 19 | private static void print(ListNode head) { 20 | if (head != null) { 21 | System.out.println("(" + head.data + ")"); 22 | print(head.next); 23 | } 24 | } 25 | 26 | public static void main(String[] args) { 27 | ListNode l 28 | = new ListNode<>(1, new ListNode<>(2, new ListNode<>(3, null))); 29 | System.out.println("before reverse"); 30 | print(l); 31 | ListNode newhead = reverseLinkedList(l); 32 | System.out.println("\nafter reverse"); 33 | print(newhead); 34 | newhead = reverseLinkedList(newhead); 35 | System.out.println("\nafter another reverse"); 36 | print(newhead); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/RomanToInteger.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class RomanToInteger { 7 | // @include 8 | public static int romanToInteger(String s) { 9 | Map T = new HashMap() { 10 | { 11 | put('I', 1); 12 | put('V', 5); 13 | put('X', 10); 14 | put('L', 50); 15 | put('C', 100); 16 | put('D', 500); 17 | put('M', 1000); 18 | } 19 | }; 20 | 21 | int sum = T.get(s.charAt(s.length() - 1)); 22 | for (int i = s.length() - 2; i >= 0; --i) { 23 | if (T.get(s.charAt(i)) < T.get(s.charAt(i + 1))) { 24 | sum -= T.get(s.charAt(i)); 25 | } else { 26 | sum += T.get(s.charAt(i)); 27 | } 28 | } 29 | return sum; 30 | } 31 | // @exclude 32 | 33 | public static void main(String[] args) { 34 | assert(7 == romanToInteger("VII")); 35 | assert(184 == romanToInteger("CLXXXIV")); 36 | assert(9 == romanToInteger("IX")); 37 | assert(40 == romanToInteger("XL")); 38 | assert(60 == romanToInteger("LX")); 39 | assert(1500 == romanToInteger("MD")); 40 | assert(400 == romanToInteger("CD")); 41 | assert(1900 == romanToInteger("MCM")); 42 | assert(9919 == romanToInteger("MMMMMMMMMCMXIX")); 43 | if (args.length == 1) { 44 | System.out.println(args[0] + " equals to " + romanToInteger(args[0])); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/RotateArray.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | package com.epi; 3 | 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | public class RotateArray { 8 | // @include 9 | public static void rotateArray(int i, List A) { 10 | i %= A.size(); 11 | reverse(0, A.size(), A); 12 | reverse(0, i, A); 13 | reverse(i, A.size(), A); 14 | } 15 | 16 | private static void reverse(int begin, int end, List A) { 17 | for (int i = begin, j = end - 1; i < j; ++i, --j) { 18 | Collections.swap(A, i, j); 19 | } 20 | } 21 | // @exclude 22 | } 23 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/RotateArrayPermutation.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Elements of Programming Interviews. All rights reserved. 2 | 3 | package com.epi; 4 | 5 | import java.util.List; 6 | 7 | public class RotateArrayPermutation { 8 | // @include 9 | public static void rotateArray(int rotateAmount, List A) { 10 | rotateAmount %= A.size(); 11 | if (rotateAmount == 0) { 12 | return; 13 | } 14 | 15 | int numCycles = (int)GCD1.GCD(A.size(), rotateAmount); 16 | int cycleLength = A.size() / numCycles; 17 | 18 | for (int c = 0; c < numCycles; ++c) { 19 | applyCyclicPermutation(rotateAmount, c, cycleLength, A); 20 | } 21 | } 22 | 23 | private static void applyCyclicPermutation(int rotateAmount, int offset, 24 | int cycleLength, List A) { 25 | int temp = A.get(offset); 26 | for (int i = 1; i < cycleLength; ++i) { 27 | int val = A.get((offset + i * rotateAmount) % A.size()); 28 | A.set((offset + i * rotateAmount) % A.size(), temp); 29 | temp = val; 30 | } 31 | A.set(offset, temp); 32 | } 33 | // @exclude 34 | } 35 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/RotateArrayTest.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Arrays; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import java.util.Random; 7 | 8 | public class RotateArrayTest { 9 | public static List randVector(int len) { 10 | Random gen = new Random(); 11 | List ret = new ArrayList<>(len); 12 | while (len-- > 0) { 13 | ret.add(gen.nextInt(len + 1)); 14 | } 15 | return ret; 16 | } 17 | 18 | public static void checkAnswer(List A, int i, 19 | List rotated) { 20 | assert A.size() == rotated.size(); 21 | for (int idx = 0; idx < A.size(); ++idx) { 22 | assert(rotated.get((idx + i) % rotated.size()).equals(A.get(idx))); 23 | } 24 | } 25 | 26 | public static void main(String[] args) { 27 | Random gen = new Random(); 28 | for (int times = 0; times < 1000; ++times) { 29 | int len; 30 | if (args.length == 1) { 31 | len = Integer.parseInt(args[0]); 32 | } else { 33 | len = gen.nextInt(10000) + 1; 34 | } 35 | List A = randVector(len); 36 | int i = gen.nextInt(len); 37 | 38 | List B = new ArrayList<>(A); 39 | RotateArrayPermutation.rotateArray(i, B); 40 | checkAnswer(A, i, B); 41 | 42 | List C = new ArrayList<>(A); 43 | RotateArray.rotateArray(i, C); 44 | checkAnswer(A, i, C); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/S2.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Arrays; 4 | 5 | // @include 6 | public class S2 extends SpellCheckService { 7 | static String wLast = null; 8 | static String[] closestToLastWord = null; 9 | 10 | public static void service(ServiceRequest req, ServiceResponse resp) { 11 | String w = req.extractWordToCheckFromRequest(); 12 | String[] result = null; 13 | synchronized (S2.class) { 14 | if (w.equals(wLast)) { 15 | result = closestToLastWord; 16 | } 17 | } 18 | if (result == null) { 19 | result = Spell.closestInDictionary(w); 20 | synchronized (S2.class) { 21 | wLast = w; 22 | closestToLastWord = result; 23 | } 24 | } 25 | resp.encodeIntoResponse(result); 26 | } 27 | } 28 | // @exclude 29 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/SearchBST.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import com.epi.BinarySearchTreePrototypeTemplate.BSTNode; 4 | 5 | public class SearchBST { 6 | // @include 7 | public static BSTNode searchBST(BSTNode tree, int key) { 8 | if (tree == null || tree.data == key) { 9 | return tree; 10 | } 11 | return key < tree.data ? searchBST(tree.left, key) 12 | : searchBST(tree.right, key); 13 | } 14 | // @exclude 15 | 16 | public static void main(String[] args) { 17 | // 43 18 | // 23 47 19 | // 37 53 20 | // 29 41 21 | // 31 22 | BSTNode tree = new BSTNode<>(43); 23 | tree.left = new BSTNode<>(23); 24 | tree.left.right = new BSTNode<>(37); 25 | tree.left.right.left = new BSTNode<>(29); 26 | tree.left.right.left.right = new BSTNode<>(31); 27 | tree.left.right.right = new BSTNode<>(41); 28 | tree.right = new BSTNode<>(47); 29 | tree.right.right = new BSTNode<>(53); 30 | assert(tree == searchBST(tree, 43)); 31 | assert(tree.left == searchBST(tree, 23)); 32 | assert(tree.right == searchBST(tree, 47)); 33 | assert(tree.right.right == searchBST(tree, 53)); 34 | assert(tree.left.right.left == searchBST(tree, 29)); 35 | assert(null == searchBST(tree, 1000)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/SearchList.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Random; 4 | 5 | public class SearchList { 6 | // @include 7 | public static ListNode search(ListNode L, int key) { 8 | while (L != null && L.data != key) { 9 | L = L.next; 10 | } 11 | // If key was not present in the list, L will have become null. 12 | return L; 13 | } 14 | // @exclude 15 | 16 | public static void main(String[] args) { 17 | ListNode L; 18 | L = new ListNode<>(2, new ListNode<>(4, new ListNode<>(3, null))); 19 | assert(L == search(L, 2)); 20 | assert(L.next == search(L, 4)); 21 | assert(L.next.next == search(L, 3)); 22 | assert(null == search(L, 100)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/SimpleWebServer.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.io.IOException; 4 | import java.net.ServerSocket; 5 | import java.net.Socket; 6 | 7 | public class SimpleWebServer { 8 | // @include 9 | public static class SingleThreadWebServer { 10 | public static final int PORT = 8080; 11 | public static void main(String[] args) throws IOException { 12 | ServerSocket serversock = new ServerSocket(PORT); 13 | for (;;) { 14 | Socket sock = serversock.accept(); 15 | processReq(sock); 16 | } 17 | } 18 | // @exclude 19 | static void processReq(Socket sock) { return; } 20 | // @include 21 | } 22 | // @exclude 23 | } 24 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/SnakeString.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Random; 4 | 5 | public class SnakeString { 6 | // @include 7 | public static String snakeString(String s) { 8 | StringBuilder result = new StringBuilder(); 9 | // Outputs the first row, i.e., s[1], s[5], s[9], ... 10 | for (int i = 1; i < s.length(); i += 4) { 11 | result.append(s.charAt(i)); 12 | } 13 | // Outputs the second row, i.e., s[0], s[2], s[4], ... 14 | for (int i = 0; i < s.length(); i += 2) { 15 | result.append(s.charAt(i)); 16 | } 17 | // Outputs the third row, i.e., s[3], s[7], s[11], ... 18 | for (int i = 3; i < s.length(); i += 4) { 19 | result.append(s.charAt(i)); 20 | } 21 | return result.toString(); 22 | } 23 | // @exclude 24 | 25 | private static String randString(int len) { 26 | Random r = new Random(); 27 | StringBuilder ret = new StringBuilder(len); 28 | while (len-- > 0) { 29 | ret.append((char)(r.nextInt(26) + 'A')); 30 | } 31 | return ret.toString(); 32 | } 33 | 34 | private static void smallTest() { 35 | assert(snakeString("Hello World!").equals("e lHloWrdlo!")); 36 | } 37 | 38 | public static void main(String[] args) { 39 | smallTest(); 40 | Random r = new Random(); 41 | String s; 42 | if (args.length == 1) { 43 | s = args[0]; 44 | } else { 45 | s = randString(r.nextInt(100) + 1); 46 | } 47 | System.out.println(snakeString(s)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/StaticInitializer.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Calendar; 4 | import java.util.Date; 5 | import java.util.TimeZone; 6 | 7 | public class StaticInitializer { 8 | // @include 9 | private static final Date BOOM_START; 10 | private static final Date BOOM_END; 11 | 12 | static { 13 | Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 14 | gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0); 15 | BOOM_START = gmtCal.getTime(); 16 | gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); 17 | BOOM_END = gmtCal.getTime(); 18 | } 19 | // @exclude 20 | } 21 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/StringConcatenation.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.List; 4 | 5 | public class StringConcatenation { 6 | // @include 7 | public static String concat(List strings) { 8 | String result = ""; 9 | for (String s : strings) { 10 | result += s; 11 | } 12 | return result; 13 | } 14 | // @exclude 15 | } 16 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/StringConcatenationStringBuilder.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.List; 4 | 5 | public class StringConcatenationStringBuilder { 6 | // @include 7 | public static String concat(List strings) { 8 | StringBuilder result = new StringBuilder(); 9 | for (String s : strings) { 10 | result.append(s); 11 | } 12 | return result.toString(); 13 | } 14 | // @exclude 15 | } 16 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/SwapBits.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Random; 4 | 5 | public class SwapBits { 6 | // @include 7 | public static long swapBits(long x, int i, int j) { 8 | // Extract the i-th and j-th bits, and see if they differ. 9 | if (((x >>> i) & 1) != ((x >>> j) & 1)) { 10 | // i-th and j-th bits differ. We will swap them by flipping their values. 11 | // Select the bits to flip with bitMask. Since x^1 = 0 when x = 1 and 1 12 | // when x = 0, we can perform the flip XOR. 13 | long bitMask = (1L << i) | (1L << j); 14 | x ^= bitMask; 15 | } 16 | return x; 17 | } 18 | // @exclude 19 | 20 | private static void simpleTest() { 21 | assert(swapBits(47, 1, 4) == 61); 22 | assert(swapBits(28, 0, 2) == 25); 23 | } 24 | 25 | public static void main(String[] args) { 26 | simpleTest(); 27 | Random r = new Random(); 28 | long x; 29 | int i, j; 30 | if (args.length == 3) { 31 | x = Long.parseLong(args[0]); 32 | i = Integer.parseInt(args[1]); 33 | j = Integer.parseInt(args[2]); 34 | } else { 35 | x = r.nextLong(); 36 | i = r.nextInt(64); 37 | j = r.nextInt(64); 38 | } 39 | System.out.println("x = " + x + ", i = " + i + ", j = " + j); 40 | System.out.println(swapBits(x, i, j)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/TODO.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | //@include 4 | public class TODO { 5 | public static void main(String[] args) { 6 | System.out.println("Dummy file"); 7 | assert(false); 8 | } 9 | } 10 | //@exclude 11 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/TailCoin.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Random; 4 | 5 | public class TailCoin { 6 | // @include 7 | // Return the number of failed trails. 8 | public static int simulateBiasedCoin(int n, int trails) { 9 | // We use it to generate random double in [0.0, 1.0]. 10 | Random gen = new Random(); 11 | double kBias = 0.4; 12 | int fails = 0; 13 | for (int i = 0; i < trails; ++i) { 14 | int biasedNum = 0; 15 | for (int j = 0; j < n; ++j) { 16 | biasedNum += (gen.nextDouble() >= kBias ? 1 : 0); 17 | } 18 | 19 | if (biasedNum < (n / 2)) { 20 | ++fails; 21 | } 22 | } 23 | return fails; 24 | } 25 | // @exclude 26 | 27 | public static void main(String[] args) { 28 | int n, trails; 29 | Random gen = new Random(); 30 | if (args.length == 2) { 31 | n = Integer.parseInt(args[0]); 32 | trails = Integer.parseInt(args[1]); 33 | } else { 34 | n = gen.nextInt(1000) + 1; 35 | trails = gen.nextInt(1000) + 1; 36 | } 37 | int fails = simulateBiasedCoin(n, trails); 38 | System.out.println("fails = " + fails); 39 | System.out.println("ratio = " + ((double)fails) / trails); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/TaskExecutionWebServer.java: -------------------------------------------------------------------------------- 1 | import java.util.concurrent.*; 2 | import java.io.*; 3 | import java.net.*; 4 | 5 | public class TaskExecutionWebServer { 6 | // @include 7 | public static class ThreadPoolWebServer { 8 | private static final int NTHREADS = 100; 9 | private static final int SERVERPORT = 8080; 10 | private static final Executor exec = Executors.newFixedThreadPool(NTHREADS); 11 | 12 | public static void main(String[] args) throws IOException { 13 | ServerSocket serversocket = new ServerSocket(SERVERPORT); 14 | while (true) { 15 | final Socket connection = serversocket.accept(); 16 | Runnable task = new Runnable() { 17 | public void run() { Worker.handleRequest(connection); } 18 | }; 19 | exec.execute(task); 20 | } 21 | } 22 | } 23 | // @exclude 24 | } 25 | 26 | class Worker { 27 | static void handleRequest(Socket connection) {} 28 | } 29 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/ThreadPerTaskWebserver.java: -------------------------------------------------------------------------------- 1 | import java.net.*; 2 | import java.io.*; 3 | 4 | public class ThreadPerTaskWebserver { 5 | // @include 6 | public static class ConcurrentWebServer { 7 | private static final int SERVERPORT = 8080; 8 | public static void main(String[] args) throws IOException { 9 | final ServerSocket serversocket = new ServerSocket(SERVERPORT); 10 | while (true) { 11 | final Socket connection = serversocket.accept(); 12 | Runnable task = new Runnable() { 13 | public void run() { Worker.handleRequest(connection); } 14 | }; 15 | new Thread(task).start(); 16 | } 17 | } 18 | } 19 | // @exclude 20 | } 21 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/TreeTraversal.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import com.epi.BinaryTreePrototypeTemplate.BinaryTreeNode; 4 | 5 | public class TreeTraversal { 6 | // @include 7 | public static void treeTraversal(BinaryTreeNode root) { 8 | if (root != null) { 9 | // Preorder: Processes the root before the traversals of left and right 10 | // children. 11 | System.out.println("Preorder: " + root.data); 12 | treeTraversal(root.left); 13 | // Inorder: Processes the root after the traversal of left child and 14 | // before the traversal of right child. 15 | System.out.println("Inorder: " + root.data); 16 | treeTraversal(root.right); 17 | // Postorder: Processes the root after the traversals of left and right 18 | // children. 19 | System.out.println("Postorder: " + root.data); 20 | } 21 | } 22 | // @exclude 23 | 24 | public static void main(String[] args) { 25 | // 3 26 | // 2 5 27 | // 1 4 6 28 | BinaryTreeNode tree = new BinaryTreeNode<>(3); 29 | tree.left = new BinaryTreeNode<>(2); 30 | tree.left.left = new BinaryTreeNode<>(1); 31 | tree.right = new BinaryTreeNode<>(5); 32 | tree.right.left = new BinaryTreeNode<>(4); 33 | tree.right.right = new BinaryTreeNode<>(6); 34 | treeTraversal(tree); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/TwoThreadIncrement.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class TwoThreadIncrement { 4 | //@include 5 | public static class IncrementThread implements Runnable { 6 | public void run() { 7 | for (int i = 0; i < TwoThreadIncrementDriver.N; i++) { 8 | TwoThreadIncrementDriver.counter++; 9 | } 10 | } 11 | } 12 | 13 | public static class TwoThreadIncrementDriver { 14 | public static int counter; 15 | public static int N; 16 | 17 | public static void main(String[] args) throws Exception { 18 | N = (args.length > 0) ? new Integer(args[0]) : 100; 19 | 20 | Thread t1 = new Thread(new IncrementThread()); 21 | Thread t2 = new Thread(new IncrementThread()); 22 | 23 | t1.start(); 24 | t2.start(); 25 | t1.join(); 26 | t2.join(); 27 | 28 | System.out.println(counter); 29 | } 30 | } 31 | //@exclude 32 | } 33 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/UniformRandomNumberGeneration.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | import java.util.Random; 4 | 5 | public class UniformRandomNumberGeneration { 6 | static int zeroOneRandom() { 7 | Random gen = new Random(); 8 | return gen.nextInt(2); 9 | } 10 | 11 | // @include 12 | public static int uniformRandom(int lowerBound, int upperBound) { 13 | int numberOfOutcomes = upperBound - lowerBound + 1, result; 14 | do { 15 | result = 0; 16 | for (int i = 0; (1 << i) < numberOfOutcomes; ++i) { 17 | // zeroOneRandom() is the provided random number generator. 18 | result = (result << 1) | zeroOneRandom(); 19 | } 20 | } while (result >= numberOfOutcomes); 21 | return result + lowerBound; 22 | } 23 | // @exclude 24 | 25 | public static void main(String[] args) { 26 | Random gen = new Random(); 27 | for (int times = 0; times < 1000; ++times) { 28 | int a, b; 29 | if (args.length == 2) { 30 | a = Integer.parseInt(args[0]); 31 | b = Integer.parseInt(args[1]); 32 | } else { 33 | a = gen.nextInt(100); 34 | b = gen.nextInt(100) + a + 1; 35 | } 36 | int x = uniformRandom(a, b); 37 | System.out.println(String.format("a = %d, b = %d", a, b)); 38 | System.out.println(String.format("random result = %d", x)); 39 | assert x >= a && x <= b; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/ValidPalindrome.java: -------------------------------------------------------------------------------- 1 | package com.epi; 2 | 3 | public class ValidPalindrome { 4 | // @include 5 | public static boolean isPalindrome(String s) { 6 | // i moves forward, and j moves backward. 7 | int i = 0, j = s.length() - 1; 8 | while (i < j) { 9 | // i and j both skip non-alphanumeric characters. 10 | while (!Character.isLetterOrDigit(s.charAt(i)) && i < j) { 11 | ++i; 12 | } 13 | while (!Character.isLetterOrDigit(s.charAt(j)) && i < j) { 14 | --j; 15 | } 16 | if (Character.toLowerCase(s.charAt(i++)) 17 | != Character.toLowerCase(s.charAt(j--))) { 18 | return false; 19 | } 20 | } 21 | return true; 22 | } 23 | // @exclude 24 | 25 | public static void main(String[] args) { 26 | assert(isPalindrome("A man, a plan, a canal: Panama")); 27 | assert(!isPalindrome("race a car")); 28 | assert(isPalindrome("Able was I, ere I saw Elba!")); 29 | assert(!isPalindrome("Ray a Ray")); 30 | assert(isPalindrome("")); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script reformats source files using the clang-format utility. 4 | # Set the list of source directories on the "for" line below. 5 | # 6 | # The file .clang-format in this directory specifies the formatting parameters. 7 | # 8 | # Files are changed in-place, so make sure you don't have anything open in an 9 | # editor, and you may want to commit before formatting in case of awryness. 10 | # 11 | # Note that clang-format is not included with OS X or Xcode; you must 12 | # install it yourself. There are multiple ways to do this: 13 | # 14 | # - If you use Xcode, install the ClangFormat-Xcode plugin. See instructions at 15 | # . 16 | # After installation, the executable can be found at 17 | # $HOME/Library/Application Support/Alcatraz/Plug-ins/ClangFormat/bin/clang-format. 18 | # 19 | # - Download an LLVM release from . 20 | # For OS X, use the pre-built binaries for "Darwin". 21 | # 22 | # - Build the LLVM tools from source. See the documentation at . 23 | 24 | # Change this if your clang-format executable is somewhere else 25 | 26 | for DIRECTORY in . 27 | do 28 | echo "Formatting code under $DIRECTORY/" 29 | find "$DIRECTORY" \( -name '*.java' \) -print0 | xargs -0 "clang-format" -i 30 | done 31 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/utils/AbstractPairWriter.java: -------------------------------------------------------------------------------- 1 | package com.epi.utils; 2 | 3 | public interface AbstractPairWriter { 4 | AbstractPairWriter writePair(String name, Object value); 5 | void close(); 6 | } 7 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/utils/AbstractTestOptions.java: -------------------------------------------------------------------------------- 1 | package com.epi.utils; 2 | 3 | public abstract class AbstractTestOptions { 4 | public abstract AbstractTestStream getStream(); 5 | public abstract void startTests(int id, String description); 6 | public abstract void endTests(); 7 | 8 | public int performanceTestLimitMultiplier() { 9 | return 4; 10 | } 11 | 12 | public int performanceTestLoadMultiplier() { 13 | return 1000; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/utils/AbstractTestStream.java: -------------------------------------------------------------------------------- 1 | package com.epi.utils; 2 | 3 | public interface AbstractTestStream { 4 | void startTest(TestType type, String description); 5 | void endTest(); 6 | 7 | void registerInput(Object value); 8 | void registerExpectedOutput(Object value); 9 | void registerUserOutput(Object value, boolean match); 10 | void registerUnhandledException(); 11 | void registerNullPointerException(); 12 | void registerPerformanceTest(PerformanceMeasure m, AbstractTestOptions options); 13 | 14 | AbstractPairWriter getInputWriter(); 15 | AbstractPairWriter getExpectedOutputWriter(); 16 | AbstractPairWriter getUserOutputWriter(boolean match); 17 | } 18 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/utils/JsonPairWriter.java: -------------------------------------------------------------------------------- 1 | package com.epi.utils; 2 | 3 | import javax.json.Json; 4 | import javax.json.JsonObjectBuilder; 5 | 6 | public class JsonPairWriter implements AbstractPairWriter { 7 | private JsonObjectBuilder builder; 8 | private JsonObjectBuilder outerBlock; 9 | private String blockName; 10 | 11 | public JsonPairWriter(String blockName, JsonObjectBuilder outerBlock) { 12 | this.outerBlock = outerBlock; 13 | this.blockName = blockName; 14 | builder = Json.createObjectBuilder(); 15 | } 16 | 17 | @Override 18 | public AbstractPairWriter writePair(String name, Object value) { 19 | JsonUniversalObjectWriter.handle(builder, name, value); 20 | return this; 21 | } 22 | 23 | @Override 24 | public void close() { 25 | outerBlock.add(blockName, builder); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/utils/JsonTestOptions.java: -------------------------------------------------------------------------------- 1 | package com.epi.utils; 2 | 3 | import java.io.PrintStream; 4 | 5 | import javax.json.Json; 6 | import javax.json.JsonArrayBuilder; 7 | import javax.json.JsonObjectBuilder; 8 | import javax.json.JsonWriter; 9 | 10 | public class JsonTestOptions extends AbstractTestOptions { 11 | private PrintStream logstream; 12 | private JsonObjectBuilder jsonRoot; 13 | private JsonArrayBuilder jsonTests; 14 | 15 | private final static String TEST_TAG = "###EPI_TESTS###\n"; 16 | 17 | public JsonTestOptions(PrintStream logstream) { 18 | this.logstream = logstream; 19 | } 20 | 21 | 22 | @Override 23 | public AbstractTestStream getStream() { 24 | return new JsonTestStream(jsonTests); 25 | } 26 | 27 | @Override 28 | public void startTests(int id, String description) { 29 | jsonRoot = Json.createObjectBuilder(); 30 | jsonTests = Json.createArrayBuilder(); 31 | 32 | jsonRoot.add("problem_id", "" + id); 33 | jsonRoot.add("problem_name", description); 34 | } 35 | 36 | @Override 37 | public void endTests() { 38 | jsonRoot.add("tests", jsonTests); 39 | logstream.print(TEST_TAG); 40 | logstream.print(jsonRoot.build().toString()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/utils/PerformanceMeasure.java: -------------------------------------------------------------------------------- 1 | package com.epi.utils; 2 | 3 | 4 | public class PerformanceMeasure { 5 | private StopWatch reference = new StopWatch(); 6 | private StopWatch user = new StopWatch(); 7 | private long limit; 8 | 9 | public StopWatch getReferenceStopwatch() { 10 | return reference; 11 | } 12 | 13 | public StopWatch getUserStopwatch() { 14 | return user; 15 | } 16 | 17 | public long getLimit(AbstractTestOptions options) { 18 | if (limit == 0) { 19 | limit = reference.getMillis() * options.performanceTestLimitMultiplier(); 20 | limit = ((limit + 999) / 1000) * 1000; 21 | } 22 | return limit; 23 | } 24 | 25 | public boolean succeeded(AbstractTestOptions options) { 26 | return user.getMillis() <= getLimit(options); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "\tReference: " + getReferenceStopwatch() + '\n' + 32 | "\tResult: " + getUserStopwatch() + '\n' + 33 | "\tLimit: " + String.valueOf(limit / 1000) + " s"; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/utils/StopWatch.java: -------------------------------------------------------------------------------- 1 | package com.epi.utils; 2 | 3 | public class StopWatch { 4 | private long start; 5 | private long duration; 6 | 7 | public void start() { 8 | //start = System.currentTimeMillis(); 9 | start = System.nanoTime() / 1000000; 10 | } 11 | 12 | public void stop() { 13 | //duration = System.currentTimeMillis() - start; 14 | duration = System.nanoTime() / 1000000 - start; 15 | } 16 | 17 | public long getMillis() { 18 | return duration; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return String.valueOf(duration / 1000) + '.' + String.format("%03d", duration % 1000) + " s"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/utils/TestType.java: -------------------------------------------------------------------------------- 1 | package com.epi.utils; 2 | 3 | public enum TestType { 4 | NORMAL, PERFORMANCE 5 | } 6 | -------------------------------------------------------------------------------- /java/src/main/java/com/epi/utils/TreeUtils.java: -------------------------------------------------------------------------------- 1 | package com.epi.utils; 2 | 3 | import com.epi.BinaryTreePrototypeTemplate; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by metopa on 30.03.2016. 9 | */ 10 | public class TreeUtils { 11 | private static BinaryTreePrototypeTemplate.BinaryTreeNode treeInsert(BinaryTreePrototypeTemplate.BinaryTreeNode node, int value) { 12 | if (node == null) { 13 | return new BinaryTreePrototypeTemplate.BinaryTreeNode<>(value); 14 | } 15 | else { 16 | if (value <= node.data) 17 | node.left = treeInsert(node.left, value); 18 | else 19 | node.right = treeInsert(node.right, value); 20 | return node; 21 | } 22 | } 23 | 24 | public static BinaryTreePrototypeTemplate.BinaryTreeNode buildTree(List values) { 25 | BinaryTreePrototypeTemplate.BinaryTreeNode root = null; 26 | for (Integer x : values) 27 | root = treeInsert(root, x); 28 | return root; 29 | } 30 | } 31 | --------------------------------------------------------------------------------