Flatten Ruby Method in C#

Flatten Ruby method in C#

Recursive solution:

IEnumerable Flatten(IEnumerable array)
{
foreach(var item in array)
{
if(item is IEnumerable)
{
foreach(var subitem in Flatten((IEnumerable)item))
{
yield return subitem;
}
}
else
{
yield return item;
}
}
}

EDIT 1:

Jon explains in the comments why it cannot be a generic method, take a look!

EDIT 2:

Matt suggested making it an extension method. Here you go, just replace the first line with:

public static IEnumerable Flatten(this IEnumerable array)

and you can use it like this:

foreach(var item in myArray.Flatten()) { ... }

Need help with algorithm to resolve index through jagged array

You shouldn't use floats here.

int[] levelDepth = new[] { 2, 3, 4 };
int requestedValue = 22;
int[] levelIndexes = new int[levelDepth.Length];

for (int i = 0; i < levelDepth.Length; i++)
{
// need to go from { 2, 3, 4 } -> { 3*4, 4, 1 }
int f = 1;
for (int j = i+1; j < levelDepth.Length; j++)
f *= levelDepth[j];

levelIndexes[i] = requestedValue / f; // integer divide
requestedValue = requestedValue % f;
}

What's a good, generic algorithm for collapsing a set of potentially-overlapping ranges?

This seems to works and is easy to understand.

    public static IEnumerable<Range<T>> Collapse<T>(this IEnumerable<Range<T>> me, IComparer<T> comparer)
{
List<Range<T>> orderdList = me.OrderBy(r => r.Start).ToList();
List<Range<T>> newList = new List<Range<T>>();

T max = orderdList[0].End;
T min = orderdList[0].Start;

foreach (var item in orderdList.Skip(1))
{
if (comparer.Compare(item.End, max) > 0 && comparer.Compare(item.Start, max) > 0)
{
newList.Add(new Range<T> { Start = min, End = max });
min = item.Start;
}
max = comparer.Compare(max, item.End) > 0 ? max : item.End;
}
newList.Add(new Range<T>{Start=min,End=max});

return newList;
}

Here is the variation which I mentioned in the comments. It's basically the same thing, but with some checking and yielding of the results instead of collecting in a list before returning.

    public static IEnumerable<Range<T>> Collapse<T>(this IEnumerable<Range<T>> ranges, IComparer<T> comparer)
{
if(ranges == null || !ranges.Any())
yield break;

if (comparer == null)
comparer = Comparer<T>.Default;

var orderdList = ranges.OrderBy(r => r.Start);
var firstRange = orderdList.First();

T min = firstRange.Start;
T max = firstRange.End;

foreach (var current in orderdList.Skip(1))
{
if (comparer.Compare(current.End, max) > 0 && comparer.Compare(current.Start, max) > 0)
{
yield return Create(min, max);
min = current.Start;
}
max = comparer.Compare(max, current.End) > 0 ? max : current.End;
}
yield return Create(min, max);
}

Convert C# SHA256 hash to Ruby

Solution:

You need to use UTF-16LE encoding to get same SHA-256 Hash

p hash = Digest::SHA256.base64digest("Hello".encode('UTF-16LE'))

How did I find that?

I used Online C# Tool to create the hash of a string "Hello" using the code below:

using System.IO;
using System;
using System.Text;
using System.Security.Cryptography;

class Program
{
static void Main()
{
byte[] bytes = new UnicodeEncoding().GetBytes("Hello");
String s = Convert.ToBase64String(new SHA256Managed().ComputeHash(bytes));
Console.WriteLine(s);
}
}

Above program produced the output oH5Pc0MkbIKybzLlb4VBjVGNiy8trnfx1W/nr1Dbl68=

Then, I wrote a Ruby Program to compute Base64-encoded SHA-256 hash of string "Hello", by encoding the string in all the supported char encodings of Ruby to figure out which char encoding will give exact same result.

require "digest/sha2"
require "base64"
s = "Hello"
Encoding.list.each { |e| puts "Encoding: #{e.to_s} => Hash: #{Digest::SHA256.base64digest(s.encode(e)) rescue "error"}"}

After running the program, I came to conclude that if you use UTF-16LE encoding, you will get exact same output.

p hash = Digest::SHA256.base64digest("Hello".encode('UTF-16LE'))

As per documentation of UnicodeEncoding, it:

Represents a UTF-16 encoding of Unicode characters.

Need help with an array in C#

This is what I ended up doing:

List<PartMeasurements> N = new List<PartMeasurements>();

N.Add(new PartMeasurements(24, new double[,] { {54, -0.146}, {9, 1.2}, {16, 0.097}, {15, 1}, {64, -0.9774} }));
N.Add(new PartMeasurements(4, new double[,] { {32, 0.76}, {45, 1.472}, {18, 0.005}, {52, 1.1}, {31, -0.1} }));
N.Add(new PartMeasurements(73, new double[,] { {81, 1.56}, {24, 1.34}, {9, 0.2}, {2, 0.6}, {55, -0.5} }));

