#!/usr/bin/ruby
#
## https://rosettacode.org/wiki/Longest_increasing_subsequence
#
func lis(deck) {
var pileTops = []
deck.each { |x|
var low = 0;
var high = pileTops.end
while (low <= high) {
var mid = ((low + high) // 2)
if (pileTops[mid]{:val} >= x) {
high = mid-1
} else {
low = mid+1
}
}
var i = low
var node = Hash(val => x)
node{:back} = pileTops[i-1] if (i != 0)
pileTops[i] = node
}
var result = []
for (var node = pileTops[-1]; node; node = node{:back}) {
result << node{:val}
}
result.reverse
}
var a = lis(%i<3 2 6 4 5 1>)
var b = lis(%i<0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15>)
say a
say b
assert_eq(a, [2, 4, 5])
assert_eq(b, [0, 2, 6, 9, 11, 15])