diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..f1ffa4fb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +# Starting from a minimalist image +FROM ruby:2.7 +# Reference for help contact me +LABEL maintainer="chris@adadev.org" + +# Create a directory for the app +RUN mkdir /app + +# Set the working directory for RUN, ADD and COPY +WORKDIR /app + +# Add entire student fork (overwrites previously added files) +ARG SUBMISSION_SUBFOLDER +ADD $SUBMISSION_SUBFOLDER /app + + +COPY ./Gemfile . +RUN gem install bundler +RUN bundle install + +# Overwrite the script and test files +ADD test.sh /app +ADD test /app + +RUN chmod +x test.sh diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..04a9dcdd --- /dev/null +++ b/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem 'rake' +gem 'minitest' +gem 'minitest-spec' +gem 'minitest-reporters' +gem "pry" +gem 'minitest-skip' + diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..878af75d --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,36 @@ +GEM + remote: https://rubygems.org/ + specs: + ansi (1.5.0) + builder (3.2.4) + coderay (1.1.3) + method_source (1.0.0) + minitest (5.14.1) + minitest-reporters (1.4.2) + ansi + builder + minitest (>= 5.0) + ruby-progressbar + minitest-skip (0.0.1) + minitest (~> 5.0) + minitest-spec (0.0.2.1) + minitest (>= 3.0) + pry (0.13.1) + coderay (~> 1.1) + method_source (~> 1.0) + rake (13.0.1) + ruby-progressbar (1.10.1) + +PLATFORMS + ruby + +DEPENDENCIES + minitest + minitest-reporters + minitest-skip + minitest-spec + pry + rake + +BUNDLED WITH + 2.1.4 diff --git a/README.md b/README.md index e38d64fc..a1f2d313 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,4 @@ Design and implement the classes and the methods. Implement the methods within t ### Going Further -Create a new class called `DoublyLinkedList` which implements a doubly linked list. Then implement the following methods: - -- `add_first` -- `add_last` -- `get_first` -- `get_at_index(index)` -- `reverse` -- `delete(value)` +There are a set of advanced methods you can choose to implement for additional practice. diff --git a/lib/linked_list.rb b/lib/linked_list.rb index 8dee5e8d..0de1ee00 100644 --- a/lib/linked_list.rb +++ b/lib/linked_list.rb @@ -18,12 +18,16 @@ def initialize # method to add a new node with the specific data value in the linked list # insert the new node at the beginning of the linked list + # Time Complexity: ? + # Space Complexity: ? def add_first(value) raise NotImplementedError end # method to find if the linked list contains a node with specified value # returns true if found, false otherwise + # Time Complexity: ? + # Space Complexity: ? def search(value) raise NotImplementedError end @@ -36,12 +40,16 @@ def find_max # method to return the min value in the linked list # returns the data value and not the node + # Time Complexity: ? + # Space Complexity: ? def find_min raise NotImplementedError end # method that returns the length of the singly linked list + # Time Complexity: ? + # Space Complexity: ? def length raise NotImplementedError end @@ -49,22 +57,30 @@ def length # method that returns the value at a given index in the linked list # index count starts at 0 # returns nil if there are fewer nodes in the linked list than the index value + # Time Complexity: ? + # Space Complexity: ? def get_at_index(index) raise NotImplementedError end # method to print all the values in the linked list + # Time Complexity: ? + # Space Complexity: ? def visit raise NotImplementedError end # method to delete the first node found with specified value + # Time Complexity: ? + # Space Complexity: ? def delete(value) raise NotImplementedError end # method to reverse the singly linked list # note: the nodes should be moved and not just the values in the nodes + # Time Complexity: ? + # Space Complexity: ? def reverse raise NotImplementedError end @@ -72,12 +88,16 @@ def reverse ## Advanced Exercises # returns the value at the middle element in the singly linked list + # Time Complexity: ? + # Space Complexity: ? def find_middle_value raise NotImplementedError end # find the nth node from the end and return its value # assume indexing starts at 0 while counting to n + # Time Complexity: ? + # Space Complexity: ? def find_nth_from_end(n) raise NotImplementedError end @@ -85,6 +105,8 @@ def find_nth_from_end(n) # checks if the linked list has a cycle. A cycle exists if any node in the # linked list links to a node already visited. # returns true if a cycle is found, false otherwise. + # Time Complexity: ? + # Space Complexity: ? def has_cycle raise NotImplementedError end @@ -93,23 +115,31 @@ def has_cycle # Additional Exercises # returns the value in the first node # returns nil if the list is empty + # Time Complexity: ? + # Space Complexity: ? def get_first raise NotImplementedError end # method that inserts a given value as a new last node in the linked list + # Time Complexity: ? + # Space Complexity: ? def add_last(value) raise NotImplementedError end # method that returns the value of the last node in the linked list # returns nil if the linked list is empty + # Time Complexity: ? + # Space Complexity: ? def get_last raise NotImplementedError end # method to insert a new node with specific data value, assuming the linked # list is sorted in ascending order + # Time Complexity: ? + # Space Complexity: ? def insert_ascending(value) raise NotImplementedError end diff --git a/test.sh b/test.sh new file mode 100755 index 00000000..8509a009 --- /dev/null +++ b/test.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +rake diff --git a/test/linked_list_test.rb b/test/linked_list_test.rb index d169c9a0..7c695018 100644 --- a/test/linked_list_test.rb +++ b/test/linked_list_test.rb @@ -27,7 +27,7 @@ @list.add_first(3) # Assert - expect(@list.get_first).must_equal 3 + expect(@list.get_at_index(0)).must_equal 3 end it 'will put the last added item to the front of the list' do @@ -36,18 +36,18 @@ @list.add_first(2) # Assert - expect(@list.get_first).must_equal 2 + expect(@list.get_at_index(0)).must_equal 2 # Act again @list.add_first(3) # Assert - expect(@list.get_first).must_equal 3 + expect(@list.get_at_index(0)).must_equal 3 end it 'will return `nil` for `getFirst` if the list is empty' do - expect(@list.get_first).must_be_nil + expect(@list.get_at_index(0)).must_be_nil end end @@ -89,10 +89,28 @@ end end - describe "addLast & getLast" do + describe 'get_at_index' do + it 'returns nil if the index is outside the bounds of the list' do + expect(@list.get_at_index(3)).must_be_nil + end + + it 'can retrieve an item at an index in the list' do + @list.add_first(1) + @list.add_first(2) + @list.add_first(3) + @list.add_first(4) + + expect(@list.get_at_index(0)).must_equal 4 + expect(@list.get_at_index(1)).must_equal 3 + expect(@list.get_at_index(2)).must_equal 2 + expect(@list.get_at_index(3)).must_equal 1 + end + end + + xdescribe "Optional addLast & getLast" do it "will add to the front if the list is empty" do @list.add_last(1) - expect(@list.get_first).must_equal 1 + expect(@list.get_at_index(0)).must_equal 1 end it "will put new items to the rear of the list" do @@ -101,35 +119,17 @@ expect(@list.get_last).must_equal 2 @list.add_last(3) - expect(@list.get_first).must_equal 2 + expect(@list.get_at_index(0)).must_equal 2 expect(@list.get_last).must_equal 3 expect(@list.length).must_equal 2 @list.add_last(4) - expect(@list.get_first).must_equal 2 + expect(@list.get_at_index(0)).must_equal 2 expect(@list.get_last).must_equal 4 expect(@list.length).must_equal 3 end end - describe 'get_at_index' do - it 'returns nil if the index is outside the bounds of the list' do - expect(@list.get_at_index(3)).must_be_nil - end - - it 'can retrieve an item at an index in the list' do - @list.add_first(1) - @list.add_first(2) - @list.add_first(3) - @list.add_first(4) - - expect(@list.get_at_index(0)).must_equal 4 - expect(@list.get_at_index(1)).must_equal 3 - expect(@list.get_at_index(2)).must_equal 2 - expect(@list.get_at_index(3)).must_equal 1 - end - end - describe 'max and min values' do it 'returns nil if the list is empty' do expect(@list.find_max()).must_be_nil @@ -145,7 +145,7 @@ count += 1 end - @list.add_last(100) + @list.add_first(100) @list.add_first(-12) expect(@list.find_max).must_equal 100 expect(@list.find_min).must_equal(-12) @@ -160,39 +160,39 @@ end it "can delete valid values from list" do - @list.add_last(9) - @list.add_last(10) + @list.add_first(9) + @list.add_first(10) @list.add_first(4) @list.add_first(3) @list.add_first(2) - # delete fist node (requires updating head) + # delete first node (requires updating head) @list.delete(2) - expect(@list.get_first).must_equal 3 + expect(@list.get_at_index(0)).must_equal 3 expect(@list.length).must_equal 4 - expect(@list.get_last).must_equal 10 + expect(@list.get_at_index(@list.length - 1)).must_equal 9 expect(@list.find_max).must_equal 10 expect(@list.find_min).must_equal 3 # delete last node @list.delete(10) - expect(@list.get_first).must_equal 3 + expect(@list.get_at_index(0)).must_equal 3 expect(@list.length).must_equal 3 - expect(@list.get_last).must_equal 9 + expect(@list.get_at_index(@list.length - 1)).must_equal 9 expect(@list.find_max).must_equal 9 expect(@list.find_min).must_equal 3 - # delete fist node (requires updating head) + # delete first node (requires updating head) @list.delete(4) - expect(@list.get_first).must_equal 3 + expect(@list.get_at_index(0)).must_equal 3 expect(@list.length).must_equal 2 - expect(@list.get_last).must_equal 9 + expect(@list.get_at_index(@list.length - 1)).must_equal 9 expect(@list.find_max).must_equal 9 expect(@list.find_min).must_equal 3 end end - describe "nth_from_the_end" do + xdescribe "Optional: nth_from_the_end" do it 'returns nil if n is outside the bounds of the list' do expect(@list.find_nth_from_end(3)).must_be_nil end @@ -219,10 +219,10 @@ @list.add_first(1) @list.reverse - expect(@list.find_nth_from_end(0)).must_equal 1 - expect(@list.find_nth_from_end(1)).must_equal 2 - expect(@list.find_nth_from_end(2)).must_equal 3 - expect(@list.find_nth_from_end(3)).must_equal 4 + expect(@list.get_at_index(0)).must_equal 4 + expect(@list.get_at_index(1)).must_equal 3 + expect(@list.get_at_index(2)).must_equal 2 + expect(@list.get_at_index(3)).must_equal 1 end end end