Another update from ingydotnet^djgoku
This commit is contained in:
parent
91df62d461
commit
948b86eafa
7604 changed files with 108452 additions and 22726 deletions
|
|
@ -0,0 +1,113 @@
|
|||
-module(longest_increasing_subsequence).
|
||||
|
||||
-export([test_naive/0, test_patience/0]).
|
||||
|
||||
% **************************************************
|
||||
% Interface to test the implementation
|
||||
% **************************************************
|
||||
|
||||
test_naive() ->
|
||||
test_gen(fun lis/1).
|
||||
|
||||
test_patience() ->
|
||||
test_gen(fun patience_lis/1).
|
||||
|
||||
test_gen(F) ->
|
||||
show_result(F([3,2,6,4,5,1])),
|
||||
show_result(F([0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15])).
|
||||
|
||||
show_result(Res) ->
|
||||
io:format("~w\n", [Res]).
|
||||
|
||||
% **************************************************
|
||||
|
||||
% **************************************************
|
||||
% Naive implementation
|
||||
% **************************************************
|
||||
|
||||
lis(L) ->
|
||||
maxBy(
|
||||
fun(SS) -> length(SS) end,
|
||||
[ lists:usort(SS)
|
||||
|| SS <- combos(L),
|
||||
SS == lists:sort(SS)]
|
||||
).
|
||||
|
||||
% **************************************************
|
||||
|
||||
% **************************************************
|
||||
% Patience sort implementation
|
||||
% **************************************************
|
||||
|
||||
patience_lis(L) ->
|
||||
patience_lis(L, []).
|
||||
|
||||
patience_lis([H | T], Stacks) ->
|
||||
NStacks =
|
||||
case Stacks of
|
||||
[] ->
|
||||
[[{H,[]}]];
|
||||
_ ->
|
||||
place_in_stack(H, Stacks, [])
|
||||
end,
|
||||
patience_lis(T, NStacks);
|
||||
patience_lis([], Stacks) ->
|
||||
case Stacks of
|
||||
[] ->
|
||||
[];
|
||||
[_|_] ->
|
||||
lists:reverse( recover_lis( get_previous(Stacks) ) )
|
||||
end.
|
||||
|
||||
place_in_stack(E, [Stack = [{H,_} | _] | TStacks], PrevStacks) when H > E ->
|
||||
PrevStacks ++ [[{E, get_previous(PrevStacks)} | Stack] | TStacks];
|
||||
place_in_stack(E, [Stack = [{H,_} | _] | TStacks], PrevStacks) when H =< E ->
|
||||
place_in_stack(E, TStacks, PrevStacks ++ [Stack]);
|
||||
place_in_stack(E, [], PrevStacks)->
|
||||
PrevStacks ++ [[{E, get_previous(PrevStacks)}]].
|
||||
|
||||
get_previous(Stack = [_|_]) ->
|
||||
hd(lists:last(Stack));
|
||||
get_previous([]) ->
|
||||
[].
|
||||
|
||||
recover_lis({E,Prev}) ->
|
||||
[E|recover_lis(Prev)];
|
||||
recover_lis([]) ->
|
||||
[].
|
||||
|
||||
% **************************************************
|
||||
|
||||
% **************************************************
|
||||
% Copied from http://stackoverflow.com/a/4762387/4162959
|
||||
% **************************************************
|
||||
|
||||
maxBy(F, L) ->
|
||||
element(
|
||||
2,
|
||||
lists:max([ {F(X), X} || X <- L])
|
||||
).
|
||||
|
||||
% **************************************************
|
||||
|
||||
% **************************************************
|
||||
% Copied from https://panduwana.wordpress.com/2010/04/21/combination-in-erlang/
|
||||
% **************************************************
|
||||
|
||||
combos(L) ->
|
||||
lists:foldl(
|
||||
fun(K, Acc) -> Acc++(combos(K, L)) end,
|
||||
[[]],
|
||||
lists:seq(1, length(L))
|
||||
).
|
||||
|
||||
combos(1, L) ->
|
||||
[[X] || X <- L];
|
||||
combos(K, L) when K == length(L) ->
|
||||
[L];
|
||||
combos(K, [H|T]) ->
|
||||
[[H | Subcombos]
|
||||
|| Subcombos <- combos(K-1, T)]
|
||||
++ (combos(K, T)).
|
||||
|
||||
% **************************************************
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
sub lis(@deck is copy) {
|
||||
my @S = [@deck.shift() => Mu].item;
|
||||
my @S = [@deck.shift() => Nil].item;
|
||||
for @deck -> $card {
|
||||
if defined my $i = first { @S[$_][*-1].key > $card }, ^@S {
|
||||
@S[$i].push: $card => @S[$i-1][*-1] // Mu
|
||||
with first { @S[$_][*-1].key > $card }, ^@S -> $i {
|
||||
@S[$i].push: $card => @S[$i-1][*-1] // Nil
|
||||
} else {
|
||||
@S.push: [ $card => @S[*-1][*-1] // Mu ].item
|
||||
@S.push: [ $card => @S[*-1][*-1] // Nil ].item
|
||||
}
|
||||
}
|
||||
reverse map *.key, (
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
(de longinc (Lst)
|
||||
(let (D NIL R NIL)
|
||||
(for I Lst
|
||||
(cond
|
||||
((< I (last D))
|
||||
(for (Y . X) D
|
||||
(T (> X I) (set (nth D Y) I)) ) )
|
||||
((< I (car R))
|
||||
(set R I)
|
||||
(when D (set (cdr R) (last D))) )
|
||||
(T (when R (queue 'D (car R)))
|
||||
(push 'R I) ) ) )
|
||||
(flip R) ) )
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
(de glutton (L)
|
||||
(let N (pop 'L)
|
||||
(maxi length
|
||||
(recur (N L)
|
||||
(ifn L
|
||||
(list (list N))
|
||||
(mapcan
|
||||
'((R)
|
||||
(if (> (car R) N)
|
||||
(list (cons N R) R)
|
||||
(list (list N) R) ) )
|
||||
(recurse (car L) (cdr L)) ) ) ) ) ) )
|
||||
|
||||
(test (2 4 5)
|
||||
(glutton (3 2 6 4 5 1)))
|
||||
|
||||
(test (2 6 9 11 15)
|
||||
(glutton (8 4 12 2 10 6 14 1 9 5 13 3 11 7 15)))
|
||||
|
||||
(test (-31 0 83 782)
|
||||
(glutton (4 65 2 -31 0 99 83 782 1)) )
|
||||
|
|
@ -1,10 +1,32 @@
|
|||
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)
|
||||
def longest_increasing_subsequence(X):
|
||||
"""Returns the Longest Increasing Subsequence in the Given List/Array"""
|
||||
N = length(X)
|
||||
P = [0 for i in range(N)]
|
||||
M = [0 for i in range(N+1)]
|
||||
L = 0
|
||||
for i in range(N):
|
||||
lo = 1
|
||||
hi = L
|
||||
while lo <= hi:
|
||||
mid = (lo+hi)//2
|
||||
if (X[M[mid]] < X[i]):
|
||||
lo = mid+1
|
||||
else:
|
||||
hi = mid-1
|
||||
|
||||
newL = lo
|
||||
P[i] = M[newL-1]
|
||||
M[newL] = i
|
||||
|
||||
if (newL > L):
|
||||
L = newL
|
||||
|
||||
S = []
|
||||
k = M[L]
|
||||
for i in range(L-1, -1, -1):
|
||||
S.append(X[k])
|
||||
k = P[k]
|
||||
return S[::-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]]:
|
||||
|
|
|
|||
|
|
@ -1,34 +1,11 @@
|
|||
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]
|
||||
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, lis(d)))
|
||||
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)))
|
||||
Loading…
Add table
Add a link
Reference in a new issue