Ruby - Unable to count the array values? - ruby-2.0

I have a program :
Question : Input a number of integer of 2 digit only , and in the out-put it should show the all input values BUT loop should stop on 42 :
example
input
1
2
87
42
99
output
1
2
87
my code
a = []
5.times do |i|
a[i] = Integer(gets.chomp)
end
a.each do |e|
break if e == '42'
puts e
end

Few things to change. First of all gets will give you a string together with \n at the end, so you need to change it to gets.chomp to remove it.
Now your loop should look like this:
a.each do |e|
break if e == '42'
puts e
end
However ruby's array has much butter function which is perfect for what you want:
puts a.take_while {|e| e != '42'}
Additional notes:
Note that it is operating on strings rather than numbers. You might need to validate the input at some point and convert it into integer values.
5.times do|i| - the |i| bit is obsolete.

Related

Extracting specific words from a single cell containing text string

Basically I have a very long text containing multiple spaces, special characters, etc. in one cell in an excel file and I need to extract only specific words from it, each one to a seperate cell in another column.
What I'm looing for:
symbols that are always 9 characters in lenght, and always contain at least one number (up to 9).
So for an example in A1 I have:
euhe: djj33 dkdakofja. kaowdk ---------- jffjbrjjjj j jrjj 08/01/2222 999ABC123
fjfjfj 321XXX888 .... ........ 123456789AA
And in the end I want to have:
999ABC123 in B1
and
321XXX888 in B2.
Right now I'm doing this by using Text to columns feature and then just looking for specific words manually but sometimes the volume is so big it takes too much time and would be cool to automate this.
Can anyone help with this? Thank you!
EDIT:
More examples:
INPUT: '10/01/2016 1,060X 8.999%!!! 1.33 0.666 928888XE0'
OUTPUT: '928888XE0'
INPUT: 'ABCDEBATX ..... ,,00,001% 20///^^ addcA7 7777a 123456789 djaoij8888888 0.000001 12#'
OUTPUT: '123456789'
INPUT: 'FAR687465 B22222222 __ djj^66 20/20/20/20 1:'
OUTPUT: 'FAR687465' in B1 'B22222222' in B2
INPUT: 'fil476 .00 20/.. BUT AAAAAAAAA k98776 000.0001'
OUTPUT: 'blank'
To clarify: the 9 character string can be anywhere, there is no rule what is before or after them, they can be next to each other, or just at the beginning and end of this wall of text, no rules here, the text is random, taken out of some system, can contain dates, etc anything... The symbols are always 9 characters long and they are not the only 9 character symbols in the text. I call them symbols but they should only consist of numbers and letters. Can be only numbers, but never only letters. A1 cell can contain multiple spaces/tabs between words/symbols.
Also if possible to do this not only for A1, but the whole column A until it finds the first blank cell.
Try this code
Sub Test()
Dim r As Range
Dim i As Long
Dim m As Long
With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "\b[a-zA-Z\d]{9}\b"
For Each r In Range("A1", Range("A" & Rows.Count).End(xlUp))
If .Test(r.Value) Then
For i = 0 To .Execute(r.Value).Count - 1
If CBool(.Execute(r.Value)(i) Like "*[0-9]*") Then
m = IIf(Cells(1, 2).Value = "", 1, Cells(Rows.Count, 2).End(xlUp).Row + 1)
Cells(m, 2).Value = .Execute(r.Value)(i)
End If
Next i
End If
Next r
End With
End Sub
This bit of code is almost it... just need to check the strings... but excel crashes on the Str line of code
Sub Test()
Dim Outputs, i As Integer, LastRow As Long, Prueba, Prueba2
Outputs = Split(Range("A1"), " ")
For i = 0 To UBound(Outputs)
If Len(Outputs(i)) = 9 Then
Prueba = 0
Prueba2 = 0
On Error Resume Next
Prueba = Val(Outputs(i))
Prueba2 = Str(Outputs(i))
On Error GoTo 0
If Prueba <> 0 And Prueba2 <> 0 Then
LastRow = Range("B10000").End(xlUp).Row + 1
Cells(LastRow, 2) = Outputs(i)
End If
End If
Next i
End Sub
If someone could help to set the string check.. that would do the thing I guess.

