How to Write Negative Loop in Ruby Like For(I=Index; I >= 0; I --)

How to write negative loop in ruby like for(i=index; i = 0; i --)

There are many ways to perform a decrementing loop in Ruby:

First way:

for i in (10).downto(0)
puts i
end

Second way:

(10).downto(0) do |i|
puts i
end

Third way:

i=10;
until i<0
puts i
i-=1
end

Decrement the array in ruby using for loop

Try this link.Its has explained types of iteration. iterator

In Ruby, if I have an array, how can I replace any negative values with 0?

Try this

array_sample = [2, 7, 3, -5, 2, -6]

array_sample.map! { |e| e > 0 ? e : 0 }

Response

[2, 7, 3, 0, 2, 0]

How does negative index work with `Array#[]=`?

I would suggest you to take a look at the first para in Array documentation. It surprisingly says: “A negative index is assumed to be relative to the end of the array—that is, an index of -1 indicates the last element of the array, -2 is the next to last element in the array, and so on.”

That means, that you may set a[-N]th element if and only |N| <= a.size. That’s why a = [1,2] ; a[-3] = 3 fails (3 > 2).

On the other hand, there is [likely] not documented feature for ruby arrays: a[INBOUNDS_IDX..NONSENSE_IDX]=SMTH will insert SMTH before INBOUNDS_IDX index:

a=[1,2]
a[2..0]='a'
a[2..1]='b'
a[2..-100]='c'
# ⇒ [1, 2, "c", "b", "a"]
a[2..-1]='q'
# ⇒ [1, 2, "q"]

Nonsense here means “less than INBOUNDS_IDX, and not treatable as index in an negative notation” (that’s why a[2..-1] in the example above is treated as a[2..(a.size - 1)].)

Given an array of positive and negative integers, re-arrange it so that you have positive integers on one end and negative integers on other

To achieve this result in constant space (but quadratic time), you can use the two-queue approach by placing one queue at each end of the array (similar to the Dutch National Flag algorithm). Read items left-to-right : adding an item to the left queue means leaving it alone, adding an item to the right queue means shifting all elements not in a queue to the left by one and placing the added item at the end. Then, to concatenate the queues, simply reverse the order of elements in the second queue.

This performs an O(n) operation (shifting elements left) up to O(n) times, which yields an O(n²) running time.

By using a method similar to merge sort, you can achieve a lower O(n log n) complexity: slice the array in two halves, recursively sort them in the form [N P] [N P] then swap the first P with the second N in O(n) time (it gets a bit tricky when they don't have exactly the same size, but it's still linear).

I have absolutely no idea of how to get this down to O(n) time.

EDIT: actually, your linked list insight is right. If the data is provided as a doubly linked list, you can implement the two-queue strategy in O(n) time, O(1) space:

sort(list):
negative = empty
positive = empty
while (list != empty)
first = pop(list)
if (first > 0)
append(positive,first)
else
append(negative,first)
return concatenate(negative,positive)

With a linked list implementation that keeps pointers to the first and last elements, then pop, append and concatenate are all O(1) operations, so the total complexity is O(n). As for space, none of the operations allocate any memory (append merely uses the memory released by pop), so it's O(1) overall.

Find the smallest positive integer that does not occur in a given sequence

If the expected running time should be linear, you can't use a TreeSet, which sorts the input and therefore requires O(NlogN). Therefore you should use a HashSet, which requires O(N) time to add N elements.

Besides, you don't need 4 loops. It's sufficient to add all the positive input elements to a HashSet (first loop) and then find the first positive integer not in that Set (second loop).

int N = A.length;
Set<Integer> set = new HashSet<>();
for (int a : A) {
if (a > 0) {
set.add(a);
}
}
for (int i = 1; i <= N + 1; i++) {
if (!set.contains(i)) {
return i;
}
}

Why does range(start, end) not include end?

Because it's more common to call range(0, 10) which returns [0,1,2,3,4,5,6,7,8,9] which contains 10 elements which equals len(range(0, 10)). Remember that programmers prefer 0-based indexing.

Also, consider the following common code snippet:

for i in range(len(li)):
pass

Could you see that if range() went up to exactly len(li) that this would be problematic? The programmer would need to explicitly subtract 1. This also follows the common trend of programmers preferring for(int i = 0; i < 10; i++) over for(int i = 0; i <= 9; i++).

If you are calling range with a start of 1 frequently, you might want to define your own function:

>>> def range1(start, end):
... return range(start, end+1)
...
>>> range1(1, 10)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Ruby. How to write a loop of 1% percentage profit for one year on a 1000$ investment

You should use BigDecimal instead of Float when dealing with monetary values:

require 'bigdecimal'

money = BigDecimal('1000')
percentage = BigDecimal('0.01')

For the loop I'd use upto which works very intuitively:

1.upto(365) do |day|
money += (money * percentage).round(2)
printf("%3d: %8.2f$\n", day, money)
end
  • money * percentage calculates the day's profit, rounded to 2 digits via round. You can adjust the rounding mode by passing a second argument.
  • printf then outputs day and money using the given formatting:

    • %3d prints an integer with width 3
    • %8.2f prints a float with 2 fractional digits and a total width of 8

Output:

  1:  1010.00$
2: 1020.10$
3: 1030.30$
...
363: 37039.07$
364: 37409.46$
365: 37783.55$


Related Topics



Leave a reply



Submit