Longest increasing subsequence: Difference between revisions
Content added Content deleted
(Fixed and updated second D entry) |
(jq) |
||
Line 686: | Line 686: | ||
</pre> |
</pre> |
||
=={{header|jq}}== |
|||
{{works with|jq|1.4}} |
|||
Use the patience sorting method to find a longest (strictly) increasing subsequence. |
|||
'''Generic functions:''' |
|||
Recent versions of jq have functions that obviate the need for the two generic functions defined in this subsection. |
|||
<lang jq>def until(cond; update): |
|||
def _until: |
|||
if cond then . else (update | _until) end; |
|||
try _until catch if .== "break" then empty else . end; |
|||
# binary search for insertion point |
|||
def bsearch(target): |
|||
. as $in |
|||
| [0, length-1] # [low, high] |
|||
| until(.[0] > .[1]; |
|||
.[0] as $low | .[1] as $high |
|||
| ($low + ($high - $low) / 2 | floor) as $mid |
|||
| if $in[$mid] >= target |
|||
then .[1] = $mid - 1 |
|||
else .[0] = $mid + 1 |
|||
end ) |
|||
| .[0];</lang> |
|||
'''lis:''' |
|||
<lang jq>def lis: |
|||
# Helper function: |
|||
# given a stream, produce an array of the items in reverse order: |
|||
def reverse(stream): reduce stream as $i ([]; [$i] + .); |
|||
# put the items into increasing piles using the structure: |
|||
# NODE = {"val": value, "back": NODE} |
|||
reduce .[] as $x |
|||
( []; # array of NODE |
|||
# binary search for the appropriate pile |
|||
(map(.val) | bsearch($x)) as $i |
|||
| setpath([$i]; |
|||
{"val": $x, |
|||
"back": (if $i > 0 then .[$i-1] else null end) }) |
|||
) |
|||
| .[length - 1] |
|||
| reverse( recurse(.back) | .val ) ; </lang> |
|||
'''Example:''' |
|||
<lang jq>[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15] | lis</lang> |
|||
{{out}} |
|||
<lang sh>$ jq -c -n -f lis.jq |
|||
[0,2,6,9,11,15]</lang> |
|||