Longest increasing subsequence: Difference between revisions
Content added Content deleted
(→{{header|Picat}}: Split into subsections. Added {{out}}) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 18: | Line 18: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="11l">F longest_increasing_subsequence(x) |
||
V n = x.len |
V n = x.len |
||
V P = [0] * n |
V P = [0] * n |
||
Line 47: | Line 47: | ||
L(d) [[3, 2, 6, 4, 5, 1], [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]] |
L(d) [[3, 2, 6, 4, 5, 1], [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]] |
||
print(‘a L.I.S. of #. is #.’.format(d, longest_increasing_subsequence(d)))</ |
print(‘a L.I.S. of #. is #.’.format(d, longest_increasing_subsequence(d)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 57: | Line 57: | ||
=={{header|360 Assembly}}== |
=={{header|360 Assembly}}== |
||
{{trans|VBScript}} |
{{trans|VBScript}} |
||
< |
<syntaxhighlight lang="360asm">* Longest increasing subsequence 04/03/2017 |
||
LNGINSQ CSECT |
LNGINSQ CSECT |
||
USING LNGINSQ,R13 base register |
USING LNGINSQ,R13 base register |
||
Line 177: | Line 177: | ||
XDEC DS CL12 temp for xdeco |
XDEC DS CL12 temp for xdeco |
||
YREGS |
YREGS |
||
END LNGINSQ</ |
END LNGINSQ</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 189: | Line 189: | ||
{{Trans|Phix}} … modified to return ''multiple'' co-longest sequences where found. It's not clear how equal values should be treated. Here the behaviour happens to be as in the demo code at the end. |
{{Trans|Phix}} … modified to return ''multiple'' co-longest sequences where found. It's not clear how equal values should be treated. Here the behaviour happens to be as in the demo code at the end. |
||
< |
<syntaxhighlight lang="applescript">on longestIncreasingSubsequences(aList) |
||
script o |
script o |
||
property inputList : aList |
property inputList : aList |
||
Line 251: | Line 251: | ||
set end of output to {finds:longestIncreasingSubsequences(input's contents)} |
set end of output to {finds:longestIncreasingSubsequences(input's contents)} |
||
end repeat |
end repeat |
||
return output</ |
return output</syntaxhighlight> |
||
{{output}} |
{{output}} |
||
< |
<syntaxhighlight lang="applescript">{{finds:{{2, 4, 5}}}, {finds:{{0, 2, 6, 9, 11, 15}}}, {finds:{{9, 10, 11}, {3, 8, 9}, {3, 6, 7}, {3, 4, 5}}}, {finds:{{4, 5, 6}}}, {finds:{{5}, {5}}}}</syntaxhighlight> |
||
=={{header|Arturo}}== |
=={{header|Arturo}}== |
||
< |
<syntaxhighlight lang="rebol">lis: function [d][ |
||
l: new [[]] |
l: new [[]] |
||
loop d 'num [ |
loop d 'num [ |
||
Line 284: | Line 284: | ||
] 'seq [ |
] 'seq [ |
||
print ["LIS of" seq "=>" lis seq] |
print ["LIS of" seq "=>" lis seq] |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 292: | Line 292: | ||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
< |
<syntaxhighlight lang="autohotkey">Lists := [[3,2,6,4,5,1], [0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15]] |
||
for k, v in Lists { |
for k, v in Lists { |
||
Line 313: | Line 313: | ||
} |
} |
||
return, D |
return, D |
||
}</ |
}</syntaxhighlight> |
||
'''Output:''' |
'''Output:''' |
||
<pre>3, 4, 5 |
<pre>3, 4, 5 |
||
Line 320: | Line 320: | ||
=={{header|C}}== |
=={{header|C}}== |
||
Using an array that doubles as linked list (more like reversed trees really). O(n) memory and O(n<sup>2</sup>) runtime. |
Using an array that doubles as linked list (more like reversed trees really). O(n) memory and O(n<sup>2</sup>) runtime. |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
Line 363: | Line 363: | ||
lis(y, sizeof(y) / sizeof(int)); |
lis(y, sizeof(y) / sizeof(int)); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 373: | Line 373: | ||
===Recursive=== |
===Recursive=== |
||
{{works with|C sharp|6}} |
{{works with|C sharp|6}} |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Collections; |
using System.Collections; |
||
using System.Collections.Generic; |
using System.Collections.Generic; |
||
Line 420: | Line 420: | ||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); |
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
===Patience sorting=== |
===Patience sorting=== |
||
{{works with|C sharp|7}} |
{{works with|C sharp|7}} |
||
< |
<syntaxhighlight lang="csharp">public static class LIS |
||
{ |
{ |
||
public static T[] Find<T>(IList<T> values, IComparer<T> comparer = null) { |
public static T[] Find<T>(IList<T> values, IComparer<T> comparer = null) { |
||
Line 449: | Line 449: | ||
Console.WriteLine(string.Join(",", LIS.Find(new [] { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }))); |
Console.WriteLine(string.Join(",", LIS.Find(new [] { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }))); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 458: | Line 458: | ||
Patience sorting |
Patience sorting |
||
=== C++11 === |
=== C++11 === |
||
< |
<syntaxhighlight lang="cpp">#include <vector> |
||
#include <list> |
#include <list> |
||
#include <algorithm> |
#include <algorithm> |
||
Line 523: | Line 523: | ||
show_lis(std::list<int> { 3, 2, 6, 4, 5, 1 }); |
show_lis(std::list<int> { 3, 2, 6, 4, 5, 1 }); |
||
show_lis(std::vector<int> { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }); |
show_lis(std::vector<int> { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }); |
||
}</ |
}</syntaxhighlight> |
||
=== C++98 === |
=== C++98 === |
||
< |
<syntaxhighlight lang="cpp">#include <vector> |
||
#include <list> |
#include <list> |
||
#include <algorithm> |
#include <algorithm> |
||
Line 607: | Line 607: | ||
show_lis(vec1); |
show_lis(vec1); |
||
show_lis(vec2); |
show_lis(vec2); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>2 4 5 |
<pre>2 4 5 |
||
Line 617: | Line 617: | ||
The combination is done using ''cons'', so what gets put on a pile is a list -- a descending subsequence. |
The combination is done using ''cons'', so what gets put on a pile is a list -- a descending subsequence. |
||
< |
<syntaxhighlight lang="clojure">(defn place [piles card] |
||
(let [[les gts] (->> piles (split-with #(<= (ffirst %) card))) |
(let [[les gts] (->> piles (split-with #(<= (ffirst %) card))) |
||
newelem (cons card (->> les last first)) |
newelem (cons card (->> les last first)) |
||
Line 628: | Line 628: | ||
(println (a-longest [3 2 6 4 5 1])) |
(println (a-longest [3 2 6 4 5 1])) |
||
(println (a-longest [0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15]))</ |
(println (a-longest [0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15]))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<lang>(2 4 5) |
<syntaxhighlight lang="text">(2 4 5) |
||
(0 2 6 9 11 15)</ |
(0 2 6 9 11 15)</syntaxhighlight> |
||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
===Common Lisp: Using the method in the video=== |
===Common Lisp: Using the method in the video=== |
||
Slower and more memory usage compared to the patience sort method. |
Slower and more memory usage compared to the patience sort method. |
||
< |
<syntaxhighlight lang="lisp">(defun longest-increasing-subseq (list) |
||
(let ((subseqs nil)) |
(let ((subseqs nil)) |
||
(dolist (item list) |
(dolist (item list) |
||
Line 655: | Line 655: | ||
(dolist (l (list (list 3 2 6 4 5 1) |
(dolist (l (list (list 3 2 6 4 5 1) |
||
(list 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15))) |
(list 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15))) |
||
(format t "~A~%" (longest-increasing-subseq l))))</ |
(format t "~A~%" (longest-increasing-subseq l))))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>(2 4 5) |
<pre>(2 4 5) |
||
Line 661: | Line 661: | ||
===Common Lisp: Using the Patience Sort approach=== |
===Common Lisp: Using the Patience Sort approach=== |
||
This is 5 times faster and and uses a third of the memory compared to the approach in the video. |
This is 5 times faster and and uses a third of the memory compared to the approach in the video. |
||
< |
<syntaxhighlight lang="lisp">(defun lis-patience-sort (input-list) |
||
(let ((piles nil)) |
(let ((piles nil)) |
||
(dolist (item input-list) |
(dolist (item input-list) |
||
Line 683: | Line 683: | ||
(dolist (l (list (list 3 2 6 4 5 1) |
(dolist (l (list (list 3 2 6 4 5 1) |
||
(list 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15))) |
(list 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15))) |
||
(format t "~A~%" (lis-patience-sort l)))</ |
(format t "~A~%" (lis-patience-sort l)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>(2 4 5) |
<pre>(2 4 5) |
||
Line 689: | Line 689: | ||
===Common Lisp: Using the Patience Sort approach (alternative)=== |
===Common Lisp: Using the Patience Sort approach (alternative)=== |
||
This is a different version of the code above. |
This is a different version of the code above. |
||
< |
<syntaxhighlight lang="lisp">(defun insert-item (item piles) |
||
(multiple-value-bind |
(multiple-value-bind |
||
(i prev) |
(i prev) |
||
Line 708: | Line 708: | ||
(dolist (l (list (list 3 2 6 4 5 1) |
(dolist (l (list (list 3 2 6 4 5 1) |
||
(list 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15))) |
(list 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15))) |
||
(format t "~A~%" (longest-inc-seq l)))</ |
(format t "~A~%" (longest-inc-seq l)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>(2 4 5) |
<pre>(2 4 5) |
||
Line 717: | Line 717: | ||
{{trans|Haskell}} |
{{trans|Haskell}} |
||
Uses the second powerSet function from the Power Set Task. |
Uses the second powerSet function from the Power Set Task. |
||
< |
<syntaxhighlight lang="d">import std.stdio, std.algorithm, power_set2; |
||
T[] lis(T)(T[] items) pure nothrow { |
T[] lis(T)(T[] items) pure nothrow { |
||
Line 731: | Line 731: | ||
[3, 2, 6, 4, 5, 1].lis.writeln; |
[3, 2, 6, 4, 5, 1].lis.writeln; |
||
[0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15].lis.writeln; |
[0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15].lis.writeln; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>[2, 4, 5] |
<pre>[2, 4, 5] |
||
Line 739: | Line 739: | ||
{{trans|Python}} |
{{trans|Python}} |
||
From the second Python entry, using the Patience sorting method. |
From the second Python entry, using the Patience sorting method. |
||
< |
<syntaxhighlight lang="d">import std.stdio, std.algorithm, std.array; |
||
/// Return one of the Longest Increasing Subsequence of |
/// Return one of the Longest Increasing Subsequence of |
||
Line 776: | Line 776: | ||
[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15]]) |
[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15]]) |
||
d.lis.writeln; |
d.lis.writeln; |
||
}</ |
}</syntaxhighlight> |
||
The output is the same. |
The output is the same. |
||
Line 782: | Line 782: | ||
{{trans|Java}} |
{{trans|Java}} |
||
With some more optimizations. |
With some more optimizations. |
||
< |
<syntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.array; |
||
T[] lis(T)(in T[] items) pure nothrow |
T[] lis(T)(in T[] items) pure nothrow |
||
Line 831: | Line 831: | ||
[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15]]) |
[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15]]) |
||
d.writeln; |
d.writeln; |
||
}</ |
}</syntaxhighlight> |
||
The output is the same. |
The output is the same. |
||
=={{header|Déjà Vu}}== |
=={{header|Déjà Vu}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="dejavu">in-pair: |
||
if = :nil dup: |
if = :nil dup: |
||
false drop |
false drop |
||
Line 861: | Line 861: | ||
!. lis [ 3 2 6 4 5 1 ] |
!. lis [ 3 2 6 4 5 1 ] |
||
!. lis [ 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 ] |
!. lis [ 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 ] |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 871: | Line 871: | ||
===Naive version=== |
===Naive version=== |
||
very slow |
very slow |
||
< |
<syntaxhighlight lang="elixir">defmodule Longest_increasing_subsequence do |
||
# Naive implementation |
# Naive implementation |
||
def lis(l) do |
def lis(l) do |
||
Line 889: | Line 889: | ||
IO.inspect Longest_increasing_subsequence.lis([3,2,6,4,5,1]) |
IO.inspect Longest_increasing_subsequence.lis([3,2,6,4,5,1]) |
||
IO.inspect Longest_increasing_subsequence.lis([0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15])</ |
IO.inspect Longest_increasing_subsequence.lis([0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 898: | Line 898: | ||
===Patience sort version=== |
===Patience sort version=== |
||
< |
<syntaxhighlight lang="elixir">defmodule Longest_increasing_subsequence do |
||
# Patience sort implementation |
# Patience sort implementation |
||
def patience_lis(l), do: patience_lis(l, []) |
def patience_lis(l), do: patience_lis(l, []) |
||
Line 925: | Line 925: | ||
IO.inspect Longest_increasing_subsequence.patience_lis([3,2,6,4,5,1]) |
IO.inspect Longest_increasing_subsequence.patience_lis([3,2,6,4,5,1]) |
||
IO.inspect Longest_increasing_subsequence.patience_lis([0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15])</ |
IO.inspect Longest_increasing_subsequence.patience_lis([0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 949: | Line 949: | ||
Function ''memo'' and ''patience2'' by [https://www.linkedin.com/in/find-roman/ Roman Rabinovich]. |
Function ''memo'' and ''patience2'' by [https://www.linkedin.com/in/find-roman/ Roman Rabinovich]. |
||
< |
<syntaxhighlight lang="erlang"> |
||
-module(longest_increasing_subsequence). |
-module(longest_increasing_subsequence). |
||
Line 1,159: | Line 1,159: | ||
% ************************************************** |
% ************************************************** |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output naive: |
Output naive: |
||
Line 1,187: | Line 1,187: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
Patience sorting |
Patience sorting |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 1,229: | Line 1,229: | ||
fmt.Printf("an L.I.S. of %v is %v\n", d, lis(d)) |
fmt.Printf("an L.I.S. of %v is %v\n", d, lis(d)) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,237: | Line 1,237: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
===Naive implementation=== |
===Naive implementation=== |
||
< |
<syntaxhighlight lang="haskell">import Data.Ord ( comparing ) |
||
import Data.List ( maximumBy, subsequences ) |
import Data.List ( maximumBy, subsequences ) |
||
import Data.List.Ordered ( isSorted, nub ) |
import Data.List.Ordered ( isSorted, nub ) |
||
Line 1,248: | Line 1,248: | ||
print $ lis [3,2,6,4,5,1] |
print $ lis [3,2,6,4,5,1] |
||
print $ lis [0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15] |
print $ lis [0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15] |
||
print $ lis [1,1,1,1]</ |
print $ lis [1,1,1,1]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,256: | Line 1,256: | ||
===Patience sorting=== |
===Patience sorting=== |
||
< |
<syntaxhighlight lang="haskell">{-# LANGUAGE FlexibleContexts, UnicodeSyntax #-} |
||
module Main (main, lis) where |
module Main (main, lis) where |
||
Line 1,307: | Line 1,307: | ||
print $ lis [3, 2, 6, 4, 5, 1] |
print $ lis [3, 2, 6, 4, 5, 1] |
||
print $ lis [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15] |
print $ lis [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15] |
||
print $ lis [1, 1, 1, 1]</ |
print $ lis [1, 1, 1, 1]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,318: | Line 1,318: | ||
The following works in both languages: |
The following works in both languages: |
||
< |
<syntaxhighlight lang="unicon">procedure main(A) |
||
every writes((!lis(A)||" ") | "\n") |
every writes((!lis(A)||" ") | "\n") |
||
end |
end |
||
Line 1,328: | Line 1,328: | ||
else p[-1] := (p[-2] < v) |
else p[-1] := (p[-2] < v) |
||
return r |
return r |
||
end</ |
end</syntaxhighlight> |
||
Sample runs: |
Sample runs: |
||
Line 1,343: | Line 1,343: | ||
These examples are simple enough for brute force to be reasonable: |
These examples are simple enough for brute force to be reasonable: |
||
< |
<syntaxhighlight lang="j">increasing=: (-: /:~)@#~"1 #:@i.@^~&2@# |
||
longestinc=: ] #~ [: (#~ ([: (= >./) +/"1)) #:@I.@increasing</ |
longestinc=: ] #~ [: (#~ ([: (= >./) +/"1)) #:@I.@increasing</syntaxhighlight> |
||
In other words: consider all 2^n bitmasks of length n, and select those which strictly select increasing sequences. Find the length of the longest of these and use the masks of that length to select from the original sequence. |
In other words: consider all 2^n bitmasks of length n, and select those which strictly select increasing sequences. Find the length of the longest of these and use the masks of that length to select from the original sequence. |
||
Line 1,350: | Line 1,350: | ||
Example use: |
Example use: |
||
<syntaxhighlight lang="j"> |
|||
<lang j> |
|||
longestinc 3,2,6,4,5,1 |
longestinc 3,2,6,4,5,1 |
||
2 4 5 |
2 4 5 |
||
Line 1,358: | Line 1,358: | ||
0 2 6 9 13 15 |
0 2 6 9 13 15 |
||
0 4 6 9 11 15 |
0 4 6 9 11 15 |
||
0 4 6 9 13 15</ |
0 4 6 9 13 15</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
A solution based on patience sorting, except that it is not necessary to keep the whole pile, only the top (in solitaire, bottom) of the pile, along with pointers from each "card" to the top of its "previous" pile. |
A solution based on patience sorting, except that it is not necessary to keep the whole pile, only the top (in solitaire, bottom) of the pile, along with pointers from each "card" to the top of its "previous" pile. |
||
< |
<syntaxhighlight lang="java">import java.util.*; |
||
public class LIS { |
public class LIS { |
||
Line 1,401: | Line 1,401: | ||
System.out.printf("an L.I.S. of %s is %s\n", d, lis(d)); |
System.out.printf("an L.I.S. of %s is %s\n", d, lis(d)); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,408: | Line 1,408: | ||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
< |
<syntaxhighlight lang="javascript">function getLis(input) { |
||
if (input.length === 0) { |
if (input.length === 0) { |
||
return []; |
return []; |
||
Line 1,441: | Line 1,441: | ||
console.log(getLongestIncreasingSubsequence([0, 7, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15])); |
console.log(getLongestIncreasingSubsequence([0, 7, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15])); |
||
console.log(getLongestIncreasingSubsequence([3, 2, 6, 4, 5, 1])); |
console.log(getLongestIncreasingSubsequence([3, 2, 6, 4, 5, 1])); |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 1,450: | Line 1,450: | ||
===Patience sorting=== |
===Patience sorting=== |
||
< |
<syntaxhighlight lang="javascript">function getLIS(input) { |
||
if (input.length === 0) { |
if (input.length === 0) { |
||
return 0; |
return 0; |
||
Line 1,489: | Line 1,489: | ||
console.log(getLongestIncreasingSubsequence([0, 7, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15])); |
console.log(getLongestIncreasingSubsequence([0, 7, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15])); |
||
console.log(getLongestIncreasingSubsequence([3, 2, 6, 4, 5, 1])); |
console.log(getLongestIncreasingSubsequence([3, 2, 6, 4, 5, 1])); |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 1,504: | Line 1,504: | ||
Recent versions of jq have functions that obviate the need for the two generic functions defined in this subsection. |
Recent versions of jq have functions that obviate the need for the two generic functions defined in this subsection. |
||
< |
<syntaxhighlight lang="jq">def until(cond; update): |
||
def _until: |
def _until: |
||
if cond then . else (update | _until) end; |
if cond then . else (update | _until) end; |
||
Line 1,520: | Line 1,520: | ||
else .[0] = $mid + 1 |
else .[0] = $mid + 1 |
||
end ) |
end ) |
||
| .[0];</ |
| .[0];</syntaxhighlight> |
||
'''lis:''' |
'''lis:''' |
||
< |
<syntaxhighlight lang="jq">def lis: |
||
# Helper function: |
# Helper function: |
||
Line 1,539: | Line 1,539: | ||
) |
) |
||
| .[length - 1] |
| .[length - 1] |
||
| reverse( recurse(.back) | .val ) ; </ |
| reverse( recurse(.back) | .val ) ; </syntaxhighlight> |
||
'''Examples:''' |
'''Examples:''' |
||
< |
<syntaxhighlight lang="jq">( [3,2,6,4,5,1], |
||
[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15] |
[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15] |
||
) | lis</ |
) | lis</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang="sh">$ jq -c -n -f lis.jq |
||
[2,4,5] |
[2,4,5] |
||
[0,2,6,9,11,15] |
[0,2,6,9,11,15] |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
{{works with|Julia|0.6}} |
{{works with|Julia|0.6}} |
||
< |
<syntaxhighlight lang="julia"> |
||
function lis(arr::Vector) |
function lis(arr::Vector) |
||
if length(arr) == 0 return copy(arr) end |
if length(arr) == 0 return copy(arr) end |
||
Line 1,574: | Line 1,574: | ||
@show lis([3, 2, 6, 4, 5, 1]) |
@show lis([3, 2, 6, 4, 5, 1]) |
||
@show lis([0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15])</ |
@show lis([0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,582: | Line 1,582: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
Uses the algorithm in the Wikipedia L.I.S. article: |
Uses the algorithm in the Wikipedia L.I.S. article: |
||
< |
<syntaxhighlight lang="scala">// version 1.1.0 |
||
fun longestIncreasingSubsequence(x: IntArray): IntArray = |
fun longestIncreasingSubsequence(x: IntArray): IntArray = |
||
Line 1,622: | Line 1,622: | ||
) |
) |
||
lists.forEach { println(longestIncreasingSubsequence(it).asList()) } |
lists.forEach { println(longestIncreasingSubsequence(it).asList()) } |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,631: | Line 1,631: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<syntaxhighlight lang="lua">function buildLIS(seq) |
||
local piles = { { {table.remove(seq, 1), nil} } } |
local piles = { { {table.remove(seq, 1), nil} } } |
||
while #seq>0 do |
while #seq>0 do |
||
Line 1,657: | Line 1,657: | ||
buildLIS({3,2,6,4,5,1}) |
buildLIS({3,2,6,4,5,1}) |
||
buildLIS({0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15}) |
buildLIS({0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15}) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 1,668: | Line 1,668: | ||
stack:=stackitem(L(i)), ! stack(L(j)) returns a refence to a new stack object, with the first item on L(i) (which is a reference to stack object) and merge using ! the copy of L(j) stack. |
stack:=stackitem(L(i)), ! stack(L(j)) returns a refence to a new stack object, with the first item on L(i) (which is a reference to stack object) and merge using ! the copy of L(j) stack. |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module LIS_example { |
Module LIS_example { |
||
Function LIS { |
Function LIS { |
||
Line 1,706: | Line 1,706: | ||
} |
} |
||
LIS_example |
LIS_example |
||
</syntaxhighlight> |
|||
</lang> |
|||
===Using arrays in an array=== |
===Using arrays in an array=== |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module LIS_example { |
Module LIS_example { |
||
Function LIS { |
Function LIS { |
||
Line 1,749: | Line 1,749: | ||
} |
} |
||
LIS_example |
LIS_example |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 1,760: | Line 1,760: | ||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
< |
<syntaxhighlight lang="maple"># dynamic programming: |
||
LIS := proc(L) |
LIS := proc(L) |
||
local i, j; |
local i, j; |
||
Line 1,785: | Line 1,785: | ||
return output[index]; |
return output[index]; |
||
end proc:</ |
end proc:</syntaxhighlight> |
||
Alternatively, output the longest subsequence using built-in command max: |
Alternatively, output the longest subsequence using built-in command max: |
||
< |
<syntaxhighlight lang="maple">i := max[index](map(numelems,output)); |
||
output[i];</ |
output[i];</syntaxhighlight> |
||
< |
<syntaxhighlight lang="maple">L := [3, 2, 6, 4, 5, 1]; |
||
M := [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]; |
M := [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]; |
||
LIS(L); |
LIS(L); |
||
LIS(M);</ |
LIS(M);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,803: | Line 1,803: | ||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
Although undocumented, Mathematica has the function LongestAscendingSequence which exactly does what the Task asks for: |
Although undocumented, Mathematica has the function LongestAscendingSequence which exactly does what the Task asks for: |
||
< |
<syntaxhighlight lang="mathematica">LongestAscendingSequence/@{{3,2,6,4,5,1},{0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15}}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>{{2,4,5},{0,2,6,9,11,15}}</pre> |
<pre>{{2,4,5},{0,2,6,9,11,15}}</pre> |
||
Line 1,809: | Line 1,809: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="nim">proc longestIncreasingSubsequence[T](d: seq[T]): seq[T] = |
||
var l: seq[seq[T]] |
var l: seq[seq[T]] |
||
for i in 0 .. d.high: |
for i in 0 .. d.high: |
||
Line 1,822: | Line 1,822: | ||
for d in [@[3,2,6,4,5,1], @[0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]]: |
for d in [@[3,2,6,4,5,1], @[0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]]: |
||
echo "A L.I.S. of ", d, " is ", longestIncreasingSubsequence(d)</ |
echo "A L.I.S. of ", d, " is ", longestIncreasingSubsequence(d)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>A L.I.S. of @[3, 2, 6, 4, 5, 1] is @[3, 4, 5] |
<pre>A L.I.S. of @[3, 2, 6, 4, 5, 1] is @[3, 4, 5] |
||
Line 1,829: | Line 1,829: | ||
=={{header|Objective-C}}== |
=={{header|Objective-C}}== |
||
Patience sorting |
Patience sorting |
||
< |
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h> |
||
@interface Node : NSObject { |
@interface Node : NSObject { |
||
Line 1,881: | Line 1,881: | ||
} |
} |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>an L.I.S. of ( |
<pre>an L.I.S. of ( |
||
Line 1,923: | Line 1,923: | ||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
===Naïve implementation=== |
===Naïve implementation=== |
||
< |
<syntaxhighlight lang="ocaml">let longest l = List.fold_left (fun acc x -> if List.length acc < List.length x |
||
then x |
then x |
||
else acc) [] l |
else acc) [] l |
||
Line 1,945: | Line 1,945: | ||
in |
in |
||
List.map (fun x -> print_endline (String.concat " " (List.map string_of_int |
List.map (fun x -> print_endline (String.concat " " (List.map string_of_int |
||
(lis x)))) sequences</ |
(lis x)))) sequences</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,953: | Line 1,953: | ||
===Patience sorting=== |
===Patience sorting=== |
||
< |
<syntaxhighlight lang="ocaml">let lis cmp list = |
||
let pile_tops = Array.make (List.length list) [] in |
let pile_tops = Array.make (List.length list) [] in |
||
let bsearch_piles x len = |
let bsearch_piles x len = |
||
Line 1,974: | Line 1,974: | ||
in |
in |
||
let len = List.fold_left f 0 list in |
let len = List.fold_left f 0 list in |
||
List.rev pile_tops.(len-1)</ |
List.rev pile_tops.(len-1)</syntaxhighlight> |
||
Usage: |
Usage: |
||
<pre># lis compare [3; 2; 6; 4; 5; 1];; |
<pre># lis compare [3; 2; 6; 4; 5; 1];; |
||
Line 1,984: | Line 1,984: | ||
===Dynamic programming=== |
===Dynamic programming=== |
||
{{trans|Raku}} |
{{trans|Raku}} |
||
< |
<syntaxhighlight lang="perl">use strict; |
||
sub lis { |
sub lis { |
||
Line 2,005: | Line 2,005: | ||
print join ' ', lis 3, 2, 6, 4, 5, 1; |
print join ' ', lis 3, 2, 6, 4, 5, 1; |
||
print join ' ', lis 0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15;</ |
print join ' ', lis 0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>2 4 5 |
<pre>2 4 5 |
||
Line 2,011: | Line 2,011: | ||
===Patience sorting=== |
===Patience sorting=== |
||
< |
<syntaxhighlight lang="perl">sub lis { |
||
my @pileTops; |
my @pileTops; |
||
# sort into piles |
# sort into piles |
||
Line 2,044: | Line 2,044: | ||
print "an L.I.S. of [@d] is [@lis]\n"; |
print "an L.I.S. of [@d] is [@lis]\n"; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>an L.I.S. of [3 2 6 4 5 1] is [2 4 5] |
<pre>an L.I.S. of [3 2 6 4 5 1] is [2 4 5] |
||
Line 2,051: | Line 2,051: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Using the Wikipedia algorithm (converted to 1-based indexing) |
Using the Wikipedia algorithm (converted to 1-based indexing) |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
<span style="color: #008080;">function</span> <span style="color: #000000;">lis</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">))</span> |
<span style="color: #008080;">function</span> <span style="color: #000000;">lis</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">))</span> |
||
Line 2,090: | Line 2,090: | ||
<span style="color: #0000FF;">?</span><span style="color: #000000;">lis</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> |
<span style="color: #0000FF;">?</span><span style="color: #000000;">lis</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> |
||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,099: | Line 2,099: | ||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
Patience sorting |
Patience sorting |
||
< |
<syntaxhighlight lang="php"><?php |
||
class Node { |
class Node { |
||
public $val; |
public $val; |
||
Line 2,135: | Line 2,135: | ||
print_r(lis(array(3, 2, 6, 4, 5, 1))); |
print_r(lis(array(3, 2, 6, 4, 5, 1))); |
||
print_r(lis(array(0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15))); |
print_r(lis(array(0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15))); |
||
?></ |
?></syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Array |
<pre>Array |
||
Line 2,156: | Line 2,156: | ||
===Mode-directed tabling=== |
===Mode-directed tabling=== |
||
{{trans|Prolog}} |
{{trans|Prolog}} |
||
< |
<syntaxhighlight lang="picat">table(+,+,max) |
||
lis_mode(In, Out,OutLen) => |
lis_mode(In, Out,OutLen) => |
||
one_is(In, [], Is), |
one_is(In, [], Is), |
||
Line 2,166: | Line 2,166: | ||
( Current = [], one_is(T, [H], Final)); |
( Current = [], one_is(T, [H], Final)); |
||
( Current = [H1|_], H1 @< H, one_is(T, [H|Current], Final)); |
( Current = [H1|_], H1 @< H, one_is(T, [H|Current], Final)); |
||
one_is(T, Current, Final).</ |
one_is(T, Current, Final).</syntaxhighlight> |
||
===Constraint modelling approach=== |
===Constraint modelling approach=== |
||
For larger instances, the sat solver is generally faster than the cp solver. |
For larger instances, the sat solver is generally faster than the cp solver. |
||
< |
<syntaxhighlight lang="picat">lis_cp(S, Res,Z) => |
||
Len = S.len, |
Len = S.len, |
||
X = new_list(Len), |
X = new_list(Len), |
||
Line 2,189: | Line 2,189: | ||
foreach(I in 1..N, J in I+1..N) |
foreach(I in 1..N, J in I+1..N) |
||
(A[I] #!= 0 #/\ A[J] #!= 0) #=> (A[I] #< A[J]) |
(A[I] #!= 0 #/\ A[J] #!= 0) #=> (A[I] #< A[J]) |
||
end.</ |
end.</syntaxhighlight> |
||
===Test=== |
===Test=== |
||
< |
<syntaxhighlight lang="picat">import sat. % for lis_cp |
||
% import cp. % Slower than sat on larger instances. |
% import cp. % Slower than sat on larger instances. |
||
Line 2,213: | Line 2,213: | ||
nl, |
nl, |
||
end, |
end, |
||
nl.</ |
nl.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,225: | Line 2,225: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
Adapted patience sorting approach: |
Adapted patience sorting approach: |
||
< |
<syntaxhighlight lang="picolisp">(de longinc (Lst) |
||
(let (D NIL R NIL) |
(let (D NIL R NIL) |
||
(for I Lst |
(for I Lst |
||
Line 2,237: | Line 2,237: | ||
(T (when R (queue 'D (car R))) |
(T (when R (queue 'D (car R))) |
||
(push 'R I) ) ) ) |
(push 'R I) ) ) ) |
||
(flip R) ) )</ |
(flip R) ) )</syntaxhighlight> |
||
Original recursive glutton: |
Original recursive glutton: |
||
< |
<syntaxhighlight lang="picolisp">(de glutton (L) |
||
(let N (pop 'L) |
(let N (pop 'L) |
||
(maxi length |
(maxi length |
||
Line 2,260: | Line 2,260: | ||
(test (-31 0 83 782) |
(test (-31 0 83 782) |
||
(glutton (4 65 2 -31 0 99 83 782 1)) )</ |
(glutton (4 65 2 -31 0 99 83 782 1)) )</syntaxhighlight> |
||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
{{works with|PowerShell|2}} |
{{works with|PowerShell|2}} |
||
< |
<syntaxhighlight lang="powershell">function Get-LongestSubsequence ( [int[]]$A ) |
||
{ |
{ |
||
If ( $A.Count -lt 2 ) { return $A } |
If ( $A.Count -lt 2 ) { return $A } |
||
Line 2,311: | Line 2,311: | ||
# Return the series (reversed into the correct order) |
# Return the series (reversed into the correct order) |
||
return $S[$Last..0] |
return $S[$Last..0] |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="powershell">( Get-LongestSubsequence 3, 2, 6, 4, 5, 1 ) -join ', ' |
||
( Get-LongestSubsequence 0, 8, 4, 12, 2, 10, 6, 16, 14, 1, 9, 5, 13, 3, 11, 7, 15 ) -join ', '</ |
( Get-LongestSubsequence 0, 8, 4, 12, 2, 10, 6, 16, 14, 1, 9, 5, 13, 3, 11, 7, 15 ) -join ', '</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>2, 4, 5 |
<pre>2, 4, 5 |
||
Line 2,323: | Line 2,323: | ||
< |
<syntaxhighlight lang="prolog">lis(In, Out) :- |
||
% we ask Prolog to find the longest sequence |
% we ask Prolog to find the longest sequence |
||
aggregate(max(N,Is), (one_is(In, [], Is), length(Is, N)), max(_, Res)), |
aggregate(max(N,Is), (one_is(In, [], Is), length(Is, N)), max(_, Res)), |
||
Line 2,337: | Line 2,337: | ||
( Current = [H1 | _], H1 < H, one_is(T, [H | Current], Final)); |
( Current = [H1 | _], H1 < H, one_is(T, [H | Current], Final)); |
||
one_is(T, Current, Final). |
one_is(T, Current, Final). |
||
</syntaxhighlight> |
|||
</lang> |
|||
Prolog finds the first longest subsequence |
Prolog finds the first longest subsequence |
||
<pre> ?- lis([0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15], Out). |
<pre> ?- lis([0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15], Out). |
||
Line 2,349: | Line 2,349: | ||
===Python: O(nlogn) Method from Wikipedia's LIS Article[https://en.wikipedia.org/wiki/Longest_increasing_subsequence#Efficient_algorithms]=== |
===Python: O(nlogn) Method from Wikipedia's LIS Article[https://en.wikipedia.org/wiki/Longest_increasing_subsequence#Efficient_algorithms]=== |
||
< |
<syntaxhighlight lang="python">def longest_increasing_subsequence(X): |
||
"""Returns the Longest Increasing Subsequence in the Given List/Array""" |
"""Returns the Longest Increasing Subsequence in the Given List/Array""" |
||
N = len(X) |
N = len(X) |
||
Line 2,381: | Line 2,381: | ||
if __name__ == '__main__': |
if __name__ == '__main__': |
||
for d in [[3,2,6,4,5,1], [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]]: |
for d in [[3,2,6,4,5,1], [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]]: |
||
print('a L.I.S. of %s is %s' % (d, longest_increasing_subsequence(d)))</ |
print('a L.I.S. of %s is %s' % (d, longest_increasing_subsequence(d)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,388: | Line 2,388: | ||
===Python: Method from video=== |
===Python: Method from video=== |
||
< |
<syntaxhighlight lang="python">def longest_increasing_subsequence(d): |
||
'Return one of the L.I.S. of list d' |
'Return one of the L.I.S. of list d' |
||
l = [] |
l = [] |
||
Line 2,398: | Line 2,398: | ||
if __name__ == '__main__': |
if __name__ == '__main__': |
||
for d in [[3,2,6,4,5,1], [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]]: |
for d in [[3,2,6,4,5,1], [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]]: |
||
print('a L.I.S. of %s is %s' % (d, longest_increasing_subsequence(d)))</ |
print('a L.I.S. of %s is %s' % (d, longest_increasing_subsequence(d)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,405: | Line 2,405: | ||
===Python: Patience sorting method=== |
===Python: Patience sorting method=== |
||
< |
<syntaxhighlight lang="python">from collections import namedtuple |
||
from functools import total_ordering |
from functools import total_ordering |
||
from bisect import bisect_left |
from bisect import bisect_left |
||
Line 2,433: | Line 2,433: | ||
for d in [[3,2,6,4,5,1], |
for d in [[3,2,6,4,5,1], |
||
[0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]]: |
[0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]]: |
||
print('a L.I.S. of %s is %s' % (d, lis(d)))</ |
print('a L.I.S. of %s is %s' % (d, lis(d)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,441: | Line 2,441: | ||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
Patience sorting. The program saves only the top card of each pile, with a link (cons) to the top of the previous pile at the time it was inserted. It uses binary search to find the correct pile. |
Patience sorting. The program saves only the top card of each pile, with a link (cons) to the top of the previous pile at the time it was inserted. It uses binary search to find the correct pile. |
||
< |
<syntaxhighlight lang="racket">#lang racket/base |
||
(require data/gvector) |
(require data/gvector) |
||
Line 2,467: | Line 2,467: | ||
(if (<= item (car (gvector-ref piles middle))) |
(if (<= item (car (gvector-ref piles middle))) |
||
(loop first middle) |
(loop first middle) |
||
(loop (add1 middle) last)))))])))</ |
(loop (add1 middle) last)))))])))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>'(2 4 5) |
<pre>'(2 4 5) |
||
Line 2,478: | Line 2,478: | ||
Straight-forward implementation of the algorithm described in the video. |
Straight-forward implementation of the algorithm described in the video. |
||
<lang |
<syntaxhighlight lang="raku" line>sub lis(@d) { |
||
my @l = [].item xx @d; |
my @l = [].item xx @d; |
||
@l[0].push: @d[0]; |
@l[0].push: @d[0]; |
||
Line 2,493: | Line 2,493: | ||
say lis([3,2,6,4,5,1]); |
say lis([3,2,6,4,5,1]); |
||
say lis([0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15]);</ |
say lis([0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15]);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>[2 4 5] |
<pre>[2 4 5] |
||
Line 2,499: | Line 2,499: | ||
===Patience sorting=== |
===Patience sorting=== |
||
<lang |
<syntaxhighlight lang="raku" line>sub lis(@deck is copy) { |
||
my @S = [@deck.shift() => Nil].item; |
my @S = [@deck.shift() => Nil].item; |
||
for @deck -> $card { |
for @deck -> $card { |
||
Line 2,514: | Line 2,514: | ||
say lis <3 2 6 4 5 1>; |
say lis <3 2 6 4 5 1>; |
||
say lis <0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15>;</ |
say lis <0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15>;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>[2 4 5] |
<pre>[2 4 5] |
||
Line 2,521: | Line 2,521: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
{{trans|VBScript}} |
{{trans|VBScript}} |
||
< |
<syntaxhighlight lang="rexx">/*REXX program finds & displays the longest increasing subsequence from a list of #'s.*/ |
||
$.=; $.1= 3 2 6 4 5 1 /*define the 1st list to be examined. */ |
$.=; $.1= 3 2 6 4 5 1 /*define the 1st list to be examined. */ |
||
$.2= 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 /* " " 2nd " " " " */ |
$.2= 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 /* " " 2nd " " " " */ |
||
Line 2,553: | Line 2,553: | ||
do L; $= @.k $; k= p.k /*perform this DO loop L times. */ |
do L; $= @.k $; k= p.k /*perform this DO loop L times. */ |
||
end /*i*/ |
end /*i*/ |
||
return strip($) /*the result has an extra leading blank*/</ |
return strip($) /*the result has an extra leading blank*/</syntaxhighlight> |
||
{{out|output|text= when using the internal default input:}} |
{{out|output|text= when using the internal default input:}} |
||
<pre> |
<pre> |
||
Line 2,564: | Line 2,564: | ||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
< |
<syntaxhighlight lang="ring"> |
||
# Project : Longest increasing subsequence |
# Project : Longest increasing subsequence |
||
Line 2,623: | Line 2,623: | ||
see svect |
see svect |
||
see "}" + nl |
see "}" + nl |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 2,632: | Line 2,632: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Patience sorting |
Patience sorting |
||
< |
<syntaxhighlight lang="ruby">Node = Struct.new(:val, :back) |
||
def lis(n) |
def lis(n) |
||
Line 2,664: | Line 2,664: | ||
p lis([3, 2, 6, 4, 5, 1]) |
p lis([3, 2, 6, 4, 5, 1]) |
||
p lis([0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15])</ |
p lis([0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>[2, 4, 5] |
<pre>[2, 4, 5] |
||
Line 2,671: | Line 2,671: | ||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
<syntaxhighlight lang="rust"> |
|||
<lang Rust> |
|||
fn lis(x: &[i32])-> Vec<i32> { |
fn lis(x: &[i32])-> Vec<i32> { |
||
let n = x.len(); |
let n = x.len(); |
||
Line 2,716: | Line 2,716: | ||
let list = vec![0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]; |
let list = vec![0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]; |
||
println!("{:?}", lis(&list)); |
println!("{:?}", lis(&list)); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,725: | Line 2,725: | ||
===Patience sorting=== |
===Patience sorting=== |
||
{{Out}}See it in running in your browser by [https://scalafiddle.io/sf/Wx8DsUO/1 ScalaFiddle (JavaScript)] or by [https://scastie.scala-lang.org/FtLHeaAwSrO6VXVOTTZ7FQ Scastie (JVM)]. |
{{Out}}See it in running in your browser by [https://scalafiddle.io/sf/Wx8DsUO/1 ScalaFiddle (JavaScript)] or by [https://scastie.scala-lang.org/FtLHeaAwSrO6VXVOTTZ7FQ Scastie (JVM)]. |
||
< |
<syntaxhighlight lang="scala">object LongestIncreasingSubsequence extends App { |
||
val tests = Map( |
val tests = Map( |
||
"3,2,6,4,5,1" -> Seq("2,4,5", "3,4,5"), |
"3,2,6,4,5,1" -> Seq("2,4,5", "3,4,5"), |
||
Line 2,757: | Line 2,757: | ||
allLongests.forall(lis => expect.contains(lis.mkString(","))) |
allLongests.forall(lis => expect.contains(lis.mkString(","))) |
||
}) |
}) |
||
}</ |
}</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>3,2,6,4,5,1 has 2 longest increasing subsequences, e.g. 2,4,5 |
<pre>3,2,6,4,5,1 has 2 longest increasing subsequences, e.g. 2,4,5 |
||
Line 2,763: | Line 2,763: | ||
===Brute force solution=== |
===Brute force solution=== |
||
< |
<syntaxhighlight lang="scala">def powerset[A](s: List[A]) = (0 to s.size).map(s.combinations(_)).reduce(_++_) |
||
def isSorted(l:List[Int])(f: (Int, Int) => Boolean) = l.view.zip(l.tail).forall(x => f(x._1,x._2)) |
def isSorted(l:List[Int])(f: (Int, Int) => Boolean) = l.view.zip(l.tail).forall(x => f(x._1,x._2)) |
||
def sequence(set: List[Int])(f: (Int, Int) => Boolean) = powerset(set).filter(_.nonEmpty).filter(x => isSorted(x)(f)).toList.maxBy(_.length) |
def sequence(set: List[Int])(f: (Int, Int) => Boolean) = powerset(set).filter(_.nonEmpty).filter(x => isSorted(x)(f)).toList.maxBy(_.length) |
||
sequence(set)(_<_) |
sequence(set)(_<_) |
||
sequence(set)(_>_)</ |
sequence(set)(_>_)</syntaxhighlight> |
||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
Patience sorting |
Patience sorting |
||
< |
<syntaxhighlight lang="scheme">(define (lis less? lst) |
||
(define pile-tops (make-vector (length lst))) |
(define pile-tops (make-vector (length lst))) |
||
(define (bsearch-piles x len) |
(define (bsearch-piles x len) |
||
Line 2,795: | Line 2,795: | ||
(display (lis < '(3 2 6 4 5 1))) (newline) |
(display (lis < '(3 2 6 4 5 1))) (newline) |
||
(display (lis < '(0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15))) (newline)</ |
(display (lis < '(0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15))) (newline)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,803: | Line 2,803: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
Dynamic programming: |
Dynamic programming: |
||
< |
<syntaxhighlight lang="ruby">func lis(a) { |
||
var l = a.len.of { [] } |
var l = a.len.of { [] } |
||
l[0] << a[0] |
l[0] << a[0] |
||
Line 2,818: | Line 2,818: | ||
say lis(%i<3 2 6 4 5 1>) |
say lis(%i<3 2 6 4 5 1>) |
||
say lis(%i<0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15>)</ |
say lis(%i<0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15>)</syntaxhighlight> |
||
Patience sorting: |
Patience sorting: |
||
< |
<syntaxhighlight lang="ruby">func lis(deck) { |
||
var pileTops = [] |
var pileTops = [] |
||
deck.each { |x| |
deck.each { |x| |
||
Line 2,847: | Line 2,847: | ||
say lis(%i<3 2 6 4 5 1>) |
say lis(%i<3 2 6 4 5 1>) |
||
say lis(%i<0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15>)</ |
say lis(%i<0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15>)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,858: | Line 2,858: | ||
Patience sorting |
Patience sorting |
||
{{works with|SML/NJ}} |
{{works with|SML/NJ}} |
||
< |
<syntaxhighlight lang="sml">fun lis cmp n = |
||
let |
let |
||
val pile_tops = DynamicArray.array (length n, []) |
val pile_tops = DynamicArray.array (length n, []) |
||
Line 2,888: | Line 2,888: | ||
app f n; |
app f n; |
||
rev (DynamicArray.sub (pile_tops, DynamicArray.bound pile_tops)) |
rev (DynamicArray.sub (pile_tops, DynamicArray.bound pile_tops)) |
||
end</ |
end</syntaxhighlight> |
||
Usage: |
Usage: |
||
<pre>- lis Int.compare [3, 2, 6, 4, 5, 1]; |
<pre>- lis Int.compare [3, 2, 6, 4, 5, 1]; |
||
Line 2,897: | Line 2,897: | ||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<syntaxhighlight lang="swift">import Foundation |
||
extension Array where Element: Comparable { |
extension Array where Element: Comparable { |
||
Line 2,944: | Line 2,944: | ||
print("\(l1) = \(l1.longestIncreasingSubsequence())") |
print("\(l1) = \(l1.longestIncreasingSubsequence())") |
||
print("\(l2) = \(l2.longestIncreasingSubsequence())")</ |
print("\(l2) = \(l2.longestIncreasingSubsequence())")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,954: | Line 2,954: | ||
{{trans|Python}} |
{{trans|Python}} |
||
Based on the Python video solution. Interpreter at [[http://cheersgames.com/swym/SwymInterpreter.html?Array.%27lis%27%0A%7B%0A%20%20%27stems%27%20%3D%20Number.Array.mutableArray%5B%20%5B%5D%20%5D%0A%20%0A%20%20forEach%28this%29%20%27value%27-%3E%0A%20%20%7B%0A%20%20%20%20%27bestStem%27%20%3D%20stems.where%7B%3D%3D%5B%5D%20%7C%7C%20.last%20%3C%20value%7D.max%7B.length%7D%0A%20%0A%20%20%20%20stems.push%28%20bestStem%20+%20%5Bvalue%5D%20%29%0A%20%20%7D%0A%20%0A%20%20return%20stems.max%7B.length%7D%0A%7D%0A%20%0A%5B3%2C2%2C6%2C4%2C5%2C1%5D.lis.trace%0A%5B0%2C8%2C4%2C12%2C2%2C10%2C6%2C14%2C1%2C9%2C5%2C13%2C3%2C11%2C7%2C15%5D.lis.trace]] |
Based on the Python video solution. Interpreter at [[http://cheersgames.com/swym/SwymInterpreter.html?Array.%27lis%27%0A%7B%0A%20%20%27stems%27%20%3D%20Number.Array.mutableArray%5B%20%5B%5D%20%5D%0A%20%0A%20%20forEach%28this%29%20%27value%27-%3E%0A%20%20%7B%0A%20%20%20%20%27bestStem%27%20%3D%20stems.where%7B%3D%3D%5B%5D%20%7C%7C%20.last%20%3C%20value%7D.max%7B.length%7D%0A%20%0A%20%20%20%20stems.push%28%20bestStem%20+%20%5Bvalue%5D%20%29%0A%20%20%7D%0A%20%0A%20%20return%20stems.max%7B.length%7D%0A%7D%0A%20%0A%5B3%2C2%2C6%2C4%2C5%2C1%5D.lis.trace%0A%5B0%2C8%2C4%2C12%2C2%2C10%2C6%2C14%2C1%2C9%2C5%2C13%2C3%2C11%2C7%2C15%5D.lis.trace]] |
||
< |
<syntaxhighlight lang="swym">Array.'lis' |
||
{ |
{ |
||
'stems' = Number.Array.mutableArray[ [] ] |
'stems' = Number.Array.mutableArray[ [] ] |
||
Line 2,969: | Line 2,969: | ||
[3,2,6,4,5,1].lis.trace |
[3,2,6,4,5,1].lis.trace |
||
[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15].lis.trace</ |
[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15].lis.trace</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,978: | Line 2,978: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{works with|Tcl|8.6}} |
{{works with|Tcl|8.6}} |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.6 |
||
proc longestIncreasingSubsequence {sequence} { |
proc longestIncreasingSubsequence {sequence} { |
||
Line 2,998: | Line 2,998: | ||
# Pick the longest subsequence; -stride requires Tcl 8.6 |
# Pick the longest subsequence; -stride requires Tcl 8.6 |
||
return [lindex [lsort -stride 2 -index 0 $subseq] end] |
return [lindex [lsort -stride 2 -index 0 $subseq] end] |
||
}</ |
}</syntaxhighlight> |
||
Demonstrating: |
Demonstrating: |
||
< |
<syntaxhighlight lang="tcl">puts [longestIncreasingSubsequence {3 2 6 4 5 1}] |
||
puts [longestIncreasingSubsequence {0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15}]</ |
puts [longestIncreasingSubsequence {0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15}]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,009: | Line 3,009: | ||
=={{header|VBScript}}== |
=={{header|VBScript}}== |
||
<syntaxhighlight lang="vb"> |
|||
<lang vb> |
|||
Function LIS(arr) |
Function LIS(arr) |
||
n = UBound(arr) |
n = UBound(arr) |
||
Line 3,047: | Line 3,047: | ||
WScript.StdOut.WriteLine LIS(Array(3,2,6,4,5,1)) |
WScript.StdOut.WriteLine LIS(Array(3,2,6,4,5,1)) |
||
WScript.StdOut.WriteLine LIS(Array(0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15)) |
WScript.StdOut.WriteLine LIS(Array(0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
Line 3,057: | Line 3,057: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{trans|Kotlin}} |
{{trans|Kotlin}} |
||
< |
<syntaxhighlight lang="ecmascript">var longestIncreasingSubsequence = Fn.new { |x| |
||
var n = x.count |
var n = x.count |
||
if (n == 0) return [] |
if (n == 0) return [] |
||
Line 3,093: | Line 3,093: | ||
[0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15] |
[0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15] |
||
] |
] |
||
lists.each { |l| System.print(longestIncreasingSubsequence.call(l)) }</ |
lists.each { |l| System.print(longestIncreasingSubsequence.call(l)) }</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,102: | Line 3,102: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
< |
<syntaxhighlight lang="zkl">fcn longestSequence(ns){ // based on Patience sorting |
||
piles:=L(); |
piles:=L(); |
||
backPtr:='wrap(np){ return(np-1,if(np) piles[np-1].len()-1 else -1) }; // maybe (-1,-1) |
backPtr:='wrap(np){ return(np-1,if(np) piles[np-1].len()-1 else -1) }; // maybe (-1,-1) |
||
Line 3,118: | Line 3,118: | ||
do{ n,p=piles[p][n]; r.write(n); p,n=p; }while(p!=-1); |
do{ n,p=piles[p][n]; r.write(n); p,n=p; }while(p!=-1); |
||
r.reverse() |
r.reverse() |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl">foreach ns in (T(T(1),T(3,2,6,4,5,1),T(4,65,2,-31,0,99,83,782,1), |
||
T(0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15),"foobar")){ |
T(0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15),"foobar")){ |
||
s:=longestSequence(ns); |
s:=longestSequence(ns); |
||
println(s.len(),": ",s," from ",ns); |
println(s.len(),": ",s," from ",ns); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |