Error when iterating over a function with two arguments in my template - phoenix-framework

I have a function in my view that I use to dynamically build HTML elements in my templates:
defmodule Recursion do
def buildElements(element,n) when n <= 1 do
element
end
def buildElements(element, n) do
[element | buildElements(element, n - 1)]
end
end
It is working great unless I try to iterate it in my template:
<%= for element <- MyProject.PageView.Recursion.buildElements("LOL", 2) do %>
<%= element %>
<% end %>
I get this error:
no function clause matching in Enum."-reduce/3-lists^foldl/2-0-"/3
What's the problem?

It's only a small change to solve your problem.
You try to add a element to a list with the [foo | bar] notation. bar must be a list while foo is a single item.
Change your element to [element] and it's done.
def buildElements(element,n) when n <= 1 do
[element]
end
def buildElements(element, n) do
[element | buildElements(element, n - 1)]
end

Related

Ruby fiber additional resume

In this example, the fiber is resumed once more to create one more output unexpectedly. The target is to print all the permutation of one array of numbers by iterating through all the possibilities with recursion and print out the result in a fiber.
class Fiber
def self.wrap
if block_given?
f=Fiber.new do |*args|
yield *args
end
return lambda{|*args| f.resume(*args) if f.alive? }
end
end
end
class FiberIterator
def initialize
#fiber_wrap=Fiber.wrap do
yield
end
end
def each
while value=#fiber_wrap.call
yield value
end
end
end
def perm(a)
FiberIterator.new{ permgen(a,a.size) }
end
def permgen (a, n)
if n == 0 then
Fiber.yield a
else
n.times do |i|
a[n-1], a[i] = a[i], a[n-1]
permgen(a, n - 1)
a[n-1], a[i] = a[i], a[n-1]
end
end
end
def printResult (a)
p a
end
it=perm([1,2,3,4])
for a in it
printResult(a)
end
The result will include an additional 3 after print out all the permutations have been printed. Could anyone help with this?
The reason is that n.times returns n:
1.times { } # => 1
and the return value from permgen is being caught and evaluated as part of it and thus printed out. Too tired atm to go through and fully understand what's yielded or resumed where and when to try and explain how it's getting caught up and printed as if it was a permutation, but you can fix the code by just changing permgen to:
def permgen (a, n)
if n == 0 then
Fiber.yield a
else
n.times do |i|
a[n-1], a[i] = a[i], a[n-1]
permgen(a, n - 1)
a[n-1], a[i] = a[i], a[n-1]
end
nil # << This is all I added
end
end
As a side note, when I ran your code it was printing a 4 not a 3 at the end, based this answer on that being a typo or the result of a different array or playing around with different sized permutations.

Need help understanding what "(2..Math.sqrt(n)).none?" means in a method that sums the primes below a number

def prime_sum_below(x)
primes = (2..x).select { |n| (2..Math.sqrt(n)).none? { |i| (n % i).zero? }}
sum = primes.inject { |sum, i| sum + i }
end
The method sums the primes below x. I have trouble understanding "(2..Math.sqrt(n)).none?". What exactly does it do?
From the ruby guide, .none? passes each element of the collection to the given block. The method returns true if the block never returns true for all elements. If the block is not given, none? will return true only if none of the collection members is true.
I don't fully understand that, could someone please clarify?
Let me rephrase it like this:
primes = (2..x).select do |n|
(2..Math.sqrt(n)).none? do |i|
(n % i).zero?
end
end
And then go through each line:
# It selects a number if the following block returns true
primes = (2..x).select do |n|
# It takes all of the elements from 2 to the square root of n
(2..Math.sqrt(n))
# Then passes that into another block, returning true if none of the elements return true
.none? do |i|
# If it never divides evenly, then it returns true
(n % i).zero?
end
end
So if (n % i).zero? returns true, it means that something goes into n, meaning n cannot be a prime number

Why does this Ruby code not return the expected answer?

I'm trying the list all factors of a number using the following method:
def find_factors(n)
factors = []
2.upto(n-1) {|x| factors << x if n % x == 0}
end
factor = find_factors(24)
puts factor
Its printing out the following:
2
instead of the list of factors! What am if doing incorrectly?
upto used with a block returns the receiver, which is 2.
A better way to write this would be:
def find_factors(n)
2.upto(n-1).select{|x| (n % x).zero?}
end
In ruby, whenever you see an array initialization before a loop, you can generally convert it to a more functional approach:
def find_factors(n)
2.upto(n-1).select{|x| n % x == 0}
end
This tends to be more compact and often more readable too.
You have to return factors at the end of your find_factors method:
def find_factors(n)
factors = []
2.upto(n-1) {|x| factors << x if n % x == 0}
factors
end

