Simple question for the following set of codes:
def nearby_az(string)
idx1 = 0
while idx1 < string.length
if string[idx1] != "a"
idx1 += 1
next #<--------------
end
idx2 = idx1 + 1
while (idx2 < string.length) && (idx2 <= idx1 + 3)
if string[idx2] == "z"
return true
end
idx2 += 1
end
idx1 += 1
end
return false
end
What does the word "next" do in the line with the commented arrow? And is "next" a method? If not, what's the correct technical jargon for this? Cheers
next is not a method, it's a keyword. It applies to the outer while loop in your example, it stops current iteration and 'calls' next one.
Related
I've just started learning ruby, and the position of where variables are defined somewhat elude me. For example, why does this code work:
def two_sum(nums)
result = nil
i = 0
while i < nums.length
k = (nums.length - 1)
if nums[i] + nums[k] == 0
result = [i,k]
end
i += 1
k -= 1
end
return result
end
And why does this code not work:
def two_sum(nums)
result = nil
i = 0
k = (nums.length - 1)
while i < nums.length
if nums[i] + nums[k] == 0
result = [i,k]
end
i += 1
k -= 1
end
return result
end
Thank you in advance!
I think you code might just have a bug
while i < nums.length
k = (nums.length - 1)
...
k -= 1 # this statement has no effect!
end
Above, the value if k is always (nums.length - 1) because you reassign it at the begin of each iteration. The other statement has no effect.
k = (nums.length - 1)
while i < nums.length
...
k -= 1
end
Above, the value of k starts at (nums.length - 1) in the first iteration and is then reduced by 1 for each iteration.
Pro tipp —
It is very unusual in Ruby to use a for/while/until loop. If you want to loop over all elements use each or each_with_index instead
array.each { |each| ... }
array.each_with_index { |each, n| ... }
In Cloud9 I use the following code and it works.
def LongestWord(sen)
i = 0
cha ="&#%*^$!~(){}|?<>"
new = ""
while i < sen.length
i2 = 0
ch = false
while i2 < cha.length
if sen[i] == cha[i2]
ch = true
end
i2 += 1
end
if ch == false
new += sen[i].to_s
end
i += 1
end
words = new.split(" ")
longest = ""
idx = 0
count = 0
while idx < words.length
word = words[idx]
if word.length > count
longest = word
count = word.length
end
idx += 1
end
# code goes here
return longest
end
# keep this function call here
# to see how to enter arguments in Ruby scroll down
LongestWord("beautifull word")
In Codebytes in the exercise "Longest Word" you have to use the same STDIN in the arguments. It is the same code but changing the argument but it doesn't work:
def LongestWord(sen)
i = 0
cha ="&#%*^$!~(){}|?<>"
new = ""
while i < sen.length
i2 = 0
ch = false
while i2 < cha.length
if sen[i] == cha[i2]
ch = true
end
i2 += 1
end
if ch == false
new += sen[i].to_s
end
i += 1
end
words = new.split(" ")
longest = ""
idx = 0
count = 0
while idx < words.length
word = words[idx]
if word.length > count
longest = word
count = word.length
end
idx += 1
end
# code goes here
return longest
end
# keep this function call here
# to see how to enter arguments in Ruby scroll down
LongestWord(STDIN.gets)
I think may be something is creating some kind of conflict with the browser. The output shows a lot of numbers. Can some one help me testing the code?. Any feedback is appreciated, thanks!
Coderbyte is running your code on an old version of Ruby - Ruby 1.8.7
In this version of Ruby, using an index into a string like sen[i] doesn't return the character at i, it returns the numeric ASCII value of that character instead. That's where the numbers are coming from.
To get the code to work on Ruby 1.8.7 you can replace some_string[i] with some_string[i, 1] - this variation returns the substring of length 1 starting at i so is the same as the behaviour of some_string[i] in more recent Ruby versions. See the docs here for more details.
I'm trying to solve this Ruby problem and I can't figure out why having a minor while loop difference renders one test false: longest_palindrome("abba") outputs "bb" instead of "abba", which is false. I can only solve it with for and while loops, so please no advanced methods. It's easier to highlight the difference in the code block (first one is the working solution, second is mine. Also assume the palindrome? method is already defined):
def longest_palindrome(string)
best_palindrome = nil
idx1 = 0
***while idx1 < string.length
length = 1
while (idx1 + length) <= string.length
substring = string.slice(idx1, length)***
if palindrome?(substring) && (best_palindrome == nil || substring.length > best_palindrome.length)
best_palindrome = substring
end
length += 1
end
idx1 += 1
end
return best_palindrome
end
def longest_palindrome(string)
longest = nil
i = 0
***while i < string.length
i2 = 1
while i2 < string.length***
if palindrome?(string.slice(i, i2)) == true && (longest == nil || string.slice(i, i2).length > longest.length)
longest = string.slice(i, i2)
end
i2 += 1
end
i += 1
end
return longest
end
This part of your code...
while i2 < string.length
... means you're never checking the maximum possible length.
"abba".slice(0,4) is the entire string, but you only ever go up to "abba".slice(0,3) which is "abb".
So you never test the entire string.
Change the line to...
while i2 <= string.length
...and it should be ok.
I wrote a function which works. There is one part in there and it can be written in an alternative manner, but the alternative way of writing it doesn't work, although it should represent the same thing as the original code I wrote. I'd like to know why the alternative way of writing it does not work. When I ran it with the alternative codes, I think it became an infinite loop because there were no outputs.
This is a snippet of the function (The code in question is commented as "#ALTERNATIVE", there are four lines in total):
if idx2 > idx
idx3 = idx2 - 1
while idx3 >= idx #ALTERNATIVE 1: idx3 > idx
if arr[idx3] > arr[idx]
return idx3
elsif idx3 == idx #ALTERNATIVE 1: idx3 == idx + 1 or idx3 - 1 == idx
return idx2
end
idx3 -= 1
end
elsif idx > idx2
idx4 = idx2 + 1
while idx4 <= idx #ALTERNATIVE 2: idx4 < idx
if arr[idx4] > arr[idx]
return idx4
elsif idx4 == idx #ALTERNATIVE 2: idx4 == idx - 1 or idx4 + 1 == idx
return idx2
end
idx4 += 1
end
end
Your alternate code doesn't work in the cases where idx and idx2 are within 1 of each other.
Imagine idx == 1 and idx2 == 2.
if idx2 > idx
idx3 = idx2 - 1 # idx3 is equal to 1 and therefore equal to `idx`
while idx3 > idx # this is false, the while loop is not run
And nothing is returned. The same type of situation would be true for the elsif clause if idx == 2 and idx2 == 1 where the while loop would never run.
I don't know why the alternative code doesn't work, perhaps you've put in an idx2 equal to idx and it exited.
However, I thought it might be prudent to show you how to write this code more idiomatically:
def furthest_number_higher_than_base(arr, base, start)
range = start < base ? start..base : (base..start).to_a.reverse
range.each { |i| return i if arr[i] > arr[base] }
start
end
Can anybody please explain this code? I don't understand specifically:
elsif idx2 > idx1
is_repeat = true
end
Why are we comparing indices to determine if a letter has been
repeated?
Also what does the 'next' term do inside of the if statement?
The full code is shown below:
# Write a method that takes in a string and returns the number of
# letters that appear more than once in the string. You may assume
# the string contains only lowercase letters. Count the number of
# letters that repeat, not the number of times they repeat in the
# string.
#
# Difficulty: hard.
def num_repeats(array)
repeats = 0
idx1 = 0
while idx1 < array.length
is_repeat = false
idx2 = 0
while idx2 < array.length
if array[idx1] != array[idx2]
idx2 += 1
next
elsif idx2 < idx1
# will have previously counted this repeat
break
elsif idx2 > idx1
is_repeat = true
end
idx2 += 1
end
if is_repeat
repeats += 1
end
idx1 += 1
end
return repeats
end
If both conditions before (if idx2 < array.length and elsif idx2 < idx1) are false but idx2 > idx1 is true, than set the local variable is_repeat to true...