Flux<Long> flux1 = Flux
.<Long>create(fluxSink -> {
for (long i = 0; i < 20; i++) {
fluxSink.next(i);
}
})
.filter(aLong -> aLong % 2 == 0)
.doOnNext(aLong -> System.out.println("flux 1 : " + aLong));
Flux<Long> flux2 = Flux
.<Long>create(fluxSink -> {
for (long i = 0; i < 20; i++) {
fluxSink.next(i);
}
})
.filter(aLong -> aLong % 2 == 1)
.doOnNext(aLong -> System.out.println("flux 2 : " + aLong));
Flux.merge(flux1, flux2)
.doOnNext(System.out::println)
.then()
.block();
Create two Flux<Long> like upper code.
flux1 create even number stream (0,2,4,6,8 ...)
flux2 create odd number stream (1,3,5,7,9 ...)
i expected when merge this 2 flux1 and flux2 work like
0,1,2,3,4 ... or 0,2,1,3,4.. depends on computing power
but always spend flux1 and spend flux2 (flux1 start)0,2,4,6,8, ... 16,18,(flux1 end)(flux2 start)1,3,5,7 ... 17,19
how to subscribe multiple flux eagerly event?
Both streams run on the same thread. When you subscribe flux1 starts pushing data until it's finished. Only then the thread is free for flux2 to continue. The merge operator emits values in the order they arrive. It doesn't switch between the first and the second stream.
If you want the streams run concurrently you need to run them on different threads, e.g. by using the publishOn operator.
Flux<Long> flux1 = Flux
.<Long>create(fluxSink -> {
for (long i = 0; i < 20; i++) {
fluxSink.next(i);
}
})
.publishOn(Schedulers.newSingle("thread-x")
.filter(aLong -> aLong % 2 == 0)
.doOnNext(aLong -> System.out.println("flux 1 : " + aLong));
Related
I am trying to find the distance of a node from the root of a binary tree but I am getting right answer up to only 3 branches only. like for the node(4) I am getting 3 and for the node (9) and node(10) I am getting 3
#include<bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node *left;
struct node *right;
node(int val)
{
data = val;
left = NULL;
right = NULL;
}
};
int find_node(node* root,int n)
{
static int length=1;
if (root== NULL)
{
return 0;
}
if (root->data==n)
{
return length;
}
length=length+(find_node(root->left,n)||find_node(root->right,n));
// find_node(root->left,n);
// find_node(root->right,n);
return length;
}
int main ()
{
struct node* root = new node(1);
root->left = new node(2);
root->right = new node(3);
root->left->left = new node(4);
root->left->right = new node(5);
root->right->left = new node(6);
root->right->right = new node(7);
root->right->right->right = new node(9);
root->right->right->right->right = new node(10);
cout <<find_node(root,10);
return 0;}
When your code reaches the first leaf node (with data 4), the following assignment will assign 1:
length=length+(find_node(root->left,n)||find_node(root->right,n));
Because the expression resolves to 1+(0||0), i.e. 1. And so 1 is returned.
The caller (at the node with data 2) will thus receive this 1, and so the above statement will yield 2, since it resolves to 1+(1||......), which is 2 -- the second operand of || is not evaluated.
The parent caller (at the node with data 1), will thus receive this 2. The assignment there resolves to 1+(2||.....), which is again 2 -- realise that || is a logical operator, so it can only evaluate to a boolean value (i.e. 0 or 1).
The issues
In summmary:
You should not use || as it can only evaluate to 0 or 1, losing the actual value from recursion that you need.
You should not use a static variable. For one, it would not reset if you would make a second call to this function from the main program code. Instead, every recursive call should just "mind its own business" and return the depth of n from the given root. The caller should add 1 to that if n was found.
Correction
int find_node(node* root, int n)
{
if (root == NULL)
{
return 0;
}
if (root->data == n)
{
return 1;
}
int length = find_node(root->left, n);
if (!length)
{
length = find_node(root->right, n);
}
if (!length)
{
return 0;
}
return 1 + length;
}
I have a spreadsheet that I use to keep track of climbing progress (snippet shown below). I have formulas and graphs that keep track of counts of specific grades over time, but I am having trouble with a formula to keep a running total (by year) of feet climbed. I intent to put this in another sheet.
Basically I would like a single cell that does something like ... if Sheet1!A:A begins with "21." and if Sheet1!E:E,"<>*%" (which means I actually completed the climb) then add the rows total climb length (Sheet1!J:J * Sheet1!I:I) to the running total for that year.
What is the best way to do this?
You can try using Apps Script and creating a script in order to manage your task.
So for example, you might want to take a look at the snippet below:
Code
function calculateTotal() {
let ss = SpreadsheetApp.getActive().getSheetByName('Sheet1');
let date = ss.getRange('A2:A').getDisplayValues();
let tries = ss.getRange('E2:E').getDisplayValues();
let lengths = ss.getRange('I2:I').getDisplayValues();
let total = 0;
for (let i =0; i<date.length; i++) {
if (date[i][0].toString().startsWith('21') != false && tries[i][0].toString().includes('%') == false) {
total = total+lengths[i][0];
}
}
ss.getRange('M2').setValue(total);
}
Explanation
The script above gathers all the values from the Sheet1 and loops through them. If the conditions check (the date should start with 21 and the E column does not contain %) then the corresponding length is added to the total; the total is then saved in the M2 cell in this case.
Further improvement
The advantage of using a script is that it is versatile and easier to manage. In this situation, you can make use of Apps Script's time-driven triggers; so assuming you plan on updating your spreadsheet every day at a specific time, you can create a trigger which will run right after it.
For example, the below function creates a trigger for the function above which will run every day at ~9.
function createTrigger() {
ScriptApp.newTrigger("calculateTotal")
.timeBased()
.atHour(9)
.everyDays(1)
.create();
}
Reference
Google Apps Script;
Apps Script Installable Triggers.
Thanks Ale13 ... using your example and adding a couple of things (also needed to parseInt totals) ...
function calculateTotal() {
let ss = SpreadsheetApp.getActive().getSheetByName('Sheet1');
let s7 = SpreadsheetApp.getActive().getSheetByName('Sheet7');
let date = ss.getRange('A2:A').getDisplayValues();
let type = ss.getRange('F2:F').getDisplayValues();
let tries = ss.getRange('E2:E').getDisplayValues();
let lengths = ss.getRange('I2:I').getDisplayValues();
let laps = ss.getRange('J2:J').getDisplayValues();
let btotal = 0;
let rtotal = 0;
for (let i =0; i<date.length; i++) {
if (date[i][0].toString().startsWith('21') != false && tries[i][0].toString().includes('%') == false) {
// Totals for Bouldering
if (type[i][0] == "B") {
btotal = btotal + parseInt(lengths[i][0]*laps[i][0]);
}
// Totals for Top Rope or Sport
else {
rtotal = rtotal + parseInt(lengths[i][0]*laps[i][0])
}
}
}
console.log("Roped total = " + rtotal)
console.log("Bouldering total = " + btotal)
s7.getRange('B2').setValue(rtotal);
s7.getRange('B3').setValue(btotal);
}
Having the following problem: given a list of events that have a partitionId property (0-10 for example), I'd like incoming events to be split according to the paritionId so that events with same partitionId are handled in order they're received.
With more or less even distribution, that would lead to 10 events (for each partition) being handled in parallel.
Besides creating 10 single-threaded dispatchers and sending the event to the right dispatcher, is there a way to accomplish the above using Project Reactor ?
Thanks.
The code below
splits source stream into partitions,
creates ParallelFlux, one "rail" per partition,
schedules "rails" into separate threads,
collects the results
Having dedicated thread for each partition guaranties its values are processed in original order.
#Test
public void partitioning() throws InterruptedException {
final int N = 10;
Flux<Integer> source = Flux.range(1, 10000).share();
// partition source into publishers
Publisher<Integer>[] publishers = new Publisher[N];
for (int i = 0; i < N; i++) {
final int idx = i;
publishers[idx] = source.filter(v -> v % N == idx);
}
// create ParallelFlux each 'rail' containing single partition
ParallelFlux.from(publishers)
// schedule partitions into different threads
.runOn(Schedulers.newParallel("proc", N))
// process each partition in its own thread, i.e. in order
.map(it -> {
String threadName = Thread.currentThread().getName();
Assert.assertEquals("proc-" + (it % 10 + 1), threadName);
return it;
})
// collect results on single 'rail'
.sequential()
// and on single thread called 'subscriber-1'
.publishOn(Schedulers.newSingle("subscriber"))
.subscribe(it -> {
String threadName = Thread.currentThread().getName();
Assert.assertEquals("subscriber-1", threadName);
});
Thread.sleep(1000);
}
I've got a tree structure.
The task is to find the biggest sum/weight of path nodes, but i can only move n times. Thats ok, but going "up"/"back" cost nothing.
How can i accomplish that?
Below is my code, but the problem is that the each node can only be accessed once, so it doesnt work.
int mSum(Node* node, int mvLeft) {
if (node == nullptr) { return 0; }
if (mvLeft == 0) { return node->value; }
mvLeft--;
int sum = max(mSum(node->left, mvLeft), mSum(node->right, mvLeft));
return node->value + max(sum, mSum(node->parent, mvLeft + 1));
}
Here is the example graph. The numbers on the nodes represent the cost of getting to it. Each node can be visited only once except going "back".
The n step limit here is 3, we're counting entering the graph too, so the proper result is 21 because: 2->8->11.
If we would have limit of 4 steps the result would be 31: 2->10->8->11
My friend tried to do it with DFS, is he right? What's the best algorithm?
Good answer is taking multiple routes at the same time.
I mean we could go with 2-length limit:
2 left 0 right
1 left 1 right
0 left 2 right
Working, but somewhat slow, code :)
Its working time is 28s while other solutions can go with 2s (10 not known tests)
int mSum(Node* node, int mvLeft) {
mvLeft--;
if (mvLeft < 0) {
return 0;
}
else if (mvLeft == 0) {
return node->value;
}
if (node->left != nullptr && node->right != nullptr) {
int max = 0;
for (int i = 0; i <= mvLeft; i++) {
max = Max(max, mSum(node->left, i) + mSum(node->right, mvLeft - i));
}
return max + node->value;
}
else if (node->left != nullptr) {
return mSum(node->left, mvLeft) + node->value;
}
else if (node->right != nullptr) {
return mSum(node->right, mvLeft) + node->value;
}
return node->value;
}
I was solving a problem in which given a linked list of characters , we have to move the vowels to the beginning such that both vowels and consonants are in chronological order. That is in the order in which they appear in original list.
Input : S->T->A->C->K->O->V->E->R->F->L->O->W
Output : A->O->E->O->S->T->C->K->V->R->F->L->W
I did it by traversing through the list once and created two lists called vowels and consonants and later merged them.
Can it be done without creating extra lists ? I mean in-place maybe using pointer manipulation?
Remember the beginning of the list. When you meet a vowel, move it to the beginning of the list; the vowel becomes the new beginning that you remember.
1. Traverse the list
2. When you encounter a vowel, check with head if its smaller or greater
3. If smaller, re-place new vowel before head, else move head and check again
4. In the end relocate head to first
temp = head;
while(current.next != null) {
if(current.isVowel()) {
if(head.isVowel()) {
//check the precedence
//Re-place the current with temp
}
else {
//Re-place current in front of head
}
}
current = current.next;
}
This is an abstract understanding. Implement it properly.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
struct list {
struct list *next;
int ch;
};
#define IS_VOWEL(p) strchr("aeiouy", tolower(p->ch))
struct list *shuffle ( struct list *lst )
{
struct list *new=NULL, **dst, **src;
dst = &new;
for (src = &lst; *src; ) {
struct list *this;
this= *src;
if (!IS_VOWEL(this)) { src= &(*src)->next; continue; }
*src = this->next;
this->next = *dst;
*dst = this;
dst = & (*dst)->next;
}
*dst = lst;
return new;
}
int main (void)
{
struct list arr[] = { {arr+1, 'S'} , {arr+2, 'T'} , {arr+3, 'A'}
, {arr+4, 'C'} , {arr+5, 'K'} , {arr+6, 'O'}
, {arr+7, 'V'} , {arr+8, 'E'} , {arr+9, 'R'}
, {arr+10, 'F'} , {arr+11, 'L'} , {arr+12, 'O'} , {NULL, 'W'} };
struct list *result;
result = shuffle (arr);
for ( ; result; result = result->next ) {
printf( "-> %c" , result->ch );
}
printf( "\n" );
return 0;
}
OUTPUT:
-> A-> O-> E-> O-> S-> T-> C-> K-> V-> R-> F-> L-> W
You can quite easily modify pointers to create two independent lists without actually having to duplicate any of the nodes, which is what I assume you mean when you say you want to avoid creating new lists. Only the pointers in the original nodes are modified.
First let's create the structures for the list:
#include <stdio.h>
#include <stdlib.h>
// Structure for singly linked list.
typedef struct sNode {
char ch;
struct sNode *next;
} tNode;
And next we provide two utility functions, the first to append a character to the list:
// Append to list, not very efficient but debug code anyway.
static tNode *append (tNode *head, char ch) {
// Allocate new node and populate it.
tNode *next = malloc (sizeof (tNode));
if (next == NULL) {
puts ("Out of memory");
exit (1);
}
next->ch = ch;
next->next = NULL;
// First in list, just return it.
if (head == NULL)
return next;
// Else get last, adjust pointer and return head.
tNode *this = head;
while (this->next != NULL)
this = this->next;
this->next = next;
return head;
}
And the second to dump a list for debugging purposes:
// Debug code to dump a list.
static void dump (tNode *this) {
if (this == NULL)
return;
printf ("(%08x)%c", this, this->ch);
while ((this = this->next) != NULL)
printf (" -> (%08x)%c", this, this->ch);
putchar ('\n');
}
Beyond that, we need an easy way to tell if a node is a vowel or not. For our purposes, we'll only use uppercase letters:
// Check for vowel (uppercase only here).
static int isVowel (tNode *this) {
char ch = this->ch;
return (ch == 'A') || (ch == 'E') || (ch == 'I')
|| (ch == 'O') || (ch == 'U');
}
Now this is the important bit, the bit that turns the single list into two distinct lists (one vowel, one consonant). Which list is which type depends on what the first entry in the list is.
What is basically does is to create a sub-list out of all the common nodes at the start of the list ("ST" in this case), another sub-list of the next non-matching type ("A"), and then starts processing the remaining nodes one by one, starting with "C".
As each subsequent node is examined, the pointers are adjusted to add it to either the first or second list (again, without actually creating new nodes). Once we reach the NULL at then end of the list, we then decide whether to append the second list to the first, or vice versa (vowels have to come first).
The code for all this pointer manipulation is shown below:
// Meat of the solution, reorganise the list.
static tNode *regroup (tNode *this) {
// No reorg on empty list.
if (this == NULL)
return this;
// Find first/last of type 1 (matches head), first of type 2.
tNode *firstTyp1 = this, *firstTyp2 = this, *lastTyp1 = this, *lastTyp2;
while ((firstTyp2 != NULL) && (isVowel (firstTyp1) == isVowel (firstTyp2 ))) {
lastTyp1 = firstTyp2;
firstTyp2 = firstTyp2->next;
}
// No type 2 means only one type, return list as is.
if (firstTyp2 == NULL)
return firstTyp1;
// Type 2 list has one entry, next node after that is for checking.
lastTyp2 = firstTyp2;
this = firstTyp2->next;
//dump (firstTyp1);
//dump (firstTyp2);
//putchar ('\n');
// Process nodes until list is exhausted.
while (this != NULL) {
// Adjust pointers to add to correct list.
if (isVowel (this) == isVowel (lastTyp1)) {
lastTyp2->next = this->next;
lastTyp1->next = this;
lastTyp1 = this;
} else {
lastTyp1->next = this->next;
lastTyp2->next = this;
lastTyp2 = this;
}
// Advance to next node.
this = this->next;
//dump (firstTyp1);
//dump (firstTyp2);
//putchar ('\n');
}
// Attach last of one list to first of the other,
// depending on which is the vowel list.
if (isVowel (firstTyp1)) {
lastTyp1->next = firstTyp2;
return firstTyp1;
}
lastTyp2->next = firstTyp1;
return firstTyp2;
}
And, finally, no complex program would be complete without a test harness of some description, so here it is, something to create and dump the list in its initial form, then reorganise it and dump the result:
int main (void) {
char *str = "STACKOVERFLOW";
tNode *list = NULL;
while (*str != '\0')
list = append (list, *(str++));
dump (list);
puts("");
list = regroup (list);
dump (list);
return 0;
}
Upon entering, compiling and running all that code, the results are as expected:
(09c03008)S -> (09c03018)T -> (09c03028)A -> (09c03038)C ->
(09c03048)K -> (09c03058)O -> (09c03068)V -> (09c03078)E ->
(09c03088)R -> (09c03098)F -> (09c030a8)L -> (09c030b8)O ->
(09c030c8)W
(09c03028)A -> (09c03058)O -> (09c03078)E -> (09c030b8)O ->
(09c03008)S -> (09c03018)T -> (09c03038)C -> (09c03048)K ->
(09c03068)V -> (09c03088)R -> (09c03098)F -> (09c030a8)L ->
(09c030c8)W
In case that's hard to read, I'll get rid of the pointers and just list the characters in order:
S -> T -> A -> C -> K -> O -> V -> E -> R -> F -> L -> O -> W
A -> O -> E -> O -> S -> T -> C -> K -> V -> R -> F -> L -> W