Skip to content

Commit

Permalink
Add simple-linked-list exercise
Browse files Browse the repository at this point in the history
  • Loading branch information
ageron committed Oct 22, 2024
1 parent fc97fcf commit 3be4c87
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,14 @@
"prerequisites": [],
"difficulty": 3
},
{
"slug": "simple-linked-list",
"name": "Simple Linked List",
"uuid": "76693889-80b3-4d93-8fe1-68c3267a1f85",
"practices": [],
"prerequisites": [],
"difficulty": 3
},
{
"slug": "spiral-matrix",
"name": "Spiral Matrix",
Expand Down
19 changes: 19 additions & 0 deletions exercises/practice/simple-linked-list/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Instructions

Write a prototype of the music player application.

For the prototype, each song will simply be represented by a number.
Given a range of numbers (the song IDs), create a singly linked list.

Given a singly linked list, you should be able to reverse the list to play the songs in the opposite order.

~~~~exercism/note
The linked list is a fundamental data structure in computer science, often used in the implementation of other data structures.
The simplest kind of linked list is a **singly** linked list.
That means that each element (or "node") contains data, along with something that points to the next node in the list.
If you want to dig deeper into linked lists, check out [this article][intro-linked-list] that explains it using nice drawings.
[intro-linked-list]: https://medium.com/basecs/whats-a-linked-list-anyway-part-1-d8b7e6508b9d
~~~~
5 changes: 5 additions & 0 deletions exercises/practice/simple-linked-list/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Introduction

You work for a music streaming company.

You've been tasked with creating a playlist feature for your music player application.
37 changes: 37 additions & 0 deletions exercises/practice/simple-linked-list/.meta/Example.roc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module [fromList, toList, push, pop, reverse, len]

SimpleLinkedList : [Nil, Cons U64 SimpleLinkedList]

fromList : List U64 -> SimpleLinkedList
fromList = \list ->
list |> List.walk Nil push

toList : SimpleLinkedList -> List U64
toList = \linkedList ->
when linkedList is
Nil -> []
Cons head tail -> tail |> toList |> List.append head

push : SimpleLinkedList, U64 -> SimpleLinkedList
push = \linkedList, item ->
Cons item linkedList

pop : SimpleLinkedList -> Result { value : U64, linkedList : SimpleLinkedList } [LinkedListWasEmpty]
pop = \linkedList ->
when linkedList is
Nil -> Err LinkedListWasEmpty
Cons head tail -> Ok { value: head, linkedList: tail }

reverse : SimpleLinkedList -> SimpleLinkedList
reverse = \linkedList ->
help = \result, rest ->
when rest is
Nil -> result
Cons head tail -> help (result |> push head) tail
help Nil linkedList

len : SimpleLinkedList -> U64
len = \linkedList ->
when linkedList is
Nil -> 0
Cons _ tail -> 1 + len tail
19 changes: 19 additions & 0 deletions exercises/practice/simple-linked-list/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"ageron"
],
"files": {
"solution": [
"SimpleLinkedList.roc"
],
"test": [
"simple-linked-list-test.roc"
],
"example": [
".meta/Example.roc"
]
},
"blurb": "Write a simple linked list implementation that uses Elements and a List.",
"source": "Inspired by 'Data Structures and Algorithms with Object-Oriented Design Patterns in Ruby', singly linked-lists.",
"source_url": "https://web.archive.org/web/20160731005714/http://brpreiss.com/books/opus8/html/page96.html"
}
33 changes: 33 additions & 0 deletions exercises/practice/simple-linked-list/SimpleLinkedList.roc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module [fromList, toList, push, pop, reverse, len]

SimpleLinkedList : {
# TODO: change this type however you need
todo : U64,
todo2 : U64,
todo3 : U64,
# etc.
}

fromList : List U64 -> SimpleLinkedList
fromList = \list ->
crash "Please implement the 'fromList' function"

toList : SimpleLinkedList -> List U64
toList = \linkedList ->
crash "Please implement the 'toList' function"

push : SimpleLinkedList, U64 -> SimpleLinkedList
push = \linkedList, item ->
crash "Please implement the 'push' function"

pop : SimpleLinkedList -> Result { value : U64, linkedList : SimpleLinkedList } _
pop = \linkedList ->
crash "Please implement the 'pop' function"

reverse : SimpleLinkedList -> SimpleLinkedList
reverse = \linkedList ->
crash "Please implement the 'reverse' function"

len : SimpleLinkedList -> U64
len = \linkedList ->
crash "Please implement the 'len' function"
76 changes: 76 additions & 0 deletions exercises/practice/simple-linked-list/simple-linked-list-test.roc
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# File last updated on 2024-10-22
app [main] {
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.15.0/SlwdbJ-3GR7uBWQo6zlmYWNYOxnvo8r6YABXD-45UOw.tar.br",
}

main =
Task.ok {}

import SimpleLinkedList exposing [fromList, toList, push, pop, reverse, len]

# can create an empty linked list
expect
result = [] |> fromList |> toList
expected = []
result == expected

# can create a linked list with a single element
expect
result = [123] |> fromList |> toList
expected = [123]
result == expected

# can create a linked list with multiple elements
expect
result = [123, 456, 789] |> fromList |> toList
expected = [123, 456, 789]
result == expected

# can push items to a linked list
expect
result = [123] |> fromList |> push 456 |> push 789 |> toList
expected = [123, 456, 789]
result == expected

# can pop an item from a linked list
expect
popResult = [123, 456, 789] |> fromList |> pop
result = popResult |> Result.try \popped -> Ok popped.value
expected = Ok 789
result == expected

# the last element should be gone after pop
expect
popResult = [123, 456, 789] |> fromList |> pop
result = popResult |> Result.try \popped -> Ok (popped.linkedList |> toList)
expected = Ok [123, 456]
result == expected

# cannot pop an empty linked list
expect
result = [] |> fromList |> pop
result |> Result.isErr

# can reverse a linked list
expect
result = [123, 456, 789] |> fromList |> reverse |> toList
expected = [789, 456, 123]
result == expected

# can reverse an empty linked list and it's still empty
expect
result = [] |> fromList |> reverse |> toList
expected = []
result == expected

# can get the length of a linked list
expect
result = [123, 456, 789] |> fromList |> len
expected = 3
result == expected

# can get the length of an empty linked list
expect
result = [] |> fromList |> len
expected = 0
result == expected

0 comments on commit 3be4c87

Please sign in to comment.