Skip to content
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
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,14 @@
"practices": [],
"prerequisites": [],
"difficulty": 4
},
{
"slug": "linked-list",
"name": "Linked List",
"uuid": "e4d7413a-6429-4d6e-bcfd-580c9a449d4e",
"practices": [],
"prerequisites": [],
"difficulty": 4
}
]
},
Expand Down
5 changes: 5 additions & 0 deletions exercises/practice/linked-list/.busted
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
return {
default = {
ROOT = { '.' }
}
}
26 changes: 26 additions & 0 deletions exercises/practice/linked-list/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Instructions

Your team has decided to use a doubly linked list to represent each train route in the schedule.
Each station along the train's route will be represented by a node in the linked list.

You don't need to worry about arrival and departure times at the stations.
Each station will simply be represented by a number.

Routes can be extended, adding stations to the beginning or end of a route.
They can also be shortened by removing stations from the beginning or the end of a route.

Sometimes a station gets closed down, and in that case the station needs to be removed from the route, even if it is not at the beginning or end of the route.

The size of a route is measured not by how far the train travels, but by how many stations it stops at.

~~~~exercism/note
The linked list is a fundamental data structure in computer science, often used in the implementation of other data structures.
As the name suggests, it is a list of nodes that are linked together.
It is a list of "nodes", where each node links to its neighbor or neighbors.
In a **singly linked list** each node links only to the node that follows it.
In a **doubly linked list** each node links to both the node that comes before, as well as the node that comes after.

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
~~~~
6 changes: 6 additions & 0 deletions exercises/practice/linked-list/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Introduction

You are working on a project to develop a train scheduling system for a busy railway network.

You've been asked to develop a prototype for the train routes in the scheduling system.
Each route consists of a sequence of train stations that a given train stops at.
18 changes: 18 additions & 0 deletions exercises/practice/linked-list/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"authors": [
"glennj"
],
"files": {
"solution": [
"linked_list.moon"
],
"test": [
"linked_list_spec.moon"
],
"example": [
".meta/example.moon"
]
},
"blurb": "Implement a doubly linked list.",
"source": "Classic computer science topic"
}
68 changes: 68 additions & 0 deletions exercises/practice/linked-list/.meta/example.moon
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
class LinkedList
new: (@head = nil, @tail = nil) =>

push: (value) =>
node = {:value, next: nil, prev: nil}
if @tail
@tail.next = node
node.prev = @tail
else
@head = node
@tail = node

unshift: (value) =>
node = {:value, next: nil, prev: nil}
if @head
@head.prev = node
node.next = @head
else
@tail = node
@head = node

pop: =>
return unless @tail
value = @tail.value
if @head == @tail
@head, @tail = nil, nil
else
@tail.prev.next = nil
@tail = @tail.prev
value

shift: =>
return unless @head
value = @head.value
if @head == @tail
@head, @tail = nil, nil
else
@head.next.prev = nil
@head = @head.next
value

count: =>
n = 0
node = @head
while node != nil
n += 1
node = node.next
n

delete: (value) =>
node = @head
while node != nil
if node.value == value
if node.prev and node.next
node.prev.next = node.next
node.next.prev = node.prev
node = nil
elseif node.next
-- this is the head
@shift!
elseif node.prev
-- this is the tail
@pop!
else
@head, @tail = nil, nil
break
-- end if
node = node.next
17 changes: 17 additions & 0 deletions exercises/practice/linked-list/.meta/spec_generator.moon
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
module_name: 'LinkedList',

generate_test: (case, level) ->
lines = {
"list = LinkedList!",
}
for op in *case.input.operations
if op.value
table.insert lines, "list\\#{op.operation} #{op.value}"
elseif op.expected
table.insert lines, "assert.are.equal #{op.expected}, list\\#{op.operation}!"
else
table.insert lines, "list\\#{op.operation}!"

table.concat [indent line, level for line in *lines], '\n'
}
67 changes: 67 additions & 0 deletions exercises/practice/linked-list/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[7f7e3987-b954-41b8-8084-99beca08752c]
description = "pop gets element from the list"

[c3f67e5d-cfa2-4c3e-a18f-7ce999c3c885]
description = "push/pop respectively add/remove at the end of the list"

[00ea24ce-4f5c-4432-abb4-cc6e85462657]
description = "shift gets an element from the list"

[37962ee0-3324-4a29-b588-5a4c861e6564]
description = "shift gets first element from the list"

[30a3586b-e9dc-43fb-9a73-2770cec2c718]
description = "unshift adds element at start of the list"

[042f71e4-a8a7-4cf0-8953-7e4f3a21c42d]
description = "pop, push, shift, and unshift can be used in any order"

[88f65c0c-4532-4093-8295-2384fb2f37df]
description = "count an empty list"

[fc055689-5cbe-4cd9-b994-02e2abbb40a5]
description = "count a list with items"

[8272cef5-130d-40ea-b7f6-5ffd0790d650]
description = "count is correct after mutation"

[229b8f7a-bd8a-4798-b64f-0dc0bb356d95]
description = "popping to empty doesn't break the list"

[4e1948b4-514e-424b-a3cf-a1ebbfa2d1ad]
description = "shifting to empty doesn't break the list"

[e8f7c600-d597-4f79-949d-8ad8bae895a6]
description = "deletes the only element"

[fd65e422-51f3-45c0-9fd0-c33da638f89b]
description = "deletes the element with the specified value from the list"

[59db191a-b17f-4ab7-9c5c-60711ec1d013]
description = "deletes the element with the specified value from the list, re-assigns tail"

[58242222-5d39-415b-951d-8128247f8993]
description = "deletes the element with the specified value from the list, re-assigns head"

[ee3729ee-3405-4bd2-9bad-de0d4aa5d647]
description = "deletes the first of two elements"

[47e3b3b4-b82c-4c23-8c1a-ceb9b17cb9fb]
description = "deletes the second of two elements"

[7b420958-f285-4922-b8f9-10d9dcab5179]
description = "delete does not modify the list if the element is not found"

[7e04828f-6082-44e3-a059-201c63252a76]
description = "deletes only the first occurrence"
21 changes: 21 additions & 0 deletions exercises/practice/linked-list/linked_list.moon
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class LinkedList
new: (...) =>
error 'Implement the constructor'

push: (value) =>
error 'Implement the push method'

unshift: (value) =>
error 'Implement the unshift method'

pop: =>
error 'Implement the pop method'

shift: =>
error 'Implement the shift method'

count: =>
error 'Implement the count method'

delete: (value) =>
error 'Implement the delete method'
Loading
Loading