Skip to content

Add new exercise simple linked list #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ build/
bin/configlet
bin/configlet.exe
gradle/
/exercises/.nb-gradle/
1 change: 1 addition & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"octal",
"luhn",
"pig-latin",
"simple-linked-list",
"linked-list",
"nth-prime",
"pascals-triangle"
Expand Down
1 change: 1 addition & 0 deletions exercises/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ include 'prime-factors'
include 'scrabble-score'
include 'sieve'
include 'simple-cipher'
include 'simple-linked-list'
include 'space-age'
include 'strain'
include 'triangle'
Expand Down
12 changes: 12 additions & 0 deletions exercises/simple-linked-list/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apply plugin: "java"
apply plugin: "eclipse"
apply plugin: "idea"

repositories {
mavenCentral()
}

dependencies {
testCompile "junit:junit:4.10"
testCompile "org.assertj:assertj-core:3.2.0"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@

import java.lang.reflect.Array;
import java.util.NoSuchElementException;
import java.util.Objects;

public class SimpleLinkedList<T> {

private static class Element<T> {

final T value;
Element next;

Element(T value) {
this.value = value;
}
}

private Element<T> head;
private int size;

public SimpleLinkedList() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Java will provide a default constructor, so this isn't necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true! thanks.

Edit: this appears to be necessary because the test framework requires it. Let me know if you are aware of some way around it. I had forgotten that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be omitted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless you know another way, this is required by the test framework.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does new SimpleLInkedList() not work if you don't have this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the test class fails to compile.

}

public SimpleLinkedList(T[] values) {
for (int ii = values.length - 1; ii >= 0; ii--) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's interesting that this is backwards (in that this linked list is implemented as a stack).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the Java LinkedList class provides push and pop methods that both operate on the head (LIFO), so that's what I was emulating, but if it should be different please let me know.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other reason I did it this way is that this is how the Ruby track implements it. There is no test metadata for this exercise, so I used the Ruby example.rb as a template.

push(values[ii]);
}
}

public final void push(T value) {
Element<T> newElement = new Element<>(value);
this.size++;
if (Objects.isNull(head)) {
head = newElement;
} else {
newElement.next = head;
head = newElement;
}
}

public T pop() {
if (Objects.isNull(head)) {
throw new NoSuchElementException();
}
T value = head.value;
head = head.next;
this.size--;
return value;
}

public void reverse() {
Element<T> current = head;
Element<T> next;
Element<T> previous = null;
while (Objects.nonNull(current)) {
next = current.next;
current.next = previous;
previous = current;
current = next;
}
head = previous;
}

public T[] asArray(Class<T> clazz) {
T[] result = newArray(clazz, this.size);
int index = 0;
Element<T> current = head;
while (Objects.nonNull(current)) {
result[index++] = current.value;
current = current.next;
}
return result;
}

private <T> T[] newArray(Class<T> clazz, int size) {
@SuppressWarnings("unchecked")
T[] arr = (T[]) Array.newInstance(clazz, size);

return arr;
}

public int size() {
return this.size;
}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@

import java.util.NoSuchElementException;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;

public class SimpleLinkedListTest {

@Test
public void aNewListIsEmpty() {
SimpleLinkedList list = new SimpleLinkedList();
assertThat(list.size()).isEqualTo(0);
}

@Test
public void canCreateFromArray() {
Integer[] values = new Integer[]{1, 2, 3};
SimpleLinkedList list = new SimpleLinkedList(values);
assertThat(list.size()).isEqualTo(3);
}

@Test(expected = NoSuchElementException.class)
public void popOnEmptyListWillThrow() {
SimpleLinkedList list = new SimpleLinkedList();
list.pop();
}

@Test
public void popReturnsLastAddedElement() {
SimpleLinkedList list = new SimpleLinkedList();
list.push(9);
list.push(8);
assertThat(list.size()).isEqualTo(2);
assertThat(list.pop()).isEqualTo(8);
assertThat(list.pop()).isEqualTo(9);
assertThat(list.size()).isEqualTo(0);
}

@Test
public void reverseReversesList() {
SimpleLinkedList list = new SimpleLinkedList();
list.push(9);
list.push(8);
list.push(7);
list.push(6);
list.push(5);
list.reverse();
assertThat(list.pop()).isEqualTo(9);
assertThat(list.pop()).isEqualTo(8);
assertThat(list.pop()).isEqualTo(7);
assertThat(list.pop()).isEqualTo(6);
assertThat(list.pop()).isEqualTo(5);
}

@Test
public void canReturnListAsArray() {
SimpleLinkedList list = new SimpleLinkedList();
list.push(9);
list.push(8);
list.push(7);
list.push(6);
list.push(5);
Integer[] expected = {5, 6, 7, 8, 9};
assertThat(list.asArray(Integer.class)).containsExactly(expected);
}

@Test
public void canReturnEmptyListAsEmptyArray() {
SimpleLinkedList list = new SimpleLinkedList();
Object[] expected = {};
assertThat(list.asArray(Object.class)).containsExactly(expected);
}

}