I'm a self taught programmer and started off with Ruby. I'm currently trying to learn algorithms and data structures and noticed something called a linked list. It looks like Ruby doesn't have that data structure (maybe in Array?). I'm familiar with arrays and hashes.
How would you describe/explain what a linked list is for someone coming from my background?
Linked lists are rather simple: they are lists which are created by linking the elements together. (Kind of obvious, when you think about it, no?)
In its most basic form, a linked list is simply either empty or a pair. The first element of the pair is a value, and the second element of the pair is a linked list representing the rest of the values.
Traditionally, the pair is called a cons cell, the first element is called the head or the car of the list and the second element is called the tail or the cdr of the list. The empty list is called Nil or simply [].
Here is an extremely simple implementation of a linked list in Ruby, which uses nothing but functions to implement a linked list (and booleans and conditionals, while we're at it):
True = ->(iff, _) { iff }
False = ->(_, els) { els }
Pair = ->(first, rest) { -> x { x.(first, rest) }}
First = -> list { list.(True ) }
Rest = -> list { list.(False) }
Here, we have a simple list with three elements:
List = Pair.(1, Pair.(2, Pair.(3, nil)))
First.(Rest.(List))
# => 2
A more realistic object-oriented encoding of a list looks like this:
class List
def cons(el) Pair.new(el, self) end
Empty = new
class Pair < self
attr_reader :first, :rest
def initialize(first, rest=Empty)
self.first, self.rest = first, rest
end
private
attr_writer :first, :rest
end
end
Again, a list with two elements:
list1 = List::Pair.new(1, List::Pair.new(2, List::Pair.new(3, List::Empty)))
# corresponds to the list [1, 2, 3]
list1.rest.first
# => 2
list2 = List::Empty.cons(6).cons(5).cons(4)
# List[4, 5, 6]
list2.rest.first
# => 5
A more complete and Rubyish implementation might look like this:
class List
include Enumerable
def self.[](*els) els.reverse_each.inject(Empty, &:cons) end
def cons(el) Pair[el, self] end
def prepend(prefix)
case
when empty? then prefix
when prefix.empty? then self
else prepend(prefix.rest).cons(prefix.first)
end
end
def to_s; "List[#{map(&:to_s).join(', ')}]" end
def inspect; "List[#{map(&:inspect).join(', ')}]" end
def each; return enum_for(__method__) unless block_given? end
class << Empty = new
def empty?; true end
alias_method :inspect, def to_s; 'Empty' end
freeze
end
Empty.freeze
class Pair < self
def initialize(first, rest=Empty)
self.first, self.rest = first, rest
freeze
end
def empty?; false end
def each(&blk)
return super unless block_given?
yield first
rest.each(&blk)
end
private
attr_writer :first, :rest
protected
attr_reader :first, :rest
class << self; alias_method :[], :new end
freeze
end
freeze
end
Some examples:
list1 = List::Pair[1, List::Pair[2, List::Pair[3, List::Empty]]]
# => List[1, 2, 3]
list2 = List::Empty.cons(6).cons(5).cons(4)
# => List[4, 5, 6]
list3 = List[7, 8, 9]
# => List[7, 8, 9]
list4 = list3.prepend(list2).prepend(list1)
# => List[1, 2, 3, 4, 5, 6, 7, 8, 9]
list4.partition(&:odd?)
# => [[1, 3, 5, 7, 9], [2, 4, 6, 8]]
In computer science, a linked list is a data structure consisting of a group of nodes which together represent a sequence. Under the simplest form, each node is composed of a data and a reference (in other words, a link) to the next node in the sequence; more complex variants add additional links. This structure allows for efficient insertion or removal of elements from any position in the sequence.
http://en.wikipedia.org/wiki/Linked_list
Here is a implementation on ruby: http://matt.weppler.me/2013/08/14/implementing-a-linked-list-in-ruby.html
Kudos for studying Ruby one of my favorites languages.
Related
For the class NumberSet, I have to define the [] method so that it takes one argument, which it uses as a filter to select members of the set and returns a new set containing those elements.
For example, I have
Filter.new { |number| number.even? }
and
SignFilter.new(:non_negative)
which are classes that I must construct.
I also have to define the & and | operators so that they work with the filters. Something along the lines of
numbers[SignFilter.new(:non_negative) & Filter.new { |number| number.even? }]
The class so far is:
class NumberSet
include Enumerable
def initialize
#arr=[]
end
def each (&block)
#arr.each do |member|
block.call (member)
end
end
def << number
#arr<<number unless #arr.include?(number)
end
end
For Filter I think something like works:
class Filter
def initialize
yield
end
end
My biggest problem is the [], $and | parts, which I have no idea how to do.
What I want to accomplish is :
numbers = NumberSet.new
[-3, -2, -1, 0, 1, 2, 3, 4, 5].each do |number|
numbers << number
end
numbers[SignFilter.new(:non_negative) & Filter.new { |number| number.even?}].to_a
#=>[0, 2, 4]
I think this should do it.
Code
SignFilter class
class SignFilter
def initialize(sign)
#sign = sign
end
def filter
case #sign
when :negative
-> i { i < 0 }
when :positive
-> i { i > 0 }
when :non_negative
-> i { i >= 0 }
when :non_positive
-> i { i <= 0 }
when :zero
-> i { i.zero? }
end
end
end
Filter class
class Filter
attr_reader :filter
def initialize &filter
#filter = filter
end
end
NumberSet class
class NumberSet
def initialize arr
#arr = arr
end
def process(op, sf, f)
sign_filter = sf.filter
filter = f.filter
#arr.send(op).each { |e| sign_filter.call(e) }
.send(op).each { |e| filter.call(e) }
end
end
Examples
sf = SignFilter.new :negative
f = Filter.new { |number| number.even? }
ns = NumberSet.new [-3, -2, -1, 0, 1, 2, 3, 4, 5]
ns.process(:reject, sf, f)
#=> [1, 3, 5]
sf = SignFilter.new :non_negative
f = Filter.new { |number| number % 3 == 0 }
ns = NumberSet.new [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
ns.process(:select, sf, f)
#=> [0, 3, 6]
Explanation
Blocks are not objects, so you can't pass them around. They can be converted to procs, however, which are objects (instances of the class Proc), and therefore can be passed. You will need to understand procs (and lambdas, which are a type of proc). Here is a good explanation. (Aside: one thing that's a little confusing about procs is the multitude of ways they can be invoked. For example, if p -> i { 3*i }, p.call(2), p.yield(2), p[2] and p.(2) all return the value 6.)
Here is what is happening:
An instance sf of the SignFilter class is created by passing the symbol denoting the signs of the elements of the array that are to be selected or rejected (:negative, :non_negative and so on). The symbol is saved in an instance variable #sign.
The SignFilter class has a method filter which returns a lambda based on the value of #sign.
An instance of the Filter class is created by passing a block which is received as a proc and saved into the instance variable #filter, which has a read accessor.
An instance of the NumberSet class is created by passing the array, which is saved into the instance variable #arr.
NumberSet#process is passed three arguments: the Enumerable method :reject or :select (saved into op), the SignFilter instance (sf) and the Filter instance (f).
Within NumberSet#process, #arr is sent op, which creates an enumerator (arr.reject or arr.select).
The SignFilter lambda is called on each element of the enumerator. An array comprised of a subcollection of #arr is returned.
The returned array is sent op, creating another reject or select enumerator.
The Filter proc is called on the each element of the new enumerator, causing the desired array to be returned.
Considering that both reject and select are not necessary (either would do), it would have been simpler to just replace .send(op) in NumberSet#process with, say, reject, but I chose to do it this way just to illustrate the generalization.
Notice that it would be easy to generalize NumberSet#process to process(sf,f,o), where, as now, sf and f provide filters and o would be an instance of an Operation class that specifies a proc to send to the filtered subcollection of #arr to invoke an Enumerable method with a block (map, group_by and so on).
Since this appears to be a homework question, I'm not going to give you the full implementation, but I'll see you on your way. The big thing you need to realize here is that methods such as [] and | can be defined as normal methods in Ruby. In Ruby, you simply send messages (such as []) to a "receiver". How you handle those methods are defined via def instructions on your class definition. So, for example:
class Filter
def |(other_filter)
# Do some work to build a new filter which is a union of this filter and other_filter
end
end
class SignFilter < Filter
# SignFilter inherits the & method from Filter, and you can then go on to implement SignFilter-specific functionality
# ...
end
class NumberSet
def [](filter)
# Given a filter, apply each of the numbers of this NumberSet to the filter, and return those which pass the filter
end
end
To invoke those methods, would do something like:
filter = Filter.new {|num| num.even? }
sign_filter = SignFilter.new(:non_negative)
union_filter = filter | sign_filter
This third line is equivalent to calling:
union_filter = filter.|(sign_filter)
or:
union_filter = filter.send("|", sign_filter)
In all three cases, the "|" message is sent to the the filter instance, with sign_filter as an additional argument. You could also do something like:
numset = NumberSet.new(1,2,3,4,5)
filtered_numbers = numset[union_filter]
This second line is equivalent to:
numset.[](union_filter)
# or
numset.send("[]", union_filter)
The original syntax is just syntactic sugar for those method calls - it's just there because it makes Ruby code look nicer, and helps the programmer mentally map it to common conventions for those kinds of operations.
I'm preparing for a technical interview and will be asked to write the algorithm for a linked list in ruby. I understand linked lists completely, but have struggled writing the code. Can someone show me how this is done? I started it below..
class Node
def initialize(item)
#item = item
#next = nil
end
end
You almost did it, really. I can give you very old-school, Lisp-like implementation, if you are brave enough to show it to your interviewer. In this approach, list is a pair (two elements touple), which first element contains the element, and second contains another pair, etc, etc. The last pair have nil as a second element. And here is the whole implementation of the list in Ruby:
class Pair
attr_reader :car, :cdr
def initialize(car, cdr=nil)
#car = car
#cdr = cdr
end
end
To construct the list, just use a lot of parenthesis, like in old, good Lisp:
list = Pair.new(1, Pair.new(2, Pair.new(3)))
Now, the world is yours. You can do whatever you want with the list, using simple recursion. Here is an example of recursive inspect:
class Pair
def inspect
if cdr.nil?
car.inspect
else
"#{car.inspect}, #{cdr.inspect}"
end
end
end
pry(main)> list = Pair.new(1, Pair.new(2, Pair.new(3)))
=> 1, 2, 3
As you mentioned in a comment, you want to search the list. Here is the code for this:
class Pair
def find(index)
find_ index, 0
end
def find_(index, i)
if index == i
car
else
cdr.find_ index, i+1
end
end
end
pry(main)> list.find 2
=> 3
This is the standard Church Encoding of Lists (and Booleans):
True = ->(iff, _) { iff }
False = ->(_, els) { els }
Pair = ->(first, rest) { -> x { x.(first, rest) }}
First = -> list { list.(True ) }
Rest = -> list { list.(False) }
List = Pair.(1, Pair.(2, nil))
First.(Rest.(List))
# => 2
It's not what you would actually write in Ruby, of course, but it is very simple and demonstrates an understanding of one of the most important principles of programming: code is data and data is code.
Here's a more realistic object-oriented encoding of lists:
class List
include Enumerable
def self.[](*els) els.reverse_each.inject(Empty, &:cons) end
def cons(el) Pair[el, self] end
def prepend(prefix)
case
when empty? then prefix
when prefix.empty? then self
else prepend(prefix.rest).cons(prefix.first)
end
end
def to_s; "List[#{map(&:to_s).join(', ')}]" end
def inspect; "List[#{map(&:inspect).join(', ')}]" end
def each; return enum_for(__method__) unless block_given? end
class << Empty = new
def empty?; true end
alias_method :inspect, def to_s; 'Empty' end
freeze
end
Empty.freeze
class Pair < self
def initialize(first, rest=Empty)
self.first, self.rest = first, rest
freeze
end
def empty?; false end
def each(&blk)
return super unless block_given?
yield first
rest.each(&blk)
end
private
attr_writer :first, :rest
protected
attr_reader :first, :rest
class << self; alias_method :[], :new end
freeze
end
freeze
end
Note that there are absolutely no conditionals and no loops in the code. That is always a good sign for object-oriented code: polymorphic method calls are more powerful than conditionals anyway, oftentimes, there simply is no need for conditionals.
Some examples:
list1 = List::Pair[1, List::Pair[2, List::Pair[3, List::Empty]]]
# => List[1, 2, 3]
list2 = List::Empty.cons(6).cons(5).cons(4)
# => List[4, 5, 6]
list3 = List[7, 8, 9]
# => List[7, 8, 9]
list4 = list3.prepend(list2).prepend(list1)
# => List[1, 2, 3, 4, 5, 6, 7, 8, 9]
list4.partition(&:odd?)
# => [[1, 3, 5, 7, 9], [2, 4, 6, 8]]
Unfortunately, this object-oriented encoding will blow the stack for larger lists (on my system List[*(1..9338)].each {} still works, but 9339 doesn't), even though each is tail-calling itself and thus should run in O(1) stack space. As Guy L. Steele pointed out multiple times, OO languages must support proper tail calls, otherwise you are required to break OO in order to avoid blowing the stack. (prepend is not coded for tail-calls, but it can be rewritten that way.)
This is a contrived example to emulate what is going on in another project. I'm sure I'm just misunderstanding some basic function of classes, but I don't know where to look to find the answer.
If I set an instance variable #empty = [] in the parent class, then I want to use the original instance variable, as well as a variation of the instance variable in a child class, I'm getting an issue where the original instance variable is no longer accessible in its original form.
class Parent
def initialize
#empty = []
end
def fill
#empty << "foo" #interestingly, changing the << to = fixes it, but that's not a possibility on my project
end
end
class Child < Parent
def initialize
super
#should_still_be_empty = #empty #trying to "make a copy" of the original
end
def show_original_variable
#should_still_be_empty
end
end
child = Child.new
child.fill #=> ["foo"], which is what it should return
child.show_original_variable #=> ["foo"], I want it to return []
UPDATE:
After playing around a little more, I noticed that this happens within the same classes, as well. Why?
class Child
def initialize
#original_empty = []
#copy_of_empty = #original_empty
end
def fill
#copy_of_empty << "foo"
end
def show_empty
#original_original_variable
end
end
child = Child.new
child.fill #=> ["foo"]
child.show_original_variable #=> ["foo"], but I want it to be empty
You question has nothing in particular to do with classes or inheritance. Rather, it deals with more basic issues related to assignment and mutation.
xs = [11,22,33]
ys = xs # Both variables hold a reference to the same data.
zs = xs.dup # But zs has a copy (at least a shallow copy).
xs << 44 # If we *mutate* xs, ys changes also.
p xs # [11, 22, 33, 44]
p ys # [11, 22, 33, 44]
p zs # [11, 22, 33]
xs = [4,5,6] # If we *assign* to xs, ys won't be affected.
p xs # [4,5,6]
p ys # [11, 22, 33, 44]
The same behaviors would be observed even if the xs array started out empty (as in your code), but it's a little easier to illustrate with data values present.
If you want #should_still_be_empty to have an independent copy of the underlying data values, you need to do something along these lines:
#should_still_be_empty = #empty.dup
Doing #copy = #original stores the reference to the original object in the #copy instance variable.
Using Object#dup will create a shallow copy of the object you're assigning and store it in the instance variable.
class Child
def initialize
#original_empty = []
#copy_of_empty = #original_empty.dup
end
def fill
#copy_of_empty << "foo"
end
def show_empty
#original_empty
end
end
child = Child.new
child.fill
#=> ["foo"]
child.show_empty
#=> []
I'm doing http://www.rubeque.com/problems/queue-continuum/solutions/51a26923ba804b00020000df and I spent a while there. I can't realize why this code doesn't pass
def initialize(queue)
#q = queue
end
def pop(n=1)
#q.shift(n)
end
def push(arr)
arr.each { |x|
#q.push(x)
}
return true
end
def to_a
#q
end
but this works perfectly.
def initialize(queue)
#q = queue
end
def pop(*n)
#q.shift(*n)
end
def push(arr)
#q.push(*arr)
return true
end
def to_a
#q
end
i'm totally confused about
def pop(*n)
#q.shift(*n)
end
and
def push(arr)
#q.push(*arr)
end
why should I take (arr) as array and than change it into... *arr which is Array of array? I'm confused, please help!
The splat works in two ways.
When receiving arguments, it combines arguments into an array.
def foo *args; args end
foo(1) # => [1]
foo(1, 2, 3) # => [1, 2, 3]
When giving arguments, it decomposes an array into arguments.
def bar x, y, z; y end
bar(*[1, 2, 3]) # => 2
def baz x; x end
baz(1) # => [1]
baz(1, 2, 3) # => Error
The *arr you are wondering is the latter case. It is not an object like [1, 2, 3] (hence, not an array of arrays). It is a part of arguments (like 1, 2, 3) passed to a method.
There are other uses of splats (as in array literals, case statements, etc.), but their function is either of the two uses above.
If I want a part of an array I can use [] or split:
arr = [1,2,3,4,5]
arr[1..3]
=> [2, 3, 4]
But is there a 'general' version of []? Can I apply it to any Enumerator?
enum = arr.each
enum.xxx_method(1..3) # is equal to arr[1..3].each
Of course you can use arr[1..3] directly. But I'm seeking a general way to handle any enumerator.
If you have an enumerator, you can count on Enumerable methods drop and take:
# abstract if necessary as enum_slice(range)
enumerator.drop(2).take(3)
If that enumerator is an array you don't need to traverse it, check the method Array#lazy_slice that I asked to be added to enumerable_lazy in relation with your previous question:
require 'enumerable/lazy'
class Array
def lazy_slice(range)
Enumerator.new do |yielder|
range.each do |index|
yielder << self[index]
end
end.lazy
end
end
some_big_array = (0..10000).to_a # fake array, it won't generally be a range
p some_big_array.lazy_slice(9995..10000).map { |x| 2*x }.to_a
#=> [19990, 19992, 19994, 19996, 19998, 20000]