Algorithm to sort three kinds of balls - algorithm

We have N balls of three different types: red(r), blue(b), and white(w).
I need to sort them so that red balls appear firsts, then all white balls and finally all blue balls.
Example:
In: bwrwrbbrwwrb
string[] arrBalls = { "b", "w", "r", "w", "r", "b", "b", "r", "w", "w", "r", "b" };
Out:rrrrwwwwbbbb
I need to found a linear O(n) algorithm.
Update: C# code
string[] arrBalls = { "b", "w", "r", "w", "r", "b", "b", "r", "w", "w", "r", "b" };
int index_red = 0;
int index_blue = arrBalls.Length - 1;
for (int i = 0; i < arrBalls.Length; i++)
{
if (arrBalls[i] == "r" && index_red != i)
{
string TempRed = arrBalls[index_red];
arrBalls[index_red] = arrBalls[i];
arrBalls[i] = TempRed;
if (arrBalls[index_red] == "r")
{
while(arrBalls[index_red] == "r")index_red++;
}
else
{
index_red++;
}
}
if (arrBalls[i] == "b" && index_blue != i)
{
string TempRed = arrBalls[index_blue];
arrBalls[index_blue] = arrBalls[i];
arrBalls[i] = TempRed;
if (arrBalls[index_blue] == "b")
{
while (arrBalls[index_blue] == "b") index_blue--;
}
else
{
index_blue--;
}
}
}

You count each one of the three types of balls into 3 variables. Let's say you counted R red balls, B blue ones and W white ones. Then you output R "r", followed by W "w", followed by B "b".

Related

Recursion infiinite loop in JS

I have been studying data structures and algos in js and I wanted to implement recursion. I knew I needed to avoid an infinite loop somehow, but I couldn't come up with how. For me, recursion is kind of hard due to infinite loops.
The question is from LeetCode.
https://leetcode.com/problems/excel-sheet-column-title/
/**
* #param {number} columnNumber
* #return {string}
*/
var convertToTitle = function(columnNumber, lis=[]) {
const chars = ["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"]
let digit = 0;
console.log("===== start")
if (columnNumber === 0) return;
if (columnNumber <= chars.length) {
console.log("columnNumber",columnNumber, "<= chars.length", chars.length)
lis.push(chars[columnNumber-1])
console.log("lis.join('')", lis.join(""))
return;
}
else {
while (true) {
if (columnNumber > chars.length ^ digit) {
console.log("should bne passed if")
digit+=1;
continue;
} else {
console.log("should bne passed else")
digit-=1;
let num = 1;
while (true) {
console.log(columnNumber, (chars.length ^ digit) * num, num, "2 while")
if (columnNumber > (chars.length ^ digit) * num) {
num+=1;
continue
} else {
console.log("2 else")
num-=1;
lis.push(chars[num-1]);
console.log("function while end".toUpperCase() , "lis:", lis, "passed num", columnNumber - (chars.length ^ digit) * num)
convertToTitle(columnNumber - (chars.length ^ digit) * num, lis)
}
}
}
}
}
}
You have a while (true) without any break conditions. Recursion by itself is similar to an infinite loop with break conditions. Try to remove the infinite loops inside the function.

Sum-String coding algorithm

I am trying to solve the first question from http://www.geeksforgeeks.org/nutanix-interview-experience-set-1-on-campus-for-internship/. In this question, we're given a string of decimal digits, and we have to figure out if there's some way to split it up into four or more substrings ["A", "B", "C", …] such that A + B = C, B + C = D, etc.
For example, if the string is "12358", then the answer is true, because we can split it up into ["1", "2", "3", "5", "8"], where 1 + 2 = 3, 2 + 3 = 5, and 3 + 5 = 8.
Similarly, if the string is "199100199", then the answer is true, because we can split it up into ["1", "99", "100", "199"], where 1 + 99 = 100 and 99 + 100 = 199.
However, if the string is "2368", then the answer is false, because there's only way to break it up into four or more substrings — namely ["2", "3", "6", "8"] — and 3 + 6 ≠ 8.
I can probably think of a solution using two or three nested loops, but I assume I need a more efficient solution?
public static boolean test3(String s, String d1, String d2, int idx1, int idx2) {
if(idx1>=s.length()) return false;
if(idx2>=s.length()) {
d1 = s.substring(0,idx1);
return test3(s,d1,d2,idx1+1,1);
}
if(!d1.isEmpty() && d1.length()+idx2<=s.length()) {
d2 = s.substring(d1.length(),d1.length()+idx2);
int sum = Integer.parseInt(d1) + Integer.parseInt(d2);
String sumStr = Integer.toString(sum);
if(s.substring(d1.length()+d2.length()).startsWith(sumStr)) {
return true;
} else {
return test3(s,d1,d2,idx1,idx2+1);
}
} else {
d1 = s.substring(0,idx1);
return test3(s,d1,d2,idx1+1,idx2);
}
}
I tried the above and it seems to work. This is my solution