Yield something when random block of calculations passed

The part I don't understand is how to make this yield so that the elements in the array have the calculation, (which is specified in the block), done to them if block_given?, prior to their being added together.
For example, the calculation could be |x| x+3 (to add 3 to each of the elements), but I want this to work for any sort of manipulation of the elements, such as |x| x**3 or |x| x*5, so that the elements inmy_ary ([1,2,3]) are changed as specified by the calculation.
So essentially I'm asking what I need to do to the part of my code that reads yield array.each{|x|} if block_given? . what I was trying to do here is say that each element in the array should have whatever is stated in the block done to the element, so that it is changed.
What I am passing to the this is something along the lines of my_ary.sum(2) {|x| x **4}.
class MyArray
attr_reader :ary
def init(ary)
#ary = ary
end
def sum(init_val = 0)
yield ary.each{|x|} if block_given?
(#ary.inject(0){|x,y|x+y}) + init_val
end
end
class MyArray
attr_reader :ary
def initialize(ary)
#ary = ary
end
def sum n, &block
new_ary = #ary.collect &block # ary after executing block
ary_sum = new_ary.inject(0){|sum, x| sum+=x} # sum all elements of the array
return ary_sum + n
end
end
def nsum n, &block, here & saves the block (code between {} or do; end) to instance of Proc. It's basically your block of code saved to variable.
#ary.collect &block here, collect want block not proc so & change proc to the block. collect execute block for each element, and return new array.
inject - yields element to the block, add it to sum, and it is returned as sum variable. On the next iteration (next yielding to the block) sum will be last value of previous iteration.
[1,2,3].inject(0){|s, x| s+=x}
# sum = 0; x = 1;
# sum = 1; x = 2
# sum = 3; x = 3
# sum = 6
# inject returns 6 because there is no elements in the array

Is this a faithful rendition of the selection sort algorithm?

I've been reading an elementary book about sort algorithms. To get my head around it, I tried to write a simple program to implement the algorithm.
EDIT: I had omitted an important line that was in a previous version - see comment below.
This is my selection sort:
class SelectionSorter
attr_reader :sorted
def initialize(list)
#unsorted = list
#sorted = []
end
def select(list)
smallest = list.first
index = 0
list.each_with_index do |e,i|
if e < smallest
smallest = e
index = i
end
end
#sorted << list.delete_at(index)
end
def sort
#unsorted.length.times { self.select(#unsorted) }
end
end
Here's a test:
require 'minitest/autorun'
require_relative 'sort'
class SelectionSortTest < MiniTest::Test
describe SelectionSorter do
it 'sorts a randomly generated list' do
list = (1..20).map { rand(100-1) + 1 }
sorted_list = list.sort
sorter = SelectionSorter.new(list)
sorter.sort
sorter.sorted.must_equal sorted_list
end
end
end
I'd love comments, particularly around whether this is actually a faithful implementation of the algorithm.
EDIT 2:
OK - here's my in-place code. This is the sort of thing I wanted to avoid, as it feels nastily procedural, with nested loops. However, I think it's a faithful implementation.
class SelectionSorter
def sort(list)
sorted_boundary = (0..(list.length)-1)
sorted_boundary.each do |sorted_index|
smallest_index = sorted_index
smallest_value = list[smallest_index]
comparison = sorted_index + 1
(comparison..(list.length-1)).each do |next_index|
if list[next_index] < smallest_value
smallest_index = next_index
smallest_value = list[smallest_index]
end
end
unless sorted_index == smallest_index
list[smallest_index] = list[sorted_index]
list[sorted_index] = smallest_value
end
end
list
end
end
I'd love to do this in a more recursive fashion, with less stored state, and without nested loops. Any suggestions?
Try adding smallest = e immediately after index = i, so you are keeping a running tally of the smallest value found so far.
I'd also note that selection sort is usually implemented in-place, i.e., scan locations 1-N of your list for the min and then swap it with the first element, then repeat the process with elements 2-N, 3-N, etc. There's no need for a second array or the expense of removing elements from the middle of an array.
I don't know the selection sort algorithm, but I can tell that your code does not do sorting. In this part:
list.each_with_index do |e,i|
if e < smallest
index = i
end
end
you end up having as index the index of the last element of #unsorted that is smaller than the first element of #unsorted (If there is no such element, then index is 0). Then, by:
#sorted << list.delete_at(index)
you take that element from #unsorted, and push it into #sorted. And you repeat this process. That does not give you sort.

Resources