Difficulty: Medium · Puzzle 6 of 6 · Topic: Queue and Array Puzzles
What are `evens`, `idx`, final `q`, `big.size()` and `tot` after these locator operations?
module p6;
int q[$] = '{1,2,3,4,5,6};
int evens[$];
int idx[$];
int big[$];
int tot;
initial begin
evens = q.find with (item % 2 == 0);
idx = q.find_index with (item > 3);
q = q.find with (item < 4);
big = q.find_first with (item > 100);
tot = q.sum with (item * 2);
$display("evens=%p idx=%p q=%p", evens, idx, q);
$display("big.size=%0d tot=%0d", big.size(), tot);
end
endmodule`find` returns matching values; `find_index` returns matching indices; both produce new queues and never modify the source. `find_first` returns a queue too, and `sum with` adds the expression, not the items.
1) `find` over the original q picks values 2,4,6 into `evens`.
2) `find_index` over the original q for `item > 3` yields indices 3,4,5 (it runs before q is reassigned).
3) `q = q.find with (item < 4)` replaces q with {1,2,3}.
4) `find_first` with no match returns an empty queue, not an error or -1, so `big.size()` is 0.
5) `sum with (item * 2)` adds twice each item of the new q: (1+2+3)*2 = 12.Answer: evens holds 2,4,6; idx holds 3,4,5; q holds 1,2,3; big.size=0 tot=12
Checked by running the code in Verilator 5; the printed output supports the answer above. The %p layout is tool-specific; the values 2,4,6 / 3,4,5 / 1,2,3 are what matter, and Icarus 13 does not support locator methods.
`find_index` reports positions in the queue as it was when the statement ran (3,4,5), and a failed `find_first` gives an empty queue rather than an index of -1.
How do results differ if you call `find_index` after reassigning `q`? Model answer: it then searches {1,2,3}, where no item is greater than 3, so it returns an empty queue (size 0) instead of {3,4,5}.
I would run each locator on the queue as it is at that moment. Find with the even test gives 2, 4, 6, and the index find on the original queue gives positions 3, 4, 5. Then the queue is replaced by the items below 4, which are 1, 2, 3, and a find first with no match gives an empty queue, so the size is 0, and the sum of twice each item is 12. The trap is thinking a failed find returns minus 1, or that the indices refer to the new queue. I would check the order of the statements.