Finding Max/Min values in a linked list - linked-list

When the while loop iterates, it skips both "if" loops and when the "q=q->next" statement runs, both the max and min values are changed as well. Am I not initializing the max/min integers correctly?
void FindMaxMin(int& max, int& min)
{
NODE* q;
q=List; //to start over
while(q != NULL)
{
max=min=q->info; //Sets max and min to first value
if(q->info>max)
max=q->info;
if(q->info<min)
min=q->info;
q=q->next;
}
}

Max/min are initialized every loop cycle to the current element value. That's why ifs are skipped (since the data is neither more nor less than the actual value - it's the same).
You should write something like this to correctly initialize max/min data:
void FindMaxMin(int& max, int& min)
{
NODE* q;
q=List; //to start over
max=min=q->info; //Sets max and min to first value
while(q != NULL)
{
if(q->info>max)
max=q->info;
if(q->info<min)
min=q->info;
q=q->next;
}
}

You reset max and min to the info value of the current node for each node iteration.
Take that initialization outside of the while loop.

Related

Is it atomic operation when exchange std::atomic with itself?

Will following code be executed atomically?
const int oldId = id.exchange((id.load()+1) % maxId);
Where id is std::atomic<int>, and maxId is some integer value.
I searched google and stackoverflow for std::atomic modulo increment. And I found some topics but I can't find clear answer how to do that properly.
In my case even better would be to use:
const int newId = id.exchange((++id) % maxId);
But I am still not sure if it will be executed atomically.
No, this is not atomic, because the load() and the exchange() are separate operations, and nothing is preventing id from getting updated after the load, but before the exchange. In that case your exchange would write a value that has been calculated based on a stale input, so you end up with a missed update.
You can implement a modulo increment using a simple compare_exchange loop:
int val = id.load();
int newVal = (val + 1) % maxId;
while (!id.compare_exchange_weak(val, newVal) {
newVal = (val + 1) % maxId;
}
If the compare_exchange fails it performs a reload and populates val with the updated value. So we can re-calculate newVal and try again.
Edit:
The whole point of the compare-exchange-loop is to handle the case that between the load and the compare-exchange somebody might change id. The idea is to:
load the current value of id
calculate the new value
update id with our own value if and only if the value currently stored in id is the same one as we read in 1. If this is the case we are done, otherwise we restart at 1.
compare_exchange is allows us to perform the comparison and the conditional update in one atomic operation. The first argument to compare_exchange is the expected value (the one we use in our comparison). This value is passed by reference. So when the comparison fails, compare_exchange automatically reloads the current value and updates the provided variable (in our case val).
And since Peter Cordes pointed out correctly that this can be done in a do-while loop to avoid the code duplication, here it is:
int val = id.load();
int newVal;
do {
newVal = (val + 1) % maxId;
} while (!id.compare_exchange_weak(val, newVal);

Optional positional parameter in Dart

I'm studying recursion and I wrote this method to calculate the N° number of the Fibonacci series:
fibonacci(int n, Map memo) {
if (memo.containsKey(n)) return memo[n]; // Memo check
if (n <= 2) return 1; // base case
// calculation
memo[n] = fibonacci(n - 1, memo) + fibonacci((n - 2), memo);
return memo[n];
}
I think it doesn't need to be explained, my problem is just how to call this function from the main, avoiding providing an empty Map.
this is how I call the function now:
fibonacci(n, {});
But I would rather prefer to call it just like this:
fibonacci(n);
The canonical approach is to make memo optional, and use a fresh map if the memo argument is omitted. Because you want to change and update the map, you can't use a default value for the parameter, because default values must be constant, and constant maps are not mutable.
So, written very concisely:
int fibonacci(int n, [Map<int, int>? memo]) {
if (n <= 2) return 1;
return (memo ??= {})[n] ??= fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
}
The ??= operator assigns to the right-hand side if the value is null.
It's used both to initialize memo to a new map if the argument was omitted,
and to update the map if a cached value wasn't present.
I'd actually reconsider using a map. We know that the Fibonacci computation will compute a value for every prior number down to 1, so I'd just use a list instead:
int fibonacci(int n, [List<int?>? memo]) {
if (n <= 2) return 1;
return (memo ??= List<int?>.filled(n - 2))[n - 3] ??=
fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
}
That should work just like the map.
(I subtract 3 from n when doing the lookup because no value below 3 needs the list - it's handled by the prior if).
There are multiple ways to do it. This is my personal favorite, because it also limits the function that is only used for internal means and it doesn't have the need to check every recursion, as you already know there is a map provided:
int fibonacci(int n) {
return _fibonacci(n, {});
}
int _fibonacci(int n, Map<int, int> memo) {
if (n <= 2) return 1; // base case
final previouslyCalculated = memo[n]; // Memo check
if(previouslyCalculated != null) {
return previouslyCalculated;
}
// calculation
final next = _fibonacci(n - 1, memo) + _fibonacci((n - 2), memo);
memo[n] = next;
return next;
}
void main() {
print(fibonacci(4));
}
As Dart does not support overloading, if you actually need both versions to be publicly available (or want both private) you would have to pick different names.
Please note that I added proper types to your methods and cleaned them up a bit for everything that would not compile once proper types are used. Make sure you always use proper types and don't rely on dynamic to somehow works it's magic. The compiler can only help you, if you are explicit about what you want to do. Otherwise they can only nod and let you run into any mistake you may have made. Be smart, let your compiler help, it will catch a lot of errors for you at compile time that you would otherwise have to spent countless hours on debugging.
This is the solution I've found so far but looks very verbose and inelegant:
fibonacci(int n, [Map<int, int>? memo]) {
memo == null ? memo = {} : null; // null check
if (memo.containsKey(n)) return memo[n];
if (n <= 2) return 1;
memo[n] = fibonacci(n - 1, memo) + fibonacci((n - 2), memo);
return memo[n];
}
In this way I can call just:
fibonacci(n);

In Google Sheets how can I randomize the order of a set of values?

Maybe I'm missing a keyword in my searches for a solution, but I didn't find what I'm looking for.
In Google Sheets I want to take a set of numbers and reorder it randomly. For example, start with the set [1,2,3,4] and get back [4,2,1,3].
Any ideas which function or a combination of functions may achieve this goal?
The entire process that I want to achieve is something like this:
I have a set of 4 fields. Their sum is fixed. I want to assign them randomized values.
So, I was thinking to iterate through this process:
Create a random integer between 0 and the max possible value (in the first iteration it's the fixed sum)
The new max value is the last max value minus the new random number.
Check if the new max is zero.
If not:
Return to the 1st step and repeat - This goes on until there are four values
If needed the 4th value shall be increased so the total will match the fixed sum.
Else, continue.
Randomize the order of the 4 values.
Assign the values to the 4 fields.
try:
=INDEX(SORT({{1; 2; 3; 4}, RANDARRAY(4, 1)}, 2, ),, 1)
or:
=INDEX(SORT({ROW(1:4), RANDARRAY(4, 1)}, 2, ),, 1)
Here are a couple of app script examples as well
function DiceRolls(nNumRolls) {
var anRolls = [];
nNumRolls = DefaultTo(nNumRolls, 1000)
for (var i = 1;i <= nNumRolls; i++) {
anRolls.push(parseInt((Math.random() * 6))+1);
}
return anRolls;
}
function CoinFlips(nNumFlips) {
var anFlips = [];
nNumFlips = DefaultTo(nNumFlips, 1000)
for (var i = 1;i <= nNumFlips; i++) {
anFlips.push(getRndInteger(1,2));
}
return anFlips;
}
function getRndInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1) ) + min;
}

MQL4 CArrayObj how can i set reserve to 0 or avoid it completely?

MQL4 CArrayObj member function At(n) returns zero and member function Total() displays 5 instead of 3 and At(n) returns 0 at index 0-1 and the expect value at 2-4. So my expected data is at 2-4 and the reserve i suspect is at 0-1. How can i stop CArrayObj from reserving space?
I tried setting the CArrayObj member function Reserve to 0, but it is set to ignore 0 as seen in the below
bool CArrayObj::Reserve(const int size){
int new_size;
//--- check
if(size<=0)
return(false);
//--- resize array
if(Available()<size)
{
new_size=m_data_max+m_step_resize*(1+(size-Available())/m_step_resize);
if(new_size<0)
//--- overflow occurred when calculating new_size
return(false);
if((m_data_max=ArrayResize(m_data,new_size))==-1)
m_data_max=ArraySize(m_data);
//--- explicitly zeroize all the loose items in the array
for(int i=m_data_total;i<m_data_max;i++)
m_data[i]=NULL;
}
//--- result
return(Available()>=size);
}
I am expecting the CArrayObj to be 3 only, as i want it to be.

Summation of Perceptron not working properly. Getting large summation

So I have a run method which summates the weights of the edges in the artificial neural network with the threshold values of the input nodes.
Sort of like this:
Now my test perceptron should produce a summation of -3, but I am getting a value of 1176!!! What is going on here?
Here is the code that I have written for my run() method, constructor, and my main method.
Constructor:
public class Perceptron {
//We want to create a variable which will represent the number of weighted edges
//in the 2-dimensional array.
protected int num_weighted_Edges;
//Inside this class we want to create a data field which is a
//2-D array of WeightedEdges. Since the weightedEdges will be in
//double data type, we will create a double type 2-dimensional
//array.
protected WeightedEdge[][] weightedEdges;
protected int[] weights;
//We set a double field named eta equal to 0.05.
protected double eta = 0.05;
//We initialize a constructor which only takes a parameter int n.
public Perceptron(int n){
//We want to create a new graph which will have n + 1 vertices
//, where we also want vertex 0 to act like the output node
//as in a neural network.
this.num_weighted_Edges = n;
weights = new int[num_weighted_Edges];
//First we need to verify that n is a positive real number
if (num_weighted_Edges < 0){
throw new RuntimeException("You cannot have a perceptron of negative value");
}
else {
//Test code for testing if this code works.
System.out.println("A perceptron of " + num_weighted_Edges + " input nodes, and 1 output node was created");
}
//Now we create a graph object with "n" number of vertices.
weightedEdges = new WeightedEdge[num_weighted_Edges + 1][num_weighted_Edges + 1];
//Create a for loop that will iterate the weightedEdges array.
//We want to create the weighted edges from vertex 1 and not vertex 0
//since vertex 0 will be the output node, so we set i = 1.
for (int i = 1; i < weightedEdges.length; i++){
for (int j = 0; j < weightedEdges[i].length; j++){
//This will create a weighted edge in between [1][0]...[2][0]...[3][0]
//The weighted edge will have a random value between -1 and 1 assigned to it.
weightedEdges[i][0] = new WeightedEdge(i, j, 1);
}
}
}
This is my run() method:
//This method will take the input nodes, do a quick verification check on it and
//sum up the weights using the simple threshold function described in class to return
//either a 1 or -1. 1 meaning fire, and -1 not firing.
public int run(int[] weights){
//So this method will act like the summation function. It will take the int parameters
//you put into the parameter field and multiply it times the input nodes in the
//weighted edge 2 d array.
//Setup a summation counter.
int sum = 0;
if (weights.length != num_weighted_Edges){
throw new RuntimeException("Array coming in has to equal the number of input nodes");
}
else {
//We iterate the weights array and use the sum counter to sum up weights.
for (int i = 0; i < weights.length; i++){
//Create a nested for loop which will iterate over the input nodes
for ( int j = 1; j < weightedEdges.length; j++){
for (int k = 0; k < weightedEdges[j].length; k++){
//This takes the weights and multiplies it times the value in the
//input nodes. The sum should equal greater than 0 or less than 0.
sum += (int) ((weightedEdges[j][0].getWeight()) * i);
//Here the plus equals sign takes the product of (weightedEdges[j][0] * i) and
//then adds it to the previous value.
}
}
}
}
System.out.println(sum);
//If the sum is greater than 0, we fire the neuron by returning 1.
if (sum > 0){
//System.out.println(1); test code
return 1;
}
//Else we don't fire and return -1.
else {
//System.out.println(-1); test code
return -1;
}
}
This is my main method:
//Main method which will stimulate the artificial neuron (perceptron, which is the
//simplest type of neuron in an artificial network).
public static void main(String[] args){
//Create a test perceptron with a user defined set number of nodes.
Perceptron perceptron = new Perceptron(7);
//Create a weight object that creates an edge between vertices 1 and 2
//with a weight of 1.5
WeightedEdge weight = new WeightedEdge(1, 2, 1.5);
//These methods work fine.
weight.getStart();
weight.getEnd();
weight.setWeight(2.0);
//Test to see if the run class works. (Previously was giving a null pointer, but
//fixed now)
int[] test_weight_Array = {-1, -1, -1, -1, -1, 1, 1};
//Tested and works to return output of 1 or -1. Also catches exceptions.
perceptron.run(test_weight_Array);
//Testing a 2-d array to see if the train method works.
int[][] test_train_Array = {{1}, {-1}, {1}, {1}, {1}, {1}, {1}, {1}};
//Works and catches exceptions.
perceptron.train(test_train_Array);
}
}
I think you should change
sum += (int) ((weightedEdges[j][0].getWeight()) * i);
to
sum += (int) ((weightedEdges[j][k].getWeight()) * i);

Resources