I need to write a function that will add two byte arrays using recursion. The test for this function is as follows :
[Test]
[TestCaseSource("Add_Function")]
public AddResult Add_WithRecursiveAlgorithm(byte[] a, byte[] b)
{
// Arrange
// Act
var result = AddRecursion(a, b);
// Assert
return new AddResult(a, b, result);
}
For example:
Input : { 1, 1, 1 }, { 1, 1, 1 }
Result: {2,2,2}
Input : { 1, 1, 255 }, {0, 0, 1 }
Result: {1,2,0}
The general rules are as follows:
• Assume inputs a & b are never null and will always be the same length.
• The algorithm should be non-destructive to the inputs.
• The algorithm should be able to handle large input lengths, >1000, but the input will never be large enough to cause a stack overflow.
Any ideas how I can do this?
public object[] Add_Function()
{
return new object[]
{
new object[]
{
new byte[] { 1, 1, 1 }, new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 }
},
new object[]
{
new byte[] { 1, 1, 255 }, new byte[] { 0, 0, 1 }, new byte[] { 1, 2, 0 }
}
};
}
[TestCaseSource("Add_Function")]
public void Add(byte[] a, byte[] b, byte[] expected)
{
// arrange
int len = Math.Max(a.Length, b.Length);
Array.Resize(ref a, len);
Array.Resize(ref b, len);
byte[] result = new byte[len];
//act
DoAdd(a, b, result, 0, len - 1);
//assert
CollectionAssert.AreEqual(expected, result);
}
private void DoAdd(byte[] a, byte[] b, byte[] result, int broughtForward, int index)
{
int carriedForward = (a[index] + b[index] + broughtForward) / (byte.MaxValue + 1);
result[index] =(byte)((a[index] + b[index] + broughtForward) % (byte.MaxValue + 1));
if (index > 0)
{
DoAdd(a,b,result, carriedForward, index-1);
}
}
Related
I'm trying to use the Span2D type to "roll" entries in a 2d array, but it's not working as expected.
By rolling I mean the following - given an array such as:
{
{ 1, 1, 1, 1, 1 },
{ 2, 2, 2, 2, 2 },
{ 0, 0, 0, 0, 0 },
}
I would like to copy the first two rows down one row, so the top row can be repopulated. After the roll operation the array should look like this:
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 2, 2, 2, 2, 2 },
}
The Span2d CopyTo method seems perfect for this - I create a Slice of the top two rows, and a slice of the bottom two rows, copy the first slice to the second slice. But instead of the expected result above, I get:
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
}
Here's a runnable class that shows the problem:
public class SpanTest
{
public static void Main()
{
int[,] array =
{
{ 1, 2, 3, 4, 5 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
};
var h = array.GetLength(0) - 1;
var w = array.GetLength(1);
Console.WriteLine($"slice height:{h} width: {w}\n-----------");
Span2D<int> span = array;
Console.WriteLine($"{span.ToStringMatrix()}-----------");
var sourceSlice = span.Slice(0, 0, h, w);
Console.WriteLine($"{sourceSlice.ToStringMatrix()}-----------");
var targetSlice = span.Slice(1, 0, h, w);
Console.WriteLine($"{targetSlice.ToStringMatrix()}-----------");
sourceSlice.CopyTo(targetSlice);
Console.WriteLine($"{span.ToStringMatrix()}-----------");
}
}
with a helper for printing the Span2Ds:
public static class Utils
{
public static string ToStringMatrix<T>(this Span2D<T> arr)
{
var sb = new StringBuilder();
for (var i = 0; i < arr.Height; i++)
{
for (var j = 0; j < arr.Width; j++)
{
sb.Append($"{arr[i, j]} ");
}
sb.Append(Environment.NewLine);
}
return sb.ToString();
}
}
How can I make the copy operation behave as expected? Thanks
Well, the answer is quite obvious actually - at least it was when it occurred to me at 5am this morning!
Span2D wraps an array, copying to itself alters the backing array during the copy process. By the time the second row is copied, it already contains the contents of the first row. And hence, the first row gets propagated throughout the 2d array.
I have a "Contact" object which contains a list called "Linked" containing the "Contact" linked to it.
public class Contact
{
public int Id { get; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public List<Contact> Linked { get; set; }
}
For example, Contact "A" has 3 linked contacts: B, C and D.
As the links are made in both directions each time, B, C and D all have A in their "Linked" contacts.
B can then have E as a contact, and so on. There is no limit.
I have to make an algo which takes a starting contact and an ending contact as a parameter and which finds the shortest path that links them.
The result must be in the form: A > B > F > H > X, if I have to find the path that goes from A to X. We must therefore find all the steps of the path in the result.
I've tried a lot of stuff (recursion, ...) but it's still getting stuck somewhere.
Do you have an idea?
Dijkstra's algorithm is probably what you are looking for.
http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
Dijkstra's algorithm (/ˈdaɪkstrəz/ DYKE-strəz) is an algorithm for finding the shortest paths between nodes in a graph, which may represent, for example, road networks. It was conceived by computer scientist Edsger W. Dijkstra in 1956 and published three years later.[4][5][6]
It should be relatively straight forward to find examples in your given language. Here is one in C#, stolen from programmingalgorithms.com
private static int MinimumDistance(int[] distance, bool[] shortestPathTreeSet, int verticesCount)
{
int min = int.MaxValue;
int minIndex = 0;
for (int v = 0; v < verticesCount; ++v)
{
if (shortestPathTreeSet[v] == false && distance[v] <= min)
{
min = distance[v];
minIndex = v;
}
}
return minIndex;
}
private static void Print(int[] distance, int verticesCount)
{
Console.WriteLine("Vertex Distance from source");
for (int i = 0; i < verticesCount; ++i)
Console.WriteLine("{0}\t {1}", i, distance[i]);
}
public static void Dijkstra(int[,] graph, int source, int verticesCount)
{
int[] distance = new int[verticesCount];
bool[] shortestPathTreeSet = new bool[verticesCount];
for (int i = 0; i < verticesCount; ++i)
{
distance[i] = int.MaxValue;
shortestPathTreeSet[i] = false;
}
distance[source] = 0;
for (int count = 0; count < verticesCount - 1; ++count)
{
int u = MinimumDistance(distance, shortestPathTreeSet, verticesCount);
shortestPathTreeSet[u] = true;
for (int v = 0; v < verticesCount; ++v)
if (!shortestPathTreeSet[v] && Convert.ToBoolean(graph[u, v]) && distance[u] != int.MaxValue && distance[u] + graph[u, v] < distance[v])
distance[v] = distance[u] + graph[u, v];
}
Print(distance, verticesCount);
}
It would then be used like so:
int[,] graph = {
{ 0, 4, 0, 0, 0, 0, 0, 8, 0 },
{ 4, 0, 8, 0, 0, 0, 0, 11, 0 },
{ 0, 8, 0, 7, 0, 4, 0, 0, 2 },
{ 0, 0, 7, 0, 9, 14, 0, 0, 0 },
{ 0, 0, 0, 9, 0, 10, 0, 0, 0 },
{ 0, 0, 4, 0, 10, 0, 2, 0, 0 },
{ 0, 0, 0, 14, 0, 2, 0, 1, 6 },
{ 8, 11, 0, 0, 0, 0, 1, 0, 7 },
{ 0, 0, 2, 0, 0, 0, 6, 7, 0 }
};
Dijkstra(graph, 0, 9);
The example above consist of 9 nodes, and the distance to each of the other nodes. If it has 0, there is no connection. In your case, there is no weight - so either there is a connection (1), or there isn't (0).
You have to change the algorithm to take in a list of contacts, instead of a two dimensional array. Try to think of the two dimensional array as a list of lists - very similar to a list of contacts, where each contact has another list of contacts.
Lets for example create a simple contacts list and their contacts:
Peter can contact Mary
Mary can contact Peter and John
John can contact Mary
This would be represented something like this in a two dimensional array:
int[,] contacts = new int[]
{
{ 0, 1, 0 }, //Peter: Peter no, Mary yes, John no
{ 1, 0, 1 }, //Mary: Peter yes, Mary no, John yes
{ 0, 1, 0 } //John: Peter no, Mary yes, John no
}
You would also have to modify the algorithm to keep track of the current path. That should be a relatively straight forward change.
Hope that it helps!
Below is an interview question about using recursion to add two arrays.
I can't figure it out though because it does not seem to allow any kind of index to keep track of where you are, I have been down a few roads - trying to test for null / default values in the array but because it is a byte[] type nothing worked.
Any help would be great thanks - this is not a homework question.
public AddResult UsingARecursiveAlgorithm_ValuesAreAdded(byte[] a, byte[] b)
{
var result = AddRecursive(a, b);
// Assert
return new AddResult(a, b, result);
}
e.g.
Input : { 1, 1, 1 }, { 1, 1, 1 }
Result: { 2, 2, 2 }
Input : { 1, 1, 255 }, { 0, 0, 1 }
Result: { 1, 2, 0 }
Conditions:
a & b are never null, and are always of the same length.
The algorithm should be non destructive to the inputs.
Edit: the second result is incorrect. It should be { 1,1,0 } -that's the way it was presented though.
private int carry = 0;
public byte[] AddRecursive(byte[] a, byte[] b)
{
//Start from bottom of the byte[] array
a = a.Reverse().ToArray();
b = b.Reverse().ToArray();
if (a.Length == 0) return new byte[] { };
int tempresult = a[0] + b[0] + carry;
byte[] z = new byte[]
{ (byte)(tempresult) };
carry = tempresult / (byte.MaxValue + 1);
return z.Concat(AddRecursive(a.Skip(1).ToArray(), b.Skip(1).ToArray())).ToArray();
}
//Test//
[Test]
public void Add_UsingARecursiveAlgorithm_ValuesAreAdded()
{
//First Test
byte[] expectedResult = addthisaddthat.AddRecursive(new byte[] { 1, 1, 1 }, new byte[] { 1, 1, 1 }).Reverse().ToArray();
Assert.That(expectedResult, Is.EqualTo(new byte[] { 2, 2, 2 }));
//Sec Test
expectedResult = addthisaddthat.AddRecursive(new byte[] { 1, 1, 255 }, new byte[] { 0, 0, 1 }).Reverse().ToArray();
Assert.That(expectedResult, Is.EqualTo(new byte[] { 1, 2, 0 }));
//Third Test
expectedResult = addthisaddthat.AddRecursive(new byte[] { 255, 255, 255 }, new byte[] { 255, 255, 255 }).Reverse().ToArray();
Assert.That(expectedResult, Is.EqualTo(new byte[] { 255, 255, 254 }));
}
Ok here is some rather "ugly" code that does what you want. I tried to write it for clarity rather than brevity:
static byte[] AddArray(byte[] ary1, byte[] ary2) {
System.Diagnostics.Debug.Assert(ary1.Length == ary2.Length);
if ((ary1 == null) || (ary2 == null)) {
throw new ArgumentException("Empty or null array");
}
// sum the last element
var ix = ary1.Length - 1;
var sum = (ary1[ix] + ary2[ix]);
if (sum > byte.MaxValue) {
if (ix == 0) {
throw new ArgumentException("Overflow");
}
// Add carry by recursing on ary1
var carry = (byte) (sum - byte.MaxValue);
var carryAry = new byte[ary1.Length];
carryAry[ix - 1] = carry;
ary1 = AddArray(ary1, carryAry);
}
if ((ary1.Length == 1) || (ary2.Length == 1)) {
return new byte[] { (byte) sum }; // end recursion
}
// create the remainder, elements from 0 it (len-1)
var ary1Remainder = new byte[ary1.Length - 1];
var ary2Remainder = new byte[ary2.Length - 1];
Array.Copy(ary1, 0, ary1Remainder, 0, ary1.Length - 1);
Array.Copy(ary2, 0, ary2Remainder, 0, ary2.Length - 1);
// recurse
var remainder = AddArray(ary1Remainder, ary2Remainder);
// build return array (using linq Concat)
var rv = (remainder.Concat(new byte[] { (byte) sum }));
return rv.ToArray(); // return as an array
}
This would be cleaner without all the casting and ToArray required because the values are byte[] and not IEnumerable<int>, but:
private byte[] AddRecursive(byte[] a, byte[] b) {
if (a.Length == 0) return new byte[]{};
return
new byte[] { (byte)(a[0] + b[0]) }.Concat(
AddRecursive(a.Skip(1).ToArray(), b.Skip(1).ToArray())
).ToArray();
}
Maybe your interviewer had something like this in mind:
using System;
using System.Linq;
public class Program
{
public static byte[] Add(byte[] a, byte[] b, int index = -1)
{
if (index < 0)
{
return Add((byte[])a.Clone(), b, 0);
}
if (index < a.Length)
{
Add(a, b, index + 1);
a[index] += b[index];
}
return a;
}
public static void Main(string[] args)
{
var r1 = Add(new byte[] { 1, 1, 1 }, new byte[] { 1, 1, 1 });
var r2 = Add(new byte[] { 1, 1, 255 }, new byte[] { 0, 0, 1 });
var r3 = Add(new byte[] { 0, 100, 200 }, new byte[] { 3, 2, 1 });
// Outputs: 2, 2, 2
Console.WriteLine(string.Join(", ", r1.Select(n => "" + n).ToArray()));
// Outputs: 1, 1, 0
Console.WriteLine(string.Join(", ", r2.Select(n => "" + n).ToArray()));
// Outputs: 3, 102, 201
Console.WriteLine(string.Join(", ", r3.Select(n => "" + n).ToArray()));
}
}
https://dotnetfiddle.net/UqSQb3
Note this (only partial) solution doesn't handle the carry on byte overflows, though.
'Hope this helps,
I have b1 and b2 which are all in byte, I am using serialport.write to send them separately. Can I send them at the same time? As in using one command instead of two. My existing code:
private void SConvert_Click(object sender, EventArgs e)
{
byte[] b1 = null, b2 = null;
string[] coords = textBox1.Text.Split('\n');
for (int i = 0; i <= coords.Length - 1; i++)
{
if (coords[i].Length > 0)
{
GetValue(coords[i], out b1, out b2);
}
if (serialPort.IsOpen)
{
serialPort.Write(b1, 0, 4);
serialPort.Write(b2, 0, 4);
}
}
}
private void GetValue(string strValue, out byte[] b1, out byte[] b2)
{
string S1, S2, S = strValue;
string[] x = S.Split(',');
string y = x[0].ToString();//{lat=-36.123333
string z = x[1].ToString();//lng=174.333333} // index outside bounds of the array
S1 = y.Substring(y.IndexOf('=') + 1);
string z1 = z.Replace("}", "0"); // replace } by 0 since do not know length of }
S2 = z1.Substring(z1.IndexOf('=') + 1);
float f1 = float.Parse(S1), f2 = float.Parse(S2);
b1 = System.BitConverter.GetBytes(f1);
b2 = System.BitConverter.GetBytes(f2);
}
Instead of
serialPort.Write(b1, 0, 4);
serialPort.Write(b2, 0, 4);
you could do just
serialPort.Write(b1.Concat(b2).ToArray(), 0, b1.Length + b2.Length);
I assume you'd like to send two byte arrays at once. Solution is simple: merge them, and send it.
byte[] buf = new byte[b1.Length + b2.Length];
Array.Copy(buf, 0, b1);
Array.Copy(buf, 0, b2, b1.Length, b2.Length);
serialPort.Write(buf, 0, buf.Length);
See also: Merging two arrays in .NET
public void parse_table(BinaryReader inFile)
{
byte[] idstring = inFile.ReadBytes(6);
Console.WriteLine(Convert.ToString(idstring));
}
It is a simple snippet: read the first 6 bytes of the file and convert that to a string.
However the console shows System.Byte[].
Maybe I'm using the wrong class for conversion. What should I be using? It will eventually be parsing filenames encoded in UTF-8, and I'm planning to use the same method to read all filenames.
It's actually:
Console.WriteLine(Encoding.Default.GetString(value));
or for UTF-8 specifically:
Console.WriteLine(Encoding.UTF8.GetString(value));
I was in a predicament where I had a signed byte array (sbyte[]) as input to a Test class and I wanted to replace it with a normal byte array (byte[]) for simplicity. I arrived here from a Google search but Tom's answer wasn't useful to me.
I wrote a helper method to print out the initializer of a given byte[]:
public void PrintByteArray(byte[] bytes)
{
var sb = new StringBuilder("new byte[] { ");
foreach (var b in bytes)
{
sb.Append(b + ", ");
}
sb.Append("}");
Console.WriteLine(sb.ToString());
}
You can use it like this:
var signedBytes = new sbyte[] { 1, 2, 3, -1, -2, -3, 127, -128, 0, };
var unsignedBytes = UnsignedBytesFromSignedBytes(signedBytes);
PrintByteArray(unsignedBytes);
// output:
// new byte[] { 1, 2, 3, 255, 254, 253, 127, 128, 0, }
The ouput is valid C# which can then just be copied into your code.
And just for completeness, here is the UnsignedBytesFromSignedBytes method:
// http://stackoverflow.com/a/829994/346561
public static byte[] UnsignedBytesFromSignedBytes(sbyte[] signed)
{
var unsigned = new byte[signed.Length];
Buffer.BlockCopy(signed, 0, unsigned, 0, signed.Length);
return unsigned;
}
I've used this simple code in my codebase:
static public string ToReadableByteArray(byte[] bytes)
{
return string.Join(", ", bytes);
}
To use:
Console.WriteLine(ToReadableByteArray(bytes));
byte[] bytes = { 1,2,3,4 };
string stringByte= BitConverter.ToString(bytes);
Console.WriteLine(stringByte);
This is just an updated version of Jesse Webbs code that doesn't append the unnecessary trailing , character.
public static string PrintBytes(this byte[] byteArray)
{
var sb = new StringBuilder("new byte[] { ");
for(var i = 0; i < byteArray.Length;i++)
{
var b = byteArray[i];
sb.Append(b);
if (i < byteArray.Length -1)
{
sb.Append(", ");
}
}
sb.Append(" }");
return sb.ToString();
}
The output from this method would be:
new byte[] { 48, ... 135, 31, 178, 7, 157 }
For some fun with linq and string interpolation:
public string ByteArrayToString(byte[] bytes)
{
if ( bytes == null ) return "null";
string joinedBytes = string.Join(", ", bytes.Select(b => b.ToString()));
return $"new byte[] {{ {joinedBytes} }}";
}
Test cases:
byte[] bytes = { 1, 2, 3, 4 };
ByteArrayToString( bytes ) .Dump();
ByteArrayToString(null).Dump();
ByteArrayToString(new byte[] {} ) .Dump();
Output:
new byte[] { 1, 2, 3, 4 }
null
new byte[] { }