public class PartMeasurements
{
public int BoxSerial_No;
public double[,] partNumber_and_Measurement = new double[5, 1];

public Numbers(int BoxSerial_No, double[,] partNumber_and_Measurement)
{
this.BoxSerial_No = BoxSerial_No;
this.partNumber_and_Measurement = partNumber_and_Measurement;
}
}

If I want to see what is in "N" I can do this:

foreach(var x in N)
{
Console.Write("{0}\t", x.BoxSerial_No);
for (int y = 0; y < x.partNumber_and_Measurement.GetLength(0); y++)
{
Console.Write("{0} ", x.partNumber_and_Measurement[y, 0]);
Console.Write("{0} ", x.partNumber_and_Measurement[y, 1]);
}
}

How to implement Enums in Ruby?

Two ways. Symbols (:foo notation) or constants (FOO notation).

Symbols are appropriate when you want to enhance readability without littering code with literal strings.

postal_code[:minnesota] = "MN"
postal_code[:new_york] = "NY"

Constants are appropriate when you have an underlying value that is important. Just declare a module to hold your constants and then declare the constants within that.

module Foo
BAR = 1
BAZ = 2
BIZ = 4
end

flags = Foo::BAR | Foo::BAZ # flags = 3

Added 2021-01-17

If you are passing the enum value around (for example, storing it in a database) and you need to be able to translate the value back into the symbol, there's a mashup of both approaches

COMMODITY_TYPE = {
currency: 1,
investment: 2,
}

def commodity_type_string(value)
COMMODITY_TYPE.key(value)
end

COMMODITY_TYPE[:currency]

This approach inspired by andrew-grimm's answer https://stackoverflow.com/a/5332950/13468

I'd also recommend reading through the rest of the answers here since there are a lot of ways to solve this and it really boils down to what it is about the other language's enum that you care about

Sum multidimensional array C#

So, firstly: how do I sum all the values from d_array[m,n]

You can use:

int sum = d_array.Cast<int>().Sum();

This will automatically flatten out the multidimensional array and take the sum of all elements.

Is it possible to calculate the sum of each row (-> one dimensional Array / vector) and then calculate again the sum of the column (-> zero-dimensional Array / scalar)?

Yes, but this would require looping manually. There is no simple one liner for this, though it would be easy to write methods to handle it, ie:

IEnumerable<T> GetRow(T[,] array, int row)
{
for (int i = 0; i <= array.GetUpperBound(1); ++i)
yield return array[row, i];
}

IEnumerable<T> GetColumn(T[,] array, int column)
{
for (int i = 0; i <= array.GetUpperBound(0); ++i)
yield return array[i, column];
}

You could then do:

var row1Sum = GetRow(d_array, 1).Sum();

Copy 2D Array in C#

EDIT:

it seems that you are trying to copy the contents of arrayTemp to GlobalDataClass.dDataArray, but you are assigning values to GlobalDataClass.dDataArray, and trying to copy empty arrayTemp to GlobalDataClass.dDataArray.

So first declare the tempArray outside the for-loop and then populate it instead of GlobalDataClass.dDataArray inside the for-loop accordingly:

string filename = openFileDialog1.FileName;
string[] line = File.ReadAllLines(filename);

var arrayTemp = new double[line.Length, 2];

using (var reader2 = File.OpenText(@filename))
{
for (int i = 0; i < line.Length; i++)
{
string lines = reader2.ReadLine();
var data = lines.Split(',');
arrayTemp[i, 0] = double.Parse(data[0]);
arrayTemp[i, 1] = double.Parse(data[1]);
}
Array.Copy(arrayTemp, GlobalDataClass.dDataArray, line.Length); // now the error should go away.
}

EDIT 2:

you don't need to read the file 2nd time in the using() clause.

Now please try the following:

string filename = openFileDialog1.FileName;
string[] line = File.ReadAllLines(filename);

var arrayTemp = new double[line.Length, 2];

for (int i = 0; i < line.Length; i++)
{
var data = line[i].Split(',');
arrayTemp[i, 0] = double.Parse(data[0]);
arrayTemp[i, 1] = double.Parse(data[1]);
}
Array.Copy(arrayTemp, GlobalDataClass.dDataArray, line.Length); // now the error should go away.

How do you rotate a two dimensional array?

Here it is in C#

int[,] array = new int[4,4] {
{ 1,2,3,4 },
{ 5,6,7,8 },
{ 9,0,1,2 },
{ 3,4,5,6 }
};

int[,] rotated = RotateMatrix(array, 4);

static int[,] RotateMatrix(int[,] matrix, int n) {
int[,] ret = new int[n, n];

for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
ret[i, j] = matrix[n - j - 1, i];
}
}

return ret;
}


Related Topics



Leave a reply



Submit