Python Iterating through a string to look for a Palindrome

So I have looked around this site and others for information on how to iterate through a string on Python, find a specific substring, reverse it and check if the two equaled in order to get a Palindrome. This is the problem though since some of the test cases are challenging to get and have confused me on how to find them through indexing.
This is my code that works for all, but two test cases:
def countPalindromes(s):
count = 0
firstindex = 0
lastindex = len(str)-1
while firstindex != lastindex and firstindex <= lastindex:
ch1 = s[firstindex:lastindex]
ch2 = s[lastindex:firstindex:-1]
if ch1 == ch2:
count +=1
firstindex +=1
lastindex -=1
return count
This code works for the following Palindromes: "racecar", " ", and "abqc".
It does not work for these Palindromes "aaaa" and "abacccaba".
For "aaaa" there are 6 palindromes and for "abacccaba" there are 8 palindromes. This is where my problem occurs, and I simply can't figure it out. For the 6 palindromes for "aaaa" I get aaaa, aaa, aa, twice for each. For "abacccaba" the 8 palindromes I have no idea as I get abacccaba, bacccab, accca, ccc, aba, aba.
I understand this is a confusing question, but I am lost how to approach the problem since I only get 2 for the "aaaa" and 4 for "abacccaba". Any ideas how I would cut out the substrings and get these values?
Thanks in advance!
while firstindex != lastindex and firstindex <= lastindex: misses the case of a single character palindrome.
You're also missing the case where aa contains three palindromes, 0:1, 0:2 and 1:2.
I think you're missing some palindromes for aaaa; there are 10:
aaaa
a
a
a
a
aa
aa
aa
aaa
aaa
If single-character palindromes do not count, then we have 6.
Either way, you need to consider all substrings as possible palindromes; not only the ones in the middle. Comparing a string against its reversed self is very easy to do in Python: s == s[::-1].
Getting all the substrings is easy too:
def get_all_substrings(input_string):
length = len(input_string)
return [input_string[i:j+1] for i in range(length) for j in range(i,length)]
and filtering out strings of length < 2 is also easy:
substrings = [a for a in get_all_substrings(string) if len(a) > 1]
Combining these should be fairly straight forward:
len([a for a in get_all_substrings(string) if len(a) > 1 and a == a[::-1]])
I think you should write a function(f) individually to check if a string is a palindrome.
Then make a function(g) that selects sub-strings of letters.
Eg: in string abcd, g will select a, b, c, d, ab, bc, cd, abc, bcd, abcd. Then apply f on each of these strings individually to get the number of palindromes.

What is the error in my python code

You are given an integer NN on one line. The next line contains NN space separated integers. Create a tuple of those NN integers. Let's call it TT.
Compute hash(T) and print it.
Note: Here, hash() is one of the functions in the __builtins__ module.
Input Format
The first line contains NN. The next line contains NN space separated integers.
Output Format
Print the computed value.
Sample Input
2
1 2
Sample Output
3713081631934410656
My code
a=int(raw_input())
b=()
i=0
for i in range (0,a):
x=int(raw_input())
c = b + (x,)
i=i+1
hash(b)
Error:
invalid literal for int() with base 10: '1 2'
There are three errors that I can spot:
First, your for-loop is not indented.
Second, you should not be adding 1 to i - the for-loop does this automatically.
Thirds - and this is where the error is thrown - is that raw_input reads the entire line. If you are reading the line '1 2', you cannot convert this to an int.
To fix this problem, I suggest doing:
line = tuple(map(int,raw_input().split(' ')))
This takes the raw input, splits it into an list, makes this list into ints, then turns this list into a tuple.
In fact, you can scrap the entire for loop. You could answer this problem in two lines of code:
raw_input()#To get rid of the first line, which we do not need
print hash(tuple(map(int,raw_input().split(' '))))
The input format
next line contains NN space separated integers
eg: 1 2 3, is not an integer (because of the spaces), that is why when you try int(raw_input()) your code throws an error. You should use split(' ') as the other answer has suggested, to separate each integer. This will remove the error.
Also, there is no need to use i=i+1 as the loop will take care of it
Try the below code:
if __name__ == '__main__':
n = int(input())
integer_list = map(int, input().split())
t = tuple(integer_list)
print(hash(t))
Try This code for Python-3
if __name__ == '__main__':
n = int(input())
integer_list = map(int, input().split())
input_list = [int(x) for x in integer_list]
t = tuple(input_list)``
print(hash(t))

