I am trying to compare a string variable to an element of a string array using a for loop in visual basic. I am comparing a user-entered string variable to an array with the lowercase alphabet, in order. I have some logical mistake because my "count" variable is always on 25 for some reason, and therefore it always says "Sorry, Try again" unless the user types a Z. Please help!
Dim lower() As String = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}
For count As Integer = 0 To 25
input = txtInput.Text
input = input.ToLower
If input.Equals(lower(count)) Then
txtResult.Text = "Correct"
Else
txtResult.Text = "Sorry, Try again"
End If
Next
The problem is that you should exit the loop (with exit for) after you find a match. Otherwise, any mismatched characters will reset txtResults.Text to "Sorry, Try again." For example, when you enter "f", txtResults.Text is set to "Correct". But when you get to g, currently, it changes txtResults.Text to "Sorry, Try again.", and h, i, etc.
This is a good exercise in programming, but there is a shortcut you can use:
lower.contains(input.lower)
Info:
http://msdn.microsoft.com/en-us/library/dy85x1sa.aspx
Welcome to StackOverflow!
The reason you get "Correct" result only if you type "z" is that "z" is the last item of the array. If you type "y", the result will be correct for count = 24 (lower(24) = "y"), but at the next step it compares "y" with lower(25), which is actually "z". So txtResult.Text will be overwritten by "Sorry, Try again".
As I get your task correctly, you want to check if the input string is exists in the array. For that purpose you may use Array.Contains method:
Dim lower() As String = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}
Dim input As String = txtInput.Text
If (lower.Contains(input)) Then
txtResult.Text = "Correct"
Else
txtResult.Text = "Sorry, Try again"
End If
Related
I am attempting to place all the characters of a string into its own index in an array and also am trying to replace " " (spaces) with 0's. The error I'm getting is that is says
?wrong number of arguments (given 0, expected 1)
but I'm not sure how to make include(' ') work.
Here is my code:
def findMe(words)
x = 0
convert = []
while x < words.length
if words[x].is_a? String && words[x].include? != " "
convert << words[x]
else
convert << 0
end
x = x + 1
end
p convert
end
findMe('Words and stuff.')
Desired Output: ["W", "o", "r", "d", "s", 0, "a", "n", "d", 0, "s", "t", "u", "f", "f", "."]
You're getting the "wrong number of arguments" error here:
words[x].include? != " "
You can quickly fix this by replacinng it with:
!words[x] == " "
A better way to do the whole thing would be:
words.gsub(" ", "0").chars
Use Array#chars.
'Words and stuff.'.chars.map { |c| c == " " ? "0" : c }
#=> ["W", "o", "r", "d", "s", "0", "a", "n", "d", "0", "s", "t", "u", "f", "f", "."]
The output of the [Character] Array currently is:
["E", "x", "a", "m", "p", "l", "e"]
It should be:
Example
It could be that " is in the array, like this: """. That output should be ".
Thank you!
The other answer(s) cover the case where your array is one of String elements (which is most likely the case here: since you haven't supplied us the type of the array, we could use Swift own type inference rules to speculatively infer the type to be [String]).
In case the elements of your array are in fact of type Character, however, you could use the Character sequence initializer of String directly:
let charArr: [Character] = ["E", "x", "a", "m", "p", "l", "e"]
let str = String(charArr) // Example
W.r.t. your comment below: if your example array is, for some reason, one of Any elements (which is generally not a good idea to use explicitly, but sometimes the case when recieving data from some external source), you first need to perform an attempted conversion of each Any element to String type, prior to concenating the converted elements to a single String instance. After the conversion, you will be working with an array of String elements, in which case the methods shown in the other answers will be the appropriate method of concenation:
// e.g. using joined()
let arr: [Any] = ["E", "x", "a", "m", "p", "l", "e"]
let str = arr.flatMap { $0 as? String }.joined()
print(str) // example
You could naturally also (attempt to) convert from Any to Character elements, but even in this case you would have to go via String instances, which means that for the [Any] case, the joined() alternative above is to prefer over the one below:
let arr: [Any] = ["E", "x", "a", "m", "p", "l", "e"]
let str = String(arr.flatMap { ($0 as? String)?.characters.first })
print(str) // example
Just use joined() with default "" separator:
let joinedString = ["E", "x", "a", "m", "p", "l", "e"].joined()
let e = ["E", "x", "a", "m", "p", "l", "e"]
print(e.reduce ("", +))
Suppose there is an array like this one:
list = ["a", "a", "a", "b", "b", "c", "d", "e", "e"]
We want to create a cycle where every next element is different from the previous element and the first element is different from the last element.
required = ["a", "b", "a", "b", "a", "c", "e", "d", "e"]
How is this done in ruby?
def create_cycle
temp = Array.new($input)
i, j, counter = 0
while i == 0
while (counter != $input.length)
j = rand(1..$input.length-1).floor
unless !($input[i][0].to_s.eql?$input[j][0])
$solution.push($input[i])
$solution.push($input[j])
puts input[i], input[j]
$input.delete_at(i)
$input.delete_at(j)
counter = counter + 1
end
end
end
end
I'm trying to learn this. Thank you for your help.
Additional notes:
The elements a, b, c, d, e represent special format strings, where
a certain property is common among them, thus the first element "a"
shares a property with the next element "a" but is not equivalent to
the first.
In the case it isn't possible to create a cycle, then, it is enough to raise a flag in command line.
I might do it like this:
>> list = [a, a, a, b, b, c, d, e, e]
>> list.sort.each_slice((list.size/2.0).round).reduce(:zip).flatten.compact
=> [a, c, a, d, a, e, b, e, b]
The general method is to:
sort the list, so all identical members are adjacent
divide the list in half from the middle
interleave the two halves together
Assuming you do not care about the order being the same as in the original array, and it is ok to have duplicates if there is no way, and also assuming the list is presorted, here is one approach - it just keeps adding elements from the beginning and end of the list till there are no elements left:
def interleaver list
result = []
el = list.first
while(el)
el = list.shift
if el
result << el
else
return result
end
el = list.pop
if el
result << el
else
return result
end
end
result
end
> a = 'a'
> b = 'b'
> c = 'c'
> d = 'd'
> e = 'e'
> list = [a, a, a, b, b, c, d, e, e]
> interleaver(list)
=> ["a", "e", "a", "e", "a", "d", "b", "c", "b"]
But if such interleaving is not possible, you will get duplicates:
> list = [a, a, a, b]
> interleaver(list)
#=> ["a","b","a","a"]
You can obtain such a string, or demonstrate that no such string exists, with the following recursive method.
Code
def doit(remaining, partial=[])
first_partial, last_partial = partial.first, partial.last
if remaining.size == 1
return ([first_partial, last_partial] & remaining).empty? ?
partial + remaining : nil
end
remaining.uniq.each_with_index do |s,i|
next if s == last_partial
rem = remaining.dup
rem.delete_at(i)
rv = doit(rem, partial + [s])
return rv if rv
end
nil
end
Examples
list = %w| a a b |
#=> ["a", "a", "b"]
doit list
#=> nil
The above demonstrates that the three elements of list cannot be permuted to satisfy the two ordering requirements.
list = %w| a a a b b c d e e |
#=> ["a", "a", "a", "b", "b", "c", "d", "e", "e"]
doit list
#=> ["a", "b", "a", "b", "c", "b", "e", "d", "e"]
This took 0.0042 second to solve on a newish MacBook Pro.
list = %w| a a a a a a a b b c d e e f f f g g g g h i i i i j j |
#=> ["a", "a", "a", "a", "a", "a", "a", "b", "b", "c", "d", "e", "e",
# "f", "f", "f", "g", "g", "g", "g", "h", "i", "i", "i", "i", "j", "j"]
doit list
#=> ["a", "b", "a", "b", "a", "b", "a", "b", "c", "b", "d", "e", "f",
# "e", "f", "g", "f", "g", "h", "g", "h", "i", "j", "i", "j", "i", "j"]
This took 0.0059 seconds to solve.
Out of curiosity, I then tried
list = (%w| a a a a a a a b b c d e e f f f g g g g h i i i i j j |).shuffle
#=> ["a", "c", "f", "b", "d", "i", "a", "a", "i", "a", "a", "g", "g",
# "a", "g", "i", "j", "b", "h", "j", "e", "e", "a", "g", "f", "i", "f"]
doit list
#=> ["a", "c", "f", "b", "d", "i", "a", "i", "a", "g", "a", "g", "a",
# "g", "i", "g", "j", "b", "h", "j", "e", "a", "e", "g", "f", "i", "f"]
This took a whooping 1.16 seconds to solve, suggesting that it may be desirable to pre-sort list (doit(list.sort)) if, of course, list is sortable.
I'm trying to find a way to remove any elements in an array that fall between two "markers", but there are a few quirks. To give a proper spec, the function I'm making is supposed to do this:
Remove any elements from the earliest start marker S to the earliest end marker E after the S, or the final element if there is none. Repeat this until there are no Ss left. Remove any remaining Es.
For example, if I had an array containing the following:
This is my current code:
# if the starting token is `1` and the ending one is `2`:
while clearing.include? 1
from = clearing.index(1)
to = clearing[from..-1].index(2) + from
clearing.slice!(from..to)
end
clearing.delete(2)
Which, when run with clearing set to:
["a", "b", "c", "d", "e", "f", 1, "g", "h", "i", "j", 1, "k", 2, "l", 2, 2, "m", "n", "o", "p", "q", "r", "s", 1, "t", "u", "v", "w", "x", 1, "y", "z"]
properly returns
["a", "b", "c", "d", "e", "f", "l", "m", "n", "o", "p", "q", "r", "s"]
Online test
It works, but it's ugly, and I'm fairly sure there's a more idiomatic way to do it. I can't find it, though, or think of it, so I'm asking here: Is my code the only (sane) way to do what I'm trying to?
This is, unfortunately, a severe case of the XY problem -- the specific task I'm trying to accomplish is removing comments from a string. I could do this with a fairly simple regex (/#.*?$/m) if I had the input string, but because it's a class assignment, I have to delete from anything starting with # to the :newline token in an array of them. Please don't suggest "This is weird, why not try solving the overall problem a different way" -- I know it's weird. I wish I could.
Overall, I think any solution is going to be as elegant as yours. The only thing I can think of is that you could make it faster by iterating over each character only once:
i = 0
loop do
break if i >= clearing.length
break if clearing[i] == 1
i += 1
end
loop do
break if i >= clearing.length
val = clearing.delete(i)
break if val == 2
end
Which is definitely less elegant.
Ruby's fairly obscure "flip-flop" operator could be used here. I'm not recommending that it be used, just sayin'.
clearing.reject { |e| (e==1..e==2) ? true : false }.reject { |e| e==2 }
#=> ["a", "b", "c", "d", "e", "f", "l", "m", "n", "o", "p", "q", "r", "s"]
The first block returns false until 1 is detected. It then returns true for the 1 and continues to return true until 2 is detected. It returns true for the 2, but then returns false until the next (if any) 1 is detected, and so on. Hence, the name "flip-flop". The example often given for the flip-flop operator is reading sections of a file that are delimited with start/end markers.
It may seem that (e==1..e==2) ? true : false could be simplified to (e==1..e==2), but that is not the case, as the latter expression is treated as a normal range. Flip-flops must have a conditional form.
Replace both rejects with reject! if clearing is to be changed in place.
I am just new to VB and I'm having trouble in doing this program since I got no idea how to access each letter in a word in just one input.
Say, I am ask to enter a string and I input "help" the output should be something like "$%&(".
My only idea with this is that each letter of the entered string should be read so that the symbols to be substituted on each letter could be determined (which is I dunno how). I only know how to, if the letters will be entered one by one and the index of the array is fixed OR the letters to be encrypted are already declared such as this:
Dim a() As String = {"h", "e", "l", "p"}
Dim b As String
Console.WriteLine("String:")
For Each b In a
Console.Write(b)
Next
Console.WriteLine()
Console.WriteLine()
Console.WriteLine("Encryption:")
For Each b In a
Select Case b
Case "A", "a"
Console.Write("!")
Case "B", "b"
Console.Write("+")
Case "C", "c"
Console.Write("#")
Case "D", "d"
Console.Write("$")
Case "E", "e"
Console.Write("%")
Case "F", "f"
Console.Write("'")
Case "G", "g"
Console.Write("(")
Case "H", "h"
Console.Write(")")
Case "I", "i"
Console.Write(",")
Case "J", "j"
Console.Write(".")
Case "K", "k"
Console.Write("~")
Case "L", "l"
Console.Write("}")
Case "M", "m"
Console.Write("|")
Case "N", "n"
Console.Write("[")
Case "O", "o"
Console.Write("\")
Case "P", "p"
Console.Write("]")
Case "Q", "q"
Console.Write("!")
Case "R", "r"
Console.Write("^")
Case "S", "s"
Console.Write("_")
Case "T", "t"
Console.Write(":")
Case "U", "u"
Console.Write(";")
Case "V", "v"
Console.Write("<")
Case "W", "w"
Console.Write("=")
Case "X", "x"
Console.Write(">")
Case "Y", "y"
Console.Write("?")
Case "Z", "z"
Console.Write("#")
End Select
Next
Console.ReadLine()
Your help will be greatly appreciated. Thanks in advance.
Dim a as String = "whatever your string is"
for i as integer = 1 to len(a)
Dim curLetter = Mid(a, i, 1) ' this will give you the current character.
' do your encrypting here.
Next
There are better ways to encrypt things, but for your purposes for now this should suffice.
Check this:
Imports System.Linq
Module StartupModule
Private _characterMaps As New Dictionary(Of Char, Char) From {
{"A"c, "!"c}, {"B"c, "+"c}, {"C"c, "#"c},
{"D"c, "$"c}, {"E"c, "%"c}, {"F"c, "'"c},
{"G"c, "("c}, {"H"c, "C"c}, {"I"c, ","c},
{"J"c, "."c}, {"K"c, "~"c}, {"L"c, "}"c},
{"M"c, "|"c}, {"N"c, "["c}, {"O"c, "\"c},
{"P"c, "]"c}, {"Q"c, "!"c}, {"R"c, "^"c},
{"S"c, "_"c}, {"T"c, ":"c}, {"U"c, ";"c},
{"V"c, "<"c}, {"W"c, "="c}, {"X"c, ">"c},
{"Y"c, "?"c}, {"Z"c, "#"c}
}
Sub Main()
Dim original As String = "Hello world!"
Dim characters = From c As Char In original.ToUpper
Select GetEncodedCharacter(c)
Console.WriteLine(New String(characters.ToArray))
Console.ReadLine()
End Sub
Private Function GetEncodedCharacter(value As Char) As Char
If _characterMaps.ContainsKey(value) Then
Return _characterMaps(value)
Else
Return value
End If
End Function
End Module