How to convert recursive algorithm to dynamic programming? [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I have this algorithm:
static int findMaxRec(int[] w, int[] v, int W, int n)
{
int max = int.MinValue;
int res;
for (int i = 0; i < n; i++)
{
if (w[i] <= W)
{
if (w[i] == W)
res = v[i]; // F(0) + v[i] = v[i]
else
res = findMaxRec(w, v, W - w[i], n) + v[i];
max = max < res ? res : max;
}
}
return max;
}
How can I convert it to dynamic programming algorithm?
I have tried several ideas but none of them seems to work. So I am stuck.
P.S. w and v are just simple number arrays, nothing fancier. W is just a number. This algorithm does not implement any particular task I just found it in a book where they ask to implement algorithms for given formulas.
UPDATE:
static int findMaxDyn(int[] F, int[] w, int[] v, int W, int n)
{
int max = int.MinValue;
int res;
for (int i = 0; i < n; i++)
{
if (w[i] <= W)
{
if (F[W - w[i]] == int.MinValue) // calculate only if -inf
{
if (w[i] == W)
res = v[i]; // F(0) + v[i] = v[i]
else
res = findMaxDyn(F, w, v, W - w[i], n) + v[i];
max = max < res ? res : max;
F[W - w[i]] = max;
}
}
}
return max;
}
This gives wrong answers that do not match to recursive algorithm. And it seems to still use recursion...
Recursion tree that I have drawn when
int [] w = new []{ 4, 3, 2, 1};
int [] v = new []{ 4, 3, 2, 1};
int W = 4;
int n = 4;

I still don't know what the algorithm is trying to do but the non-recursive function could be:
public static int findMaxRec_NonRecursive(int[] Vect_w, int[] Vect_v, int W, int n)
{
List<int> prevWValues = new List<int>();
List<int> prevVValues = new List<int>();
List<int> prevIndex_i = new List<int>();
List<int> prevMaxValue = new List<int>();
int ListIndex = 0, iniIndex = 0, max = int.MinValue;
startOver:
for (int i = iniIndex; i < n; i++)
{
if (Vect_w[i] <= W)
{
if (Vect_w[i] == W)
max = Math.Max(Vect_v[i], max);
else
{
if (prevWValues.Count > ListIndex)
{
prevWValues[ListIndex] = W;
prevIndex_i[ListIndex] = i;
prevVValues[ListIndex] = Vect_v[i];
prevMaxValue[ListIndex] = max;
}
else
{
prevWValues.Add(W);
prevIndex_i.Add(i);
prevVValues.Add(Vect_v[i]);
prevMaxValue.Add(max);
}
W -= Vect_w[i];
ListIndex++;
iniIndex = 0;
max = int.MinValue;
goto startOver;
}
}
}
if (ListIndex>0)
{
ListIndex--;
iniIndex = prevIndex_i[ListIndex]+1;
W = prevWValues[ListIndex];
max = Math.Max(max+ prevVValues[ListIndex], prevMaxValue[ListIndex]);
goto startOver;
}
return max;
}
Sorry for the 'gotos', I just found it easier to program for this case. Also I have renamed a little your input variables not to drive crazy.
EDIT
As others have pointed out, it could be used as a Knapsack algorithm, so knowing what it is intended to do, you could optimize/simplify a little more (the complexity of these kind of algorithms grow exponentially with n). For instance, you can sort the input Vect_W values and replace lists by arrays.
public static int findMaxRec_NonRecursive(int[] Vect_w, int[] Vect_v, int W, int n)
{
Array.Sort(Vect_w, Vect_v);
n = Math.Min(n, Vect_w.Length);
//Remove here repeated elements in Vect_w selecting the one with higher Vect_v if uniqueness is not assured
int minVectW = Vect_w[0];
int L = W / minVectW + 1;
int[] prevWValues = new int[L];
int[] prevVValues = new int[L];
int[] prevIndex_i = new int[L];
int[] prevMaxValue = new int[L];
int ListIndex = 0, iniIndex = n - 1, max = int.MinValue, PrevUsefullIndex = 0;
startOver:
for (int i = iniIndex; i >= 0; i--)
{
if (Vect_w[i] <= W)
{
if (PrevUsefullIndex < i)
PrevUsefullIndex = i;
if (Vect_w[i] == W)
max = Math.Max(Vect_v[i], max);
else
{
int newW = W - Vect_w[i];
if (newW < minVectW)
max = Math.Max(Vect_v[i], max);
else
{
prevWValues[ListIndex] = W;
prevIndex_i[ListIndex] = i;
prevVValues[ListIndex] = Vect_v[i];
prevMaxValue[ListIndex] = max;
W = newW;
ListIndex++;
iniIndex = PrevUsefullIndex;
PrevUsefullIndex = 0;
max = int.MinValue;
goto startOver;
}
}
}
}
if (ListIndex > 0)
{
ListIndex--;
iniIndex = prevIndex_i[ListIndex] - 1;
W = prevWValues[ListIndex];
max = Math.Max(max + prevVValues[ListIndex], prevMaxValue[ListIndex]);
goto startOver;
}
return max;
}
EDIT 2
I just found out that the initial recursive algorithm posted is not well conditioned, for example in the case where the best branch is the first branch. I think it should have an additional condition to avoid that:
//[...]
else
{
int innerMax = findMaxRec(w, v, W - w[i], n);
if (innerMax == int.MinValue)
innerMax = 0;
res = innerMax + v[i];
}
//[...]
I have also added a condition in the non-recursive algorithm that does pretty much the same by checking if the branch can be officialy closed when the new W is lower than the smallest vect_W element.

Related

Getting Time limit Exceed for last 3 Test Cases in a Program:C# [duplicate]

Given an array of n integers and a number, d, perform left rotations on the array. Then print the updated array as a single line of space-separated integers.
Sample Input:
5 4
1 2 3 4 5
The first line contains two space-separated integers denoting the respective values of n (the number of integers) and d (the number of left rotations you must perform).
The second line contains n space-separated integers describing the respective elements of the array's initial state.
Sample Output:
5 1 2 3 4
static void Main(String[] args)
{
string[] arr_temp = Console.ReadLine().Split(' ');
int n = Int32.Parse(arr_temp[0]);
int d = Int32.Parse(arr_temp[1]);
string[] arr = Console.ReadLine().Split(' ');
string[] ans = new string[n];
for (int i = 0; i < n; ++i)
{
ans[(i + n - d) % n] = arr[i];
}
for (int j = 0; j < n; ++j)
{
Console.Write(ans[j] + " ");
}
}
How to use less memory to solve this problem?
This will use less memory in most cases as the second array is only as big as the shift.
public static void Main(string[] args)
{
int[] n = { 1, 2, 3, 4, 5 };
LeftShiftArray(n, 4);
Console.WriteLine(String.Join(",", n));
}
public static void LeftShiftArray<T>(T[] arr, int shift)
{
shift = shift % arr.Length;
T[] buffer = new T[shift];
Array.Copy(arr, buffer, shift);
Array.Copy(arr, shift, arr, 0, arr.Length - shift);
Array.Copy(buffer, 0, arr, arr.Length - shift, shift);
}
This problem can get a bit tricky but also has a simple solution if one is familiar with Queues and Stacks.
All I have to do is define a Queue (which will contain the given array) and a Stack.
Next, I just have to Push the Dequeued index to the stack and Enqueue the Popped index in the Queue and finally return the Queue.
Sounds confusing? Check the code below:
static int[] rotLeft(int[] a, int d) {
Queue<int> queue = new Queue<int>(a);
Stack<int> stack = new Stack<int>();
while(d > 0)
{
stack.Push(queue.Dequeue());
queue.Enqueue(stack.Pop());
d--;
}
return queue.ToArray();
}
Do you really need to physically move anything? If not, you could just shift the index instead.
Actually you asked 2 questions:
How to efficiently rotate an array?
and
How to use less memory to solve this problem?
Usually efficiency and low memory usage are mutually exclusive. So I'm going to answer your second question, still providing the most efficient implementation under that memory constraint.
The following method can be used for both left (passing negative count) or right (passing positive count) rotation. It uses O(1) space (single element) and O(n * min(d, n - d)) array element copy operations (O(min(d, n - d)) array block copy operations). In the worst case scenario it performs O(n / 2) block copy operations.
The algorithm is utilizing the fact that
rotate_left(n, d) == rotate_right(n, n - d)
Here it is:
public static class Algorithms
{
public static void Rotate<T>(this T[] array, int count)
{
if (array == null || array.Length < 2) return;
count %= array.Length;
if (count == 0) return;
int left = count < 0 ? -count : array.Length + count;
int right = count > 0 ? count : array.Length - count;
if (left <= right)
{
for (int i = 0; i < left; i++)
{
var temp = array[0];
Array.Copy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = temp;
}
}
else
{
for (int i = 0; i < right; i++)
{
var temp = array[array.Length - 1];
Array.Copy(array, 0, array, 1, array.Length - 1);
array[0] = temp;
}
}
}
}
Sample usage like in your example:
var array = Enumerable.Range(1, 5).ToArray(); // { 1, 2, 3, 4, 5 }
array.Rotate(-4); // { 5, 1, 2, 3, 4 }
Isn't using IEnumerables better? Since It won't perform all of those maths, won't allocate that many arrays, etc
public static int[] Rotate(int[] elements, int numberOfRotations)
{
IEnumerable<int> newEnd = elements.Take(numberOfRotations);
IEnumerable<int> newBegin = elements.Skip(numberOfRotations);
return newBegin.Union(newEnd).ToArray();
}
IF you don't actually need to return an array, you can even remove the .ToArray() and return an IEnumerable
Usage:
void Main()
{
int[] n = { 1, 2, 3, 4, 5 };
int d = 4;
int[] rotated = Rotate(n,d);
Console.WriteLine(String.Join(" ", rotated));
}
I have also tried this and below is my approach...
Thank you
public static int[] RotationOfArray(int[] A, int k)
{
if (A == null || A.Length==0)
return null;
int[] result =new int[A.Length];
int arrayLength=A.Length;
int moveBy = k % arrayLength;
for (int i = 0; i < arrayLength; i++)
{
int tmp = i + moveBy;
if (tmp > arrayLength-1)
{
tmp = + (tmp - arrayLength);
}
result[tmp] = A[i];
}
return result;
}
I have tried to used stack and queue in C# to achieve the output as follows:
public int[] rotateArray(int[] A, int rotate)
{
Queue<int> q = new Queue<int>(A);
Stack<int> s;
while (rotate > 0)
{
s = new Stack<int>(q);
int x = s.Pop();
s = new Stack<int>(s);
s.Push(x);
q = new Queue<int>(s);
rotate--;
}
return q.ToArray();
}
I've solve the challange from Hackerrank by following code. Hope it helps.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ConsoleApp1
{
class ArrayLeftRotationSolver
{
TextWriter mTextWriter;
public ArrayLeftRotationSolver()
{
mTextWriter = new StreamWriter(#System.Environment.GetEnvironmentVariable("OUTPUT_PATH"), true);
}
public void Solve()
{
string[] nd = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(nd[0]);
int d = Convert.ToInt32(nd[1]);
int[] a = Array.ConvertAll(Console.ReadLine().Split(' '), aTemp => Convert.ToInt32(aTemp))
;
int[] result = rotLeft(a, d);
mTextWriter.WriteLine(string.Join(" ", result));
mTextWriter.Flush();
mTextWriter.Close();
}
private int[] rotLeft(int[] arr, int shift)
{
int n = arr.Length;
shift %= n;
int[] vec = new int[n];
for (int i = 0; i < n; i++)
{
vec[(n + i - shift) % n] = arr[i];
}
return vec;
}
static void Main(string[] args)
{
ArrayLeftRotationSolver solver = new ArrayLeftRotationSolver();
solver.Solve();
}
}
}
Hope this helps.
public static int[] leftrotation(int[] arr, int d)
{
int[] newarr = new int[arr.Length];
var n = arr.Length;
bool isswapped = false;
for (int i = 0; i < n; i++)
{
int index = Math.Abs((i) -d);
if(index == 0)
{
isswapped = true;
}
if (!isswapped)
{
int finalindex = (n) - index;
newarr[finalindex] = arr[i];
}
else
{
newarr[index] = arr[i];
}
}
return newarr;
}
Take the Item at position 0 and add it at the end. remove the item at position 0. repeat n times.
List<int> iList = new List<int>();
private void shift(int n)
{
for (int i = 0; i < n; i++)
{
iList.Add(iList[0]);
iList.RemoveAt(0);
}
}
An old question, but I thought I'd add another possible solution using just one intermediate array (really, 2 if you include the LINQ Take expression). This code rotates to right rather than left, but may be useful nonetheless.
public static Int32[] ArrayRightRotation(Int32[] A, Int32 k)
{
if (A == null)
{
return A;
}
if (!A.Any())
{
return A;
}
if (k % A.Length == 0)
{
return A;
}
if (A.Length == 1)
{
return A;
}
if (A.Distinct().Count() == 1)
{
return A;
}
for (var i = 0; i < k; i++)
{
var intermediateArray = new List<Int32> {A.Last()};
intermediateArray.AddRange(A.Take(A.Length - 1).ToList());
A = intermediateArray.ToArray();
}
return A;
}
O(1) space, O(n) time solution
I think in theory this is as optimal as it gets, since it makes a.Length in-place swaps and 1 temp variable swap per inner loop.
However I suspect O(d) space solutions would be faster in real life due to less code branching (fewer CPU command pipeline resets) and cache locality (mostly sequential access vs in d element steps).
static int[] RotateInplaceLeft(int[] a, int d)
{
var swapCount = 0;
//get canonical/actual d
d = d % a.Length;
if(d < 0) d += a.Length;
if(d == 0) return a;
for (var i = 0; swapCount < a.Length; i++) //we're done after a.Length swaps
{
var dstIdx = i; //we need this becasue of ~this: https://youtu.be/lJ3CD9M3nEQ?t=251
var first = a[i]; //save first element in this group
for (var j = 0; j < a.Length; j++)
{
var srcIdx = (dstIdx + d) % a.Length;
if(srcIdx == i)// circled around
{
a[dstIdx] = first;
swapCount++;
break; //hence we're done with this group
}
a[dstIdx] = a[srcIdx];
dstIdx = srcIdx;
swapCount++;
}
}
return a;
}
If you take a look at constrains you will see that d <= n (number of rotations <= number of elements in array). Because of that this can be solved in 1 line.
static int[] rotLeft(int[] a, int d)
{
return a.Skip(d).Concat(a.Take(d)).ToArray();
}
// using the same same array, and only one temp variable
// shifting everything several times by one
// works, simple, but slow
public static int[] ArrayRotateLeftCyclical(int[] a, int shift)
{
var length = a.Length;
for (int j = 0; j < shift; j++)
{
int t = a[0];
for (int i = 0; i < length; i++)
{
if (i == length - 1)
a[i] = t;
else
a[i] = a[i + 1];
}
}
return a;
}
Let's say if I have a array of integer 'Arr'. To rotate the array 'n' you can do as follows:
static int[] leftRotation(int[] Arr, int n)
{
int tempVariable = 0;
Queue<int> TempQueue = new Queue<int>(a);
for(int i=1;i<=d;i++)
{
tempVariable = TempQueue.Dequeue();
TempQueue.Enqueue(t);
}
return TempQueue.ToArray();`
}
Let me know if any comments. Thanks!
This is my attempt. It is easy, but for some reason it timed out on big chunks of data:
int arrayLength = arr.Length;
int tmpCell = 0;
for (int rotation = 1; rotation <= d; rotation++)
{
for (int i = 0; i < arrayLength; i++)
{
if (arr[i] < arrayElementMinValue || arr[i] > arrayElementMaxValue)
{
throw new ArgumentException($"Array element needs to be between {arrayElementMinValue} and {arrayElementMaxValue}");
}
if (i == 0)
{
tmpCell = arr[0];
arr[0] = arr[1];
}
else if (i == arrayLength - 1)
{
arr[arrayLength - 1] = tmpCell;
}
else
{
arr[i] = arr[i + 1];
}
}
}
what about this?
public static void RotateArrayAndPrint(int[] n, int rotate)
{
for (int i = 1; i <= n.Length; i++)
{
var arrIndex = (i + rotate) > n.Length ? n.Length - (i + rotate) : (i + rotate);
arrIndex = arrIndex < 0 ? arrIndex * -1 : arrIndex;
var output = n[arrIndex-1];
Console.Write(output + " ");
}
}
It's very straight forward answer.
Main thing is how you choose the start index.
public static List<int> rotateLeft(int d, List<int> arr) {
int n = arr.Count;
List<int> t = new List<int>();
int h = d;
for (int j = 0; j < n; j++)
{
if ((j + d) % n == 0)
{
h = 0;
}
t.Add(arr[h]);
h++;
}
return t;
}
using this code, I have successfully submitted to hacker rank problem,
// fast and beautiful method
// reusing the same array
// using small temp array to store replaced values when unavoidable
// a - array, s - shift
public static int[] ArrayRotateLeftWithSmallTempArray(int[] a, int s)
{
var l = a.Length;
var t = new int[s]; // temp array with size s = shift
for (int i = 0; i < l; i++)
{
// save cells which will be replaced by shift
if (i < s)
t[i] = a[i];
if (i + s < l)
a[i] = a[i + s];
else
a[i] = t[i + s - l];
}
return a;
}
https://github.com/sam-klok/ArraysRotation
public static void Rotate(int[] arr, int steps)
{
for (int i = 0; i < steps; i++)
{
int previousValue = arr[arr.Length - 1];
for (int j = 0; j < arr.Length; j++)
{
int currentValue = arr[j];
arr[j] = previousValue;
previousValue = currentValue;
}
}
}
Here is an in-place Rotate implementation of a trick posted by גלעד ברקן in another question. The trick is:
Example, k = 3:
1234567
First reverse in place each of the two sections delineated by n-k:
4321 765
Now reverse the whole array:
5671234
My implementation, based on the Array.Reverse method:
/// <summary>
/// Rotate left for negative k. Rotate right for positive k.
/// </summary>
public static void Rotate<T>(T[] array, int k)
{
ArgumentNullException.ThrowIfNull(array);
k = k % array.Length;
if (k < 0) k += array.Length;
if (k == 0) return;
Debug.Assert(k > 0);
Debug.Assert(k < array.Length);
Array.Reverse(array, 0, array.Length - k);
Array.Reverse(array, array.Length - k, k);
Array.Reverse(array);
}
Live demo.
Output:
Array: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
Rotate(5)
Array: 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7
Rotate(-2)
Array: 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9

Computing the height of a tree C#

I have been writing this code for computing the height of a tree in c#. the input for this question would be first: the number of nodes and then the quantity for each of them. then the output would be the height of the tree.
input
5
4 -1 4 1 1
output
3
public long Solve(long nodeCount, long[] tree)
{
List<long>[] Node = new List<long>[nodeCount];
long root = 0;
for(int i =0;i<nodeCount;i++ )
{
Node[i] = new List<long>();
}
for(int j =0; j<nodeCount;j++)
{
if (tree[j] == -1)
root = j;
else
Node[tree[j]].Add(j);
}
Queue<long> Q = new Queue<long>();
Q.Enqueue(root);
long Height = 0;
while(Q.Any())
{
for(int i =0; i<Q.Count(); i++)
{
long nodee = Q.Dequeue();
if(Node[nodee] != null)
{
foreach(long N in Node[nodee])
{
Q.Enqueue(N);
}
}
}
Height = Height+1;
}
return Height;
}
this code is returning wrong results to my test cases. what is the problem?
You can swap the pointer direction of the tree nodes in O(n) when using 2 arrays (as pointer for the 2 children of the indexed node):
int size = 5;
int arr[size] = {4, -1, 4, 1, 1};
int a[size];
int b[size];
for (int i = 0; i < size; i++) {
a[i] = -1;
b[i] = -1;
} // I'm not c++ expert (I guess there are better way of init array with the same value...
int root = -1;
for (int i = 0; i < size; i++) {
if (arr[i] == -1)
root = i;
else if (a[arr[i]] != -1)
b[arr[i]] = i;
else
a[arr[i]] = i;
}
This is done in 1 for loop.
You can now use those 2 array to get you height is recursive way:
int findHeight(int current, int count, int a[], int b[]) {
int maxV = count;
if (a[current] > -1)
maxV = max(findHeight(a[current], count + 1, a, b), maxV);
if (b[current] > -1)
maxV = max(findHeight(b[current], count + 1, a, b), maxV);
return maxV;
}
Execute this with:
int height = findHeight(root, 1, a, b); //(as root is the first level)
Total run time complexity is O(n)
Hope that help

Reorder digits in integer using C#

I want to ask how I can reorder the digits in an Int32 so they result in the biggest possible number.
Here is an example which visualizes what I am trying to do:
2927466 -> 9766422
12492771 -> 97742211
I want to perform the ordering of the digits without using the System.Linq namespace and without converting the integer into a string value.
This is what I got so far:
public static int ReorderInt32Digits(int v)
{
int n = Math.Abs(v);
int l = ((int)Math.Log10(n > 0 ? n : 1)) + 1;
int[] d = new int[l];
for (int i = 0; i < l; i++)
{
d[(l - i) - 1] = n % 10;
n /= 10;
}
if (v < 0)
d[0] *= -1;
Array.Sort(d);
Array.Reverse(d);
int h = 0;
for (int i = 0; i < d.Length; i++)
{
int index = d.Length - i - 1;
h += ((int)Math.Pow(10, index)) * d[i];
}
return h;
}
This algorithm works flawlessly but I think it is not very efficient.
I would like to know if there is a way to do the same thing more efficiently and how I could improve my algorithm.
You can use this code:
var digit = 2927466;
String.Join("", digit.ToString().ToCharArray().OrderBy(x => x));
Or
var res = String.Join("", digit.ToString().ToCharArray().OrderByDescending(x => x) );
Not that my answer may or may not be more "efficient", but when I read your code you calculated how many digits there are in your number so you can determine how large to make your array, and then you calculated how to turn your array back into a sorted integer.
It would seem to me that you would want to write your own code that did the sorting part without using built in functionality, which is what my sample does. Plus, I've added the ability to sort in ascending or descending order, which is easy to add in your code too.
UPDATED
The original algorithm sorted the digits, now it sorts the digits so that the end result is the largest or smallest depending on the second parameter passed in. However, when dealing with a negative number the second parameter is treated as opposite.
using System;
public class Program
{
public static void Main()
{
int number1 = 2927466;
int number2 = 12492771;
int number3 = -39284925;
Console.WriteLine(OrderDigits(number1, false));
Console.WriteLine(OrderDigits(number2, true));
Console.WriteLine(OrderDigits(number3, false));
}
private static int OrderDigits(int number, bool asc)
{
// Extract each digit into an array
int[] digits = new int[(int)Math.Floor(Math.Log10(Math.Abs(number)) + 1)];
for (int i = 0; i < digits.Length; i++)
{
digits[i] = number % 10;
number /= 10;
}
// Order the digits
for (int i = 0; i < digits.Length; i++)
{
for (int j = i + 1; j < digits.Length; j++)
{
if ((!asc && digits[j] > digits[i]) ||
(asc && digits[j] < digits[i]))
{
int temp = digits[i];
digits[i] = digits[j];
digits[j] = temp;
}
}
}
// Turn the array of digits back into an integer
int result = 0;
for (int i = digits.Length - 1; i >= 0; i--)
{
result += digits[i] * (int)Math.Pow(10, digits.Length - 1 - i);
}
return result;
}
}
Results:
9766422
11224779
-22345899
See working example here... https://dotnetfiddle.net/RWA4XV
public static int ReorderInt32Digits(int v)
{
var nums = Math.Abs(v).ToString().ToCharArray();
Array.Sort(nums);
bool neg = (v < 0);
if(!neg)
{
Array.Reverse(nums);
}
return int.Parse(new string(nums)) * (neg ? -1 : 1);
}
This code fragment below extracts the digits from variable v. You can modify it to store the digits in an array and sort/reverse.
int v = 2345;
while (v > 0) {
int digit = v % 10;
v = v / 10;
Console.WriteLine(digit);
}
You can use similar logic to reconstruct the number from (sorted) digits: Multiply by 10 and add next digit.
I'm posting this second answer because I think I got the most efficient algorithm of all (thanks for the help Atul) :)
void Main()
{
Console.WriteLine (ReorderInt32Digits2(2927466));
Console.WriteLine (ReorderInt32Digits2(12492771));
Console.WriteLine (ReorderInt32Digits2(-1024));
}
public static int ReorderInt32Digits2(int v)
{
bool neg = (v < 0);
int mult = neg ? -1 : 1;
int result = 0;
var counts = GetDigitCounts(v);
for (int i = 0; i < 10; i++)
{
int idx = neg ? 9 - i : i;
for (int j = 0; j < counts[idx]; j++)
{
result += idx * mult;
mult *= 10;
}
}
return result;
}
// From Atul Sikaria's answer
public static int[] GetDigitCounts(int n)
{
int v = Math.Abs(n);
var result = new int[10];
while (v > 0) {
int digit = v % 10;
v = v / 10;
result[digit]++;
}
return result;
}

How to reverse a number and compare it with its original value [duplicate]

This question already has answers here:
How do I check if a number is a palindrome?
(53 answers)
Closed 8 years ago.
I'm trying to multiply two numbers and then reverse the answer and then compare the original value with the reversed value to see if they are the same numbers. After I reverse the value how do I set it back to an int or a string so I can compare them?
int i = 0;
var x = Enumerable.Range(100,999);
var y = Enumerable.Range(100,999);
foreach (var xValue in x)
{
foreach (var yValue in y)
{
i = (xValue * yValue);
var t = i.ToString();
var tempt = t.Reverse();
var temp = new string(tempt);
if (i.ToString() == temp)
{
}
}
}
Like this perhaps? (One shouldn't really give away answers to projecteuler problems, but this is only problem 4, so what the heck)
public int SolveProblem004()
{
int result = 0;
for (int a = 999; a >= 100; --a) {
for (int b = 999; b >= a; --b) {
int product = a * b;
if (product <= result) break;
if (IsPalindromic(product)) { result = product; break; }
}
}
return result;
}
public static bool IsPalindromic(int i)
{
return i == Reverse(i);
}
public static int Reverse(int number)
{
if (number < 0) return -Reverse(-number);
if (number < 10) return number;
int reverse = 0;
while (number > 0) {
reverse = reverse * 10 + number % 10;
number /= 10;
}
return reverse;
}
int n; //given number
int left = n;
int rev = 0;
while(left>0)
{
r = left % 10; //take the last number
rev = rev * 10 + r; //add it to a new number to flip it
left = left / 10; //left = Math.floor(left / 10);
}
You can do it this way:
int i = 0;
var x = Enumerable.Range(100, 999);
var y = Enumerable.Range(100, 999);
foreach (var xValue in x)
{
foreach (var yValue in y)
{
i = (xValue * yValue);
char[] number = i.ToString().ToCharArray();
char[] reversedNumber = i.ToString().ToCharArray();
Array.Reverse(reversedNumber);
if (new string(number).Equals(new string(reversedNumber)))
{
}
}
}
It will enter inside if loop if number is the same as reversed number and will just pass by in oposite case.

Return an int array length n containing first n digits of pi? (c#)

Per the subject line I am trying to return an int array length n containing the first n digits of pi.
So MakePi(3) --> {3, 1, 4}
I know I need to get pi and it gets stored as a double. I need to convert the double to a char so that I can search through the array to find each char, n in length. Then convert it back to an int array.
I am having issues on where to go from here. I know there is a loop but I can't get my brain to figure out exactly what I need to do. Thanks!
public int[] MakePie(int n)
{
double pi = Math.PI;
char newPi = Convert.ToChar(pi);
char[] newArray = new char[n];
newArray[0] = newPi;
int numbers = Convert.ToInt32(pi);
for (int i = 0; i < n; i++)
{
}
return newArray;
}
try this: it will also get rid of the decimal.
public static int[] MakePie(int n)
{
double pi = Math.PI;
var str = pi.ToString().Remove(1, 1);
var chararray = str.ToCharArray();
var numbers = new int[n];
for (int i = 0; i < n; i++)
{
numbers[i] = int.Parse(chararray[i].ToString());
}
return numbers;
}
Edited to return array of int
var res = pi.ToString().Where(x => x != '.').Take(n).Select(x => (int)char.GetNumericValue(x)).ToArray();
Here is a solution that does not require a string conversion, since your ultimate goal was to return an int[].
public int[] MakePie(int n){
double pi = Math.PI;
int[] result = new int[n];
for (int i = 0; i < n; i++) {
result[i] = (int) Math.Floor(pi);
pi -= result[i];
pi *= 10;
}
return result;
}
private int[] getPiVal()
{
string pi = Math.PI + "";
int[] piarray = new int[3];
for (int i = 0; i < 3; i++)
{
piarray[i] = Convert.ToInt32(pi[i] + "");
}
return piarray;
}
My strategy was to get each digit I wanted in the units position by multiplying PI by the relevant power of ten, and then getting the result of that number mod 10.
public int[] MakePi(int n)
{
int[] result = new int[n];
for (int i = 0; i < n; i++)
{
result[i] = (int)(Math.PI * Math.Pow(10, i)) % 10;
}
return result;
}

Categories