Algorithm to count occurance in a consecutive amount of time - arrays

I have a set of data that that tells me the on/off status of a component as a function of time. The data looks like this :
0 1
120 1
240 0
360 0
480 1
600 1
720 1
840 0
960 0
1080 0
1200 1
1320 1
1440 0
1560 0
1680 1
1800 0
1920 1
First column shows the time in second and the second column shows the status (1 is on, 0 is off).
I need to know the what is the 600 seconds with the most 1 in it. For example, 0-600 has 3*120 s so 360 seconds where component is on. But 120-720 has 4 etc... This means that this is not only 0-600, 600-1200, it can by any 600 seconds. The hard thing is that this is a cycle, meaning that the worst hour could be from 1920 to 480 (Note that this cycle has 2040s meaning time 2040 is also time 0). The time steps are not always equal. In this case it is a constant 120s, but it could be a mix of 120s and 150s for example.
The only thing I can think of is to scan the file from 0-600, check time is was on, 120-720, 240-840 etc... but it is very time consuming. Especially since I can have very big files.
The program is in Perl, but I only need the algorithm (if it exists). Do any of you has an idea on what would be the best approach?
Thank you

It isn't quite clear what value you're trying to calculate, but your core problem appears to be finding an algorithm for getting the samples in each sliding 600s window. The sliding window can be implemented as an array. Add new samples to the end and purge old samples to keep the total size <= 600s. The only tricky part is accounting for the time values being modulo 2040.
use strict;
use warnings;
use Data::Dump qw(pp);
my #window;
while (my $line = <DATA>) {
chomp $line;
my ($t, $on) = split / +/, $line;
# add sample to sliding window
push #window, { t => $t, on => $on};
# limit window size to 600s
while (1) {
last if #window <= 1;
my $start = $window[0]{t};
my $stop = $window[-1]{t};
# account for time values being mod 2040
if ($stop < $start) {
$stop += 2040;
}
if ($stop - $start > 600) {
# purge old sample from window
shift #window;
}
else {
last;
}
}
# do something with #window
pp \#window;
}
__DATA__
0 1
120 1
240 0
360 0
480 1
600 1
720 1
840 0
960 0
1080 0
1200 1
1320 1
1440 0
1560 0
1680 1
1800 0
1920 1
0 1
120 1
240 0
360 0
The values in #window look like this:
# no wrapping
[
{ on => 1, t => 0 },
{ on => 1, t => 120 },
{ on => 0, t => 240 },
{ on => 0, t => 360 },
{ on => 1, t => 480 },
{ on => 1, t => 600 },
]
# with wrapping
[
{ on => 0, t => 1560 },
{ on => 1, t => 1680 },
{ on => 0, t => 1800 },
{ on => 1, t => 1920 },
{ on => 1, t => 0 },
{ on => 1, t => 120 },
]

The problem may be solved in the following manner.
Define an integer n; Keep adding the ones to n until a zero occurs. That is, if a zero occurs set n to zero. In the process record the maximum n occurrence and the seconds at that time. To do this define another variable m and let m be the max value. Now if n becomes greater than m then m=n. In this way you can get near the 600s interval containing maximum number of 1s. Good luck. I hope, it worked.

Assuming that points are sorted by time, you can keep buffer of consecutive points in a way that time difference between first point and last point do not exceed 600. Here is the code in C#:
// Class for data point
class Point {
public int Time { get; private set; }
public bool On { get; private set; }
public Point(int time, bool on) {
Time = time;
On = on;
}
}
Point[] points = {
new Point(0, true),
new Point(120, true),
new Point(240, false),
new Point(360, false),
new Point(480, true),
new Point(600, true),
new Point(720, true),
new Point(840, false),
new Point(960, false),
new Point(1080, false),
new Point(1200, true),
new Point(1320, true),
new Point(1440, false),
new Point(1560, false),
new Point(1680, true),
new Point(1800, false),
new Point(1920, true),
};
int GetMaxIntervalCount(IEnumerable<Point> points) {
LinkedList<Point> buff = new LinkedList<Point>();
int buffCount = 0, res = -1;
foreach (Point point in points) {
buff.AddFirst(point);
while (buff.Count > 0) {
Point last = buff.Last.Value;
if (Math.Abs(last.Time - point.Time) > 600) {
buff.RemoveLast();
if (last.On) {
--buffCount;
}
} else {
break;
}
}
if (point.On) {
++buffCount;
}
res = Math.Max(res, buffCount);
}
return res;
}
Currently it returns only maximum count, but it can be easily adjusted to also keep actual buffer. Time complexity of a method is O(N) (each point will be
"touched" at most 2 times - on adding and deleting from buffer).

