Update all new Tasks
This commit is contained in:
parent
00a190b0a6
commit
91df62d461
5697 changed files with 93386 additions and 804 deletions
10
Task/Longest-increasing-subsequence/00DESCRIPTION
Normal file
10
Task/Longest-increasing-subsequence/00DESCRIPTION
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
Calculate and show here a [[wp:Longest increasing subsequence|longest increasing subsequence]] of the list:
|
||||
:<math>\{3, 2, 6, 4, 5, 1\}</math>
|
||||
And of the list:
|
||||
:<math>\{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15\}</math>
|
||||
|
||||
Note that a list may have more than one subsequence that is of the maximum length.
|
||||
|
||||
;Ref:
|
||||
# [http://www.youtube.com/watch?v=4fQJGoeW5VE Dynamic Programming #1: Longest Increasing Subsequence] on Youtube
|
||||
# An efficient solution can be based on [[wp:Patience sorting|Patience sorting]].
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
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 {
|
||||
D := LIS(v)
|
||||
MsgBox, % D[D.I].seq
|
||||
}
|
||||
|
||||
LIS(L) {
|
||||
D := []
|
||||
for i, v in L {
|
||||
D[i, "Length"] := 1, D[i, "Seq"] := v, D[i, "Val"] := v
|
||||
Loop, % i - 1 {
|
||||
if(D[A_Index].Val < v && D[A_Index].Length + 1 > D[i].Length) {
|
||||
D[i].Length := D[A_Index].Length + 1
|
||||
D[i].Seq := D[A_Index].Seq ", " v
|
||||
if (D[i].Length > MaxLength)
|
||||
MaxLength := D[i].Length, D.I := i
|
||||
}
|
||||
}
|
||||
}
|
||||
return, D
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <tr1/memory>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
template <typename E>
|
||||
struct Node {
|
||||
E value;
|
||||
std::tr1::shared_ptr<Node<E> > pointer;
|
||||
};
|
||||
|
||||
template <class E>
|
||||
struct node_ptr_less {
|
||||
bool operator()(const std::tr1::shared_ptr<Node<E> > &node1,
|
||||
const std::tr1::shared_ptr<Node<E> > &node2) const {
|
||||
return node1->value < node2->value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename E>
|
||||
std::vector<E> lis(const std::vector<E> &n) {
|
||||
typedef std::tr1::shared_ptr<Node<E> > NodePtr;
|
||||
|
||||
std::vector<NodePtr> pileTops;
|
||||
// sort into piles
|
||||
for (typename std::vector<E>::const_iterator it = n.begin(); it != n.end(); it++) {
|
||||
NodePtr node(new Node<E>());
|
||||
node->value = *it;
|
||||
typename std::vector<NodePtr>::iterator j =
|
||||
std::lower_bound(pileTops.begin(), pileTops.end(), node, node_ptr_less<E>());
|
||||
if (j != pileTops.begin())
|
||||
node->pointer = *(j-1);
|
||||
if (j != pileTops.end())
|
||||
*j = node;
|
||||
else
|
||||
pileTops.push_back(node);
|
||||
}
|
||||
// extract LIS from piles
|
||||
std::vector<E> result;
|
||||
for (NodePtr node = pileTops.back(); node != NULL; node = node->pointer)
|
||||
result.push_back(node->value);
|
||||
std::reverse(result.begin(), result.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int arr1[] = {3,2,6,4,5,1};
|
||||
std::vector<int> vec1(arr1, arr1 + sizeof(arr1)/sizeof(*arr1));
|
||||
std::vector<int> result1 = lis(vec1);
|
||||
std::copy(result1.begin(), result1.end(), std::ostream_iterator<int>(std::cout, ", "));
|
||||
std::cout << std::endl;
|
||||
|
||||
int arr2[] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
|
||||
std::vector<int> vec2(arr2, arr2 + sizeof(arr2)/sizeof(*arr2));
|
||||
std::vector<int> result2 = lis(vec2);
|
||||
std::copy(result2.begin(), result2.end(), std::ostream_iterator<int>(std::cout, ", "));
|
||||
std::cout << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct node {
|
||||
int val, len;
|
||||
struct node *next;
|
||||
};
|
||||
|
||||
void lis(int *v, int len)
|
||||
{
|
||||
int i;
|
||||
struct node *p, *n = calloc(len, sizeof *n);
|
||||
for (i = 0; i < len; i++)
|
||||
n[i].val = v[i];
|
||||
|
||||
for (i = len; i--; ) {
|
||||
// find longest chain that can follow n[i]
|
||||
for (p = n + i; p++ < n + len; ) {
|
||||
if (p->val > n[i].val && p->len >= n[i].len) {
|
||||
n[i].next = p;
|
||||
n[i].len = p->len + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find longest chain
|
||||
for (i = 0, p = n; i < len; i++)
|
||||
if (n[i].len > p->len) p = n + i;
|
||||
|
||||
do printf(" %d", p->val); while ((p = p->next));
|
||||
putchar('\n');
|
||||
|
||||
free(n);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int x[] = { 3, 2, 6, 4, 5, 1 };
|
||||
int y[] = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 };
|
||||
|
||||
lis(x, sizeof(x) / sizeof(int));
|
||||
lis(y, sizeof(y) / sizeof(int));
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
(defn place [piles card]
|
||||
(let [[les gts] (->> piles (split-with #(<= (ffirst %) card)))
|
||||
newelem (cons card (->> les last first))
|
||||
modpile (cons newelem (first gts))]
|
||||
(concat les (cons modpile (rest gts)))))
|
||||
|
||||
(defn a-longest [cards]
|
||||
(let [piles (reduce place '() cards)]
|
||||
(->> piles last first reverse)))
|
||||
|
||||
(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]))
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
(2 4 5)
|
||||
(0 2 6 9 11 15)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
(defun longest-increasing-subseq (list)
|
||||
(let ((subseqs nil))
|
||||
(dolist (item list)
|
||||
(let ((longest-so-far (longest-list-in-lists (remove-if-not #'(lambda (l) (> item (car l))) subseqs))))
|
||||
(push (cons item longest-so-far) subseqs)))
|
||||
(reverse (longest-list-in-lists subseqs))))
|
||||
|
||||
(defun longest-list-in-lists (lists)
|
||||
(let ((longest nil)
|
||||
(longest-len 0))
|
||||
(dolist (list lists)
|
||||
(let ((len (length list)))
|
||||
(when (> len longest-len)
|
||||
(setf longest list
|
||||
longest-len len))))
|
||||
longest))
|
||||
|
||||
(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)))
|
||||
(format t "~A~%" (longest-increasing-subseq l))))
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
(defun lis-patience-sort (input-list)
|
||||
(let ((piles nil))
|
||||
(dolist (item input-list)
|
||||
(setf piles (insert-item item piles)))
|
||||
(reverse (caar (last piles)))))
|
||||
|
||||
(defun insert-item (item piles)
|
||||
(let ((not-found t))
|
||||
(loop
|
||||
while not-found
|
||||
for pile in piles
|
||||
and prev = nil then pile
|
||||
and i from 0
|
||||
do (when (<= item (caar pile))
|
||||
(setf (elt piles i) (push (cons item (car prev)) (elt piles i))
|
||||
not-found nil)))
|
||||
(if not-found
|
||||
(append piles (list (list (cons item (caar (last piles))))))
|
||||
piles)))
|
||||
|
||||
(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)))
|
||||
(format t "~A~%" (lis-patience-sort l)))
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
(defun insert-item (item piles)
|
||||
(multiple-value-bind
|
||||
(i prev)
|
||||
(do* ((prev nil (car x))
|
||||
(x piles (cdr x))
|
||||
(i 0 (1+ i)))
|
||||
((or (null x) (<= item (caaar x))) (values i prev)))
|
||||
(if (= i (length piles))
|
||||
(append piles (list (list (cons item (caar (last piles))))))
|
||||
(progn (push (cons item (car prev)) (elt piles i))
|
||||
piles))))
|
||||
|
||||
(defun longest-inc-seq (input)
|
||||
(do* ((piles nil (insert-item (car x) piles))
|
||||
(x input (cdr x)))
|
||||
((null x) (reverse (caar (last piles))))))
|
||||
|
||||
(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)))
|
||||
(format t "~A~%" (longest-inc-seq l)))
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import std.stdio, std.algorithm, power_set2;
|
||||
|
||||
T[] lis(T)(T[] items) pure nothrow {
|
||||
//return items.powerSet.filter!isSorted.max!q{ a.length };
|
||||
return items
|
||||
.powerSet
|
||||
.filter!isSorted
|
||||
.minPos!q{ a.length > b.length }
|
||||
.front;
|
||||
}
|
||||
|
||||
void main() {
|
||||
[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,0 +1,38 @@
|
|||
import std.stdio, std.algorithm, std.array;
|
||||
|
||||
/// Return one of the Longest Increasing Subsequence of
|
||||
/// items using patience sorting.
|
||||
T[] lis(T)(in T[] items) pure nothrow
|
||||
if (__traits(compiles, T.init < T.init))
|
||||
out(result) {
|
||||
assert(result.length <= items.length);
|
||||
assert(result.isSorted);
|
||||
assert(result.all!(x => items.canFind(x)));
|
||||
} body {
|
||||
if (items.empty)
|
||||
return null;
|
||||
|
||||
static struct Node { T val; Node* back; }
|
||||
auto pile = [[new Node(items[0])]];
|
||||
|
||||
OUTER: foreach (immutable di; items[1 .. $]) {
|
||||
foreach (immutable j, ref pj; pile)
|
||||
if (pj[$ - 1].val > di) {
|
||||
pj ~= new Node(di, j ? pile[j - 1][$ - 1] : null);
|
||||
continue OUTER;
|
||||
}
|
||||
pile ~= [new Node(di, pile[$ - 1][$ - 1])];
|
||||
}
|
||||
|
||||
T[] result;
|
||||
for (auto ptr = pile[$ - 1][$ - 1]; ptr != null; ptr = ptr.back)
|
||||
result ~= ptr.val;
|
||||
result.reverse();
|
||||
return result;
|
||||
}
|
||||
|
||||
void main() {
|
||||
foreach (d; [[3,2,6,4,5,1],
|
||||
[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15]])
|
||||
d.lis.writeln;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import std.stdio, std.algorithm, std.range, std.array;
|
||||
|
||||
T[] lis(T)(in T[] items) pure nothrow
|
||||
if (__traits(compiles, T.init < T.init))
|
||||
out(result) {
|
||||
assert(result.length <= items.length);
|
||||
assert(result.isSorted);
|
||||
assert(result.all!(x => items.canFind(x)));
|
||||
} body {
|
||||
if (items.empty)
|
||||
return null;
|
||||
|
||||
static struct Node {
|
||||
T value;
|
||||
Node* pointer;
|
||||
}
|
||||
Node*[] pileTops;
|
||||
auto nodes = minimallyInitializedArray!(Node[])(items.length);
|
||||
|
||||
// Sort into piles.
|
||||
foreach (idx, x; items) {
|
||||
auto node = &nodes[idx];
|
||||
node.value = x;
|
||||
immutable i = pileTops.length -
|
||||
pileTops.assumeSorted!q{a.value < b.value}
|
||||
.upperBound(node)
|
||||
.length;
|
||||
if (i != 0)
|
||||
node.pointer = pileTops[i - 1];
|
||||
if (i != pileTops.length)
|
||||
pileTops[i] = node;
|
||||
else
|
||||
pileTops ~= node;
|
||||
}
|
||||
|
||||
// Extract LIS from nodes.
|
||||
size_t count = 0;
|
||||
for (auto n = pileTops[$ - 1]; n != null; n = n.pointer)
|
||||
count++;
|
||||
auto result = minimallyInitializedArray!(T[])(count);
|
||||
for (auto n = pileTops[$ - 1]; n != null; n = n.pointer)
|
||||
result[--count] = n.value;
|
||||
return result;
|
||||
}
|
||||
|
||||
void main() {
|
||||
foreach (d; [[3,2,6,4,5,1],
|
||||
[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15]])
|
||||
d.writeln;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
in-pair:
|
||||
if = :nil dup:
|
||||
false drop
|
||||
else:
|
||||
@in-pair &> swap &< dup
|
||||
|
||||
get-last lst:
|
||||
get-from lst -- len lst
|
||||
|
||||
lis-sub pile i di:
|
||||
for j range 0 -- len pile:
|
||||
local :pj get-from pile j
|
||||
if > &< get-last pj di:
|
||||
push-to pj & di if j get-last get-from pile -- j :nil
|
||||
return
|
||||
push-to pile [ & di get-last get-last pile ]
|
||||
|
||||
lis d:
|
||||
local :pile [ [ & get-from d 0 :nil ] ]
|
||||
for i range 1 -- len d:
|
||||
lis-sub pile i get-from d i
|
||||
[ for in-pair get-last get-last pile ]
|
||||
|
||||
!. lis [ 3 2 6 4 5 1 ]
|
||||
!. lis [ 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 ]
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type Node struct {
|
||||
val int
|
||||
back *Node
|
||||
}
|
||||
|
||||
func lis (n []int) (result []int) {
|
||||
var pileTops []*Node
|
||||
// sort into piles
|
||||
for _, x := range n {
|
||||
j := sort.Search(len(pileTops), func (i int) bool { return pileTops[i].val >= x })
|
||||
node := &Node{ x, nil }
|
||||
if j != 0 { node.back = pileTops[j-1] }
|
||||
if j != len(pileTops) {
|
||||
pileTops[j] = node
|
||||
} else {
|
||||
pileTops = append(pileTops, node)
|
||||
}
|
||||
}
|
||||
|
||||
if len(pileTops) == 0 { return []int{} }
|
||||
for node := pileTops[len(pileTops)-1]; node != nil; node = node.back {
|
||||
result = append(result, node.val)
|
||||
}
|
||||
// reverse
|
||||
for i := 0; i < len(result)/2; i++ {
|
||||
result[i], result[len(result)-i-1] = result[len(result)-i-1], result[i]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func main() {
|
||||
for _, d := range [][]int{{3, 2, 6, 4, 5, 1},
|
||||
{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}} {
|
||||
fmt.Printf("an L.I.S. of %v is %v\n", d, lis(d))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import Data.Ord ( comparing )
|
||||
import Data.List ( maximumBy, subsequences )
|
||||
import Data.List.Ordered ( isSorted, nub )
|
||||
|
||||
lis :: Ord a => [a] -> [a]
|
||||
lis = maximumBy (comparing length) . map nub . filter isSorted . subsequences
|
||||
-- longest <-- unique <-- increasing <-- all
|
||||
|
||||
main = do
|
||||
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 [1,1,1,1]
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
{-# LANGUAGE FlexibleContexts, UnicodeSyntax #-}
|
||||
|
||||
module Main (main, lis) where
|
||||
|
||||
import Control.Monad.ST ( ST, runST )
|
||||
import Control.Monad ( (>>=), (=<<), foldM )
|
||||
import Data.Array.ST ( Ix, STArray, readArray, writeArray, newArray )
|
||||
import Data.Array.MArray ( MArray )
|
||||
|
||||
infix 4 ≡
|
||||
|
||||
(≡) :: Eq α ⇒ α → α → Bool
|
||||
(≡) = (==)
|
||||
|
||||
(∘) = (.)
|
||||
|
||||
|
||||
lis ∷ Ord α ⇒ [α] → [α]
|
||||
lis xs = runST $ do
|
||||
let lxs = length xs
|
||||
pileTops ← newSTArray (min 1 lxs , lxs) []
|
||||
i ← foldM (stack pileTops) 0 xs
|
||||
readArray pileTops i >>= return ∘ reverse
|
||||
|
||||
stack ∷ (Integral ι, Ord ε, Ix ι, MArray α [ε] μ)
|
||||
⇒ α ι [ε] → ι → ε → μ ι
|
||||
stack piles i x = do
|
||||
j ← bsearch piles x i
|
||||
writeArray piles j ∘ (x:) =<< if j ≡ 1 then return []
|
||||
else readArray piles (j-1)
|
||||
return $ if j ≡ i+1 then i+1 else i
|
||||
|
||||
bsearch ∷ (Integral ι, Ord ε, Ix ι, MArray α [ε] μ)
|
||||
⇒ α ι [ε] → ε → ι → μ ι
|
||||
bsearch piles x = go 1
|
||||
where go lo hi | lo > hi = return lo
|
||||
| otherwise =
|
||||
do (y:_) ← readArray piles mid
|
||||
if y < x then go (succ mid) hi
|
||||
else go lo (pred mid)
|
||||
|
||||
where mid = (lo + hi) `div` 2
|
||||
|
||||
newSTArray ∷ Ix ι ⇒ (ι,ι) → ε → ST σ (STArray σ ι ε)
|
||||
newSTArray = newArray
|
||||
|
||||
|
||||
main ∷ IO ()
|
||||
main = do
|
||||
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 [1, 1, 1, 1]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
procedure main(A)
|
||||
every writes((!lis(A)||" ") | "\n")
|
||||
end
|
||||
|
||||
procedure lis(A)
|
||||
r := [A[1]] | fail
|
||||
every (put(pt := [], [v := !A]), p := !pt) do
|
||||
if put(p, p[-1] < v) then r := (*p > *r, p)
|
||||
else p[-1] := (p[-2] < v)
|
||||
return r
|
||||
end
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
increasing=: (-: /:~)@#~"1 #:@i.@^~&2@#
|
||||
longestinc=: ] #~ [: (#~ ([: (= >./) +/"1)) #:@I.@increasing
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
longestinc 3,2,6,4,5,1
|
||||
2 4 5
|
||||
3 4 5
|
||||
longestinc 0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15
|
||||
0 2 6 9 11 15
|
||||
0 2 6 9 13 15
|
||||
0 4 6 9 11 15
|
||||
0 4 6 9 13 15
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
import java.util.*;
|
||||
|
||||
public class LIS {
|
||||
public static <E extends Comparable<? super E>> List<E> lis(List<E> n) {
|
||||
List<Node<E>> pileTops = new ArrayList<Node<E>>();
|
||||
// sort into piles
|
||||
for (E x : n) {
|
||||
Node<E> node = new Node<E>();
|
||||
node.value = x;
|
||||
int i = Collections.binarySearch(pileTops, node);
|
||||
if (i < 0) i = ~i;
|
||||
if (i != 0)
|
||||
node.pointer = pileTops.get(i-1);
|
||||
if (i != pileTops.size())
|
||||
pileTops.set(i, node);
|
||||
else
|
||||
pileTops.add(node);
|
||||
}
|
||||
// extract LIS from nodes
|
||||
List<E> result = new ArrayList<E>();
|
||||
for (Node<E> node = pileTops.size() == 0 ? null : pileTops.get(pileTops.size()-1);
|
||||
node != null; node = node.pointer)
|
||||
result.add(node.value);
|
||||
Collections.reverse(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static class Node<E extends Comparable<? super E>> implements Comparable<Node<E>> {
|
||||
public E value;
|
||||
public Node<E> pointer;
|
||||
public int compareTo(Node<E> y) { return value.compareTo(y.value); }
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<Integer> d = Arrays.asList(3,2,6,4,5,1);
|
||||
System.out.printf("an L.I.S. of %s is %s\n", d, lis(d));
|
||||
d = Arrays.asList(0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15);
|
||||
System.out.printf("an L.I.S. of %s is %s\n", d, lis(d));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
var _ = require('underscore');
|
||||
function findIndex(input){
|
||||
var len = input.length;
|
||||
var maxSeqEndingHere = _.range(len).map(function(){return 1;});
|
||||
for(var i=0; i<len; i++)
|
||||
for(var j=i-1;j>=0;j--)
|
||||
if(input[i] > input[j] && maxSeqEndingHere[j] >= maxSeqEndingHere[i])
|
||||
maxSeqEndingHere[i] = maxSeqEndingHere[j]+1;
|
||||
return maxSeqEndingHere;
|
||||
}
|
||||
|
||||
function findSequence(input, result){
|
||||
var maxValue = Math.max.apply(null, result);
|
||||
var maxIndex = result.indexOf(Math.max.apply(Math, result));
|
||||
var output = [];
|
||||
output.push(input[maxIndex]);
|
||||
for(var i = maxIndex ; i >= 0; i--){
|
||||
if(maxValue==0)break;
|
||||
if(input[maxIndex] > input[i] && result[i] == maxValue-1){
|
||||
output.push(input[i]);
|
||||
maxValue--;
|
||||
}
|
||||
}
|
||||
output.reverse();
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
var x = [0, 7, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15];
|
||||
var y = [3, 2, 6, 4, 5, 1];
|
||||
|
||||
var result = findIndex(x);
|
||||
var final = findSequence(x, result);
|
||||
console.log(final);
|
||||
|
||||
var result1 = findIndex(y);
|
||||
var final1 = findSequence(y, result1);
|
||||
console.log(final1);
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
function buildLIS(seq)
|
||||
local piles = { { {table.remove(seq, 1), nil} } }
|
||||
while #seq>0 do
|
||||
local x=table.remove(seq, 1)
|
||||
for j=1,#piles do
|
||||
if piles[j][#piles[j]][1]>x then
|
||||
table.insert(piles[j], {x, (piles[j-1] and #piles[j-1])})
|
||||
break
|
||||
elseif j==#piles then
|
||||
table.insert(piles, {{x, #piles[j]}})
|
||||
end
|
||||
end
|
||||
end
|
||||
local t={}
|
||||
table.insert(t, piles[#piles][1][1])
|
||||
local p=piles[#piles][1][2]
|
||||
for i=#piles-1,1,-1 do
|
||||
table.insert(t, piles[i][p][1])
|
||||
p=piles[i][p][2]
|
||||
end
|
||||
table.sort(t)
|
||||
print(unpack(t))
|
||||
end
|
||||
|
||||
buildLIS({3,2,6,4,5,1})
|
||||
buildLIS({0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15})
|
||||
|
|
@ -0,0 +1 @@
|
|||
LongestAscendingSequence/@{{3,2,6,4,5,1},{0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15}}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
let longest l = List.fold_left (fun acc x -> if List.length acc < List.length x
|
||||
then x
|
||||
else acc) [] l
|
||||
|
||||
let subsequences d l =
|
||||
let rec check_subsequences acc = function
|
||||
| x::s -> check_subsequences (if (List.hd (List.rev x)) < d
|
||||
then x::acc
|
||||
else acc) s
|
||||
| [] -> acc
|
||||
in check_subsequences [] l
|
||||
|
||||
let lis d =
|
||||
let rec lis' l = function
|
||||
| x::s -> lis' ((longest (subsequences x l)@[x])::l) s
|
||||
| [] -> longest l
|
||||
in lis' [] d
|
||||
|
||||
let _ =
|
||||
let sequences = [[3; 2; 6; 4; 5; 1]; [0; 8; 4; 12; 2; 10; 6; 14; 1; 9; 5; 13; 3; 11; 7; 15]]
|
||||
in
|
||||
List.map (fun x -> print_endline (String.concat " " (List.map string_of_int
|
||||
(lis x)))) sequences
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
let lis cmp list =
|
||||
let pile_tops = Array.make (List.length list) [] in
|
||||
let bsearch_piles x len =
|
||||
let rec aux lo hi =
|
||||
if lo > hi then
|
||||
lo
|
||||
else
|
||||
let mid = (lo + hi) / 2 in
|
||||
if cmp (List.hd pile_tops.(mid)) x < 0 then
|
||||
aux (mid+1) hi
|
||||
else
|
||||
aux lo (mid-1)
|
||||
in
|
||||
aux 0 (len-1)
|
||||
in
|
||||
let f len x =
|
||||
let i = bsearch_piles x len in
|
||||
pile_tops.(i) <- x :: if i = 0 then [] else pile_tops.(i-1);
|
||||
if i = len then len+1 else len
|
||||
in
|
||||
let len = List.fold_left f 0 list in
|
||||
List.rev pile_tops.(len-1)
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Node : NSObject {
|
||||
@public
|
||||
id val;
|
||||
Node *back;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Node
|
||||
@end
|
||||
|
||||
@interface NSArray (LIS)
|
||||
- (NSArray *)longestIncreasingSubsequenceWithComparator:(NSComparator)comparator;
|
||||
@end
|
||||
|
||||
@implementation NSArray (LIS)
|
||||
- (NSArray *)longestIncreasingSubsequenceWithComparator:(NSComparator)comparator {
|
||||
NSMutableArray *pileTops = [[NSMutableArray alloc] init];
|
||||
// sort into piles
|
||||
for (id x in self) {
|
||||
Node *node = [[Node alloc] init];
|
||||
node->val = x;
|
||||
int i = [pileTops indexOfObject:node
|
||||
inSortedRange:NSMakeRange(0, [pileTops count])
|
||||
options:NSBinarySearchingInsertionIndex|NSBinarySearchingFirstEqual
|
||||
usingComparator:^NSComparisonResult(Node *node1, Node *node2) {
|
||||
return comparator(node1->val, node2->val);
|
||||
}];
|
||||
if (i != 0)
|
||||
node->back = pileTops[i-1];
|
||||
pileTops[i] = node;
|
||||
}
|
||||
|
||||
// follow pointers from last node
|
||||
NSMutableArray *result = [[NSMutableArray alloc] init];
|
||||
for (Node *node = [pileTops lastObject]; node; node = node->back)
|
||||
[result addObject:node->val];
|
||||
return [[result reverseObjectEnumerator] allObjects];
|
||||
}
|
||||
@end
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
@autoreleasepool {
|
||||
for (NSArray *d in @[@[@3, @2, @6, @4, @5, @1],
|
||||
@[@0, @8, @4, @12, @2, @10, @6, @14, @1, @9, @5, @13, @3, @11, @7, @15]])
|
||||
NSLog(@"an L.I.S. of %@ is %@", d,
|
||||
[d longestIncreasingSubsequenceWithComparator:^NSComparisonResult(id obj1, id obj2) {
|
||||
return [obj1 compare:obj2];
|
||||
}]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
class Node {
|
||||
public $val;
|
||||
public $back = NULL;
|
||||
}
|
||||
|
||||
function lis($n) {
|
||||
$pileTops = array();
|
||||
// sort into piles
|
||||
foreach ($n as $x) {
|
||||
// binary search
|
||||
$low = 0; $high = count($pileTops)-1;
|
||||
while ($low <= $high) {
|
||||
$mid = (int)(($low + $high) / 2);
|
||||
if ($pileTops[$mid]->val >= $x)
|
||||
$high = $mid - 1;
|
||||
else
|
||||
$low = $mid + 1;
|
||||
}
|
||||
$i = $low;
|
||||
$node = new Node();
|
||||
$node->val = $x;
|
||||
if ($i != 0)
|
||||
$node->back = $pileTops[$i-1];
|
||||
$pileTops[$i] = $node;
|
||||
}
|
||||
$result = array();
|
||||
for ($node = count($pileTops) ? $pileTops[count($pileTops)-1] : NULL;
|
||||
$node != NULL; $node = $node->back)
|
||||
$result[] = $node->val;
|
||||
|
||||
return array_reverse($result);
|
||||
}
|
||||
|
||||
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)));
|
||||
?>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
sub lis(@d) {
|
||||
my @l = [].item xx @d;
|
||||
@l[0].push: @d[0];
|
||||
for 1 ..^ @d -> $i {
|
||||
for ^$i -> $j {
|
||||
if @d[$j] < @d[$i] && @l[$i] < @l[$j] + 1 {
|
||||
@l[$i] = [ @l[$j][] ]
|
||||
}
|
||||
}
|
||||
@l[$i].push: @d[$i];
|
||||
}
|
||||
return max :by(*.elems), @l;
|
||||
}
|
||||
|
||||
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]);
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
sub lis(@deck is copy) {
|
||||
my @S = [@deck.shift() => Mu].item;
|
||||
for @deck -> $card {
|
||||
if defined my $i = first { @S[$_][*-1].key > $card }, ^@S {
|
||||
@S[$i].push: $card => @S[$i-1][*-1] // Mu
|
||||
} else {
|
||||
@S.push: [ $card => @S[*-1][*-1] // Mu ].item
|
||||
}
|
||||
}
|
||||
reverse map *.key, (
|
||||
@S[*-1][*-1], *.value ...^ !*.defined
|
||||
)
|
||||
}
|
||||
|
||||
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>;
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
sub lis {
|
||||
my @l = map [], 1 .. @_;
|
||||
push @{$l[0]}, +$_[0];
|
||||
for my $i (1 .. @_-1) {
|
||||
for my $j (0 .. $i - 1) {
|
||||
if ($_[$j] < $_[$i] and @{$l[$i]} < @{$l[$j]} + 1) {
|
||||
$l[$i] = [ @{$l[$j]} ];
|
||||
}
|
||||
}
|
||||
push @{$l[$i]}, $_[$i];
|
||||
}
|
||||
my ($max, $l) = 0, [];
|
||||
for (@l) {
|
||||
($max, $l) = (scalar(@$_), $_) if @$_ > $max;
|
||||
}
|
||||
return @$l;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
sub lis {
|
||||
my @pileTops;
|
||||
# sort into piles
|
||||
foreach my $x (@_) {
|
||||
# binary search
|
||||
my $low = 0, $high = $#pileTops;
|
||||
while ($low <= $high) {
|
||||
my $mid = int(($low + $high) / 2);
|
||||
if ($pileTops[$mid]{val} >= $x) {
|
||||
$high = $mid - 1;
|
||||
} else {
|
||||
$low = $mid + 1;
|
||||
}
|
||||
}
|
||||
my $i = $low;
|
||||
my $node = {val => $x};
|
||||
$node->{back} = $pileTops[$i-1] if $i != 0;
|
||||
$pileTops[$i] = $node;
|
||||
}
|
||||
my @result;
|
||||
for (my $node = $pileTops[-1]; $node; $node = $node->{back}) {
|
||||
push @result, $node->{val};
|
||||
}
|
||||
|
||||
return reverse @result;
|
||||
}
|
||||
|
||||
foreach my $r ([3, 2, 6, 4, 5, 1],
|
||||
[0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]) {
|
||||
my @d = @$r;
|
||||
my @lis = lis(@d);
|
||||
print "an L.I.S. of [@d] is [@lis]\n";
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
lis(In, Out) :-
|
||||
% we ask Prolog to find the longest sequence
|
||||
aggregate(max(N,Is), (one_is(In, [], Is), length(Is, N)), max(_, Res)),
|
||||
reverse(Res, Out).
|
||||
|
||||
|
||||
% we describe the way to find increasing subsequence
|
||||
one_is([], Current, Current).
|
||||
|
||||
|
||||
one_is([H | T], Current, Final) :-
|
||||
( Current = [], one_is(T, [H], Final));
|
||||
( Current = [H1 | _], H1 < H, one_is(T, [H | Current], Final));
|
||||
one_is(T, Current, Final).
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
def longest_increasing_subsequence(d):
|
||||
'Return one of the L.I.S. of list d'
|
||||
l = []
|
||||
for i in range(len(d)):
|
||||
l.append(max([l[j] for j in range(i) if l[j][-1] < d[i]] or [[]], key=len)
|
||||
+ [d[i]])
|
||||
return max(l, key=len)
|
||||
|
||||
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]]:
|
||||
print('a L.I.S. of %s is %s' % (d, longest_increasing_subsequence(d)))
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
from collections import namedtuple
|
||||
from functools import total_ordering
|
||||
from bisect import bisect_left
|
||||
|
||||
@total_ordering
|
||||
class Node(namedtuple('Node_', 'val back')):
|
||||
def __iter__(self):
|
||||
while self is not None:
|
||||
yield self.val
|
||||
self = self.back
|
||||
def __lt__(self, other):
|
||||
return self.val < other.val
|
||||
def __eq__(self, other):
|
||||
return self.val == other.val
|
||||
|
||||
def lis(d):
|
||||
"""Return one of the L.I.S. of list d using patience sorting."""
|
||||
if not d:
|
||||
return []
|
||||
pileTops = []
|
||||
for di in d:
|
||||
j = bisect_left(pileTops, Node(di, None))
|
||||
new_node = Node(di, pileTops[j-1] if j > 0 else None)
|
||||
if j == len(pileTops):
|
||||
pileTops.append(new_node)
|
||||
else:
|
||||
pileTops[j] = new_node
|
||||
|
||||
return list(pileTops[-1])[::-1]
|
||||
|
||||
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]]:
|
||||
print('a L.I.S. of %s is %s' % (d, lis(d)))
|
||||
1
Task/Longest-increasing-subsequence/README
Normal file
1
Task/Longest-increasing-subsequence/README
Normal file
|
|
@ -0,0 +1 @@
|
|||
Data source: http://rosettacode.org/wiki/Longest_increasing_subsequence
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#lang racket/base
|
||||
(require data/gvector)
|
||||
|
||||
(define (gvector-last gv)
|
||||
(gvector-ref gv (sub1 (gvector-count gv))))
|
||||
|
||||
(define (lis-patience-sort input-list)
|
||||
(let ([piles (gvector)])
|
||||
(for ([item (in-list input-list)])
|
||||
(insert-item! piles item))
|
||||
(reverse (gvector-last piles))))
|
||||
|
||||
(define (insert-item! piles item)
|
||||
(if (zero? (gvector-count piles))
|
||||
(gvector-add! piles (cons item '()))
|
||||
(cond
|
||||
[(not (<= item (car (gvector-last piles))))
|
||||
(gvector-add! piles (cons item (gvector-last piles)))]
|
||||
[(<= item (car (gvector-ref piles 0)))
|
||||
(gvector-set! piles 0 (cons item '()))]
|
||||
[else (let loop ([first 1] [last (sub1 (gvector-count piles))])
|
||||
(if (= first last)
|
||||
(gvector-set! piles first (cons item (gvector-ref piles (sub1 first))))
|
||||
(let ([middle (quotient (+ first last) 2)])
|
||||
(if (<= item (car (gvector-ref piles middle)))
|
||||
(loop first middle)
|
||||
(loop (add1 middle) last)))))])))
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
Node = Struct.new(:val, :back)
|
||||
|
||||
def lis(n)
|
||||
pileTops = []
|
||||
# sort into piles
|
||||
for x in n
|
||||
# binary search
|
||||
low, high = 0, pileTops.size-1
|
||||
while low <= high
|
||||
mid = low + (high - low) / 2
|
||||
if pileTops[mid].val >= x
|
||||
high = mid - 1
|
||||
else
|
||||
low = mid + 1
|
||||
end
|
||||
end
|
||||
i = low
|
||||
node = Node.new(x)
|
||||
node.back = pileTops[i-1] if i > 0
|
||||
pileTops[i] = node
|
||||
end
|
||||
|
||||
result = []
|
||||
node = pileTops.last
|
||||
while node
|
||||
result.unshift(node.val)
|
||||
node = node.back
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
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])
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
object LongestIncreasingSubsequence extends App {
|
||||
def longest(l: Array[Int]) = l match {
|
||||
case _ if l.length < 2 => Array(l)
|
||||
case l =>
|
||||
def increasing(done: Array[Int], remaining: Array[Int]): Array[Array[Int]] = remaining match {
|
||||
case Array() => Array(done)
|
||||
case Array(head, _*) =>
|
||||
(if (head > done.last) increasing(done :+ head, remaining.tail) else Array()) ++
|
||||
increasing(done, remaining.tail) // all increasing combinations
|
||||
}
|
||||
val all = (1 to l.length).flatMap(i => increasing(l take i takeRight 1, l.drop(i+1))).sortBy(-_.length)
|
||||
all.takeWhile(_.length == all.head.length).toArray // longest from all increasing combinations
|
||||
}
|
||||
|
||||
val tests = Map(
|
||||
"3,2,6,4,5,1" -> Array("2,4,5", "3,4,5"),
|
||||
"0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15" -> Array("0,2,6,9,11,15", "0,2,6,9,13,15", "0,4,6,9,13,15", "0,4,6,9,11,15")
|
||||
)
|
||||
def asInts(s: String): Array[Int] = s split "," map Integer.parseInt
|
||||
assert(tests forall {case (given, expect) =>
|
||||
val lis = longest(asInts(given))
|
||||
println(s"$given has ${lis.size} longest increasing subsequences, e.g. "+lis.last.mkString(","))
|
||||
expect contains lis.last.mkString(",")
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
(define (lis less? lst)
|
||||
(define pile-tops (make-vector (length lst)))
|
||||
(define (bsearch-piles x len)
|
||||
(let aux ((lo 0)
|
||||
(hi (- len 1)))
|
||||
(if (> lo hi)
|
||||
lo
|
||||
(let ((mid (quotient (+ lo hi) 2)))
|
||||
(if (less? (car (vector-ref pile-tops mid)) x)
|
||||
(aux (+ mid 1) hi)
|
||||
(aux lo (- mid 1)))))))
|
||||
(let aux ((len 0)
|
||||
(lst lst))
|
||||
(if (null? lst)
|
||||
(reverse (vector-ref pile-tops (- len 1)))
|
||||
(let* ((x (car lst))
|
||||
(i (bsearch-piles x len)))
|
||||
(vector-set! pile-tops i (cons x (if (= i 0)
|
||||
'()
|
||||
(vector-ref pile-tops (- i 1)))))
|
||||
(aux (if (= i len) (+ len 1) len) (cdr lst))))))
|
||||
|
||||
(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)
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
fun lis cmp n =
|
||||
let
|
||||
val pile_tops = DynamicArray.array (length n, [])
|
||||
fun bsearch_piles x =
|
||||
let
|
||||
fun aux (lo, hi) =
|
||||
if lo > hi then
|
||||
lo
|
||||
else
|
||||
let
|
||||
val mid = (lo + hi) div 2
|
||||
in
|
||||
if cmp (hd (DynamicArray.sub (pile_tops, mid)), x) = LESS then
|
||||
aux (mid+1, hi)
|
||||
else
|
||||
aux (lo, mid-1)
|
||||
end
|
||||
in
|
||||
aux (0, DynamicArray.bound pile_tops)
|
||||
end
|
||||
fun f x =
|
||||
let
|
||||
val i = bsearch_piles x
|
||||
in
|
||||
DynamicArray.update (pile_tops, i,
|
||||
x :: (if i = 0 then [] else DynamicArray.sub (pile_tops, i-1)))
|
||||
end
|
||||
in
|
||||
app f n;
|
||||
rev (DynamicArray.sub (pile_tops, DynamicArray.bound pile_tops))
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package require Tcl 8.6
|
||||
|
||||
proc longestIncreasingSubsequence {sequence} {
|
||||
# Get the increasing subsequences (and their lengths)
|
||||
set subseq [list 1 [lindex $sequence 0]]
|
||||
foreach value $sequence {
|
||||
set max {}
|
||||
foreach {len item} $subseq {
|
||||
if {[lindex $item end] < $value} {
|
||||
if {[llength [lappend item $value]] > [llength $max]} {
|
||||
set max $item
|
||||
}
|
||||
} elseif {![llength $max]} {
|
||||
set max [list $value]
|
||||
}
|
||||
}
|
||||
lappend subseq [llength $max] $max
|
||||
}
|
||||
# Pick the longest subsequence; -stride requires Tcl 8.6
|
||||
return [lindex [lsort -stride 2 -index 0 $subseq] end]
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
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}]
|
||||
Loading…
Add table
Add a link
Reference in a new issue