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.)
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 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.
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]
I am new to Ruby, is there a way to yield values from Ruby functions? If yes, how? If not, what are my options to write lazy code?
Ruby's yield keyword is something very different from the Python keyword with the same name, so don't be confused by it. Ruby's yield keyword is syntactic sugar for calling a block associated with a method.
The closest equivalent is Ruby's Enumerator class. For example, the equivalent of the Python:
def eternal_sequence():
i = 0
while True:
yield i
i += 1
is this:
def eternal_sequence
Enumerator.new do |enum|
i = 0
while true
enum.yield i # <- Notice that this is the yield method of the enumerator, not the yield keyword
i +=1
end
end
end
You can also create Enumerators for existing enumeration methods with enum_for. For example, ('a'..'z').enum_for(:each_with_index) gives you an enumerator of the lowercase letters along with their place in the alphabet. You get this for free with the standard Enumerable methods like each_with_index in 1.9, so you can just write ('a'..'z').each_with_index to get the enumerator.
I've seen Fibers used in that way, look at an example from this article:
fib = Fiber.new do
x, y = 0, 1
loop do
Fiber.yield y
x,y = y,x+y
end
end
20.times { puts fib.resume }
If you are looking to lazily generate values, #Chuck's answer is the correct one.
If you are looking to lazily iterate over a collection, Ruby 2.0 introduced the new .lazy enumerator.
range = 1..Float::INFINITY
puts range.map { |x| x+1 }.first(10) # infinite loop
puts range.lazy.map { |x| x+1 }.first(10) # [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Ruby supports generators out of the box using Enumerable::Generator:
require 'generator'
# Generator from an Enumerable object
g = Generator.new(['A', 'B', 'C', 'Z'])
while g.next?
puts g.next
end
# Generator from a block
g = Generator.new { |g|
for i in 'A'..'C'
g.yield i
end
g.yield 'Z'
}
# The same result as above
while g.next?
puts g.next
end
https://ruby-doc.org/stdlib-1.8.7/libdoc/generator/rdoc/Generator.html
Class Enumerator and its method next behave similar
https://docs.ruby-lang.org/en/3.1/Enumerator.html#method-i-next
range = 1..Float::INFINITY
enumerator = range.each
puts enumerator.class # => Enumerator
puts enumerator.next # => 1
puts enumerator.next # => 2
puts enumerator.next # => 3