Related

Please tell me how to fill in the fields in the list that lies on the map

I have a map
Map<Id, List<ExpenseController.MonthRow>> monthsPerKeeper = new Map<Id, List<ExpenseController.MonthRow>>();
This is how she looks:
Right now I'm only showing the months ("monthNumber") that are full.
I need to fill in all the missing ("monthNumber") and the ("amount") field for that ("monthNumber") should be 0.
It should look like this:
I tried to get the value from the map by id (that is, the List)
but I don't know how to refer to the fields in this List to fill them in
for (Id c : monthsPerKeeper.keySet()) {
if(monthsPerKeeper.containsKey(c)) {
for (ExpenseController.MonthRow a : monthsPerKeeper.get(c)) {
List<ExpenseController.MonthRow> monthsListAdd = new List<ExpenseController.MonthRow>();
for (Integer i = 1; i < 13; i++) {
if (!monthsPerKeeper.get(c).monthNumber.containsKey(i)) {
ExpenseController.MonthRow row = new ExpenseController.MonthRow();
row.monthName = ExpenseController.monthNumbers.get(i);
row.amount = 0;
row.monthNumber = i;
monthsListAdd.add(row);
}
}
}
}
}
so you have monthsListAdd with say 5 dummy months and want to add it to the original list of 7 real months? Many ways to do it, seeing how your screenshot list is unsorted and really the gaps (no expenses this month) can be anywhere... I'd probably reverse the whole thing, start with 12 placeholders with 0 amounts and just update them as I go through list...
Anyway:
After that for (ExpenseController.MonthRow a : monthsPerKeeper.get(c)) { ends add this:
monthsPerKeeper.get(c).addAll(monthsListAdd);
I stil think you'll have this in rubbish order so maybe read up about "implements Comparable" to sort your list of helper objects after they're all added up?
edit
To make it cleaner I'd use a Map where key is month number and value is... well, if all you need is Amount then probably Map<Integer,Decimal> would do. If you'd want to display more - Map<Integer, ExpenseController.MonthRow> probably. Or you know, use the fact that List could have month numbers as indexes ;)
Consider this query (works in my sandbox and returns me something but with gaps. And that's OK)
SELECT CALENDAR_MONTH(CloseDate), SUM(Amount)
FROM Opportunity
WHERE CloseDate = THIS_YEAR AND IsWon = true AND Owner.Profile.Name = 'System Administrator' AND Amount != null
GROUP BY CALENDAR_MONTH(CloseDate)
It's not even sorted - but I don't care.
Map<Integer, Decimal> myMap = new Map<Integer, Decimal>{
1 => 0,
2 => 0,
3 => 0,
4 => 0,
5 => 0,
6 => 0,
7 => 0,
8 => 0,
9 => 0,
10 => 0,
11 => 0,
12 => 0
};
for(AggregateResult ar : [SELECT CALENDAR_MONTH(CloseDate) m, SUM(Amount) a
FROM Opportunity
WHERE CloseDate = THIS_YEAR AND IsWon = true AND Owner.Profile.Name = 'System Administrator' AND Amount != null
GROUP BY CALENDAR_MONTH(CloseDate)]){
myMap.put((Integer) ar.get('m'), (Decimal) ar.get('a'));
}
for(Integer i = 1; i < 13; ++i){
System.debug(i + ' ' + DateTime.newInstance(2022,i,1).format('MMMM') + ': ' + myMap.get(i));
// instead of debug you'd have your someList.add(new ExpenseController.MonthRow(...) or whatever
}

CakePHP count() return wrong results?

CakePHP 3.6.14
This code reproduce wrong number:
$where = [
'Postings.source' => $source,
'Postings.approved' => 1,
'Postings.deleted' => 0,
'Postings.disabled' => 0
];
if ($source !== null) {
$where['Postings.created >='] = '(NOW() - INTERVAL 3 DAY)';
}
$count = $this->Postings
->find()
->where($where)
->count();
debug($count); exit;
// 77568 total of all records
########## DEBUG ##########
[
'Postings.source' => 'xzy',
'Postings.approved' => (int) 1,
'Postings.deleted' => (int) 0,
'Postings.disabled' => (int) 0,
'Postings.created >=' => '(NOW() - INTERVAL 3 DAY)'
]
//SQL produced by this query:
SELECT (COUNT(*)) AS `count`
FROM postings Postings
WHERE (
Postings.source = 'xzy'
AND Postings.approved = 1
AND Postings.deleted = 0
AND Postings.disabled = 0
AND Postings.created >= '(NOW() - INTERVAL 3 DAY)' // <<<< with quotes
)
but raw sql query:
SELECT COUNT(*) as `count
FROM `postings`
WHERE `source` = 'xzy'
AND `approved` = 1
AND `deleted` = 0
AND `disabled` = 0
AND `created` >= (NOW() - INTERVAL 3 DAY) // <<< without quotes
// return correct num 2119
How to fix?
Values on the right hand side of a key => value condition are always subject to binding/casting/escaping, unless it's an expression object. Look at the generated query, your SQL snippet will end up as a string literal, ie:
created >= '(NOW() - INTERVAL 3 DAY)'
Long story short, use an expression, either a raw one:
$where['Postings.created >='] = $this->Postings->query()->newExpr('NOW() - INTERVAL 3 DAY');
or use the functions builder:
$builder = $this->Postings->query()->func();
$where['Postings.created >='] = $builder->dateAdd($builder->now(), -3, 'DAY');
See also
Cookbook > Database Access & ORM > Query Builder > Advanced Conditions
Cookbook > Database Access & ORM > Query Builder > Using SQL Functions
You should use Query builder and add to select method count function.
Everything is described here: https://book.cakephp.org/3.0/en/orm/query-builder.html#using-sql-functions

Bad SQL query Disk full (/tmp/#sql_58f_0); waiting for someone to free some space

I have Presta, and I like it but..
Now I get this strange error:
Bad SQL query Disk full (/tmp/#sql_58f_0); waiting for someone to free
some space...
I googled a lot, but did not find any solution.
After I added EAN codes in my products field, my shop shows:
No featured products at this time.
Prior to this all seemed to look fine.
I restored an old backup (from 2 months ago) and noticed that it already did had the same SQL error and after I added one EAN code, I see the same no featured products.
Not sure if the restore placed the shop back in 100 old condition, but with ean code's I have a total non working shop.
Even removing them dos not solve my problem.
I turned on debugging and received this as result:
{PrestaShopDatabaseException]
Disk full (/tmp/#sql_58f_0); waiting for someone to free some space...
SELECT
a.`id_category`, `name`, `description`, sa.`position` AS `position`, `active`
, sa.position position
FROM `ps_category` a
LEFT JOIN `ps_category_lang` b ON (b.`id_category` = a.`id_category` AND b.`id_lang` = 1 AND b.`id_shop` = 1)
LEFT JOIN `ps_category_shop` sa ON (a.`id_category` = sa.`id_category` AND sa.id_shop = 1)
WHERE 1 AND `id_parent` = 2
ORDER BY sa.`position` ASC LIMIT 0, 50
at line 791 in file classes/db/Db.php:
786. if ($webservice_call && $errno) {
787. $dbg = debug_backtrace();
788. WebserviceRequest::getInstance()->setError(500, '[SQL Error] '.$this->getMsgError().'. From '.(isset($dbg[3]['class']) ? $dbg[3]['class'] : '').'->'.$dbg[3]['function'].'() Query was : '.$sql, 97);
789. } elseif (_PS_DEBUG_SQL_ && $errno && !defined('PS_INSTALLATION_IN_PROGRESS')) {
790. if ($sql) {
**791. throw new PrestaShopDatabaseException($this->getMsgError().'<br /><br /><pre>'.$sql.'</pre>');**
792. }
793.
794. throw new PrestaShopDatabaseException($this->getMsgError());
795. }
796. }
DbCore->displayError - [line 425 - classes/db/Db.php] - [1 Arguments]
420. $this->result = $this->_query($sql);
421. }
422. }
423.
424. if (_PS_DEBUG_SQL_) {
**425. $this->displayError($sql);**
426. }
427.
428. return $this->result;
429. }
430.
DbCore->query - [line 643 - classes/db/Db.php] - [1 Arguments]
Argument [0]
SELECT
a.`id_category`, `name`, `description`, sa.`position` AS `position`, `active`
, sa.position position
FROM `ps_category` a
LEFT JOIN `ps_category_lang` b ON (b.`id_category` = a.`id_category` AND b.`id_lang` = 1 AND b.`id_shop` = 1)
LEFT JOIN `ps_category_shop` sa ON (a.`id_category` = sa.`id_category` AND sa.id_shop = 1)
WHERE 1 AND `id_parent` = 2
ORDER BY sa.`position` ASC LIMIT 0, 50
DbCore->executeS - [line 3212 - classes/controller/AdminController.php] - [3 Arguments]
3207. '.($this->_tmpTableFilter ? ' * FROM (SELECT ' : '').$this->_listsql.$sql_from.$sql_join.' WHERE 1 '.$sql_where.
3208. $sql_order_by.$sql_limit;
3209. $list_count = 'SELECT COUNT(*) AS `'._DB_PREFIX_.$this->table.'` '.$sql_from.$sql_join.' WHERE 1 '.$sql_where;
3210. }
3211.
**3212. $this->_list = Db::getInstance()->executeS($this->_listsql, true, false);**
3213.
3214. if ($this->_list === false) {
3215. $this->_list_error = Db::getInstance()->getMsgError();
3216. break;
3217. }
AdminControllerCore->getList - [line 253 - controllers/admin/AdminCategoriesController.php] - [6 Arguments]
248. return parent::renderList();
249. }
250.
251. public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
252. {
**253. parent::getList($id_lang, $order_by, $order_way, $start, $limit, Context::getContext()->shop->id);**
254. // Check each row to see if there are combinations and get the correct action in consequence
255.
256. $nb_items = count($this->_list);
257. for ($i = 0; $i < $nb_items; $i++) {
258. $item = &$this->_list[$i];
AdminCategoriesControllerCore->getList - [line 2333 - classes/controller/AdminController.php] - [1 Arguments]
Argument [0]
1
AdminControllerCore->renderList - [line 248 - controllers/admin/AdminCategoriesController.php]
243. $this->tpl_list_vars['delete_category'] = true;
244. $this->tpl_list_vars['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
245. $this->tpl_list_vars['POST'] = $_POST;
246. }
247.
**248. return parent::renderList();**
249. }
250.
251. public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
252. {
253. parent::getList($id_lang, $order_by, $order_way, $start, $limit, Context::getContext()->shop->id);
AdminCategoriesControllerCore->renderList - [line 2034 - classes/controller/AdminController.php]
2029. } elseif ($this->display == 'details') {
2030. $this->content .= $this->renderDetails();
2031. } elseif (!$this->ajax) {
2032. $this->content .= $this->renderModulesList();
2033. $this->content .= $this->renderKpis();
**2034. $this->content .= $this->renderList();**
2035. $this->content .= $this->renderOptions();
2036.
2037. // if we have to display the required fields form
2038. if ($this->required_database) {
2039. $this->content .= $this->displayRequiredFields();
AdminControllerCore->initContent - [line 199 - controllers/admin/AdminCategoriesController.php]
194. 'url_delete' => htmlentities($_SERVER['REQUEST_URI']),
195. 'boxes' => $this->boxes,
196. ));
197. }
198.
**199. parent::initContent();**
200. }
201.
202. public function setMedia()
203. {
204. parent::setMedia();
AdminCategoriesControllerCore->initContent - [line 189 - classes/controller/Controller.php]
184. if (!$this->content_only && ($this->display_header || (isset($this->className) && $this->className))) {
185. $this->initHeader();
186. }
187.
188. if ($this->viewAccess()) {
**189. $this->initContent();**
190. } else {
191. $this->errors[] = Tools::displayError('Access denied.');
192. }
193.
194. if (!$this->content_only && ($this->display_footer || (isset($this->className) && $this->className))) {
ControllerCore->run - [line 367 - classes/Dispatcher.php]
362. if (isset($params_hook_action_dispatcher)) {
363. Hook::exec('actionDispatcher', $params_hook_action_dispatcher);
364. }
365.
366. // Running controller
**367. $controller->run();**
368. } catch (PrestaShopException $e) {
369. $e->displayMessage();
370. }
371. }
372.
DispatcherCore->dispatch - [line 58 - admin/index.php]
53. if (!isset($_REQUEST['controller']) && isset($_REQUEST['tab'])) {
54. $_REQUEST['controller'] = strtolower($_REQUEST['tab']);
55. }
56.
57. // Prepare and trigger admin dispatcher
**58. Dispatcher::getInstance()->dispatch();**
Google isn't much help.
Have you seen this before, and how can I (or someone else) fix this?
Thank you for feedback!
p.s. the domain is Giantjeans.com
It seems that in your web hosting the disk space (in this case the database size) is less or the SQL-server is having too many requests to the database at the same time.
Because of which Prestashop is not able to write the data. In order to fix the issues, you need to check the server error to know the exact reason.
It is recommended that you upgrade your server and get some more free space.

Perl, grouping Array of Array element based on one column and condition

I have an AoA construct with four columns and many rows. Following is an example of data (input).
DQ556929 103480190 103480214 154943
DQ540839 103325247 103325275 2484
DQ566549 103322763 103322792 99
DQ699634 103322664 103322694 0
DQ544472 103322664 103322692 373
DQ709105 103322291 103322318 46
DQ705937 103322245 103322273 486
DQ699398 103321759 103321788 1211
DQ710151 103320548 103320577 692251
DQ548430 102628297 102628326 1
DQ558403 102628296 102628321 855795
DQ692476 101772501 101772529 481463
DQ544274 101291038 101291068 484047
DQ723982 100806991 100807020 1
DQ709023 100806990 100807020 3
DQ712307 100806987 100807014 0
DQ709654 100806987 100807012 571051
DQ707370 100235936 100235962 1481849
I want to group and write into a file all the row elements (sequentially).
Conditions are if column four values less than 1000 and minimum two values are next to each other, group them else if the value less than 1000 and lies between the values more than 1000 treat them as single and append separately in the same file and the values which are more than 1000 also write as a block but with out affecting the order of the 2nd and third column.
This file is output of my previous program, now for this I have tried implementing my hands but getting some weird results. Here is my chunk of code, but non functional. Guys I need just help if i am executing my logic well here, I am open for any comments as a beginner. And also correct me anywhere.
my #dataf= sort{ $a->[1]<=> $b->[1]} #data;
#dataf=reverse #dataf;
for(my $i>=0;$i<=$#Start;$i++)
{
print "$sortStart[$i]\n";
my $diff = $sortStart[$i] - $sortStart[$i+1];
$dataf[$i][3]= $diff;
# $IDdiff{$ID[$i]}=$diff;
}
#print Dumper(#dataf);
open (CLUST, ">> ./clustTest.txt" );
for (my $k=0;$k<=$#Start;$k++)
{
for (my $l=0;$l<=3;$l++)
{
# my $tempdataf = shift $dataf[$k][$l];
# print $tempdataf;
if ($dataf[$k][3]<=1000)
{
$flag = 1;
do
{
print CLUST"----- Cluster $clustNo -----\n";
print CLUST"$dataf[$k][$l]\t";
if ($dataf[$k][3]<=1000)
{
$flag1 = 1;
}else {$flag1=0;}
$clustNo++;
}until($flag1==0 && $data[$k][3] > 1000);
if($flag1==0 && $data[$k][3] > 1000)
{
print CLUST"Singlet \n";
print CLUST"$dataf[$k][$l]\t";
next;
}
#print CLUST"$dataf[$k][$l]\t"; ##IDdiff
}
print CLUST"\n";
}
}
Expected output in file:
Singlets
DQ556929 103480190 103480214 154943
DQ540839 103325247 103325275 2484
Cluster1
DQ566549 103322763 103322792 99
DQ699634 103322664 103322694 0
DQ544472 103322664 103322692 373
DQ709105 103322291 103322318 46
DQ705937 103322245 103322273 486
Singlets
DQ699398 103321759 103321788 1211
DQ710151 103320548 103320577 692251
DQ548430 102628297 102628326 1
DQ558403 102628296 102628321 855795
DQ692476 101772501 101772529 481463
DQ544274 101291038 101291068 484047
Cluster2
DQ723982 100806991 100807020 1
DQ709023 100806990 100807020 3
DQ712307 100806987 100807014 0
Singlets
DQ709654 100806987 100807012 571051
DQ707370 100235936 100235962 1481849
This seems to produce the expected output. I'm not sure I understood the specification correctly, so there might be errors and edge cases.
How it works: it remembers what kind of section it's currently outputting ($section, Singlet or Cluster). It accumulates lines in the #cluster array if they belong together, when an incompatible line arrives, the cluster is printed and a new one is started. If the cluster to print has only one member, it's treated as a singlet.
#!/usr/bin/perl
use warnings;
use strict;
my $section = q();
my #cluster;
my $cluster_count = 1;
sub output {
if (#cluster > 1) {
print "Cluster$cluster_count\n";
$cluster_count++;
} elsif (1 == #cluster) {
print $section = 'Singlet', "s\n" unless 'Singlet' eq $section;
}
print for #cluster;
#cluster = ();
}
my $last = 'INF';
while (<>) {
my ($id, $from, $to, $value) = split;
if ($value > 1000 || 1000 < abs($last - $from)) {
output();
} else {
$section = 'Cluster';
}
push #cluster, $_;
$last = $to;
}
output();

Loop queue algorithm issue

I'm trying to do the following, and can't figure out how exactly do It without crashing or infinite looping:
I have to create a queue in which I have to distribute different tasks a different number of times each, alternatively with this kind of info:
Task X: [NextOne,LastOne]
Task 1: [30,32]
Task 2: [76,81]
Task 3: [2,2]
Task 4: [5,8]
Meaning that "Task X" will be made "LastOne - NextOne" times, and if both are equal, it won't be enqueued, and they enter the queue in X order.
With this example, the queue should look like:
FIRST
Task1[30]
Task2[76]
Task4[5]
Task1[31]
Task2[77]
Task4[6]
Task1[32]
Task2[78]
Task4[7]
Task2[79]
Task4[8]
Task2[80]
Task2[81]
LAST
It's not a language issue, it's more of an algorithm issue I have here. Using PHP I've made the following:
$tasks = array(
'Task1' => array(30,32),
'Task2' => array(76,81),
'Task3' => array(2,2),
'Task4' => array(5,8)
);
$aux = array();
$i=0;
foreach($tasks as $s=>$n) {
$aux[$i]['task'] = $s;
$aux[$i]['times'] = $n[1]-$n[0];
$aux[$i]['first'] = $n[0];
$i++;
}
But as you imagine this actually does nothing, just change the shape of the information. I'm really stuck here I don't know why, this actually shouldn't be hard to figure out. I'd appreciate any help.
In python (I may be misinterpreting your "it's not a language issue" comment - forgive me):
tasks = [
("Task1", 30, 32),
("Task2", 76, 81),
("Task3", 2, 2),
("Task4", 5, 8) ]
while not tasks == []:
# Pop first task off the current list
(n, s, e) = tasks[0]
tasks = tasks[1:]
print n, s
if s != e:
tasks.append( (n, s+1, e) )
Sorry it's not in php - it's not my forte, but perhaps this'll help? Output:
Task1 30
Task2 76
Task3 2
Task4 5
Task1 31
Task2 77
Task4 6
Task1 32
Task2 78
Task4 7
Task2 79
Task4 8
Task2 80
Task2 81
I guess you can use $s as a key for the hash(or array equivalent) and just increase the value by 1 whenever it encounters the element with the same key. The default value would be 0 in this case.
For example,
Task1 => array(30,32)
will be come in order like
Task1[30] (default value to 0)
...
...
Task1[31] (add 1 which becomes 1)
...
Task1[32] (add 1 which becomes 2)
This means that Task1 has appeared 3 times overall, and the final times value should be 2.
I think you can use array_key_exists helper function to check if certain task had appeared previously.
In C#
The result is as you wish.
I added a number as a flag: 1 = Not to be enqueued, 2 = Last record of the task.
Not efficient but works!
private static void Main()
{
var tasks = new Dictionary<string, int[]>
{
{"Task1", new[] {30, 32, 0}},
{"Task2", new[] {76, 81, 0}},
{"Task3", new[] {2, 2, 0}},
{"Task4", new[] {5, 8, 0}}
};
int loopCounter = 0;
Console.WriteLine("FIRST");
while (loopCounter < tasks.Count)
{
foreach (var task in tasks)
{
if (task.Value[0] == task.Value[1])
{
if (task.Value[2] == 2)
{
loopCounter++;
Console.WriteLine(task.Key + "[" + task.Value[0] + "]");
task.Value[2] = 1;
}
else if (task.Value[2] == 0)
{
loopCounter++;
task.Value[2] = 1;
}
}
else
{
Console.WriteLine(task.Key + "[" + task.Value[0] + "]");
task.Value[0]++;
if (task.Value[0] == task.Value[1])
task.Value[2] = 2;
}
}
}
Console.WriteLine("LAST");
Console.ReadLine();
}
Output:
FIRST
Task1[30]
Task2[76]
Task4[5]
Task1[31]
Task2[77]
Task4[6]
Task1[32]
Task2[78]
Task4[7]
Task2[79]
Task4[8]
Task2[80]
Task2[81]
LAST
Hope this helps.

Resources