getting numbers from lines of text - ruby

I want to parse a text file, where
I get numbers that are between parenthesis like
this:
1 2 3 (4 - 7) 8 9
1 3 8 (7 - 8) 2 1
1 2 (8 - 10) 3 2
should return an array for each:
array1:
4
7
8
array2:
7
8
10
I am thinking of using split for each line, like line.split("("), but that doesn't quite doing the trick.. I was wondering if there is something more sophisticated for the job.
Any help appreciated,
Ted

data = <<EOS
1 2 3 (4 - 7) 8 9
1 3 8 (7 - 8) 2 1
1 2 (8 - 10) 3 2
EOS
lines = data.split("\n")
def get_inner(lines)
lines.map { |line| line.partition("(")[2].partition(")")[0].split(" - ")}
end
a1, a2 = *[get_inner(lines).map {|a| a.first },get_inner(lines).map {|a| a.last }]
puts a1
puts a2
# =>
4
7
8
7
8
10

I would look into using things like Substring / IndexOf as well as split.
You could also try a regular expression to find numbers seperated by spaces in between the ( ) but regular expressions can be a bit of a pain.

Hmm just found this
http://www.rubular.com/ I got the expression I needed
((\d+)-(\d+))

Related

Ruby rookie here : Need help in printing a one sided pyramid using a given Integer

input integer 6
output :
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
Tried with loops but failed to get the output.
def pyramid(i)
(1..i).each do |n|
1.upto(n) do |x|
print "#{x} " # Mind double quotes
end
puts
end
end
pyramid(6)
Read more about Ruby I/O
Read more about loops in Ruby

How can I subtract columns from a 2D array of JULIA?

I'm new to julia and I have a problem.
I am working with Julia (Jupyter notebook) and I do not know how can I do column 3 - column 2 and write the result as a new column at the end of the matrix/array2D.
I have tried this:
newCol = array[(1:end),3] - array[(1:end),2]
Any suggestion?
You can subtract the two columns and then concatenate it with the original array using the normal build-an-array syntax:
julia> arr
2x3 Array{Int32,2}:
1 2 3
5 6 7
julia> [arr [arr[:,3] - arr[:,2]]]
2x4 Array{Int32,2}:
1 2 3 1
5 6 7 1
Or use hcat:
julia> hcat(arr,arr[:,3] - arr[:,2])
2x4 Array{Int32,2}:
1 2 3 1
5 6 7 1
(Note that neither of these act in place, so you'd need to assign the result somewhere if you want to use it later.)

GNU Octave, convert matrix to a String

In GNU Octave I have a 1xn matrix:
octave:1> s=[1;2;3;4;5;6;7]
s =
1
2
3
4
5
6
7
I would like to convert this matrix to a space delimited string like this:
"1 2 3 4 5 6 7"
I tried using mat2str and cellstr without much success. Is this possible?
Octave, How to convert matrix to string:
If your matrix is a single column, invert it so it is a row like this:
octave:1> s=[1;2;3;4;5;6;7]
s =
1
2
3
4
5
6
7
mat2str(s')
Which prints:
ans = [1 2 3 4 5 6 7]
This looks like it is not a string because it has left and right square brackets, but it is a string. You can remove the left and right brackets like this:
substr(s,2,length(s)-2)
Which cuts off the first and last characters, which prints:
s = 1 2 3 4 5 6 7
Which is a string.

Print numbers in a range

I am trying to print all numbers between 1 and 50, using the following code:
[1..50].each{|n| puts n}
but the console print
[1..50]
I want to print something like this
1
2
3
4
...
50
Try the following code:
(1..50).each { |n| puts n }
The problem is that you're using [] delimiter instead of () one.
You can use [1..10] with a minor tweak:
[*1..10].each{ |i| p i }
outputs:
1
2
3
4
5
6
7
8
9
10
The * (AKA "splat") "explodes" the range into its components, which are then used to populate the array. It's similar to writing (1..10).to_a.
You can also do:
puts [*1..10]
to print the same thing.
So, try:
[*1..10].join(' ') # => "1 2 3 4 5 6 7 8 9 10"
or:
[*1..10] * ' ' # => "1 2 3 4 5 6 7 8 9 10"
To get the output you want.
The error here is that you are creating an Array object with a range as its only element.
> [1..10].size
=> 1
If you want to call methods like each on a range, you have to wrap the range in parentheses to avoid the method being called on the range's last element rather than on the range itself.
=> (1..10).each { |i| print i }
12345678910
Other ways to achieve the same:
(1..50).each { |n| print n }
1.up_to(50) { |n| print n }
50.times { |n| print n }
You can cast your range (in parentheses) to an array ([1 2 3 4 5 6... 48 49 50]) and join each item (e.g. with ' ' if you want all items in one line).
puts (1..50).to_a.join(' ')
# => 1 2 3 4 5 6 7 ... 48 49 50

trying to create a matrix in ruby

i have a file called terain.dat which contains this matrix:
10
1 1 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 12 12 12
1 2 3 4 5 6 7 12 12 12
1 2 3 4 5 6 7 12 12 12
i want to read in the file and use the first number on the first line as the size of the matrix (which is 10 X 10 in this case). And then fill the 10 X 10 matrix with the numbers below.
this is what i have so far:
class Terrain
def initialize file_name
#input = IO.readlines(file_name) #read in file # reads in the file with the terrain detials
#matrix_size = #input[0].to_i # changes the first index to an int (so i can make a10X10 matrix)
#land = Matrix.[#matrix_size, #matrix_size] # will this make a 10 X 10 matrix??
end
end
i was wondering if this will make a 10X10 matrix and how do i fill it??
I'd write:
terrain = open("terrain.data") do |file|
size = file.lines.first.to_i
rows = file.lines.first(size).map { |line| line.split.map(&:to_i) }
Matrix.rows(rows)
end
actually no. The Matrix.[] is used for setting the values of a row.
So Matrix.[10,10] would create a Matrix with 2 rows, and in each column a 10.
What you are searching for is Matrix.build(row_size, column_size) where column_size defaults to row_size. This gives you an enumerator which you can use to set the values. (or you just pass a block to Matrix.build
I'd suggest a different approach:
arr = []
#input.each_index do |index|
arr[index] = #input[index].split ' '
end
#land = Matrix.build(10,10) do |row, column|
arr[row][column].to_i
end
You could skip over the first line, read the other lines, chomp them to remove the new lines and then split on white space. This will give you an array of arrays, which you can feed to Matrix.rows.
No need to declare the size. Try the following:
class Terrain
attr_accessor :m
def initialize file_name
data = IO.readlines(file_name)
data.each_line do |l|
data << l.split.map {|e| e.to_i}
end
#m = Matrix[*#data]
end
end
Or, even better:
class Terrain
attr_accessor :m
def initialize file_name
File.open(file_name).each do |l|
data << l.split.map {|e| e.to_i}
end
#m = Matrix[*#data]
end
end
No need for the size:
class Terrain
def initialize(file_name)
File.open(file_name) do |f|
#m = Matrix[*f.lines.map { |l| l.split.map(&:to_i) }]
end
end
end

Resources