Return string value to array from loop (Ruby)

Not sure if that's the term I should use for it but what I'm trying to do is add len amount of characters to an array, then output that to a .txt. I have the generation done to my satisfaction but I'm not sure how to pack the strings into an array. Right now it just spits out all the strings into the console because of the puts statement, just to make sure it works.
#Password list generator by Nightc||ed, ©2015
norm = ["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"]
caps = ["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"]
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
puts "How many passwords would you like to generate?"
num = gets.to_i
system "cls"
puts "Password length (1-x):"
len = gets.to_i
system "cls"
puts """
Which characters would you like to use?
[1] a-z, 0-9
[2] A-Z, 0-9
[3] a-z, A-Z, 0-9
"""
arr = []
type = gets.chomp
if type == "1"
arr = [norm,nums]
elsif type == "2"
arr = [caps,nums]
elsif type == "3"
arr = [norm,caps,nums]
else
exit
end
num.times do |pass|
len.times do |char|
arr2 = arr.to_a.sample
char = arr2.to_a.sample
puts char
end
end
sleep
here your code simplified
#Password list generator by Nightc||ed, ©2015
norm = [*"a".."z"]
caps = [*"A".."Z"]
nums = [*0..9]
num, len, type = [
"How many passwords would you like to generate?",
"Password length (1-x):",
"Which characters would you like to use?
[1] a-z, 0-9
[2] A-Z, 0-9
[3] a-z, A-Z, 0-9"].map do |msg|
puts msg
gets.to_i
end
arr = case type
when 1 then
norm + nums
when 2 then
caps + nums
when 3 then
norm + caps + nums
else
exit
end
passwords = num.times.map { arr.sample(len).join }
puts passwords.inspect
sleep
I think you can simplify your life by replacing the if... and below with the following:
case type
when "1"
arr = [norm,nums].flatten
when "2"
arr = [caps,nums].flatten
when "3"
arr = [norm,caps,nums].flatten
else
exit
end
passwd_set = []
num.times { passwd_set << arr.sample(len).join }
p passwd_set
I find case statements easier to read, and more easily extended. Flattening the arrays makes it so sample can directly produce the desired number of characters/symbols, and those can be joined to produce a string which can be appended to your passwd_set array.
You can add to an array using the << method. For example:
arr = []
3.times do |el|
arr << el
end
arr.inspect #=> [0, 1, 2]
Another option would be the push method:
arr = []
(0..2).each { |el| arr.push(el)}

Caesar Cipher shift on a string using shifting number

I have this question.
Using the Ruby language, have the function CaesarCipher(str,num) take the str parameter and perform a Caesar Cipher shift on it using the num parameter as the shifting number. A Caesar Cipher works by shifting each letter in the string N places down in the alphabet (in this case N will be num). Punctuation, spaces, and capitalization should remain intact. For example if the string is "Caesar Cipher" and num is 2 the output should be "Ecguct Ekrjgt".
Any my code looks like this. I think the onlt problem i have is to update each letter and then each word within the loops. please help. thank you
def Caesar_cipher(str, num)
if num > 25
num -= 26
end
alphabet = ["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"]
str = str.split(" ")
str.each do |word|
word.each_char do |c|
if alphabet.include?(c)
n = alphabet.index(c) + num
if n > 25
n -= 26
end
c = alphabet[n]
end
end
end
return str
end
puts Caesar_cipher("zabcd", 1) // "zabcd"
str = str.split("")
alphabet = ["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"]
alphabet2 = ["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"]
while num > 25
num -= 26
end
str = str.map do |char|
if alphabet.include?(char)
n = alphabet.index(char) + num
while n > 25
n -= 26
end
char = alphabet[n]
elsif alphabet2.include?(char)
m = alphabet2.index(char) + num
while m > 25
m -= 26
end
char = alphabet2[m]
else
char
end
char
end
return str.join
end
def cipher_shift(s, n)
letters = [*'a'..'z']
s.chars.map {|x| letters.include?(x.downcase) ? (x.ord + n).chr : x}.join
end

Fastest way to get values from 2d array

I have 2d aray similar to this:
string[,] arr = {
{ "A", "A", "A", "A", "A", "A", "A", "D", "D", "D", "D", "D", "D", "D", "D" },
{ "1", "1", "1", "1", "1", "1", "1", "0", "0", "0", "0", "0", "0", "0", "0" },
{ "2", "2", "2", "2", "2", "2", "2", "00", "00", "00", "00", "00", "00", "00", "00" }
};
I am trying to get following result from above array:
A 1 2
A 1 2
A 1 2
A 1 2
A 1 2
A 1 2
Get all "A" from the array at length 0. Than get corrospoding values of it from other columns.
This is big 2d array with over 6k values. But design is exactly same as described above. I have tried 2 ways so far:
1st method: using for loop to go through all the values:
var myList = new List<string>();
var arrLength = arr.GetLength(1)-1;
for (var i = 0; i < arrLength; i++)
{
if (arr[0,i].Equals("A"))
myList.Add(arr[0, i]);
else
continue;
}
}
2nd method: creating list and than going through all values:
var dataList = new List<string>();
var list = Enumerable.Range(0, arr.GetLength(1))
.Select(i => arr[0, i])
.ToList();
var index = Enumerable.Range(0, arr.GetLength(1))
.Where(index => arr[0, index].Contains("A"))
.ToArray();
var sI = index[0];
var eI = index[index.Length - 1];
myList.AddRange(list.GetRange(sI, eI - sI));
They both seem to be slow, not efficient enough. Is there any better way of doing this?
I like to approach these kinds of algorithms in a way that my code ends up being self-documenting. Usually, describing the algorithm with your code, and not bloating it with code features, tends to produce pretty good results.
var matchingValues =
from index in Enumerable.Range(0, arr.GetLength(1))
where arr[0, index] == "A"
select Tuple.Create(arr[1, index], arr[2, index]);
Which corresponds to:
// find the tuples produced by
// mapping along one length of an array with an index
// filtering those items whose 0th item on the indexed dimension is A"
// reducing index into the non-0th elements on the indexed dimension
This should parallelize extremely well, as long as you keep to the simple "map, filter, reduce" paradigm and refrain from introducing side-effects.
Edit:
In order to return an arbitrary collection of the columns associated with an "A", you can:
var targetValues = new int[] { 1, 2, 4, 10 };
var matchingValues =
from index in Enumerable.Range(0, arr.GetLength(1))
where arr[0, index] == "A"
select targetValues.Select(x => arr[x, index]).ToArray();
To make it a complete collection, simply use:
var targetValues = Enumerable.Range(1, arr.GetLength(0) - 1).ToArray();
As "usr" said: back to the basics if you want raw performance. Also taking into account that the "A" values can start at an index > 0:
var startRow = -1; // "row" in the new array.
var endRow = -1;
var match = "D";
for (int i = 0; i < arr.GetLength(1); i++)
{
if (startRow == -1 && arr[0,i] == match) startRow = i;
if (startRow > -1 && arr[0,i] == match) endRow = i + 1;
}
var columns = arr.GetLength(0);
var transp = new String[endRow - startRow,columns]; // transposed array
for (int i = startRow; i < endRow; i++)
{
for (int j = 0; j < columns; j++)
{
transp[i - startRow,j] = arr[j,i];
}
}
Initializing the new array first (and then setting the "cell values) is the main performance boost.

Resources