enter image description here
The link for the error is above; I keep getting a noMethodError for a symbol and I am very confused
numList = [4,3,78,2,0,2]
def bubbleSort(list)
again = true
while again
copy = list
i = 0
until i == list.length do
list.each_with_index do |num, index|
if list[index+1] < num
tempNum = list[index+1]
list[index+1] = num
list[index] = tempNum
end
end
i = i+1
end
if copy != list
again = true
else
again = false
end
p copy
end
end
bubbleSort(numList)
As noted in comments, you are iterating with an index:
list.each_with_index do |num, index|
But this includes the last index, which you're trying to access one past.
if list[index+1] < num
list[index+1] return nil, which will give the error you're seeing.
irb(main):083:0> nil < 42
Traceback (most recent call last):
5: from C:/Ruby26-x64/bin/irb.cmd:31:in `<main>'
4: from C:/Ruby26-x64/bin/irb.cmd:31:in `load'
3: from C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
2: from (irb):83
1: from (irb):83:in `rescue in irb_binding'
NoMethodError (undefined method `<' for nil:NilClass)
It'd be important to avoid this access. I would also suggest avoiding the again boolean flag. Rather use loop and break out of the loop at the appropriate time.
def bubbleSort(list)
loop do
copy = list
i = 0
until i == list.length
list.each_with_index do |num, index|
next if index == list.length - 1
if list[index+1] < num
tempNum = list[index+1]
list[index+1] = num
list[index] = tempNum
end
end
i = i+1
end
break if copy == list
p copy
end
end
Taking a step back and looking at how bubble sort works though, your implementation can be improved.
Each cycle through the array a bubble sort will advance the largest element to the end of the array. You don't need to cycle over the whole array each times, but can decrease the inner loop by one iteration each time.
You can also track the number of swaps. If no swaps are performed, the array is clearly sorted already, and the outer loop can be exited.
+---+---+---+---+
| 4 | 2 | 3 | 1 | (starting state for loop)
+---+---+---+---+
>---<
+---+---+---+---+
| 2 | 4 | 3 | 1 | (swap 4 and 2)
+---+---+---+---+
>---<
+---+---+---+---+
| 2 | 3 | 4 | 1 | (swap 4 and 3)
+---+---+---+---+
>---<
+---+---+---+---+
| 2 | 3 | 1 | 4 | (swap 4 and 1)
+---+---+---+---+
Three swaps are performed. The last position in the array is sorted.
+---+---+---+---+
| 2 | 3 | 1 | 4 | (starting state for loop)
+---+---+---+---+
>---<
+---+---+---+---+
| 2 | 1 | 3 | 4 | (swap 3 and 1)
+---+---+---+---+
+---+---+---+---+
| 2 | 1 | 3 | 4 | (no swap needed for 1 and 3)
+---+---+---+---+
One swap is performed. Now the last two positions are sorted.
+---+---+---+---+
| 2 | 1 | 3 | 4 | (starting state for loop)
+---+---+---+---+
>---<
+---+---+---+---+
| 1 | 2 | 3 | 4 | (swap 2 and 1)
+---+---+---+---+
One swap is performed. We know the last three positions are sorted. The first position therefore is sorted.
If the array is already sorted and we keep track of swaps:
+---+---+---+---+
| 1 | 2 | 3 | 4 | (starting state for loop)
+---+---+---+---+
+---+---+---+---+
| 1 | 2 | 3 | 4 | (no swap needed for 1 and 2)
+---+---+---+---+
+---+---+---+---+
| 1 | 2 | 3 | 4 | (no swap needed for 2 and 3)
+---+---+---+---+
+---+---+---+---+
| 1 | 2 | 3 | 4 | (no swap needed for 3 and 4)
+---+---+---+---+
Since zero swaps are performed, the array is known to be sorted. While bubble sort is worst case O(n^2), this technique can make it best case O(n).
def bubble_sort(arr)
(arr.length-1).times do |x|
swaps = 0
0.upto(arr.length-x-2) do |i|
if arr[i] > arr[i+1]
temp = arr[i+1]
arr[i+1] = arr[i]
arr[i] = temp
swaps += 1
end
end
break if swaps == 0
end
arr
end
Related
This is about developing a distributed consensus.
Let's assume we have N nodes ( N1, N2, ..., Nn ),each of the nodes has a different value( A1, A2, ..., An ).These nodes can communicate with each other, and replace their value if it's bigger then the other node's value.
For example if I'm N1 when I communicate with N2 and I find A2 < A1, then I will replace my value with A2
I need to find the least number of exchanges so that more than half of the nodes ( > n / 2 ) hold the smallest possible value.
An exchange is a single communication between two nodes that results may result in a change in one of the two involved node's value, if and only if the other one has different and smaller value.
Given the postulated properties, one of which is values An were postulated to be initially different, the solution is derived from how large the requested strictly dominant majority MAJ actually is, thus setting the minimum (optimistic case supremum) of amount of exchanges .xg!-operations needed, which sets the [TIME]-domain complexity inductively alike this :
n == 2
MAJ ~ 2 _(1)_----->----(2).xg! _1_
xg! = 1
(3)
/ \
/ \
/ \
/ \
/ \
n == 3 / \
MAJ ~ 2 _(1)_----->----(2).xg! _1_
xg! = 1
.xg!_1_(4)-----------(3)
|. . |
| . . |
| . . |
^ . . |
| . . |
n == 4 |. , |
MAJ ~ 3 _(1)_----->----(2).xg! _1_
xg! = 2
________________________________________________________
n == 5 | 6 | 7 | 8 | 9| 10 | 11 | ... | n
MAJ ~ 3 | 4 | 4 | 5 | 5| 6 | 6 | ... | 1 + n // 2
xg! = 2 | 3 | 3 | 4 | 4| 5 | 5 | ... | n // 2
You are given an array of counters N initiated with zero.
You have a list of actions A to perform on N array.
each action is an int x
ie A = [1,5,3]
for each k in A as x actions
if x <= len(N) then increase N[i-1] by one
else set all N items with max of max value of N
you should return the counters array after the last action
Exercise Link
The first and simpler solution
wont pass 100% because of time complexity
create counters array with all 0 in size of len(A)
for each idx,action in A
if action <= len(N)
counters[idx-1]++
else
maxVal = max(counters)
now set max maxVal to all counters items
return counters
small improvement, store maxVal variable in the top and update it with each increase of the counter items. Then when you need to set all items, you dont need to find max value.
Better solution
that passes the tests 100%
We will still go through actions, and we store the max value and another new variable forcedVal. we will not update the whole counters array each time we need but only update the forcedVal with the max. Then when ever we need to ++ an item we will first check if it is smaller then forcedVal and if so we will give it forcedVal value before the ++.
create counters array with all 0 in size of len(A)
create max var with 0
create forcedVal var with 0
for each idx,action in A
if action <= len(N)
cur = counters[idx-1]
if cur < forceVal ? cur = forceVal
cur++
if cur > max
max = cur
counters[idx-1] = cur
else
forcedVal = max
here we do a single loop to set our counters
for each cnt in counters
if cnt < forcedVal ? cnt = forcedVal
return counters
this is how it will look with this example
Solution(5, [3, 4, 4, 6, 1, 4, 4])
| c[0] | c[1] | c[2] | c[3] | c[4] | action | max | forcedVal |
|------|------|------|------|------|--------|-----|-----------|
| 0 | 0 | 0 | 0 | 0 | null | 0 | 0 |
| 0 | 0 | 1 | 0 | 0 | 3 | 1 | 0 |
| 0 | 0 | 1 | 1 | 0 | 4 | 1 | 0 |
| 0 | 0 | 1 | 2 | 0 | 4 | 2 | 0 |
| 0 | 0 | 1 | 2 | 0 | 6 | 2 | 2 |
| 3 | 0 | 1 | 2 | 0 | 1 | 3 | 2 |
| 3 | 0 | 1 | 3 | 0 | 4 | 3 | 2 |
| 3 | 0 | 1 | 4 | 0 | 4 | 4 | 2 |
as you can see above after all we have left with:
3, 0, 1, 4, 0
we will our final cleanup loop to set all items to at least the value of forcedVal and we get
3, 2, 2, 4, 2
func Solution(N int, A []int) []int {
counters := make([]int, N)
var max int
var forcedVal int
for _, v := range A {
if v > N {
forcedVal = max
} else {
cur := counters[v-1]
if cur < forcedVal {
cur = forcedVal
}
cur++
if cur > max {
max = cur
}
counters[v-1] = cur
}
}
for i := range counters {
if counters[i] < forcedVal {
counters[i] = forcedVal
}
}
return counters
}
Is there a way to output an array of arrays as a table in ruby? I'm looking for something that is useful from the console, like powershell's format-table command.
An array that would be passed could be something like:
a = [[1.23, 5, :bagels], [3.14, 7, :gravel], [8.33, 11, :saturn]]
And the output could be something like:
-----------------------
| 1.23 | 5 | bagels |
| 3.14 | 7 | gravel |
| 8.33 | 11 | saturn |
-----------------------
I accepted sagarpandya82's answer, but here's my better implementation:
class Array
def to_table
column_sizes = self.reduce([]) do |lengths, row|
row.each_with_index.map{|iterand, index| [lengths[index] || 0, iterand.to_s.length].max}
end
puts head = '-' * (column_sizes.inject(&:+) + (3 * column_sizes.count) + 1)
self.each do |row|
row = row.fill(nil, row.size..(column_sizes.size - 1))
row = row.each_with_index.map{|v, i| v = v.to_s + ' ' * (column_sizes[i] - v.to_s.length)}
puts '| ' + row.join(' | ') + ' |'
end
puts head
end
end
You could try something like this:
a = [[1.23, 5, :bagels], [3.14, 7, :gravel], [8.33, 11, :saturn]]
bar = '-'*(a[0][0].to_s.length + 4 + a[0][1].to_s.length + 3 + a[0][2].to_s.length + 4)
puts bar
a.each do |i|
i.each.with_index do |j,k|
if k == 1 && j < 10
print "| #{j} "
else
print "| #{j} "
end
end
print '|'
puts
end
puts bar
returns:
----------------------
| 1.23 | 5 | bagels |
| 3.14 | 7 | gravel |
| 8.33 | 11 | saturn |
----------------------
bar is just an estimate of how long the top and bottom dash-bar will be. In general this code checks each sub-array and prints out its elements with | in the appropriate places. The only tricky bit is the second element of each sub-array. Here we check to see if it is double digit or single digit. The print-format is different for each.
Bear in mind that this code works specifically for your example and makes a lot of assumptions. Having said that it can be easily modified to taste.
I've made a small improvement on the #dart-egregious snippet
class Array
def to_table(header: true)
column_sizes = self.reduce([]) do |lengths, row|
row.each_with_index.map{|iterand, index| [lengths[index] || 0, iterand.to_s.length].max}
end
head = '+' + column_sizes.map{|column_size| '-' * (column_size + 2) }.join('+') + '+'
puts head
to_print = self.clone
if (header == true)
header = to_print.shift
print_table_data_row(column_sizes, header)
puts head
end
to_print.each{ |row| print_table_data_row(column_sizes, row) }
puts head
end
private
def print_table_data_row(column_sizes, row)
row = row.fill(nil, row.size..(column_sizes.size - 1))
row = row.each_with_index.map{|v, i| v = v.to_s + ' ' * (column_sizes[i] - v.to_s.length)}
puts '| ' + row.join(' | ') + ' |'
end
end
Using:
data = [
['column 1', 'column 2', 'ciolumn 3'],
['row 1 col 2', 'row 1 col 2', 'row 1 col 3'],
['row 1 col 2', 'row 1 col 2', 'row 1 col 3']
]
data.to_table
+-------------+-------------+-------------+
| column 1 | column 2 | ciolumn 3 |
+-------------+-------------+-------------+
| row 1 col 2 | row 1 col 2 | row 1 col 3 |
| row 1 col 2 | row 1 col 2 | row 1 col 3 |
+-------------+-------------+-------------+
data.to_table(header: false)
+-------------+-------------+-------------+
| column 1 | column 2 | ciolumn 3 |
| row 1 col 2 | row 1 col 2 | row 1 col 3 |
| row 1 col 2 | row 1 col 2 | row 1 col 3 |
+-------------+-------------+-------------+
I am new to programming and computer science. HTML is all I know and I have been facing problems with vbscript.
This program (my first in vbscript) was given by my teacher. But I really do not understand anything. I referred to my book but in vain.
I am not even sure if this is the right SE to post the question.
Please help.
What you have there is a loop with another nested loop, both of which print some text to the screen (document.write("...")).
The outer loop
For i = 1 To 5 Step 1
...
Next
iterates from 1 to 5 in steps of 1 (which is redundant, since 1 is the default step size, so you could just omit the Step 1). If you printed the value of i inside the loop
For i = 1 To 5 Step 1
document.Write(i & "<br>")
Next
You'd get the following output:
1
2
3
4
5
In your code sample you just print <br>, though, so each cycle of the outer loop just prints a line break.
In addition to printing line breaks in the outer loop you also have a nested loop, which for each cycle of the outer loop iterates from 1 to the current value of i, again in steps of 1.
For j = 1 To i Step 1
...
Next
So in the first cycle of the outer loop (i=1) the inner loop iterates from 1 to 1, in the second cycle of the outer loop (i=2) it iterates from 1 to 2, and so on.
For i = 1 To 5 Step 1
document.Write(i & "<br>")
For j = 1 To i Step 1
document.Write("*")
Next
Next
Since the inner loop prints an asterisk with each cycle you get i asterisks per line before the inner loop ends, the outer loop then goes into the next cycle and prints a line break, thus ending the current output line.
A good (although somewhat tedious) way to get an understanding of how the loops work is to note the current value of each variable as well as the current output line in a table on a sheet of paper, e.g. like this:
code line | instruction | i | j | output line
----------+------------------------+-------+-------+------------
1 | For i = 1 To 5 Step 1 | 1 | Empty |
2 | document.Write("<br>") | 1 | Empty | <br>
3 | For j = 1 To i Step 1 | 1 | 1 |
4 | document.Write("*") | 1 | 1 | *
5 | Next | 1 | 1 | *
6 | Next | 1 | 1 | *
1 | For i = 1 To 5 Step 1 | 2 | 1 | *
2 | document.Write("<br>") | 2 | 1 | *<br>
3 | For j = 1 To i Step 1 | 2 | 1 |
4 | document.Write("*") | 2 | 1 | *
5 | Next | 2 | 1 | *
3 | For j = 1 To i Step 1 | 2 | 2 | *
4 | document.Write("*") | 2 | 2 | **
5 | Next | 2 | 2 | **
6 | Next | 2 | 2 | **
1 | For i = 1 To 5 Step 1 | 3 | 2 | **
2 | document.Write("<br>") | 3 | 2 | **<br>
3 | For j = 1 To i Step 1 | 3 | 1 |
4 | document.Write("*") | 3 | 1 | *
... | ... | ... | ... | ...
binary search split an array to two part and search in them.
but my teacher ask us to find a solution for split array to four part then search in parts.
binary search:
binary_search(A, target):
lo = 1, hi = size(A)
while lo <= hi:
mid = lo + (hi-lo)/2
if A[mid] == target:
return mid
else if A[mid] < target:
lo = mid+1
else:
hi = mid-1
but I want split array to 4 part then search.
are is way?
A normal binary search splits the array (container) into two pieces, usually at the midpoint:
+---+---+---+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+---+---+---+---+---+---+---+---+
|
V
+---+---+---+---+ +---+---+---+---+
| 1 | 2 | 3 | 4 | | 5 | 6 | 7 | 8 |
+---+---+---+---+ +---+---+---+---+
Based on the midpoint value, the search key is either in the lower section (left) or the higher section (right).
If we take the same concept and split into 4 pieces, the key will be in one of the four quandrants:
+---+---+ +---+---+ +---+---+ +---+---+
| 1 | 2 | | 3 | 4 | | 5 | 6 | | 7 | 8 |
+---+---+ +---+---+ +---+---+ +---+---+
By comparing key to the highest quadrant slot, one can determine which quadrant the key lies in.
In a binary search, the midpoint is found by dividing the search range by 2.
In a 4 part search, the quadrants are found by dividing by four.
Try this algorithm out using pen and paper before coding. When you develop steps that work, then code. This is called designing then coding. A popular development process.
Nobody should be spoon-feeding you code. Work it out yourself.
Edit 1: Search Trees
Arrays and trees are very different with an array, you know where all the items are and you can use an index to access the elements. With a binary or search tree, you need to follow the links; as you don't know where each element is.
A divide by 4 search tree, is usually follows the principles of a B-Tree. Instead of single nodes, you have a page of nodes:
+---------------------------+
| Page Details |
+-----+---------------------+
| key | pointer to sub-tree |
+-----+---------------------+
| key | pointer to sub-tree |
+-----+---------------------+
| key | pointer to sub-tree |
+-----+---------------------+
| key | pointer to sub-tree |
+-----+---------------------+
The page node is an array of nodes. Most algorithms use a binary search in the array of nodes. When the key range is found, the algorithm then traverses the link to the appropriate sub-tree. The process repeats until the key is found in the Page node or on a leaf node.
What is your data structure and where lies your confusion?