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
Related
I am trying to sort an array of letters alphabetically, but keep the special character in the same spot, in ruby.
For example,
word = ["f", "a", "s", "t", "-", "c", "a", "r", "s"]
How can I sort the whole thing alphabetically, but keep the "-" where it is. If I sort how it is now then the "-" will go to the front which I don't want. I have tried fifteen different ways, and I can't figure it out. Can you help?
Some really verbose way to do this, to explain the logic around what you need to achieve. There's some 'cleaner' methods to achieve this, but I feel this gives more understanding.
Adding an additional special character to the array for better test coverage:
let(:input) { ["f", "a", "s", "t", "-", "c", "a", "r", "s", "/"] }
let(:desired_output) { ["a", "a", "c", "f", "-", "r", "s", "s", "t", "/"] }
it "takes the input and gives the desired output" do
expect(sort_alphanumeric_characters(input)).to eq(desired_output)
end
Call .map and .select on the array to enumerate over the values and then call .with_index as you'll need to retain indicies for later.
def sort_alphanumeric_characters(word_as_array)
# assuming you mean non-alphanumeric
# collect those indicies which are 'special' characters
# the regex matches the string with anything outside of the alphanumeric range. Note the '^'
special_character_indicies = word_as_array.map.with_index { |val, indx| indx if val =~ /[^a-zA-Z0-9]/ }.compact
# collect all characters by index that were not yielded as 'special'
alphanumeric_array = word_as_array.select.with_index { |char, indx| char unless special_character_indicies.include? indx }
# sort the alphanumeric array
sorted_alphanumeric_array = alphanumeric_array.sort
# use Array#insert to place the 'special' by index
special_character_indicies.each do |special_indx|
special_char = word_as_array[special_indx]
sorted_alphanumeric_array.insert(special_indx, special_char)
end
# return desired output
sorted_alphanumeric_array
end
As soon as I posted I had a lightning bolt (love it when that happens). This is really not that great of a solution, but it did work!!
def scramble_words(str)
idx = 0
chars = str.delete("^a-z").chars
first_ele = chars.shift
last_ele = chars.pop
str.chars.each_with_index {|c, i| idx = i if c =~ /[^a-z" "]/ }
(first_ele + chars.sort.join + last_ele).insert(idx, str[idx])
end
p scramble_words('card-carrying') == 'caac-dinrrryg'
p scramble_words("shan't") == "sahn't"
p scramble_words('-dcba') == '-dbca'
I just started with Ruby. I need to build a method that takes two letters as arguments and returns an array of two arrays containing the same two letters and the letters included between them. The first array should contain only vowels whereas the second array only consonants. E.g.:
def alphamek('a', 'd')
should return:
[['a'], ['b', 'c', 'd']]
I tried this:
def alphamek(letter1, letter2)
first_array = (letter1..letter2).scan[aeiou].to_a
second_array = (letter1..letter2).scan[^aeiou].to_a
multi_array = [[first_array], [second_array]]
end
but it doesn't seem to work. Any ideas?
Not really that hard if you work it from a regular expression perspective and leverage a tool like partition:
VOWEL = /[aeiou]/i
def alphamek(a, b)
(a..b).partition { |l| VOWEL.match(l) }
end
Another way of doing that is to use the methods Array#& and Array#-.
VOWELS = %w| a e i o u |
#=> [“a“, ”e”, ”i”, ”o”, ”u”]
def doit(first_letter, last_letter)
letters = (first_letter..last_letter).to_a
[VOWELS & letters, letters - VOWELS]
end
doit 'f', 't'
#=> [["i", "o"], ["f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t"]]
doit 'f', 'o'
#=> [["i", "o"], ["f", "g", "h", "j", "k", "l", "m", "n"]]
doit 'v', 'z'
#=> [[], ["v", "w", "x", "y", "z"]]
You are calling scan on the Range (letter1..letter2). That method does not exist.
What you can do is call select since Ranges are enumerable, see the documentation on an explanation for select: http://ruby-doc.org/core-2.5.0/Enumerable.html#method-i-select
Here's a working alternative that closely resembles your approach (as you intended it to work):
def alphamek(letter1, letter2)
vowels = 'aeiou'
# select all letters that are vowels
first_array = (letter1..letter2).select { |letter| vowels.include?(letter) }
# reject all letters that are vowels
second_array = (letter1..letter2).reject { |letter| vowels.include?(letter) }
return first_array, second_array # => [[...], [...]]
end
reject is simply the opposite of select, I prefer to use it instead of inverting the condition.
Anyway, there is an even better approach to this partitioning:
def alphamek(letter1, letter2)
vowels = 'aeiou'
(letter1..letter2).partition { |letter| vowels.include?(letter) }
end
This does the same as the other approach. partition splits the enumerable into two arrays, the first one contains the values for which the block evaluates to true, the second those for which it evaluates to false.
See partition in the docs: http://ruby-doc.org/core-2.5.0/Enumerable.html#method-i-partition
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 ("", +))
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 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