diff --git a/linked_list/01A-find-nth-value.rb b/linked_list/01A-find-nth-value.rb index 8eb2709..9b62141 100644 --- a/linked_list/01A-find-nth-value.rb +++ b/linked_list/01A-find-nth-value.rb @@ -3,13 +3,51 @@ # # Notice that this problem has no assumptions that we had in the earlier problem. +require_relative 'linked_list' +require "minitest/autorun" + def value_of_nth_node(ll, n) + current_node = ll.head + (n-1).times do + return "Input too large" if !(current_node.next) + current_node = current_node.next + end + return current_node.value end +class TestValueOfNthNode < Minitest::Test + def setup + @long_linked_list = LinkedList.new + (1..100).each do |i| + @long_linked_list.insert(i) + end + @medium_linked_list = LinkedList.new + 20.downto(1).each do |j| + @medium_linked_list.insert(j) + end + @short_linked_list = LinkedList.new + @short_linked_list.insert(1) + end -require "minitest/autorun" + def test_first_node_of_long_linked_list + assert_equal 100, value_of_nth_node(@long_linked_list, 1) + end -class TestValueOfNthNode < Minitest::Test - def setup + def test_last_node_of_long_linked_list + assert_equal 1, value_of_nth_node(@long_linked_list, 100) + end + + def test_middle_node_of_long_linked_list + assert_equal 46, value_of_nth_node(@long_linked_list, 55) + end + + def test_first_node_of_short_linked_list + assert_equal 1, value_of_nth_node(@short_linked_list, 1) + end + + def test_nth_node_of_medium_linked_list + assert_equal 15, value_of_nth_node(@medium_linked_list, 15) + assert_equal 20, value_of_nth_node(@medium_linked_list, 20) + assert_equal "Input too large", value_of_nth_node(@medium_linked_list, 21) end end diff --git a/linked_list/02-find-nth-from-last.rb b/linked_list/02-find-nth-from-last.rb index 2f17c82..5d74e31 100644 --- a/linked_list/02-find-nth-from-last.rb +++ b/linked_list/02-find-nth-from-last.rb @@ -3,6 +3,53 @@ # # Notice that this problem has no assumptions that we had in the earlier problem. -def find_nth_from_last(ll, n) +require_relative 'linked_list' +require "minitest/autorun" +def length_of_linked_list(ll, n) + current_node = ll.head + return 0 if !(current_node) + len = 1 + while !!(current_node.next) + len += 1 + current_node = current_node.next + end + + + return "Input too large" if n > len + current_node = ll.head + (len - n).times do + current_node = current_node.next + end + + return current_node.value end + +class TestValueOfNthNode < Minitest::Test + def setup + @long_linked_list = LinkedList.new + (1..100).each do |i| + @long_linked_list.insert(i) + end + @short_linked_list = LinkedList.new + @short_linked_list.insert(1) + @new_linked_list = LinkedList.new + end + + def test_length_of_long_linked_list + assert_equal 100, length_of_linked_list(@long_linked_list, 100) + end + + def test_length_of_short_linked_list + assert_equal 1, length_of_linked_list(@short_linked_list, 1) + end + + def test_length_of_new_linked_list + assert_equal 0, length_of_linked_list(@new_linked_list, 0) + end + + def test_nth_from_last_of_long_linked_list + assert_equal 45, length_of_linked_list(@long_linked_list, 45) + assert_equal "Input too large", length_of_linked_list(@long_linked_list, 120) + end +end \ No newline at end of file diff --git a/linked_list/03-find-intersection-of-two-linked-lists.rb b/linked_list/03-find-intersection-of-two-linked-lists.rb index 9f57c9a..32e12e9 100644 --- a/linked_list/03-find-intersection-of-two-linked-lists.rb +++ b/linked_list/03-find-intersection-of-two-linked-lists.rb @@ -1,5 +1,7 @@ -# Given 2 linked lists ll1 and ll2 that intersect, you need to find the value of the node of intersection. -# Write a method that takes 2 linked lists as arguments and return the value of the intersection node +# Given 2 linked lists ll1 and ll2 that intersect, you need to find the +# value of the node of intersection. +# Write a method that takes 2 linked lists as arguments and return the +# value of the intersection node require_relative 'linked_list' diff --git a/linked_list/04-find-start-of-circular-linked-list.rb b/linked_list/04-find-start-of-circular-linked-list.rb index cb6706f..c15f059 100644 --- a/linked_list/04-find-start-of-circular-linked-list.rb +++ b/linked_list/04-find-start-of-circular-linked-list.rb @@ -1,8 +1,46 @@ -# Write a method that takes a circular linked list as argument and returns the zero-based-index of the start of loop of linked list. -# +# Write a method that takes a circular linked list as argument and returns +# the zero-based-index of the start of loop of linked list. # Assume that the linked list is circular. # Circular linked list is a linked list of the shape 9 -def find_index_of_start_of_loop(ll) +require_relative 'linked_list' +require "minitest/autorun" +def find_start_of_loop(ll) + fast_runner = ll.head + slow_runner = ll.head + while !!(fast_runner.try(:next).try(:next)) + fast_runner = fast_runner.next.next + slow_runner = slow_runner.next + if fast_runner == slow_runner + fast_runner = ll.head + while (fast_runner != slow_runner) + slow_runner = slow_runner.next + fast_runner = fast_runner.next + end + + return fast_runner.value + end + end +end + +class TestJointLocation < Minitest::Test + def setup + @circular_linked_list = LinkedList.new + 20.downto(1).each do |i| + @circular_linked_list.insert(i) + end + current_node = @circular_linked_list.head + older_node = nil + while !!(current_node.next) + older_node = current_node if current_node.value == 5 + current_node = current_node.next + end + current_node.next = older_node + return @circular_linked_list + end + + def test_linked_list_is_infinite + assert_equal 5, find_start_of_loop(@circular_linked_list) + end end diff --git a/linked_list/linked_list.rb b/linked_list/linked_list.rb index 4710f66..f00b17d 100644 --- a/linked_list/linked_list.rb +++ b/linked_list/linked_list.rb @@ -34,5 +34,4 @@ def delete end end -class TestLinkedList < Minitest::Test -end +