September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -1,3 +0,0 @@
|
|||
[[5,"Make tea"], [4,"Feed cat"], [3,"Clear drains"], [2,"Tax return"],
|
||||
[1,"Solve RC tasks"]]
|
||||
Type: List(OrderedKeyEntry(Integer,String))
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct { void * data; int pri; } q_elem_t;
|
||||
typedef struct { q_elem_t *buf; int n, alloc; } pri_queue_t, *pri_queue;
|
||||
|
||||
#define priq_purge(q) (q)->n = 1
|
||||
#define priq_size(q) ((q)->n - 1)
|
||||
/* first element in array not used to simplify indices */
|
||||
pri_queue priq_new(int size)
|
||||
{
|
||||
if (size < 4) size = 4;
|
||||
|
||||
pri_queue q = malloc(sizeof(pri_queue_t));
|
||||
q->buf = malloc(sizeof(q_elem_t) * size);
|
||||
q->alloc = size;
|
||||
q->n = 1;
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
void priq_push(pri_queue q, void *data, int pri)
|
||||
{
|
||||
q_elem_t *b;
|
||||
int n, m;
|
||||
|
||||
if (q->n >= q->alloc) {
|
||||
q->alloc *= 2;
|
||||
b = q->buf = realloc(q->buf, sizeof(q_elem_t) * q->alloc);
|
||||
} else
|
||||
b = q->buf;
|
||||
|
||||
n = q->n++;
|
||||
/* append at end, then up heap */
|
||||
while ((m = n / 2) && pri < b[m].pri) {
|
||||
b[n] = b[m];
|
||||
n = m;
|
||||
}
|
||||
b[n].data = data;
|
||||
b[n].pri = pri;
|
||||
}
|
||||
|
||||
/* remove top item. returns 0 if empty. *pri can be null. */
|
||||
void * priq_pop(pri_queue q, int *pri)
|
||||
{
|
||||
void *out;
|
||||
if (q->n == 1) return 0;
|
||||
|
||||
q_elem_t *b = q->buf;
|
||||
|
||||
out = b[1].data;
|
||||
if (pri) *pri = b[1].pri;
|
||||
|
||||
/* pull last item to top, then down heap. */
|
||||
--q->n;
|
||||
|
||||
int n = 1, m;
|
||||
while ((m = n * 2) < q->n) {
|
||||
if (m + 1 < q->n && b[m].pri > b[m + 1].pri) m++;
|
||||
|
||||
if (b[q->n].pri <= b[m].pri) break;
|
||||
b[n] = b[m];
|
||||
n = m;
|
||||
}
|
||||
|
||||
b[n] = b[q->n];
|
||||
if (q->n < q->alloc / 2 && q->n >= 16)
|
||||
q->buf = realloc(q->buf, (q->alloc /= 2) * sizeof(b[0]));
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/* get the top element without removing it from queue */
|
||||
void* priq_top(pri_queue q, int *pri)
|
||||
{
|
||||
if (q->n == 1) return 0;
|
||||
if (pri) *pri = q->buf[1].pri;
|
||||
return q->buf[1].data;
|
||||
}
|
||||
|
||||
/* this is O(n log n), but probably not the best */
|
||||
void priq_combine(pri_queue q, pri_queue q2)
|
||||
{
|
||||
int i;
|
||||
q_elem_t *e = q2->buf + 1;
|
||||
|
||||
for (i = q2->n - 1; i >= 1; i--, e++)
|
||||
priq_push(q, e->data, e->pri);
|
||||
priq_purge(q2);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int i, p;
|
||||
const char *c, *tasks[] ={
|
||||
"Clear drains", "Feed cat", "Make tea", "Solve RC tasks", "Tax return" };
|
||||
int pri[] = { 3, 4, 5, 1, 2 };
|
||||
|
||||
/* make two queues */
|
||||
pri_queue q = priq_new(0), q2 = priq_new(0);
|
||||
|
||||
/* push all 5 tasks into q */
|
||||
for (i = 0; i < 5; i++)
|
||||
priq_push(q, tasks[i], pri[i]);
|
||||
|
||||
/* pop them and print one by one */
|
||||
while ((c = priq_pop(q, &p)))
|
||||
printf("%d: %s\n", p, c);
|
||||
|
||||
/* put a million random tasks in each queue */
|
||||
for (i = 0; i < 1 << 20; i++) {
|
||||
p = rand() / ( RAND_MAX / 5 );
|
||||
priq_push(q, tasks[p], pri[p]);
|
||||
|
||||
p = rand() / ( RAND_MAX / 5 );
|
||||
priq_push(q2, tasks[p], pri[p]);
|
||||
}
|
||||
|
||||
printf("\nq has %d items, q2 has %d items\n", priq_size(q), priq_size(q2));
|
||||
|
||||
/* merge q2 into q; q2 is empty */
|
||||
priq_combine(q, q2);
|
||||
printf("After merge, q has %d items, q2 has %d items\n",
|
||||
priq_size(q), priq_size(q2));
|
||||
|
||||
/* pop q until it's empty */
|
||||
for (i = 0; (c = priq_pop(q, 0)); i++);
|
||||
printf("Popped %d items out of q\n", i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
1: Solve RC tasks
|
||||
2: Tax return
|
||||
3: Clear drains
|
||||
4: Feed cat
|
||||
5: Make tea
|
||||
|
||||
q has 1048576 items, q2 has 1048576 items
|
||||
After merge, q has 2097152 items, q2 has 0 items
|
||||
Popped 2097152 items out of q
|
||||
54
Task/Priority-queue/Phix/priority-queue.phix
Normal file
54
Task/Priority-queue/Phix/priority-queue.phix
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
integer tasklist = new_dict()
|
||||
|
||||
procedure add_task(integer priority, string desc)
|
||||
integer k = getd_index(priority,tasklist)
|
||||
if k=0 then
|
||||
putd(priority,{desc},tasklist)
|
||||
else
|
||||
sequence descs = getd_by_index(k,tasklist)
|
||||
putd(priority,append(descs,desc),tasklist)
|
||||
end if
|
||||
end procedure
|
||||
|
||||
function list_task_visitor(integer priority, sequence descs, integer /*user_data*/)
|
||||
?{priority,descs}
|
||||
return 1
|
||||
end function
|
||||
|
||||
procedure list_tasks()
|
||||
traverse_dict(routine_id("list_task_visitor"), 0, tasklist,true)
|
||||
end procedure
|
||||
|
||||
function pop_task_visitor(integer priority, sequence descs, integer rid)
|
||||
string desc = descs[1]
|
||||
descs = descs[2..$]
|
||||
if length(descs)=0 then
|
||||
deld(priority,tasklist)
|
||||
else
|
||||
putd(priority,descs,tasklist)
|
||||
end if
|
||||
call_proc(rid,{priority,desc})
|
||||
return 0
|
||||
end function
|
||||
|
||||
procedure pop_task(integer rid)
|
||||
if dict_size(tasklist)!=0 then
|
||||
traverse_dict(routine_id("pop_task_visitor"), rid, tasklist,true)
|
||||
end if
|
||||
end procedure
|
||||
|
||||
add_task(3,"Clear drains")
|
||||
add_task(4,"Feed cat")
|
||||
add_task(5,"Make tea")
|
||||
add_task(1,"Solve RC tasks")
|
||||
add_task(2,"Tax return")
|
||||
|
||||
procedure do_task(integer priority, string desc)
|
||||
?{priority,desc}
|
||||
end procedure
|
||||
|
||||
list_tasks()
|
||||
?"==="
|
||||
pop_task(routine_id("do_task"))
|
||||
?"==="
|
||||
list_tasks()
|
||||
20
Task/Priority-queue/Zkl/priority-queue-1.zkl
Normal file
20
Task/Priority-queue/Zkl/priority-queue-1.zkl
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
class PQ{
|
||||
fcn init(numLevels=10){ // 0..numLevels, bigger # == lower priorty
|
||||
var [const] queue=(1).pump(numLevels+1,List.createLong(numLevels).write,L().copy);
|
||||
}
|
||||
fcn add(item,priorty){ queue[priorty].append(item); }
|
||||
fcn peek{ if(q:=queue.filter1()) return(q[-1]); Void }// -->Void if empty
|
||||
fcn pop { if(q:=queue.filter1()) return(q.pop()); Void }// -->Void if empty
|
||||
var [private] state=L();
|
||||
fcn [private] next{ // iterate
|
||||
qi,ii:=state;
|
||||
foreach n in ([qi..queue.len()-1]){
|
||||
q:=queue[n];
|
||||
if(ii>=q.len()) ii=0;
|
||||
else{ state.clear().append(n,ii+1); return(q[ii]) }
|
||||
}
|
||||
Void.Stop
|
||||
}
|
||||
fcn walker{ state.clear().append(0,0); Walker(next) } // iterator front end
|
||||
fcn toString{ "PQ(%d) items".fmt(queue.reduce(fcn(sum,q){ sum+q.len() },0)) }
|
||||
}
|
||||
13
Task/Priority-queue/Zkl/priority-queue-2.zkl
Normal file
13
Task/Priority-queue/Zkl/priority-queue-2.zkl
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
pq:=PQ();
|
||||
foreach x in
|
||||
(T("Clear drains",3, "Feed cat",4, "Make tea",5, "Solve RC tasks",1, "Tax return",2,
|
||||
"Clean room",10,"Wash cat",10)){
|
||||
pq.add(x,__xWalker.next())
|
||||
}
|
||||
pq.println();
|
||||
println("Number 1 thing to do: ",pq.peek());
|
||||
println("Top 2 things to do: ",pq.walker().walk(2));
|
||||
println("Do this next year: ",pq.walker().walk()[-1]);
|
||||
println("ToDo list:");
|
||||
foreach item in (pq){ item.println() }
|
||||
pq.println();
|
||||
Loading…
Add table
Add a link
Reference in a new issue