Convert an array in ruby into an output stream - ruby

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

Related

Arithmetic sequence Ruby

It is a code to find the missing sequence of an arithmetic sequence and finding common difference and also checking is it is an increasing or decreasing sequence. Take user input for further operation
For Ex: enter array elements
2 4 6 10 12 14
missing number is 8 instead of
enter array elements
2
4
6
10
12
14
missing number is 8
puts "enter arithmetic sequence"
o = Array.new
x = gets.chomp
item = x.split(" ")
o.push(item)
puts "#{o}"
len = o.length
sum = (len + 1) * (o[0] + o[len - 1]) / 2
summ = 0
o.each { |a| summ+=a }
res = sum - summ
if(o[1]>o[0])
puts "its an increasing sequence"
else
puts "its a decreasing sequence"
end
common_difference = o[1] - o[0]
puts "Common difference is #{common_difference}"
puts "missing number is #{res}"
The operations like sum common difference are working, but requirement is that we need to take user input in a single line instead of taking in multiple line, split that and store in an array.
For taking sum I used actual sum - target sum method.
Main issue is that it rise an error
`*': Array can't be coerced into Integer
How to convert array elements that is in string format to int using to_i method or Integer method
Expected Output
i/p 2 4 6 8 12 14
o/p
missing number 10
requirement is that we need to take user input in a single line instead of taking in multiple line, split that and store in an array
gets.chomp returns a string with trailing newline removed, e.g. (the 2nd line being user input)
x = gets.chomp
2 4 6 8 12 14
x #=> "2 4 6 8 12 14"
split converts that string to an array:
x.split
#=> ["2", "4", "6", "8", "12", "14"]
what's missing is the conversion to integer. To convert each element of an array, there's map:
x.split.map { |s| s.to_i }
#=> => [2, 4, 6, 8, 12, 14]
or its short-hand notation:
x.split.map(&:to_i)
#=> => [2, 4, 6, 8, 12, 14]
applied to your code:
puts "enter arithmetic sequence"
x = gets.chomp
o = x.split.map(&:to_i)
puts "#{o}"
# ...
Note that there's no need to create an empty array. You can just assign the result of map to o.
The rest of your code seems to work as expected. But you should check out Cary Swoveland's answer for more succinct way of finding the missing element.
Try this:
def missing_number(arr)
((arr.size + 1) * (arr.first + arr.last))/2 - arr.sum
end
missing_number [2, 4, 6, 10, 12, 14] #=> 8
missing_number [11, 8, 5, 2, -4, -7] #=> -1
missing_number [1.2, 2.0, 2.4, 2.8, 3.2] #=> 1.6000000000000014
Suppose arr were not missing any values. For example,
arr = [2, 4, 6, 8, 10, 12, 14]
Then:
arr.sum
#=> 56
which, because it is an arithmetic series, we could alternatively compute as follows:
(arr.size * (arr.first + arr.last))/2
#=> 56
In fact,
arr = [2, 4, 6, 10, 12, 14]
and
arr.sum
#=> 48
As I explained above, we can calculate the sum of the values of arr after the missing value has been inserted as follows:
((arr.size + 1) * (arr.first + arr.last))/2
#=> 56
The missing value therefore equals 56 - 48 #=> 8.
Here is another way to find the missing value that is slightly less efficient.
def missing_number(arr)
arr.each_cons(2).max_by { |a,b| (b-a).abs }.sum/2
end
missing_number [2, 4, 6, 10, 12, 14] #=> 8
missing_number [11, 8, 5, 2, -4, -7] #=> -1
missing_number [1.2, 2.0, 2.4, 2.8, 3.2] #=> 1.6
Suppose
arr = [11, 8, 5, 2, -4, -7]
The steps are as follows.
enum = arr.each_cons(2)
#=> #<Enumerator: [11, 8, 5, 2, -4, -7]:each_cons(2)>
We can see the (5) values that the enumerator will generate and pass to Enumerable#max_by by converting enum to an array:
enum.to_a
#=> [[11, 8], [8, 5], [5, 2], [2, -4], [-4, -7]]
Next let's look at the values that max_by will compare:
enum.map { |a,b| (b-a).abs }
#=> [3, 3, 3, 6, 3]
We therefore obtain the following:
c = enum.max_by { |a,b| (b-a).abs }
#=> [2, -4]
The last two steps calculate the average of 2 and -4:
d = c.sum
#=> -2
d/2
#=> -1

Ruby split array into X groups

I need to split an array into X smaller array. I don't care about the number of elements in the smaller arrays I just need to create X arrays from a larger one. I've been doing some reading and it seems like I need a method similar to the in_groups method from rails. I am not using rails right now, just ruby.
Requiring Rails just to get that function is overkill. Just use each_slice:
team = ['alice', 'andy', 'bob', 'barry', 'chloe', 'charlie']
=> ["alice", "andy", "bob", "barry", "chloe", "charlie"]
team.each_slice(2).to_a
=> [["alice", "andy"], ["bob", "barry"], ["chloe", "charlie"]]
each_slice's parameter is the number of elements in each slice (except possibly the last slice). Since you're looking for X slices, you can do something like this:
team.each_slice(team.length/X).to_a
That's not perfect, as you'll get one extra slice if the array length is not a multiple of X, but gets you in the ballpark and you can tweak it from there depending on what exactly your needs are.
Since you say you don't care how many are in each, you could just use the length/x approach above, then check to see if you have one too many slices. If so, just join the last two slices into one jumbo-size slice. This might avoid some fussy math or floating point operations.
You can make your own method, here's a basic idea:
class Array
def my_group(x)
start = 0
size = (self.size() / Float(x)).ceil
while x > 0
yield self[start, size]
size = ((self.size() - 1 - start) / Float(x)).ceil
start += size
x -= 1
end
end
end
%w(1 2 3 4 5 6 7 8 9 10).my_group(3) {|group| p group}
# =>["1", "2", "3", "4"]
# =>["4", "5", "6"]
# =>["7", "8", "9"]
I decided to put:
require 'active_support/core_ext/array/grouping'
if x is a count of groups:
x = 2
a = [1,2,3,4,5,6,7,8,9,10,11,12]
a.in_groups(x)
=> [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
if group by x pieces:
x = 2
a = [1,2,3,4,5,6,7,8,9,10,11,12]
a.each_slice(x).to_a
=> [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
If you need to have N groups, you can use the in_groups monkey-patch provided by ActiveSupport, as mentioned in another answer:
require 'active_support/core_ext/array/grouping'
my_array = [1,2,3,4,5]
my_array.in_groups(2)
# => [[1, 2, 3], [4, 5, nil]]
my_array.in_groups(2, false)
# => [[1, 2, 3], [4, 5]]
If you care about the number of elements in the group as opposed to the number of groups, you can use each_slice provided by Ruby core:
my_array = [1,2,3,4,5]
my_array.each_slice(2).to_a
# => [[1, 2], [3, 4], [5]]

split the contents of the array into two other arrays

Simple example but I want to understand how it is done so I can apply it else where I have a main array with 6 elements. I want to take 3 of the elements from the main array and put it in a array and then take the other 3 from main array and put them in b array. I will use this to apply it to dealing cards to two players
main = [1, 2, 3, 4, 5, 6]
a = [ ]
b = [ ]
main = [1, 2, 3, 4, 5, 6]
#=> [1, 2, 3, 4, 5, 6]
main.first(3)
#=> [1, 2, 3]
main.last(3)
#=> [4, 5, 6]
a = [1, 2, 3, 4, 5, 6]
#=> [1, 2, 3, 4, 5, 6]
b = a.take(3)
#=> [1, 2, 3]
c = a.drop(3)
#=> [4, 5, 6]
All may have given the right answer, But as I understood from your question (I will use this to apply it to dealing cards to two players) When you dealing cards, as you deal cards to player main array should remove that element from self array to overcome Redundancy Problem (duplication). When you deal the all cards main array must be empty.
For this solution have a look at Array#shift
> main = [1,2,3,4,5,6] # I have 6 cards on my hand before dealing cards to players
=> [1, 2, 3, 4, 5, 6]
> a = main.shift(3) # given 3 cards to Player a
=> [1, 2, 3]
> b = main.shift(3) # given 3 cards to Player b
=> [4, 5, 6]
> main # after dealing all cards to two players I should not have any card on my hand
=> []
You have many ways to do the same thing in Ruby. Splitting arrays isn't an exception. Many answers (and comments) told you some of the ways to do that. If your program is dealing cards, you won't stop there. First, you'll probably have more than 6 cards. Second, you're probably going to have more than 2 players. Let's say the cards are C and the players are P. You need to write a method that, no matter how many Cs or Ps there are, the method is going to give each Player an equal number of Ccards (or return an error if it can't give it an equal number of cards). So for 6 cards and 2 players, it will give 3 cards each. For 12 cards and 3 players, 4 cards each. For 3 cards and 2 players, it's going to produce an error because the cards can't be evenly split:
def split_cards_evenly_between_players(cards, players)
if cards.size % players != 0
raise 'Cannot split evenly!'
else
groups_to_split_into = cards.size / players
cards.each_slice(groups_to_split_into).to_a
end
end
Let's go through the code. If the cards can't be evenly split between players, then the remainder by dividing them won't be 0 (6 cards / 3 players = remainder 0. 7 cards / 3 players = remainder 1). That's what line 2 checks. If the cards CAN be split, then we first find the groups to split into (which is dividing the number of cards by the number of players). Then we just split the array into that many groups with Enumerable#each_slice. Finally, since this doesn't produce an array, we need .to_a to convert it. The return value in Ruby is always the value of the last expression executed. The only expression in this method is the if/then expression which also returns the value of the last expression executed (which is the line where each_slice is). Let's try it out:
p split_cards_evenly_between_players([1,2,3,4,5,6,7,8,9,10,11,12],2) #=> [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
p split_cards_evenly_between_players([4,5,1,2,5,3], 3) #=> [[4, 5], [1, 2], [5, 3]]
p split_cards_evenly_between_players([1,2,3],2) #=> Error: Cannot split evenly!
The nice thing about Ruby is its simple syntax and the fact it tries to get out of your way while solving a problem so you can focus more on the actual problem than the code.

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.

ruby: what does the asterisk in "p *1..10" mean

the line
p *1..10
does exactly the same thing as
(1..10).each { |x| puts x }
which gives you the following output:
$ ruby -e "p *1..10"
1
2
3
4
5
6
7
8
9
10
it's a great shortcut when working with textmate for example, but what does the asterisk do? how does that work? couldn't find anything on the net...
It's the splat operator. You'll often see it used to split an array into parameters to a function.
def my_function(param1, param2, param3)
param1 + param2 + param3
end
my_values = [2, 3, 5]
my_function(*my_values) # returns 10
More commonly it is used to accept an arbitrary number of arguments
def my_other_function(to_add, *other_args)
other_args.map { |arg| arg + to_add }
end
my_other_function(1, 6, 7, 8) # returns [7, 8, 9]
It also works for multiple assignment (although both of these statements will work without the splat):
first, second, third = *my_values
*my_new_array = 7, 11, 13
For your example, these two would be equivalent:
p *1..10
p 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Resources