Reading unknown length line

I have an unknown length line that is in this format
bobaboao dsaas : 5->2 2->3 4->6 7->2 1->4 5->1 8->1 222->1 23->13 ...
I need to read each
"X->Y"
and send to function
Dist(X,Y)
until the end of the line
How can I do this in MATLAB?
I'd use regexp with 'tokens', which pulls out the bits of the match in between parentheses (()):
>> C = regexp(s,'(\d*)->(\d*)','tokens')
C =
{1x2 cell} {1x2 cell} {1x2 cell} {1x2 cell} {1x2 cell} ...
{1x2 cell} {1x2 cell} {1x2 cell} {1x2 cell}
>> xy = str2double(vertcat(C{:})).'
xy =
5 2 4 7 1 5 8 222 23
2 3 6 2 4 1 1 1 13
Then you have X = xy(1,:); and Y = xy(2,:);.
Explained: \d is a digit ([0-9]), \d* means any number of digits. Wrapping them in () makes them tokens. The whole pattern defines a match, but the tokens are extracted into a cell array of cell arrays, one cell array for each match, containing cell arrays for the tokens. It's easy to make a single matrix with vertcat and convert it with str2double.
One suggestion I have is to use regular expressions so that you search for substrings within that string in your example that specifically have one ID, followed by -> followed by another ID. Once we find these exact patterns in your string, we simply extract those out and place them into a cell array. In other words, supposing that our string was stored in s (I'm actually going to use your example), do this:
s = 'bobaboao dsaas : 5->2 2->3 4->6 7->2 1->4 5->1 8->1 222->1 23->13';
g = regexp(s, '[0-9]+->[0-9]+', 'match');
Let's go through this code slowly. s stores the string that you're analyzing, then the next line finds substrings in your string s that finds a sequence of at least one digit, followed by a ->, followed by at least one digit. The 'match' flag extracts out the strings that match this pattern we are finding in s. g is the output of this line, and each string is stored in a cell array. We thus get:
g =
Columns 1 through 7
'5->2' '2->3' '4->6' '7->2' '1->4' '5->1' '8->1'
Columns 8 through 9
'222->1' '23->13'
Note that storing into a cell array is important, because the length of each substring may be different.
Once we extract these substrings, what we can do is extract the numbers before and after the ->. We simply apply two more regular expression calls to get the numbers before and after:
X = regexp(g, '^[0-9]+', 'match');
Y = regexp(g, '[0-9]+$', 'match');
The first call looks for substrings at the beginning of each string in g that starts with a number, while the second call looks for substrings at the end of each string in g that ends with a number. What will be returned are the numbers contained in cell arrays. Also, the numbers themselves are strings. Because each element in the cell is a string, we should convert these back into actual numbers. We should also place these into a numeric vector for you to use with your code:
X = cellfun(#str2double, X);
Y = cellfun(#str2double, Y);
cellfun is a function that allows you to apply a particular function to each cell in a cell array. In this case, we want to convert each number in the cell array as it's a string into double. Therefore, use str2double to facilitate this conversion. Once we're done, we will get numeric vectors that give you the numbers before the -> and after the ->.
We finally get:
X =
5 2 4 7 1 5 8 222 23
Y =
2 3 6 2 4 1 1 1 13
I found a tricky way:
0)delete the alphabetical sequence by writing the following line:
str(1:strfind(str,':'))=''
1)concatenate this string in the following way:
newStr=['[',str,']']
, so that now your new string will be: '[5->2 2->3 4->6 7->2 1->4 5->1 8->1 222->1 23->13]'
2)delete all the '>' , you can do it by the command:
newStr(newStr=='>')=''
,so that now you will have '[5-2 2-3 4-6 7-2 1-4 5-1 8-1 222-1 23-13]',
pay attention that this is actually a string that represents a vector that contains the distances between the numbers, and that leads us to step 3...
3)evaluate the string we get:
distances=eval(newStr);
if you want the distances without + an - , just use abs() function.

