Move the pointer along an array, n number of times - ruby

I want to move through just two indexes of an array. Something along these lines
iterate_amount = 2
array = [2,4,6,7]
iterate_amount.times do |x|
puts x
end #=> 2,4
I just don't know how I can place the 'array' in the loop to tell the interpreter this is the array I want to move through two indexes.

You can use Enumerable#cycle:
array = [2,4,6,7]
array.cycle(2) do |x|
puts x
end
prints
2
4
6
7
2
4
6
7
UPDATE
Use Array#[] with specifying start, length OR with specifying range.
>> array[0, 2]
=> [2, 4]
>> array[0..1]
=> [2, 4]
>> array[0...2]
=> [2, 4]

use Array#take http://ruby-doc.org/core-2.0.0/Array.html#method-i-take
>> a = [2,4,6,7]
=> [2, 4, 6, 7]
>> a.take 2
=> [2, 4]

Related

Convert an array in ruby into an output stream

I have an array [2, 4, 6, 8, 3], i need to convert it into an output stream as below:
2 4 6 8 3
Converting into string and chopping the commas and quotes is not helping as it always prints as "2 4 6 8 3" if it is a string.
This is the input given:
5
2 4 6 8 3
This is the code i wrote
def insertionSort( ar)
key = ar.last
(ar.size-2).downto(0){
|x|
if(key < ar[x])
ar[x+1] = ar[x]
p ar
else
ar[x+1] = key
p ar
break
end
}
end
# Tail starts here
count = gets.to_i
ar = gets.strip.split.map {|i| i.to_i}
insertionSort( ar )
My Output:
[2, 4, 6, 8, 8]
[2, 4, 6, 6, 8]
[2, 4, 4, 6, 8]
[2, 3, 4, 6, 8]
Expected Outuput:
2 4 6 8 8
2 4 6 6 8
2 4 4 6 8
2 3 4 6 8
Test Result:
Fail
Your question isn't at all clear, but, maybe this is what you want:
ary = [2, 4, 6, 8, 3]
ary.join(' ') # => "2 4 6 8 3"
ary * ' ' # => "2 4 6 8 3"
Perhaps you don't understand how to loop?
ary = [2, 4, 6, 8, 3]
5.times do
puts ary.join(' ')
end
# >> 2 4 6 8 3
# >> 2 4 6 8 3
# >> 2 4 6 8 3
# >> 2 4 6 8 3
# >> 2 4 6 8 3
Or maybe you don't understand how command-line apps read STDIN?
Dealing with STDIN is useful when writing pipes: Chaining one small specialized application to another, and letting them collectively do a big task is the basic premise for *nix systems. Monolithic apps that try to do everything are a major PITA to write/maintain and use.
If you want to read a single line of input, either from STDIN or the keyboard, gets is good. If you want to read a series of lines, look at Ruby's ARGF class, and become very familiar with how STDIN and $stdin work.
Writing a Ruby command-line script is easy, but, just like doing it in Perl, Python or C, you have to be aware how the incoming data is accessed, what type of data it is (always a string), and how it's structured: characters terminated by a new-line ("\n") or carriage-return+new-line ("\r\n").
Perhaps you don't understand how to_i works?
"2 4 6 8 3".to_i # => 2
"24683".to_i # => 24683
"2_4_6_8_3".to_i # => 24683
to_i reads the string from the first character and continues until it finds a non-digit. So, in the above examples, 2 is the first digit in the first string, followed by a space. The space is a non-digit so to_i stops processing and only returns 2. In the second example, there are no spaces, so to_i processes the entire string and returns it as a single value. In the third, because Ruby, like some other languages, accepts _ as a part of a numeric string, to_i returns the full value again. _ is used to mark the comma positions in values, like 1_000_000.
As you write more code, take the time to write it clearly and cleanly. You want code that reduces the visual noise and makes it easy to take into your brain. Ruby makes it easy to write clean and expressive code that is easy to understand, but bad coding style can reduce Ruby code to unreadable quickly, especially to those of us who are used to seeing it written in an idiomatic style.
This isn't an attempt to fix your algorithm, it's just to show how you should style your code:
def insertion_sort(ar)
key = ar.last
(ar.size - 2).downto(0) { |x|
if (key < ar[x])
ar[x + 1] = ar[x]
p ar
else
ar[x + 1] = key
p ar
break
end
}
end
# Tail starts here
count = gets.to_i
ar = gets.strip.split.map { |i| i.to_i }
insertion_sort(ar)
Methods are always written in snake_case, never CamelCase.
Use whitespace; It gives your eyes and brain logical breaks that help define what is going on. Operators and control structures benefit from having whitespace before and after, and above and below.
Use spaces to indent, with tab-stops set to 2-spaces. This is the Ruby standard. Why those? Consistency as people move code between different editors; If you're working in a professional coding house you'll probably find a lot more rigid coding standards in place.
> a = [1, 2, 3, 4]
> puts "[#{a.join(', ')}]"
=> [1, 2, 3, 4]
Does not work on multi-dimensional arrays, or arrays within arrays.
> a = [1, 2, [3, 4, 5, 6], [7, 8, 9]]
> puts "[#{a.join(', ')}]"
=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
But, if you do this, it should work for multi-dimensional arrays:
Example 1:
> a = [1, 2, [3, 4, 5, 6], [7, 8, 9]]
> a.each do |sub_a|
> puts "[#{a.join(', ')}]"
> end
=> [1, 2, [3, 4, 5, 6], [7, 8, 9]]
Example 2:
> a = [1, [2, [3, 4, [5, 6, 7, 8], 9, 0]], 'x', 'y', 'z']
> a.each do |sub_a|
> puts "[#{a.join(', ')}]"
> end
=> [1, [2, [3, 4, [5, 6, 7, 8], 9, 0]], "x", "y", "z"]
After reading the HackerRank "Insertion Point" question you referenced, the input appears to be coming from stdin. If your code includes
s = gets
it will wait for you to enter a string. Suppose you enter 1 2 3 4 (no quotes). Then s will hold "1 2 3 4\n".
If you want to convert this to an array:
a = s.split # => ["1","2","3","4"]
If you want the elements of a to be integers, rather than strings:
a.map! {|e| e.to_i} # => [1,2,3,4]
which (since Ruby version 1.9) can also be written:
a.map!(&:to_i) # => [1,2,3,4]
The 'Ruby way' would be to chain these operations:
a = gets.split.map(&:to_i) # => [1,2,3,4]
Note that we don't need ! with map now.
If you want this array to be a row i of some (existing array) b
b[i] = a

