mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
adding more examples to the computer_science folder, and fiddling with operator precedence
This commit is contained in:
parent
af53a04932
commit
e6f010b983
6 changed files with 780 additions and 598 deletions
106
examples/computer_science/linked_list.coffee
Normal file
106
examples/computer_science/linked_list.coffee
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
# "Classic" linked list implementation that doesn't keep track of its size.
|
||||||
|
LinkedList: =>
|
||||||
|
this._head: null # Pointer to the first item in the list.
|
||||||
|
|
||||||
|
|
||||||
|
# Appends some data to the end of the list. This method traverses the existing
|
||||||
|
# list and places the value at the end in a new node.
|
||||||
|
LinkedList::add: data =>
|
||||||
|
|
||||||
|
# Create a new node object to wrap the data.
|
||||||
|
node: {data: data, next: null}
|
||||||
|
|
||||||
|
current: this._head ||= node
|
||||||
|
|
||||||
|
if this._head isnt node
|
||||||
|
current: current.next while current.next
|
||||||
|
current.next: node
|
||||||
|
|
||||||
|
this
|
||||||
|
|
||||||
|
|
||||||
|
# Retrieves the data at the given position in the list.
|
||||||
|
LinkedList::item: index =>
|
||||||
|
|
||||||
|
# Check for out-of-bounds values.
|
||||||
|
return null if index < 0
|
||||||
|
|
||||||
|
current: this._head or null
|
||||||
|
i: -1
|
||||||
|
|
||||||
|
# Advance through the list.
|
||||||
|
current: current.next while current and index > (i += 1)
|
||||||
|
|
||||||
|
# Return null if we've reached the end.
|
||||||
|
current and current.data
|
||||||
|
|
||||||
|
|
||||||
|
# Remove the item from the given location in the list.
|
||||||
|
LinkedList::remove: index =>
|
||||||
|
|
||||||
|
# Check for out-of-bounds values.
|
||||||
|
return null if index < 0
|
||||||
|
|
||||||
|
current: this._head or null
|
||||||
|
i: -1
|
||||||
|
|
||||||
|
# Special case: removing the first item.
|
||||||
|
if index is 0
|
||||||
|
this._head: current.next
|
||||||
|
else
|
||||||
|
|
||||||
|
# Find the right location.
|
||||||
|
[previous, current]: [current, current.next] while index > (i += 1)
|
||||||
|
|
||||||
|
# Skip over the item to remove.
|
||||||
|
previous.next: current.next
|
||||||
|
|
||||||
|
# Return the value.
|
||||||
|
current and current.data
|
||||||
|
|
||||||
|
|
||||||
|
# Calculate the number of items in the list.
|
||||||
|
LinkedList::size: =>
|
||||||
|
current: this._head
|
||||||
|
count: 0
|
||||||
|
|
||||||
|
while current
|
||||||
|
count += 1
|
||||||
|
current: current.next
|
||||||
|
|
||||||
|
count
|
||||||
|
|
||||||
|
|
||||||
|
# Convert the list into an array.
|
||||||
|
LinkedList::toArray: =>
|
||||||
|
result: []
|
||||||
|
current: this._head
|
||||||
|
|
||||||
|
while current
|
||||||
|
result.push(current.data)
|
||||||
|
current: current.next
|
||||||
|
|
||||||
|
result
|
||||||
|
|
||||||
|
|
||||||
|
# The string representation of the linked list.
|
||||||
|
LinkedList::toString: => this.toArray().toString()
|
||||||
|
|
||||||
|
|
||||||
|
# Tests.
|
||||||
|
list: new LinkedList()
|
||||||
|
|
||||||
|
list.add("Hi")
|
||||||
|
print(list.size() is 1)
|
||||||
|
print(list.item(0) is "Hi")
|
||||||
|
print(list.item(1) is null)
|
||||||
|
|
||||||
|
list: new LinkedList()
|
||||||
|
list.add("zero").add("one").add("two")
|
||||||
|
print(list.size() is 3)
|
||||||
|
print(list.item(2) is "two")
|
||||||
|
print(list.remove(1) is "one")
|
||||||
|
print(list.item(0) is "zero")
|
||||||
|
print(list.item(1) is "two")
|
||||||
|
print(list.size() is 2)
|
||||||
|
print(list.item(-10) is null)
|
36
examples/computer_science/luhn_algorithm.coffee
Normal file
36
examples/computer_science/luhn_algorithm.coffee
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# Use the Luhn algorithm to validate a numeric identifier, such as credit card
|
||||||
|
# numbers, national insurance numbers, etc.
|
||||||
|
# See: http://en.wikipedia.org/wiki/Luhn_algorithm
|
||||||
|
|
||||||
|
is_valid_identifier: identifier =>
|
||||||
|
|
||||||
|
sum: 0
|
||||||
|
alt: false
|
||||||
|
|
||||||
|
for i in [(identifier.length - 1)..0]
|
||||||
|
|
||||||
|
# Get the next digit.
|
||||||
|
num: parseInt(identifier.charAt(i), 10)
|
||||||
|
|
||||||
|
# If it's not a valid number, abort.
|
||||||
|
return false if isNaN(num)
|
||||||
|
|
||||||
|
# If it's an alternate number...
|
||||||
|
if alt
|
||||||
|
num *= 2
|
||||||
|
num: (num % 10) + 1 if num > 9
|
||||||
|
|
||||||
|
# Flip the alternate bit.
|
||||||
|
alt: !alt
|
||||||
|
|
||||||
|
# Add to the rest of the sum.
|
||||||
|
sum += num
|
||||||
|
|
||||||
|
# Determine if it's valid.
|
||||||
|
sum % 10 is 0
|
||||||
|
|
||||||
|
|
||||||
|
# Tests.
|
||||||
|
print(is_valid_identifier("49927398716") is true)
|
||||||
|
print(is_valid_identifier("4408041234567893") is true)
|
||||||
|
print(is_valid_identifier("4408041234567890") is false)
|
19
examples/computer_science/merge_sort.coffee
Normal file
19
examples/computer_science/merge_sort.coffee
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Sorts an array in ascending natural order using merge sort.
|
||||||
|
merge_sort: list =>
|
||||||
|
|
||||||
|
return list if list.length is 1
|
||||||
|
|
||||||
|
result: []
|
||||||
|
pivot: Math.floor(list.length / 2)
|
||||||
|
left: merge_sort(list.slice(0, pivot))
|
||||||
|
right: merge_sort(list.slice(pivot))
|
||||||
|
|
||||||
|
while left.length and right.length
|
||||||
|
result.push(if left[0] < right[0] then left.shift() else right.shift())
|
||||||
|
|
||||||
|
result.concat(left).concat(right)
|
||||||
|
|
||||||
|
|
||||||
|
# Test the function.
|
||||||
|
print(merge_sort([3, 2, 1]).join(' ') is '1 2 3')
|
||||||
|
print(merge_sort([9, 2, 7, 0, 1]).join(' ') is '0 1 2 7 9')
|
23
examples/computer_science/selection_sort.coffee
Normal file
23
examples/computer_science/selection_sort.coffee
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# An in-place selection sort.
|
||||||
|
selection_sort: list =>
|
||||||
|
len: list.length
|
||||||
|
|
||||||
|
# For each item in the list.
|
||||||
|
for i in [0...len]
|
||||||
|
|
||||||
|
# Set the minimum to this position.
|
||||||
|
min: i
|
||||||
|
|
||||||
|
# Check the rest of the array to see if anything is smaller.
|
||||||
|
(min: j if list[j] < list[min]) for j in [i+1...len]
|
||||||
|
|
||||||
|
# Swap if a smaller item has been found.
|
||||||
|
[list[i], list[min]]: [list[min], list[i]] if i isnt min
|
||||||
|
|
||||||
|
# The list is now sorted.
|
||||||
|
list
|
||||||
|
|
||||||
|
|
||||||
|
# Test the function.
|
||||||
|
print(selection_sort([3, 2, 1]).join(' ') is '1 2 3')
|
||||||
|
print(selection_sort([9, 2, 7, 0, 1]).join(' ') is '0 1 2 7 9')
|
|
@ -37,8 +37,8 @@ prechigh
|
||||||
right WHEN LEADING_WHEN IN OF BY
|
right WHEN LEADING_WHEN IN OF BY
|
||||||
right THROW FOR NEW SUPER
|
right THROW FOR NEW SUPER
|
||||||
left EXTENDS
|
left EXTENDS
|
||||||
left ASSIGN '||=' '&&=' '?='
|
left '||=' '&&=' '?='
|
||||||
right RETURN
|
right ASSIGN RETURN
|
||||||
right '=>' '==>' UNLESS IF ELSE WHILE
|
right '=>' '==>' UNLESS IF ELSE WHILE
|
||||||
preclow
|
preclow
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue