Recursion does not work with one line solution - c#

The question is about Leetcode 938.
My first solution is
return root == null ? 0 : root.val < low || root.val > high ? RangeSumBST(root.left, low, high) + RangeSumBST(root.right, low, high) : RangeSumBST(root.left, low, high) + RangeSumBST(root.right, low, high) + root.val;
And it is accepted.
Then I tried another one line solution for simplicity and readability
return root == null ? 0 : RangeSumBST(root.left, low, high) + RangeSumBST(root.right, low, high) + root.val < low || root.val > high ? 0 : root.val;
But it seems recursion doesn't work with the second solution. Only the most root value can be returned.
I would like to know what's the difference between these two solutions and why recursion does not work with the second solution.

As the other's answers ,let make it more simpler.
//solution #1
return (condition) ?
( constant value ) //check condition T then constant value add 0
:
( constant value) + root.val; //check condition F then constant value add root.val
//solution #2
return (( constant value ) + root.val ) < low|| root.val > high ?
0 // check new condition T then get only 0
:
root.val; // check new condition F then get only root.val
as #Fildor's answer you should add the parenthesis
return root == null ? 0 : ( RangeSumBST(root.left, low, high) + RangeSumBST(root.right, low, high) ) + ( (root.val < low || root.val > high) ? 0 : root.val );

Related

What does the opposite outcome of Unity Math.Clamp()?

Is there a method of making sure a integer can't be between two numbers, kind of like Unity's Mathf.Clamp() method but instead of not allowing it to be above or below two numbers, make sure its not between two numbers.
If it's not between the two numbers, what should it be - the upper value or the lower value? If you want the closest, you could do:
int ClosestIfBetween(int val, int low, int high)
{
if (val > low && val < high)
{
int mid = (high - low) / 2 + low;
return val < mid ? low : high;
}
return val;
}

C# does array.length start from 0?

I know that when you're referencing an array it starts from 0, but does array.length start from 0 or does it start from 1?
Because if I specify an array size to be 10, I reference it 0-9, does this mean array.length is 0-9?
I'm asking because I'm using array.length as the maximum size of a randomly generated number but I'm doing it like this
randomArrayPointer = randomIntNum( 0 , ( posPercents.Length - 1 ) ); //generates a random number that fits the arrays range
if( randomArrayPointer < posPercents.Length ) //ensures the integer is less than the length of the array
{
return ( posPercents [ randomArrayPointer ] );
}
else
{
return ( posPercents [ 0 ] );
}
Here is my method randomIntNumber (I +1 to the maximum because when specifying 1 to 10 as the inputs for Random() it will give me a number between 0-9)
public static int randomIntNum( int min , int max )
{
if( max != 1 & ( max != ( min + 1 ) ) ) //if max isn't 1 and max isn't the minimum + 1
{
max = max - 1; //remove 1, this corrects the random generator so that the parameters sent don't need adjusting
}
int newInt;
newInt = rnd.Next( min , max );
return ( newInt );
}
Edit:
This is my method now, thanks everyone.
public static double randomPercentChange( Boolean? positive )
{
if( positive == true )
{
return ( posPercents [ rnd.Next( posPercents.Length ) ] );
}
else if( positive == false )
{
return ( negPercents [ rnd.Next( negPercents.Length ) ] );
}
else if( positive == null )
{
return ( 1 );
}
return 1;
}
EDIT 2: 4 years on I am sorely embarrassed by this question, but it is a great reference point for progress
If your array is empty, it contains 0 elements and has length 0.
If your array has 1 element in 0 index, then its length is equal to 1.
If your array has 2 elements in 0 and 1 indexes, then its length is equal 2.
and so on...
Array.Length refers to the size of the array, i.e how many elements it can hold. Arrays are 0 based when indexing them, so an example iteration would look like...
for(var i = 0; i < myArray.Length; i++)
{
var elm = myArray[i];
//do something with the element
}
I suppose your question is, "why is the last value in your array at index posPercents.Length - 1 instead of posPercents.Length?"
Since arrays are zero based, posPercents.Length = 10, but the last value is not at index 10. It is at index 9, hence its index is posPercents.Length - 1.

Formula to produce 1 for positive integers and 0 otherwise

I have a function (f) the takes a number of items (n) and a number of columns (c) and returns the optimal layout as an array of items per column. I define optimal as being as square as possible. So f(4,4) would return [4,4,4,4], f(17,4) would return [5,4,4,4], and f(1,4) would return [1,0,0,0]. My function works correctly in all my tests, but I am looking to alter it. My desire to do this is not because I am looking increase performance. I just want to do this, because I am experimenting and want to learn different techniques.
Here is the code:
public static int[] f(int n, int c){
int[] a = new int[c];
if(c>0 && n>=0){
int opt = (n-(n%c))/c;
n = n - (opt*c);
for(int i = 0;i<a.Length;i++){
a[i] = opt;
if(n>0){
a[i]++;
n--;
}
}
}
return a;
}
The function works by first determining the optimal number of items per col:
int opt = (n-(n%c))/c;
So f(17,4) would yield 4, f(19,4) would also yield 4, and f(3,4) would yield 0. Then the reminder is calculated:
n = n - (opt*c);
I then loop through the array (of length c) and assign a[i] equal to the optimal value. Finally, if the reminder is greater than 0 I add 1 to a[i]. This equally distributes the reminder across the array. This is the part I would like to alter.
Instead of checking if(n>0) and adding 1 to the array is there a formula I could use that might look like:
a[i] = opt + n*?????;
So n*??? would always equal 1 if n is greater than 0 and 0 if n is 0 or less?
The simple answer to your question is to use an expression with the conditional operator:
a[i] = opt + (n > 0 ? 1 : 0);
(n > 0 ? 1 : 0) will be 1 if n is greater than 0, and 0 otherwise.
On that note, there is a clearer and more concise way to implement your algorithm.
Determine the total number of items that can be distributed evenly between the slots (call this average). This has the value n / c (using integer division).
Determine the remainder that would be left after those are evenly distributed (call this remainder). This has the value n % c.
Put the value average + 1 in the first remainder slots, and put average in the rest.
The implementation for this would be:
public static int[] Distribute(int total, int buckets)
{
if (total < 0) { throw new ArgumentException("cannot be less than 0", "total"); }
if (buckets < 1) { throw new ArgumentException("cannot be less than 1", "buckets"); }
var average = total / buckets;
var remainder = total % buckets;
var array = new int[buckets];
for (var i = 0; i < buckets; i++)
{
array[i] = average + (i < remainder ? 1 : 0);
}
return array;
}
And the obligatory Linq version:
public static int[] DistributeLinq(int total, int buckets)
{
if (total < 0) { throw new ArgumentException("cannot be less than 0", "total"); }
if (buckets < 1) { throw new ArgumentException("cannot be less than 1", "buckets"); }
var average = total / buckets;
var remainder = total % buckets;
return Enumerable.Range(1, buckets)
.Select(v => average + (v <= remainder ? 1 : 0))
.ToArray();
}
If you want to use a formula:
Math.Max(n - Math.Abs(n - 1), 0)
should do the trick.
Your code should look like:
a[i] = opt + Math.Max(n - Math.Abs(n - 1), 0)
Another option for a formula would be
Math.Max(Math.Sign(n), 0)
If you are looking for a mathematical formula, I'm not sure you're going to find it as the function is discontinuous at n = 0.
How about a simple function which outputs int on a bool expression?
int IsPositive(int number)
{
//if number is > 0 return integer one (1), else return integer zero (0)
return number > 0 ? 1 : 0;
}
You can then use this in your code as such:
a[i] = opt + IsPositive(n);
//opt + 1 if n > 0, opt + 0 if n <= 0
Update: per your comment, you can just move the evaluation inline:
a[i] = opt + (n > 0 ? 1 : 0);
As an aside: you should make #BradleyDotNET's comment one of your programming mottos.

How can I write a symmetrical version of a snap to value formula (in C#)

I would like to write a component that can move a value up by an increment amount, or move to the nearest increment.
Assuming the increment was 0.0005, for an Up() method, here would be the expected inputs and outputs:
1.0005 -> 1.0010 (at increment so it moves by the increment)
1.0006 -> 1.0010 (not at increment, so moves to increment)
1.0007 -> 1.0010
1.0008 -> 1.0010
1.0009 -> 1.0010
1.0010 -> 1.0015 (at increment so it moves by the increment)
1.0011 -> 1.0015
1.0012 -> 1.0015
etc
And the Down() method would do the same, in reverse.
I have come up with this formula for up:
return (value + increment) - (value % increment);
I expected that the Down() method would be similar but I can't find what it is. The only way I've been able to get it to work is by doing:
decimal mod = value % increment;
return mod != 0 ? value - mod : value - increment
Surely if the operation is the same in reverse, then the formulas should be the same.
public static decimal Increment(decimal dec, decimal inc) {
var mod = (dec % inc);
return dec - Math.Abs(mod) + (inc < 0 && mod != 0 ? Math.Abs(inc) : 0) + inc;
}
Without the ternary operator:
public static decimal Increment(decimal dec, decimal inc) {
var mod = (dec % inc);
var signInc = Math.Sign(inc);
return dec - Math.Abs(mod) +
((decimal)(Math.Pow(signInc, 2) - signInc) / 2) *
Math.Abs(Math.Sign(mod)) *
Math.Abs(inc)
+ inc;
}
((decimal)(Math.Pow(signInc, 2) - signInc) / 2) *
Math.Abs(Math.Sign(mod)) *
Math.Abs(inc)
replaces the ternary expression. Math.Pow(signInc, 2) - signInc) / 2 returns 1 if inc is negative and 0 otherwise. Math.Abs(Math.Sign(mod)) returns 0 if mod is 0 and 1 otherwise; making the result of the first multiplication 1 if inc < 0 && mod != 0 and 0 otherwise.
formula
value - Abs(value % increment) + Abs(increment/2) + increment/2
take value 1.0006 as example with increment (+_)0.0005
when up increment is +0.0005
1.0006-0.0001+0.00025+0.00025 = 1.0010
when down increment is -0.0005
1.0006-0.0001+0.00025-0.00025 = 1.0005

Asp with C# Prime Number

I'm a 17 year old student currently in software engineering and web development and im having trouble right now with some of my coding. I need to make a project that will alow the user to input a number anywherefrom 0 to 999 and tell whether it is a prime number or not. The code i have so far is....
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public void primeNumber()
{
int primeNumber1 = int.Parse(Request.Form["Text4"]);
if (primeNumber1 % 1 == 0 & ! (primeNumber1 % 2 == 0 &
primeNumber1 % 3 == 0 &
primeNumber1 % 4 == 0 &
primeNumber1 % 5 == 0 &
primeNumber1 % 6 == 0 &
primeNumber1 % 7 == 0 &
primeNumber1 % 8 == 0 &
primeNumber1 % 9 == 0))
{
Response.Write(" This is a prime number! ");
}
else
{
Response.Write(" This is not a prime Number! ");
}
}
}
... but i cannot get this program to display the correct answer. Any help would be greatly appreciated. Thanks!
You have got the concept of prime numbers wrong. Your code would for example report that 3 is not a prime number, because you check if the number divides evenly in three even if the number entered is three.
The simplest solution would be to loop from 2 and up to primeNumber1 - 1 and check if any of those divides evenly with the number. As you are using a loop, you also need a variable to hold what the result was, as you don't have a single expression that returns the result.
Something like:
bool prime = true;
for (int i = 2; i <= primeNumber1 - 1; i++) {
if (primeNumber1 % i == 0) {
prime = false;
}
}
This is of course the simplest possible solution that solves the problem, for reasonably small numbers. You can for example improve on the solution by exiting out of the loop as soon as you know that it's not a prime number.
You also don't need to loop all the way to primeNumber1 - 1, but only as high as the square root of the number, but you can find out about that if you read up on methods for checking prime numbers.
You need to handle the special cases of 1 and 2 also. By definition 1 is not a prime number, but 2 is.
http://en.wikipedia.org/wiki/Prime_number
bool IsPrime(int number) {
if (number == 1) return false;
if (number == 2) return true;
for (int i = 2; i < number; ++i) {
if (number % i == 0) return false;
}
return true;
}
A little google-fu or a little navel-gazing about prime numbers in general, will lead you to the naive algorithm:
For all n such that 0 < n:
There are two "special case" prime numbers, 1 and 2.
All even numbers > 2 are non-prime, by definition
If you think about the nature of factoring, the largest possible factor you have to consider is the square root of n, since above that point, the factors are reflexive (i.e., the possible factorizations of 100 are 1*100 , 2*50 , 4*25 , 5*20 , 10*10 , 20*5 , 25*4, 50*2 and 100*1 — and the square root of 100 is...10).
That should lead you to an implementation that looks something like this:
static bool IsPrime( int n )
{
if ( n < 1 ) throw new ArgumentOutOfRangeException("n") ;
bool isPrime = true ;
if ( n > 2 )
{
isPrime = ( 0 != n & 0x00000001 ) ; // eliminate all even numbers
if ( isPrime )
{
int limit = (int) Math.Sqrt(n) ;
for ( int i = 3 ; i <= limit && isPrime ; i += 2 )
{
isPrime = ( 0 != n % i ) ;
}
}
}
return isPrime ;
}
Anytime you find yourself in programming repeating a test on a sequential range of numbers you're doing the wrong thing. A better construct for this is a loop. This will give you the range of numbers in an identifier which can then be used to write the repetive code one time. For example I could rewrite this code
primeNumber1 % 2 == 0 &
primeNumber1 % 3 == 0 &
primeNumber1 % 4 == 0 &
primeNumber1 % 5 == 0 &
primeNumber1 % 6 == 0 &
primeNumber1 % 7 == 0 &
primeNumber1 % 8 == 0 &
primeNumber1 % 9 == 0))
As follows
bool anyFactors = false;
for (int i = 2; i <= 9; i++) {
if (primeNumber1 % i != 0) {
anyFactors = true;
break;
}
}
At this point I can now substitute the value allTrue for the original condition you wrote.
if (primeNumber1 % 1 == 0 && !anyFactors)
I can also expand the number of values tested here by substiting a different number for the conditional check of the loop. If I wanted to check 999 values I would instead write
for (int i = 2; i <= 999; i++) {
...
}
Additionally you don't want to use & in this scenario. That is for bit level and operations. You are looking for the logical and operator &&
Try the code below:
bool isPrimeNubmer(int n)
{
if (n >=0 && n < 4) //1, 2, 3 are prime numbers
return true;
else if (n % 2 == 0) //even numbers are not prime numbers
return false;
else
{
int j = 3;
int k = (n + 1) / 2 ;
while (j <= k)
{
if (n % j == 0)
return false;
j = j + 2;
}
return true;
}
}

Categories

Resources