Taking the input as a comma separated list from a user

this is my code to return the elements that are present
exactly once in the array
a = [1,2,2,3,3,4,5]
p a.select{|i| a.count(i) == 1}
# >> [1, 4, 5]
can anyone please suggest how to take the array as keyboard input from user??
print "Enter an array: "
STDOUT.flush
arr = STDIN.gets.chomp.split(/,/).map(&:to_i)
# Enter an array: 1,2,2,3,3,4,5 <ENTER>
arr # => [1, 2, 2, 3, 3, 4, 5]
Here's a pretty concise way of collecting a set amount of input into an array:
n = 7
a = n.times.collect { gets.chomp.to_i }
Then you can use your existing code on a.
irb(main):022:0> a = n.times.collect{gets.chomp.to_i}
1
2
2
3
3
4
5
=> [1, 2, 2, 3, 3, 4, 5]
irb(main):023:0> a.select{|i| a.count(i) == 1}
=> [1, 4, 5]
Below way:
s=gets.chomp
a = s.split("")
Use the gets method to get a string from standard input. (It's short for "get string"!)
chomp removes trailing whitespace, i.e. the newline character that results from pressing enter at the end of your input.
So, calling str = gets.chomp and entering 1 2 2 3 3 4 5 at the prompt will set str to "1 2 2 3 3 4 5". Then, just use str.split to convert it to an array.

Inverting an array of arrays (matrix) in ruby

I have "text" which is an array of arrays, let's say:
1 2 3
4 5 6
7 8 9
and I just want to create another array of arrays but like this:
1 4 7
2 5 8
3 6 9
I cant get it working. It says: undefined method '[]=' for nil:NilClass
vect = Array.new()
3.times{|i|
3.times{|j|
vect[j][i] = text[i][j]
}
}
"text" is not a very good name for an array of arrays containing integers. That said, you might want to look into array.transpose.
You declare an empty array, but you don't fill it in with empty arrays.
Because the array you are using is empty, vect[j] will always return nil and not an array as you expect.
Here is the corrected code:
vect = [[], [], [], []]
4.times do |i|
4.times do |j|
vect[j][i] = text[i][j]
end
end
You can also you the Matrix class for those purposes, for instance:
require 'matrix'
m1 = Matrix[[1,2,3], [4,5,6],[7,8,9]]
m1.to_a.each {|r| puts r.inspect} #=> This is just print the matrix in that format.
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
- Transposed Version -
m1.transpose.to_a.each {|r| puts r.inspect} #=> Note the method `transpose` called. The rest is just for printin.
[1, 4, 7]
[2, 5, 8]
[3, 6, 9]

How to drop the end of an array in Ruby

Array#drop removes the first n elements of an array. What is a good way to remove the last m elements of an array? Alternately, what is a good way to keep the middle elements of an array (greater than n, less than m)?
This is exactly what Array#pop is for:
x = [1,2,3]
x.pop(2) # => [2,3]
x # => [1]
You can also use Array#slice method, e.g.:
[1,2,3,4,5,6].slice(1..4) # => [2, 3, 4, 5]
or
a = [1,2,3,4,5,6]
a.take 3 # => [1, 2, 3]
a.first 3 # => [1, 2, 3]
a.first a.size - 1 # to get rid of the last one
The most direct opposite of drop (drop the first n elements) would be take, which keeps the first n elements (there's also take_while which is analogous to drop_while).
Slice allows you to return a subset of the array either by specifying a range or an offset and a length. Array#[] behaves the same when passed a range as an argument or when passed 2 numbers
this will get rid of last n elements:
a = [1,2,3,4,5,6]
n = 4
p a[0, (a.size-n)]
#=> [1, 2]
n = 2
p a[0, (a.size-n)]
#=> [1, 2, 3, 4]
regard "middle" elements:
min, max = 2, 5
p a.select {|v| (min..max).include? v }
#=> [2, 3, 4, 5]
I wanted the return value to be the array without the dropped elements. I found a couple solutions here to be okay:
count = 2
[1, 2, 3, 4, 5].slice 0..-(count + 1) # => [1, 2, 3]
[1, 2, 3, 4, 5].tap { |a| a.pop count } # => [1, 2, 3]
But I found another solution to be more readable if the order of the array isn't important (in my case I was deleting files):
count = 2
[1, 2, 3, 4, 5].reverse.drop count # => [3, 2, 1]
You could tack another .reverse on there if you need to preserve order but I think I prefer the tap solution at that point.
You can achieve the same as Array#pop in a non destructive way, and without needing to know the lenght of the array:
a = [1, 2, 3, 4, 5, 6]
b = a[0..-2]
# => [1, 2, 3, 4, 5]
n = 3 # if we want drop the last n elements
c = a[0..-(n+1)]
# => [1, 2, 3]
Array#delete_at() is the simplest way to delete the last element of an array, as so
arr = [1,2,3,4,5,6]
arr.delete_at(-1)
p arr # => [1,2,3,4,5]
For deleting a segment, or segments, of an array use methods in the other answers.
You can also add some methods
class Array
# Using slice
def cut(n)
slice(0..-n-1)
end
# Using pop
def cut2(n)
dup.tap{|x| x.pop(n)}
end
# Using take
def cut3(n)
length - n >=0 ? take(length - n) : []
end
end
[1,2,3,4,5].cut(2)
=> [1, 2, 3]

How to get the last element of an array in Ruby?

Example:
a = [1, 3, 4, 5]
b = [2, 3, 1, 5, 6]
How do I get the last value 5 in array a or last value 6 in array b without using a[3] and b[4]?
Use -1 index (negative indices count backward from the end of the array):
a[-1] # => 5
b[-1] # => 6
or Array#last method:
a.last # => 5
b.last # => 6
One other way, using the splat operator:
*a, last = [1, 3, 4, 5]
a => [1, 3, 4]
last => 5

Resources