Fortran: Integer to String Example

I'm trying to write a simple Fortran code, for practicing. It is supposed to multiply numbers in a range. Each time, the resulting product is converted into a string because I want to see if it consists of the same digits.
I tested the way I transform an integer into a string and typed the components of the string, and everything was going correctly. Then, I need to compare the components of the string, for which I use string(number:number). But I couldn't get the code to do this correctly.
Here's the code and the output:
program test
implicit none
character(10) myString
character(1) a,b,c,d,e,f
integer::i,j,k
do i=900,901,1
j=900
k=i*j
write(*,*)'k =', k
write(myString,'(i10)') k
write(*,*)'myString = ', myString
a=myString(1:1)
b=myString(2:2)
c=myString(3:3)
d=myString(4:4)
e=myString(5:5)
f=myString(6:6)
print*,a,b,c,d,e,f
if (d==f) then
print*,'hobla'
else
print*,'fobla'
end if
end do
stop
end program test
So I defined characters: a,b,c,d,e,f to contain the components of the string. And used myString(i:i) to locate each component and store it in one of the characters a,b,c,d,e,f.
But it seems only the first two are working correctly, the rest is not being stored!
Output:
k = 810000
myString = 810000
81
fobla
k = 810900
myString = 810900
81
fobla
Notice 81. This was supposed to give 810000 the first time, and print "hobla". And give 810900 the second time and print "fobla". But this didn't happen!
Can anybody show me how to let myString accept the zeros as characters?
This statement
write(myString,'(i10)') k
writes the value of k into a 10-character field. Since k has only 6 significant digits the first 4 characters in myString are filled with blanks. Then you assign the first 6 characters of myString (that is 4 blanks and the digits 8 and 1) to the variables a,b,c,d,e,f and print them out -- 4 blanks and 2 digits.
Try printing out the other characters in positions 7..10 of myString and you should see your 'missing' digits.
Okay, so I figured out the problem. Consider the following modifications to your code:
program test
implicit none
character(10) myString
character(1) a,b,c,d,e,f
integer::i,j,k
do i=900,901,1
j=900
k=i*j
write(*,*)'k =', k
write(myString,'(i10)') k
write(*,*)'myString = ', myString
a=myString(1:1)
b=myString(2:2)
c=myString(3:3)
d=myString(4:4)
e=myString(5:5)
f=myString(6:6)
write(*,*) a
write(*,*) b
write(*,*) c
write(*,*) d
write(*,*) e
write(*,*) f
if (d==f) then
print*,'hobla'
else
print*,'fobla'
end if
end do
stop
end program test
The resulting output is:
k = 810000
myString = 810000
8
1
fobla
k = 810900
myString = 810900
8
1
fobla
This happens because the I format right-justifies numbers when printed. So there is a bunch of leading white-spaces because your number is only 6 digits while your string you are writing into is 10. So you get 4 leading spaces.
If you change your format string so you have:
write(myString,'(i10.10)') k
then instead of padding with spaces it will pad with 0's. That way you can always have digits to compare if you would rather.