Dim As Integer n, j, k, k0, r
Dim As String X(2)
Dim As Integer i = 0  ' índice de cadena de entrada
X(0) = "1"

Input "Indica cuantas repeticiones: ", r
Print Chr(10) & "Secuencia:"

Print X(i)
For n = 1 To r-1
    j = 1 - i  ' índice de cadena de salida
    X(j) = ""
    k = 1
    While k <= Len(X(i))
        k0 = k + 1
        While ((k0 <= Len(X(i))) And (Mid(X(i), k, 1) = Mid(X(i), k0, 1)))
            k0 += 1
        Wend
        X(j) += Str(k0 - k) + Mid(X(i), k, 1)
        k = k0
    Wend
    i = j
    Print X(j)
Next n
End


LookAndSay = "12211123"
println["Starting Value: " + LookAndSay]

LASStr = { |LaS|
   length[[email protected]] + length[[email protected]] + [email protected]
   /*
      The returned results from the Regex are divided between a distinct matching
      character and any following identical characters. For example, a string
      of 2222 would be returned from this function as [2,222].
      The function adds the length of both elements (1 and 3 in the example
      above) and returns that value with the matching character.
      i.e. Length of 1st element = 1, Length of 2nd element = 3, value of 1st element = 2
      1 + 3 = 4 & value 2. Returned result is "42" i.e. "Four 2s."
   */
}

// Calculate the next 10 Look and Say Sequence Values

for i = 1 to 10
{
   LookAndSayReg = LookAndSay =~ %r/(\d)(\1{0,})/g
   LookAndSay = join["",mapList[LASStr,LookAndSayReg]]
   println["$i - $LookAndSay"]
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public static class LIS
{
    public static IEnumerable<T> FindRec<T>(IList<T> values, IComparer<T> comparer = null) =>
        values == null ? throw new ArgumentNullException() :
            FindRecImpl(values, Sequence<T>.Empty, 0, comparer ?? Comparer<T>.Default).Reverse();

    private static Sequence<T> FindRecImpl<T>(IList<T> values, Sequence<T> current, int index, IComparer<T> comparer) {
        if (index == values.Count) return current;
        if (current.Length > 0 && comparer.Compare(values[index], current.Value) <= 0)
            return FindRecImpl(values, current, index + 1, comparer);
        return Max(
            FindRecImpl(values, current, index + 1, comparer),
            FindRecImpl(values, current + values[index], index + 1, comparer)
        );
    }

    private static Sequence<T> Max<T>(Sequence<T> a, Sequence<T> b) => a.Length < b.Length ? b : a;

    class Sequence<T> : IEnumerable<T>
    {
        public static readonly Sequence<T> Empty = new Sequence<T>(default(T), null);

        public Sequence(T value, Sequence<T> tail)
        {
            Value = value;
            Tail = tail;
            Length = tail == null ? 0 : tail.Length + 1;
        }

        public T Value { get; }
        public Sequence<T> Tail { get; }
        public int Length { get; }

        public static Sequence<T> operator +(Sequence<T> s, T value) => new Sequence<T>(value, s);

        public IEnumerator<T> GetEnumerator()
        {
            for (var s = this; s.Length > 0; s = s.Tail) yield return s.Value;
        }

        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    }
}


Public Sub Main()
Dim i, j, cnt As Integer
Dim txt$, curr$, result$ As String

txt$ = "1211"
i = 1

Print "Sequence: " & txt$ & " = ";
  Repeat
    j = 1
    result$ = ""
      Repeat
        curr$ = Mid(txt$, j, 1)
        cnt = 0
          Repeat
            Inc cnt
            Inc j
          Until Mid(txt$, j, 1) <> curr$
        result$ &= Str(cnt) & curr$
      Until j > Len(txt$)
    Print result$
    txt$ = result$
    Dec i
  Until i <= 0
End


#include <vector>
#include <list>
#include <algorithm>
#include <iostream>

template <typename T>
struct Node {
    T value;
    Node* prev_node;
};

template <typename Container>
Container lis(const Container& values) {
    using E = typename Container::value_type;
    using NodePtr = Node<E>*;
    using ConstNodePtr = const NodePtr;

    std::vector<NodePtr> pileTops;
    std::vector<Node<E>> nodes(values.size());

    // sort into piles
    auto cur_node = std::begin(nodes);
    for (auto cur_value = std::begin(values); cur_value != std::end(values); ++cur_value, ++cur_node)
    {
        auto node = &*cur_node;
        node->value = *cur_value;

        // lower_bound returns the first element that is not less than 'node->value'
        auto lb = std::lower_bound(pileTops.begin(), pileTops.end(), node,
            [](ConstNodePtr& node1, ConstNodePtr& node2) -> bool { return node1->value < node2->value; });

        if (lb != pileTops.begin())
            node->prev_node = *std::prev(lb);

        if (lb == pileTops.end())
            pileTops.push_back(node);
        else
            *lb = node;
    }

    // extract LIS from piles
    // note that LIS length is equal to the number of piles
    Container result(pileTops.size());
    auto r = std::rbegin(result);

    for (NodePtr node = pileTops.back(); node != nullptr; node = node->prev_node, ++r)
        *r = node->value;

    return result;
}

template <typename Container>
void show_lis(const Container& values)
{
    auto&& result = lis(values);
    for (auto& r : result) {
        std::cout << r << ' ';
    }
    std::cout << std::endl;
}

int main()
{
    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 });
}


package main

import (
    "fmt"
    "strconv"
)

func lss(s string) (r string) {
    c := s[0]
    nc := 1
    for i := 1; i < len(s); i++ {
        d := s[i]
        if d == c {
            nc++
            continue
        }
        r += strconv.Itoa(nc) + string(c)
        c = d
        nc = 1
    }
    return r + strconv.Itoa(nc) + string(c)
}

func main() {
    s := "1"
    fmt.Println(s)
    for i := 0; i < 8; i++ {
        s = lss(s)
        fmt.Println(s)
    }
}


(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]))


(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))))


def lookAndSay(sequence) {
    def encoded = new StringBuilder()
    (sequence.toString() =~ /(([0-9])\2*)/).each { matcher ->
        encoded.append(matcher[1].size()).append(matcher[2])
    }
    encoded.toString()
}


import Control.Monad (liftM2)
import Data.List (group)

-- this function is composed out of many functions; data flows from the bottom up
lookAndSay :: Integer -> Integer
lookAndSay = read                                   -- convert digits to integer
           . concatMap                              -- concatenate for each run,
               (liftM2 (++) (show . length)         --    the length of it
                            (take 1))               --    and an example member
           . group                                  -- collect runs of the same digit
           . show                                   -- convert integer to digits

-- less comments
lookAndSay2 :: Integer -> Integer
lookAndSay2 = read . concatMap (liftM2 (++) (show . length)
                                            (take 1))
            . group . show

-- same thing with more variable names
lookAndSay3 :: Integer -> Integer
lookAndSay3 n = read (concatMap describe (group (show n)))
  where describe run = show (length run) ++ take 1 run

main = mapM_ print (iterate lookAndSay 1)           -- display sequence until interrupted


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;
}


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 ]


using Std;

class Main
{

	static function main()
	{
		var test = "1";
		for (i in 0...11) {
			Sys.println(test);
			test = lookAndSay(test);
		}
	}

	static function lookAndSay(s:String)
	{
		if (s == null || s == "") return "";

		var results = "";
		var repeat = s.charAt(0);
		var amount = 1;
		for (i in 1...s.length)
		{
			var actual = s.charAt(i);
			if (actual != repeat)
			{
				results += amount.string();
				results += repeat;
				repeat = actual;
				amount = 0;
			}
			amount++;
		}
		results += amount.string();
		results += repeat;

		return results;
	}
}


procedure main()
every 1 to 10 do
   write(n := nextlooknsayseq(\n | 1))
end

procedure nextlooknsayseq(n)  #: return next element in look and say sequence
n2 := ""
n ? until pos(0) do {
   i := tab(any(&digits)) | fail  # or fail if not digits
   move(-1)
   n2 ||:= *tab(many(i)) || i     # accumulate count+digit
   }
return n2
end


defmodule Longest_increasing_subsequence do
  # Naive implementation
  def lis(l) do
    (for ss <- combos(l), ss == Enum.sort(ss), do: ss)
    |> Enum.max_by(fn ss -> length(ss) end)
  end

  defp combos(l) do
    Enum.reduce(1..length(l), [[]], fn k, acc -> acc ++ (combos(k, l)) end)
  end
  defp combos(1, l), do: (for x <- l, do: [x])
  defp combos(k, l) when k == length(l), do: [l]
  defp combos(k, [h|t]) do
    (for subcombos <- combos(k-1, t), do: [h | subcombos]) ++ combos(k, t)
  end
end

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])


-module(longest_increasing_subsequence).

-export([test_naive/0, test_memo/0, test_patience/0, test_patience2/0, test_compare/1]).

% **************************************************
% Interface to test the implementation
% **************************************************

test_compare(N) when N =< 20 ->
    Funs = [
        {"Naive", fun lis/1},
        {"Memo", fun memo/1},
        {"Patience", fun patience_lis/1},
        {"Patience2", fun patience2/1}
    ],
    do_compare(Funs, N);
test_compare(N) when N =< 500 ->
    Funs = [
        {"Memo", fun memo/1},
        {"Patience", fun patience_lis/1},
        {"Patience2", fun patience2/1}
    ],
    do_compare(Funs, N);
test_compare(N) ->
    Funs = [
        {"Patience", fun patience_lis/1},
        {"Patience2", fun patience2/1}
    ],
    do_compare(Funs, N).

do_compare(Funs, N) ->
    List = [rand:uniform(1000) || _ <- lists:seq(1,N)],
    Results = [{Name, timer:tc(fun() -> F(List) end)} || {Name,F} <- Funs],
    Times = [{Name, Time} || {Name, {Time, _Result}} <- Results],
    io:format("Result Times: ~p~n", [Times]).

test_naive() ->
    test_gen(fun lis/1).

test_memo() ->
    test_gen(fun memo/1).

test_patience() ->
    test_gen(fun patience_lis/1).

test_patience2() ->
    test_gen(fun patience2/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)]
    ).

% **************************************************
% 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)).
% **************************************************

% **************************************************
% Memoization implementation, Roman Rabinovich
% **************************************************
memo(S) ->
    put(test, #{}),
    memo(S, -1).

memo([], _) -> [];
memo([H | Tail] = S, Min) when H > Min ->
    case maps:get({S,Min}, get(test), undefined) of
        undefined ->
            L1 = [H | memo(Tail, H)],
            L2 = memo(Tail, Min),
            case length(L1) >= length(L2) of
                true ->
                    Map = get(test),
                    put(test, Map#{{S, Min} => L1}),
                    L1;
                _ ->
                    Map = get(test),
                    put(test, Map#{{S, Min} => L2}),
                    L2
            end;
        X -> X
    end;
memo([_|Tail], Min) ->
    memo(Tail, Min).

% **************************************************

% **************************************************
% 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([]) ->
    [].

% **************************************************

% **************************************************
% Patience2 by Roman Rabinovich, improved performance over above
% **************************************************
patience2([]) -> [];
patience2([H|L]) ->
    Piles = [[{H, undefined}]],
    patience2(L, Piles, []).

patience2([], Piles, _) ->
    get_seq(lists:reverse(Piles));

patience2([H|T], [[{PE,_}|_Rest] = Pile| Piles], PrevPiles) when H =< PE ->
    case PrevPiles of
        [] -> patience2(T, [[{H, undefined}|Pile]|Piles], []);
        [[{K,_}|_]|_] -> patience2(T, lists:reverse(PrevPiles) ++ [[{H, K}|Pile]|Piles], [])
    end;

patience2([H|_T] = L, [[{PE,_}|_Rest] = Pile| Piles], PrevPiles) when H > PE ->
    patience2(L, Piles, [Pile|PrevPiles]);

patience2([H|T], [], [[{K,_}|_]|_]=PrevPiles) ->
    patience2(T, lists:reverse([[{H,K}]|PrevPiles]), []).

get_seq([]) -> [];
get_seq([[{K,P}|_]|Rest]) ->
    get_seq(P, Rest, [K]).

get_seq(undefined, [], Seq) -> Seq;
get_seq(K, [Pile|Rest], Seq) ->
    case lists:keyfind(K, 1, Pile) of
        undefined -> get_seq(K, Rest, Seq);
        {K, P} -> get_seq(P, Rest, [K|Seq])
    end.

% **************************************************


public static String lookandsay(String number){
	StringBuilder result= new StringBuilder();

	char repeat= number.charAt(0);
	number= number.substring(1) + " ";
	int times= 1;

	for(char actual: number.toCharArray()){
		if(actual != repeat){
			result.append(times + "" + repeat);
			times= 1;
			repeat= actual;
		}else{
			times+= 1;
		}
	}
	return result.toString();
}


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))
    }
}


function lookandsay(str) {
    return str.replace(/(.)\1*/g, function(seq, p1){return seq.length.toString() + p1})
}

var num = "1";
for (var i = 10; i > 0; i--) {
    alert(num);
    num = lookandsay(num);
}


def look_and_say:
  def head(c; n): if .[n:n+1] == c then head(c; n+1) else n end;
  tostring
  | if length == 0 then ""
    else head(.[0:1]; 1) as $len
      | .[0:$len] as $head
      | ($len | tostring) + $head[0:1] + (.[$len:] | look_and_say)
    end ;

# look and say n times
def look_and_say(n):
  if n == 0 then empty
  else look_and_say as $lns
       | $lns, ($lns|look_and_say(n-1))
  end ;


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]


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


function lookandsay(s::String)
    rst = IOBuffer()
    c = 1
    for i in 1:length(s)
        if i != length(s) && s[i] == s[i+1]
            c += 1
        else
            print(rst, c, s[i])
            c = 1
        end
    end
    String(take!(rst))
end

function lookandsayseq(n::Integer)
    rst = Vector{String}(undef, n)
    rst[1] = "1"
    for i in 2:n
        rst[i] = lookandsay(rst[i-1])
    end
    rst
end

println(lookandsayseq(10))


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));
    }
}


// version 1.0.6

fun lookAndSay(s: String): String {
    val sb = StringBuilder()
    var digit = s[0]
    var count = 1
    for (i in 1 until s.length) {
        if (s[i] == digit)
            count++
        else {
            sb.append("$count$digit")
            digit = s[i]
            count = 1
        }
    }
    return sb.append("$count$digit").toString()
}

fun main(args: Array<String>) {
    var las = "1"
    for (i in 1..15) {
        println(las)
        las = lookAndSay(las)
    }
}


define rle(str::string)::string => {
	local(orig = #str->values->asCopy,newi=array, newc=array, compiled=string)
	while(#orig->size) => {
		if(not #newi->size) => {
			#newi->insert(1)
			#newc->insert(#orig->first)
			#orig->remove(1)
		else
			if(#orig->first == #newc->last) => {
				#newi->get(#newi->size) += 1
			else
				#newi->insert(1)
				#newc->insert(#orig->first)
			}
			#orig->remove(1)
		}
	}
	loop(#newi->size) => {
		#compiled->append(#newi->get(loop_count)+#newc->get(loop_count))
	}
	return #compiled
}
define las(n::integer,run::integer) => {
	local(str = #n->asString)
	loop(#run) => { #str = rle(#str) }
	return #str
}
loop(15) => {^ las(1,loop_count) + '\r' ^}


function getLis(input) {
  if (input.length === 0) {
    return [];
  }

  var lisLenPerIndex = [];
  let max = { index: 0, length: 1 };

  for (var i = 0; i < input.length; i++) {
    lisLenPerIndex[i] = 1;
    for (var j = i - 1; j >= 0; j--) {
      if (input[i] > input[j] && lisLenPerIndex[j] >= lisLenPerIndex[i]) {
        var length = lisLenPerIndex[i] = lisLenPerIndex[j] + 1;
        if (length > max.length) {
          max = { index: i, length };
        }
      }
    }
  }

  var lis = [input[max.index]];
  for (var i = max.index; i >= 0 && max.length !== 0; i--) {
    if (input[max.index] > input[i] && lisLenPerIndex[i] === max.length - 1) {
      lis.unshift(input[i]);
      max.length--;
    }
  }

  return lis;
}

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]));


function lookAndSay S
   put 0 into C
   put char 1 of S into lastChar
   repeat with i = 2 to length(S)
      add 1 to C
      if char i of S is lastChar then next repeat
      put C & lastChar after R
      put 0 into C
      put char i of S into lastChar
   end repeat
   return R & C + 1 & lastChar
end lookAndSay

on demoLookAndSay
   put 1 into x
   repeat 10
      put x & cr after message
      put lookAndSay(x) into x
   end repeat
   put x after message
end demoLookAndSay


def until(cond; update):
  def _until:
    if cond then . else (update | _until) end;
  try _until catch if .== "break" then empty else . end;

# binary search for insertion point
def bsearch(target):
  . as $in
  | [0, length-1] # [low, high]
  | until(.[0] > .[1];
          .[0] as $low | .[1] as $high
          | ($low + ($high - $low) / 2 | floor) as $mid
          | if $in[$mid] >= target
            then .[1] = $mid - 1
            else .[0] = $mid + 1
            end )
  | .[0];


function lis(arr::Vector)
    if length(arr) == 0 return copy(arr) end
    L = Vector{typeof(arr)}(length(arr))
    L[1] = [arr[1]]

    for i in 2:length(arr)
        nextL = []
        for j in 1:i
            if arr[j] < arr[i] && length(L[j]) ≥ length(nextL)
                nextL = L[j]
            end
        end
        L[i] = vcat(nextL, arr[i])
    end

    return L[indmax(length.(L))]
end

@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])


// version 1.1.0

fun longestIncreasingSubsequence(x: IntArray): IntArray =
    when (x.size) {
        0    -> IntArray(0)
        1    -> x
        else -> {
            val n = x.size
            val p = IntArray(n)
            val m = IntArray(n + 1)
            var len = 0
            for (i in 0 until n) {
                var lo = 1
                var hi = len
                while (lo <= hi) {
                    val mid = Math.ceil((lo + hi) / 2.0).toInt()
                    if (x[m[mid]] < x[i]) lo = mid + 1
                    else hi = mid - 1
                }
                val newLen = lo
                p[i] = m[newLen - 1]
                m[newLen] = i
                if (newLen > len) len = newLen
            }
            val s = IntArray(len)
            var k = m[len]
            for (i in len - 1 downTo 0) {
                s[i] = x[k]
                k = p[k]
            }
            s
        }
    }

fun main(args: Array<String>) {
    val lists = listOf(
        intArrayOf(3, 2, 6, 4, 5, 1),
        intArrayOf(0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15)
    )
    lists.forEach { println(longestIncreasingSubsequence(it).asList()) }
}


to look.and.say.loop :in :run :c :out
  if empty? :in [output (word :out :run :c)]
  if equal? first :in :c [output look.and.say.loop bf :in :run+1 :c :out]
  output look.and.say.loop bf :in 1 first :in (word :out :run :c)
end
to look.and.say :in
  if empty? :in [output :in]
  output look.and.say.loop bf :in 1 first :in "||
end

show cascade 10 [print ? look.and.say ?] 1


--returns an iterator over the first n copies of the look-and-say sequence
function lookandsayseq(n)
  local t = {1}
  return function()
    local ret = {}
    for i, v in ipairs(t) do
      if t[i-1] and v == t[i-1] then
        ret[#ret - 1] = ret[#ret - 1] + 1
      else
        ret[#ret + 1] = 1
        ret[#ret + 1] = v
      end
    end
    t = ret
    n = n - 1
    if n > 0 then return table.concat(ret) end
  end
end
for i in lookandsayseq(10) do print(i) end


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})


generate_seq := proc(s)
	local times, output, i;
	times := 1;
	output := "";
	for i from 2 to StringTools:-Length(s) do
		if (s[i] <> s[i-1]) then
			output := cat(output, times, s[i-1]);
			times := 1; # re-assign
		else
			times ++;
		end if;
	end do;
	cat(output, times, s[i - 1]);
end proc:

Look_and_Say :=proc(n)
	local value, i;
	value := "1";
	print(value);
	for i from 2 to n do
		value := generate_seq(value);
		print(value);
	end do;
end proc:

#Test:
Look_and_Say(10);


Module LIS_example {
	Function LIS {
		LD=Stack.Size-1
		dim L(0 to LD)
		For i=0 to LD : Read V: L(i):=Stack:=V:next
		M=1
		M1=LD
		for i=LD-1 to 0
			for j=LD to i+1
				if stackitem(L(i))<stackitem(L(j)) then
					if len(L(i))<=len(L(j)) then L(i) =stack:=stackitem(L(i)), ! stack(L(j))
				end if
			next
			if len(L(i))>=M then M1=i:M=Len(L(i))
		next
		=L(M1)
	}
	Const seq$="sequence", subseq$="Longest increasing subsequence"
	Document doc$
	Disp(seq$, Stack:=3,2,6,4,5,1)
	Disp(subseq$, Lis(3,2,6,4,5,1))
	Disp(seq$, Stack:=0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15)
	Disp(subseq$, LIS(0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15))
	Print #-2,Doc$
	Clipboard Doc$

	Sub Disp(title$, m)
		local n=each(m), s$
		while n
			s$+=", "+str$(stackitem(n),"")
		end while
		s$=trim$(mid$(s$, 2))
		Doc$=title$+": "+s$+{
		}
	End Sub
}
LIS_example


# dynamic programming:
LIS := proc(L)
	local i, j;
	local index := 1;
	local output := Array(1..numelems(L), i -> Array(1..0));

	for i from 1 to numelems(L) do
		for j from 1 to i - 1 do
			if (L[j] < L[i]) and (upperbound(output[j]) > upperbound(output[i])) then
				output[i] := copy(output[j]);
			end if;
		end do;
		# append current value
		output[i] ,= L[i];
	end do;

	#output longest subsequence using loop
	for i from 2 to numelems(L) do
		if (upperbound(output[i]) > upperbound(output[index])) then
			index := i;
		end if;
	end do;

	return output[index];

end proc:


LookAndSay[n_Integer?Positive]:= Reverse @@@ Tally /@ Split @ IntegerDigits @ n // Flatten // FromDigits


proc longestIncreasingSubsequence[T](d: seq[T]): seq[T] =
  var l: seq[seq[T]]
  for i in 0 .. d.high:
    var x: seq[T]
    for j in 0 ..< i:
      if l[j][l[j].high] < d[i] and l[j].len > x.len:
        x = l[j]
    l.add x & @[d[i]]
  for x in l:
    if x.len > result.len:
      result = x

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)


#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;
}


fn lookAndSay num =
(
    local result = ""
    num += " "
    local current = num[1]
    local numReps = 1

    for digit in 2 to num.count do
    (
        if num[digit] != current then
        (
            result += (numReps as string) + current
            numReps = 1
            current = num[digit]
        )
        else
        (
            numReps += 1
        )
    )
    result
)

local num = "1"

for i in 1 to 10 do
(
    print num
    num = lookAndSay num
)


vardef lookandsay(expr s) =
string r; r := "";
if string s:
  i := 0;
  forever: exitif not (i < length(s));
    c := i+1;
    forever: exitif ( (substring(c,c+1) of s) <> (substring(i,i+1) of s) );
      c := c + 1;
    endfor
    r := r & decimal (c-i) & substring(i,i+1) of s;
    i := c;
  endfor
fi
r
enddef;

string p; p := "1";
for el := 1 upto 10:
  message p;
  p := lookandsay(p);
endfor

end


// Look and Say Sequence
repeats = function(digit, string)
	count = 0
	for c in string
		if c != digit then break
		count = count + 1
	end for
	return str(count)
end function

numbers = "1"
print numbers
for i in range(1,10) // warning, loop size > 15 gets long numbers very quickly
	number = ""
	position = 0
	while position < numbers.len
		repeatCount = repeats(numbers[position], numbers[position:])
		number = number + repeatCount + numbers[position]
		position = position + repeatCount.val
	end while
	print number
	numbers = number
end for


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


MODULE LookAndSay;
FROM InOut IMPORT WriteString, WriteLn;
FROM Strings IMPORT Assign, Length;

CONST
    MaxSize = 128;
    Steps = 14;

VAR
    buf1, buf2: ARRAY [0..MaxSize-1] OF CHAR;
    step: CARDINAL;

PROCEDURE LookSay(in: ARRAY OF CHAR; VAR out: ARRAY OF CHAR);
    VAR count, inIdx, outIdx: CARDINAL;
        curChar: CHAR;
BEGIN
    inIdx := 0;
    outIdx := 0;
    WHILE in[inIdx] # CHR(0) DO
        curChar := in[inIdx];
        count := 0;
        REPEAT
            INC(inIdx);
            INC(count);
        UNTIL in[inIdx] # curChar;
        out[outIdx] := CHR(ORD('0') + count);
        out[outIdx+1] := curChar;
        outIdx := outIdx + 2;
    END;
    out[outIdx] := CHR(0);
END LookSay;

BEGIN
    Assign("1", buf1);
    FOR step := 1 TO Steps DO
        WriteString(buf1);
        WriteLn();
        LookSay(buf1, buf2);
        Assign(buf2, buf1);
    END;
END LookAndSay.


with javascript_semantics
function lis(sequence x, integer n = length(x))
    sequence p = repeat(0,n),
             m = repeat(0,n)
    integer len = 0
    for i=1 to n do
        integer lo = 1
        integer hi = len
        while lo<=hi do
            integer mid = ceil((lo+hi)/2)
            if x[m[mid]]<x[i] then
                lo = mid + 1
            else
                hi = mid - 1
            end if
        end while
        if lo>1 then
            p[i] = m[lo-1]
        end if
        m[lo] = i
        if lo>len then len = lo end if
    end for
    sequence res = repeat(0,len)
    if len>0 then
        integer k = m[len]
        for i=len to 1 by -1 do
            res[i] = x[k]
            k = p[k]
        end for
    end if
    return res
end function

constant tests = {{3, 2, 6, 4, 5, 1},
                  {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}}
for i=1 to length(tests) do
    ?lis(tests[i])
end for


;;;	Compute the following number in the sequence
(define (next-number s)
	(let (n 0 c (first s) res "")
		(dostring (x s)
			(if (= (char x) c)	; the iteration variable is the ASCII code
				(++ n)
				(begin
					(setq res (string res n c))
					(setq n 1 c (char x)))))
		(setq res (string res n c))
		res))
;
;;;	Print out the first n+1 numbers, starting from 1
(define (go n)
	(let (s "1")
		(println s)
		(dotimes (x n)
			(setq s (next-number s))
			(println s))))
;
(go 10)


iterator lookAndSay(n: int): string =
  var current = "1"
  yield current
  for round in 2..n:
    var ch = current[0]
    var count = 1
    var next = ""
    for i in 1..current.high:
      if current[i] == ch:
        inc count
      else:
        next.add $count & ch
        ch = current[i]
        count = 1
    current = next & $count & ch
    yield current

for s in lookAndSay(12):
  echo s


<?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)));
?>


#import <Foundation/Foundation.h>

-(NSString*)lookAndSay:(NSString *)word{
    if (!word) {
        return nil;
    }
    NSMutableString *result = [NSMutableString new];

    char repeat = [word characterAtIndex:0];
    int times = 1;
    word = [NSString stringWithFormat:@"%@ ",[word substringFromIndex:1] ];

    for (NSInteger index = 0; index < word.length; index++) {
        char actual = [word characterAtIndex:index];
        if (actual != repeat) {
            [result appendFormat:@"%d%c", times, repeat];
            times = 1;
            repeat = actual;
        } else {
            times ++;
        }
    }

    return [result copy];
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSString *num = @"1";
    for (int i=1;i<=10;i++) {
        NSLog(@"%@", num);

        num = [self lookAndSay:num];
    }
}


table(+,+,max)
lis_mode(In, Out,OutLen) =>
  one_is(In, [], Is),
  Out = reverse(Is),
  OutLen = Out.length.

one_is([], Current, Current2) => Current = Current2.
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).


(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) ) )


function Get-LongestSubsequence ( [int[]]$A )
    {
    If ( $A.Count -lt 2 ) { return $A }

    #  Start with an "empty" pile
    #  (We will only store the top value in each "pile".)
    $Pile = @( [int]::MaxValue )
    $Last = 0

    #  Hashtable to hold the back pointers
    $BP = @{}

    #  For each number in the orginal sequence...
    ForEach ( $N in $A )
        {
        #  Find the first pile with a value greater than N
        $i = 0..$Last | Where { $N -lt $Pile[$_] } | Select -First 1

        #  Place N on the pile
        $Pile[$i] = $N

        #  Set the back pointer for this value to the value of the previous pile
        $BP["$N"] = $Pile[$i-1]

        #  If this is the previously empty pile, add a new empty pile
        If ( $i -eq $Last )
            {
            $Pile += @( [int]::MaxValue )
            $Last++
            }
        }

    #  Ignore the empty pile
    $Last--

    #  Start with the value of the last pile
    $N = $Pile[$Last]
    $S = @( $N )

    #  Add the remainder of the values by walking through the back pointers
    ForEach ( $i in $Last..1 )
        {
        $S += ( $N = $BP["$N"] )
        }

    #  Return the series (reversed into the correct order)
    return $S[$Last..0]
    }


let rec seeAndSay = function
  | [], nys -> List.rev nys
  | x::xs, [] -> seeAndSay(xs, [x; 1])
  | x::xs, y::n::nys when x=y -> seeAndSay(xs, y::1+n::nys)
  | x::xs, nys -> seeAndSay(xs, x::1::nys)


import: mapping

: lookAndSay ( n -- )
   [ 1 ] #[ dup .cr group map( [#size, #first] ) expand ] times( n ) ;


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).


def longest_increasing_subsequence(X):
    """Returns the Longest Increasing Subsequence in the Given List/Array"""
    N = len(X)
    P = [0] * N
    M = [0] * (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]]:
        print('a L.I.S. of %s is %s' % (d, longest_increasing_subsequence(d)))


declare
  %% e.g. "21" -> "1211"
  fun {LookAndSayString S}
     for DigitGroup in {Group S} append:Add do
        {Add {Int.toString {Length DigitGroup}}}
        {Add [DigitGroup.1]}
     end
  end

  %% lazy sequence of integers starting with N
  fun {LookAndSay N}
     fun lazy {Loop S}
        {String.toInt S}|{Loop {LookAndSayString S}}
     end
  in
     {Loop {Int.toString N}}
  end

  %% like Haskell's "group"
  fun {Group Xs}
     case Xs of nil then nil
     [] X|Xr then
	Ys Zs
        {List.takeDropWhile Xr fun {$ W} W==X end ?Ys ?Zs}
     in
        (X|Ys) | {Group Zs}
     end
  end
in
  {ForAll {List.take {LookAndSay 1} 10} Show}


step(n)={
  my(v=eval(Vec(Str(n))),cur=v[1],ct=1,out="");
  v=concat(v,99);
  for(i=2,#v,
    if(v[i]==cur,
      ct++
    ,
      out=Str(out,ct,cur);
      cur=v[i];
      ct=1
    )
  );
  eval(out)
};
n=1;for(i=1,20,print(n);n=step(n))


#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)))))])))


program LookAndSayDemo(input, output);

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}

uses
  SysUtils;

function LookAndSay(s: string): string;
var
  item: char;
  index: integer;
  count: integer;
begin
  Result := '';
  item := s[1];
  count := 1;
  for index := 2 to length(s) do
    if item = s[index] then
      inc(count)
    else
    begin
      Result := Result + intTostr(count) + item;
      item := s[index];
      count := 1;
    end;
  Result := Result + intTostr(count) + item;
end;

var
  number: string;

begin
  writeln('Press RETURN to continue and ^C to stop.');
  number := '1';
  while not eof(input) do
  begin
   write(number);
   readln;
   number := LookAndSay(number);
  end;
end.


sub lookandsay {
  my $str = shift;
  $str =~ s/((.)\2*)/length($1) . $2/ge;
  return $str;
}

my $num = "1";
foreach (1..10) {
  print "$num\n";
  $num = lookandsay($num);
}


/*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.  */
      $.2= 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 /*   "    "  2nd   "   "  "     "      */

        do j=1   while  $.j\=='';     say        /* [↓]  process all of the list for LIS*/
        say ' input: '  $.j                      /*display the (original) input list.   */
        call LIS        $.j                      /*invoke the  LIS  function.           */
        say 'output: '  result                   /*display the  output (result from LIS)*/
        end   /*j*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
LIS: procedure; parse arg x;   n= words(x);   if n==0  then return ''
     p.=;                            m.= p.
           do #=1  to n;  _= # - 1;  @._= word(x, #)    /*build an array (@) from input.*/
           end   /*#*/
     L= 0
           do j=0  to n-1;  lo= 1
           HI= L
                     do  while LO<=HI;    middle= (LO+HI) % 2
                          _= m.middle            /*create a temporary value for @ index.*/
                     if @._<@.j  then LO= middle + 1
                                 else HI= middle - 1
                     end   /*while*/
           newLO= LO
                  _= newLO - 1                   /*create a temporary value for M index.*/
           p.j= m._
           m.newLO= j
           if newLO>L  then L= newLO
           end   /*i*/
     k= m.L;                $=                   /* [↓]  build a list for the result.   */
                     do L;  $= @.k $;  k= p.k    /*perform this  DO  loop   L   times.  */
                     end   /*i*/
     return strip($)                             /*the result has an extra leading blank*/


# Project : Longest increasing subsequence

tests = [[3, 2, 6, 4, 5, 1], [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]]
res = []
for x=1 to len(tests)
    lis(tests[x])
    showarray(res)
end

func lis(X)
     N = len(X)
     P = list(N)
     M = list(N)
     for nr = 1 to len(P)
         P[nr] = 0
     next
     for nr = 1 to len(M)
         P[nr] = 0
     next
     len = 0
     for i=1 to N
         lo = 1
         hi = len
         while lo <= hi
               mid = floor((lo+hi)/2)
               if X[M[mid]]<X[i]
                  lo = mid + 1
               else
                  hi = mid - 1
               ok
         end
         if lo>1
            P[i] = M[lo-1]
         ok
         M[lo] = i
         if lo>len
            len = lo
         ok
     next
     res = list(len)
     if len>0
        k = M[len]
        for i=len to 1 step -1
            res[i] = X[k]
            k = P[k]
        next
     ok
     return res

func showarray(vect)
     see "{"
     svect = ""
     for n = 1 to len(vect)
         svect = svect + vect[n] + ", "
     next
     svect = left(svect, len(svect) - 2)
     see svect
     see "}" + nl


function lookandsay(string s)
    string res = ""
    integer p = s[1], c = 1
    for i=2 to length(s) do
        if p=s[i] then
            c += 1
        else
            res &= sprintf("%d%s",{c,p})
            p = s[i]
            c = 1
        end if
    end for
    res &= sprintf("%d%s",{c,p})
    return res
end function

string s = "1"
?s
for i=1 to 10 do
    s = lookandsay(s)
    ?s
end for


<?php

function lookAndSay($str) {

	return preg_replace_callback('#(.)\1*#', function($matches) {

		return strlen($matches[0]).$matches[1];
	}, $str);
}

$num = "1";

foreach(range(1,10) as $i) {

	echo $num."<br/>";
	$num = lookAndSay($num);
}

?>


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])


fn lis(x: &[i32])-> Vec<i32> {
    let n = x.len();
    let mut m = vec![0; n];
    let mut p = vec![0; n];
    let mut l = 0;

    for i in 0..n {
        let mut lo = 1;
        let mut hi = l;

        while lo <= hi {
            let mid = (lo + hi) / 2;

            if x[m[mid]] <= x[i] {
                lo = mid + 1;
            } else {
                hi = mid - 1;
            }
        }

        let new_l = lo;
        p[i] = m[new_l - 1];
        m[new_l] = i;

        if new_l > l {
            l = new_l;
        }
    }

    let mut o = vec![0; l];
    let mut k = m[l];
    for i in (0..l).rev() {
        o[i] = x[k];
        k    = p[k];
    }

    o
}

fn main() {
    let list = vec![3, 2, 6, 4, 5, 1];
    println!("{:?}", lis(&list));
    let list = vec![0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15];
    println!("{:?}", lis(&list));
}


go =>
   S1 = "1",
   foreach(_ in 1..11)
      println(S1),
      S1 := runs(S1)
   end,
   println(S1),
   nl.

runs(X) = V =>
  S = "",
  Last = X[1],
  C = 1,
  foreach(I in 2..X.length)
    if X[I] == Last then
       C := C + 1
    else
       S := S ++ C.to_string() ++ [X[I-1]],
       C := 1,
       Last := X[I]
    end
  end,
  V = S ++ C.to_string() ++ [Last].


(de las (Lst)
   (make
      (while Lst
         (let (N 1  C)
            (while (= (setq C (pop 'Lst)) (car Lst))
               (inc 'N) )
            (link N C) ) ) ) )


100H:
BDOS: PROCEDURE (FN, ARG); DECLARE FN BYTE, ARG ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; CALL BDOS(0,0); END EXIT;
PRINT: PROCEDURE (S); DECLARE S ADDRESS; CALL BDOS(9,S); END PRINT;

COPY$STRING: PROCEDURE (SRC, DEST);
    DECLARE (SRC, DEST, I) ADDRESS;
    DECLARE (S BASED SRC, D BASED DEST) BYTE;
    I = 0;
    DO WHILE S(I) <> '$';
        D(I) = S(I);
        I = I + 1;
    END;
    D(I) = '$';
END COPY$STRING;

COUNT: PROCEDURE (POS) BYTE;
    DECLARE POS ADDRESS, (I, P BASED POS) BYTE;
    I = 1;
    DO WHILE P(I) = P;
        I = I + 1;
    END;
    RETURN I;
END COUNT;

LOOK$SAY: PROCEDURE (OLD, NEW);
    DECLARE (OLD, NEW) ADDRESS;
    DECLARE (O BASED OLD, N BASED NEW, C) BYTE;
    DO WHILE O <> '$';
        C = COUNT(OLD);
        N = O;
        N(1) = C + '0';
        NEW = NEW + 2;
        OLD = OLD + C;
    END;
    N = '$';
END LOOK$SAY;

DECLARE STEPS LITERALLY '15';
DECLARE BUF$SIZE LITERALLY '128';

DECLARE BUFR1 (BUF$SIZE) BYTE INITIAL ('1$');
DECLARE BUFR2 (BUF$SIZE) BYTE;
DECLARE I BYTE;

DO I=1 TO STEPS;
    CALL PRINT(.BUFR1);
    CALL PRINT(.(13,10,'$'));
    CALL LOOK$SAY(.BUFR1, .BUFR2);
    CALL COPY$STRING(.BUFR2, .BUFR1);
END;
CALL EXIT;
EOF


object LongestIncreasingSubsequence extends App {
  val tests = Map(
    "3,2,6,4,5,1" -> Seq("2,4,5", "3,4,5"),
    "0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15" -> Seq("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 lis(l: Array[Int]): Seq[Array[Int]] =
    if (l.length < 2) Seq(l)
    else {
      def increasing(done: Array[Int], remaining: Array[Int]): Seq[Array[Int]] =
        if (remaining.isEmpty) Seq(done)
        else
          (if (remaining.head > done.last)
            increasing(done :+ remaining.head, remaining.tail)
          else Nil) ++ 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) // longest of all increasing combinations
    }

  def asInts(s: String): Array[Int] = s split "," map (_.toInt)

  assert(tests forall {
    case (given, expect) =>
      val allLongests: Seq[Array[Int]] = lis(asInts(given))
      println(
        s"$given has ${allLongests.length} longest increasing subsequences, e.g. ${
          allLongests.last.mkString(",")}")
      allLongests.forall(lis => expect.contains(lis.mkString(",")))
  })
}


FUNCTION RLEncode (i AS STRING) AS STRING
    DIM tmp1 AS STRING, tmp2 AS STRING, outP AS STRING
    DIM Loop0 AS LONG, count AS LONG

    FOR Loop0 = 1 TO LEN(i)
        tmp1 = MID$(i, Loop0, 1)
        IF tmp1 <> tmp2 THEN
            IF count > 1 THEN
                outP = outP & TRIM$(STR$(count)) & tmp2
                tmp2 = tmp1
                count = 1
            ELSEIF 0 = count THEN
                tmp2 = tmp1
                count = 1
            ELSE
                outP = outP & "1" & tmp2
                tmp2 = tmp1
            END IF
        ELSE
            INCR count
        END IF
    NEXT

    outP = outP & TRIM$(STR$(count)) & tmp2
    FUNCTION = outP
END FUNCTION

FUNCTION lookAndSay(BYVAL count AS LONG) AS STRING
    DIM iii AS STRING, tmp AS STRING

    IF count > 1 THEN
        iii = lookAndSay(count - 1)
    ELSEIF count < 2 THEN
        iii = "1"
    END IF

    tmp = RLEncode(iii)
    lookAndSay = tmp
END FUNCTION

FUNCTION PBMAIN () AS LONG
    DIM v AS LONG
    v = VAL(INPUTBOX$("Enter a number."))
    MSGBOX lookAndSay(v)
END FUNCTION


function Get-LookAndSay ($n = 1) {
    $re = [regex] '(.)\1*'
    $ret = ""
    foreach ($m in $re.Matches($n)) {
        $ret += [string] $m.Length + $m.Value[0]
    }
    return $ret
}

function Get-MultipleLookAndSay ($n) {
    if ($n -eq 0) {
        return @()
    } else {
        $a = 1
        $a
        for ($i = 1; $i -lt $n; $i++) {
            $a = Get-LookAndSay $a
            $a
        }
    }
}


F is_long_year(year)
   F p(year)
      R (year + (year I/ 4) - (year I/ 100) + (year I/ 400)) % 7
   R p(year) == 4 | p(year - 1) == 3

L(year) 2000..2100
   I is_long_year(year)
      print(year, end' ‘ ’)


(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)


look_and_say(L) :-
	maplist(write, L), nl,
	encode(L, L1),
	look_and_say(L1).

% This code is almost identical to the code of "run-length-encoding"
encode(In, Out) :-
	packList(In, R1),
	append(R1,Out).

% use of library clpfd allows packList(?In, ?Out) to works
% in both ways In --> Out and In <-- Out.

:- use_module(library(clpfd)).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ?- packList([a,a,a,b,c,c,c,d,d,e], L).
%  L = [[3,a],[1,b],[3,c],[2,d],[1,e]] .
% ?- packList(R,  [[3,a],[1,b],[3,c],[2,d],[1,e]]).
% R = [a,a,a,b,c,c,c,d,d,e] .
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
packList([],[]).

packList([X],[[1,X]]) :- !.

packList([X|Rest],[XRun|Packed]):-
    run(X,Rest, XRun,RRest),
    packList(RRest,Packed).

run(Var,[],[1,Var],[]).

run(Var,[Var|LRest],[N1, Var],RRest):-
    N #> 0,
    N1 #= N + 1,
    run(Var,LRest,[N, Var],RRest).

run(Var,[Other|RRest], [1,Var],[Other|RRest]):-
    dif(Var,Other).


BYTE FUNC P(CARD y)
RETURN ((y+(y/4)-(y/100)+(y/400)) MOD 7)

BYTE FUNC IsLongYear(CARD y)
  IF P(y)=4 OR P(y-1)=3 THEN
    RETURN (1)
  FI
RETURN (0)

PROC Main()
  CARD y
  BYTE LMARGIN=$52,oldLMARGIN

  oldLMARGIN=LMARGIN
  LMARGIN=0 ;remove left margin on the screen
  Put(125) PutE() ;clear the screen

  FOR y=1900 TO 2400
  DO
    IF IsLongYear(y) THEN
      PrintC(y) Put(32)
    FI
  OD

  LMARGIN=oldLMARGIN ;restore left margin on the screen
RETURN


-------------------------------------------------------------
-- Calculate long years
-- Reference: https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year
-------------------------------------------------------------
with Ada.Text_IO;             use Ada.Text_IO;
with Ada.Calendar;            use Ada.Calendar;
with Ada.Calendar.Formatting; use Ada.Calendar.Formatting;

procedure Main is
   First_Day : Time;
   Last_Day  : Time;
   package AC renames Ada.Calendar;
   type Counter is mod 10;
   Count : Counter := 0;
begin
   for Yr in Year_Number loop

      First_Day := AC.Time_Of (Year => Yr, Month => 1, Day => 1);
      Last_Day  := AC.Time_Of (Year => Yr, Month => 12, Day => 31);

      -- If Jan 1 is Thursday or Dec 31 is Thursday then
      -- the year is a long year

      if Day_Of_Week (First_Day) = Thursday
        or else Day_Of_Week (Last_Day) = Thursday
      then
         if Count = 0 then
            New_Line;
         end if;
         Put (Yr'Image);
         Count := Count + 1;
      end if;
   end loop;
end Main;


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


using system;

// Remove the trailing "L" from the string representation of bigints.
__show__ x::bigint = init (str x);

say x = val $ strcat $ map (sprintf "%d%s") $ look $ chars $ str x with
  look [] = [];
  look [email protected](x:_) = (#takewhile (==x) xs,x) : look (dropwhile (==x) xs);
end;

iteraten 5 say 1; // [1,11,21,1211,111221]

// This prints the entire sequence, press Ctrl-C to abort.
do (puts.str) (iterate say 1);


If OpenConsole()
  Define i, j, cnt, txt$, curr$, result$
  Print("Enter start sequence: "): txt$=Input()
  Print("How many repetitions: "): i=Val(Input())
  ;
  PrintN(#CRLF$+"Sequence:"+#CRLF$+txt$)
  Repeat
    j=1
    result$=""
    Repeat
      curr$=Mid(txt$,j,1)
      cnt=0
      Repeat
        cnt+1
        j+1
      Until Mid(txt$,j,1)<>curr$
      result$+Str(cnt)+curr$
    Until j>Len(txt$)
    PrintN(result$)
    txt$=result$
    i-1
  Until i<=0
  ;
  PrintN(#CRLF$+"Press ENTER to exit."): Input()
  CloseConsole()
EndIf


BEGIN # find "long years" - years which have 53 weeks this is equivalent to #
      # finding years where 1st Jan or 31st Dec are Thursdays               #
    # returns the day of the week of the specified date (d/m/y), Sunday = 1 #
    PROC day of week = ( INT d, m, y )INT:
         BEGIN
            INT mm := m;
            INT yy := y;
            IF mm <= 2 THEN
                mm := mm + 12;
                yy := yy - 1
            FI;
            INT j = yy OVER 100;
            INT k = yy MOD  100;
            (d + ( ( mm + 1 ) * 26 ) OVER 10 + k + k OVER 4 + j OVER 4 + 5 * j ) MOD 7
         END # day of week # ;
    # returns TRUE if year is a long year, FALSE otherwise                  #
    PROC is long year = ( INT year )BOOL:
        day of week( 1, 1, year ) = 5 OR day of week( 31, 12, year ) = 5;
    # show long years from 2000-2099                                        #
    print( ( "long years 2000-2099:" ) );
    FOR year FROM 2000 TO 2099 DO
        IF is long year( year ) THEN print( ( " ", whole( year, 0 ) ) ) FI
    OD
END


BEGIN

COMMENT
  FIND ISO CALENDAR YEARS HAVING 53 WEEKS. THE SIMPLEST
  TEST IS THAT A GIVEN YEAR WILL BE "LONG" IF EITHER THE
  FIRST OR LAST DAY IS A THURSDAY;

% CALCULATE P MOD Q %
INTEGER FUNCTION MOD(P, Q);
INTEGER P, Q;
BEGIN
   MOD := P - Q * (P / Q);
END;

COMMENT
  RETURN DAY OF WEEK (SUN=0, MON=1, ETC.) FOR A GIVEN
  GREGORIAN CALENDAR DATE USING ZELLER'S CONGRUENCE;
INTEGER FUNCTION DAYOFWEEK(MO, DA, YR);
INTEGER MO, DA, YR;
BEGIN
  INTEGER Y, C, Z;
  IF MO < 3 THEN
    BEGIN
      MO := MO + 10;
      YR := YR - 1;
    END
  ELSE MO := MO - 2;
  Y := MOD(YR, 100);
  C := YR / 100;
  Z := (26 * MO - 2) / 10;
  Z := Z + DA + Y + (Y / 4) + (C /4) - 2 * C + 777;
  DAYOFWEEK := MOD(Z, 7);
END;

% RETURN 1 IF YEAR IS LONG, OTHERWISE 0 %
INTEGER FUNCTION ISLONGYEAR(YR);
INTEGER YR;
BEGIN
  INTEGER THURSDAY;
  THURSDAY := 4;
  IF (DAYOFWEEK(1,1,YR) = THURSDAY) OR
     (DAYOFWEEK(12,31,YR) = THURSDAY) THEN
       ISLONGYEAR := 1
  ELSE
       ISLONGYEAR := 0;
END;

% MAIN PROGRAM STARTS HERE %
INTEGER YEAR;
WRITE("ISO YEARS THAT WILL BE LONG IN THIS CENTURY:");
WRITE("");
FOR YEAR := 2000 STEP 1 UNTIL 2099 DO
  BEGIN
    IF ISLONGYEAR(YEAR) = 1 THEN WRITEON(YEAR);
  END;

END


begin % find "long years" - years which have 53 weeks %
      % this is equivalent to finding years where     %
      % 1st Jan or 31st Dec are Thursdays             %
    % finds the day of the week - Sunday = 1          %
    integer procedure Day_of_week ( integer value d, m, y );
        begin
            integer j, k, mm, yy;
            mm := m;
            yy := y;
            if mm <= 2 then begin
                mm := mm + 12;
                yy := yy - 1;
            end if_m_le_2;
            j := yy div 100;
            k := yy rem 100;
            (d + ( ( mm + 1 ) * 26 ) div 10 + k + k div 4 + j div 4 + 5 * j ) rem 7
        end Day_of_week;
    % returns true if year is a long year, false otherwise %
    logical procedure isLongYear ( integer value year );
        Day_of_week( 1, 1, year ) = 5 or Day_of_week( 31, 12, year ) = 5;
    % show long years from 2000-2099 %
    write( "long years 2000-2099:" );
    for year := 2000 until 2099 do begin
        if isLongYear( year ) then writeon( I_W := 5, S_W := 0, year )
    end for_year
end.


import Foundation

extension Array where Element: Comparable {
  @inlinable
  public func longestIncreasingSubsequence() -> [Element] {
    var startI = [Int](repeating: 0, count: count)
    var endI = [Int](repeating: 0, count: count + 1)
    var len = 0

    for i in 0..<count {
      var lo = 1
      var hi = len

      while lo <= hi {
        let mid = Int(ceil((Double(lo + hi)) / 2))

        if self[endI[mid]] <= self[i] {
          lo = mid + 1
        } else {
          hi = mid - 1
        }
      }

      startI[i] = endI[lo-1]
      endI[lo] = i

      if lo > len {
        len = lo
      }
    }

    var s = [Element]()
    var k = endI[len]

    for _ in 0..<len {
      s.append(self[k])
      k = startI[k]
    }

    return s.reversed()
  }
}

let l1 = [3, 2, 6, 4, 5, 1]
let l2 = [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]

print("\(l1) = \(l1.longestIncreasingSubsequence())")
print("\(l2) = \(l2.longestIncreasingSubsequence())")


Array.'lis'
{
  'stems' = Number.Array.mutableArray[ [] ]

  forEach(this) 'value'->
  {
    'bestStem' = stems.where{==[] || .last < value}.max{.length}

    stems.push( bestStem + [value] )
  }

  return stems.max{.length}
}

[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


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]
}


def lookandsay(number):
    result = ""

    repeat = number[0]
    number = number[1:]+" "
    times = 1

    for actual in number:
        if actual != repeat:
            result += str(times)+repeat
            times = 1
            repeat = actual
        else:
            times += 1

    return result

num = "1"

for i in range(10):
    print num
    num = lookandsay(num)


las:{{raze string[count@'x],'@'[;0]x:where[differ x]_x}\[x;1#"1"]}
las 8


dec31weekday ← {7|(⍵+⌊(⍵÷4)+⌊(⍵÷400)-⌊⍵÷100)}
isolongyear ← {(4 = dec31weekday ⍵) ∨ (3 = dec31weekday (⍵ - 1))}


on isLongYear(y)
    -- ISO8601 weeks begin on Mondays and belong to the year in which they have the most days.
    -- A year which begins on a Thursday, or which begins on a Wednesday and is a leap year,
    -- has majority stakes in the weeks it overlaps at *both* ends and so has 53 weeks instead of 52.
    -- Leap years divisible by 400 begin on Saturdays and so don't so need to be considered in the leap year check.

    tell (current date) to set {Jan1, its day, its month, its year} to {it, 1, January, y}
    set startWeekday to Jan1's weekday

    return ((startWeekday is Thursday) or ((startWeekday is Wednesday) and (y mod 4 is 0) and (y mod 100 > 0)))
end isLongYear

set longYears to {}
repeat with y from 2001 to 2100
    if (isLongYear(y)) then set end of longYears to y
end repeat

return longYears


longYear?: function [year][
    date: to :date .format: "dd/MM/yyyy" ~"01/01/|year|"

    or? date\Day = "Thursday"
        and? leap? year
             date\Day = "Wednesday"
]

print "Years with 53 weeks between 2000 and 2100:"
print select 2000..2100 => longYear?


Function LIS(arr)
	n = UBound(arr)
	Dim p()
	ReDim p(n)
	Dim m()
	ReDim m(n)
	l = 0
	For i = 0 To n
		lo = 1
		hi = l
		Do While lo <= hi
			middle = Int((lo+hi)/2)
			If arr(m(middle)) < arr(i) Then
				lo = middle + 1
			Else
				hi = middle - 1
			End If
		Loop
		newl = lo
		p(i) = m(newl-1)
		m(newl) = i
		If newL > l Then
			l = newl
		End If
	Next
	Dim s()
	ReDim s(l)
	k = m(l)
	For i = l-1 To 0 Step - 1
		s(i) = arr(k)
		k = p(k)
	Next
	LIS = Join(s,",")
End Function

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))


var longestIncreasingSubsequence = Fn.new { |x|
    var n = x.count
    if (n == 0) return []
    if (n == 1) return x
    var p = List.filled(n, 0)
    var m = List.filled(n+1, 0)
    var len = 0
    for (i in 0...n) {
        var lo = 1
        var hi = len
        while (lo <= hi) {
            var mid = ((lo + hi)/2).ceil
            if (x[m[mid]] < x[i]) {
                lo = mid + 1
            } else {
                hi = mid - 1
            }
        }
        var newLen = lo
        p[i] = m[newLen - 1]
        m[newLen] = i
        if (newLen > len) len = newLen
    }
    var s = List.filled(len, 0)
    var k = m[len]
    for (i in len-1..0) {
        s[i] = x[k]
        k = p[k]
    }
    return s
}

var lists = [
    [3, 2, 6, 4, 5, 1],
    [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]
]
lists.each { |l| System.print(longestIncreasingSubsequence.call(l)) }


  [ stack ] is instances

  [ 1 instances put
    $ "" swap
    behead swap space join
    witheach
      [ 2dup != iff
        [ rot instances share
          number$ join
          rot join swap
          1 instances replace ]
        else
          [ drop
            1 instances tally ] ]
    drop instances release ]       is lookandsay ( $ --> $ )

  $ "1"
  15 times
    [ dup echo$ cr
      lookandsay ]
  echo$ cr


look.and.say <- function(x, return.an.int=FALSE)
{
   #convert number to character vector
   xstr <- unlist(strsplit(as.character(x), ""))
   #get run length encoding
   rlex <- rle(xstr)
   #form new string
   odds <- as.character(rlex$lengths)
   evens <- rlex$values
   newstr <- as.vector(rbind(odds, evens))
   #collapse to scalar
   newstr <- paste(newstr, collapse="")
   #convert to number, if desired
   if(return.an.int) as.integer(newstr) else newstr
}


#lang racket

(define (encode str)
  (regexp-replace* #px"(.)\\1*" str (lambda (m c) (~a (string-length m) c))))

(define (look-and-say-sequence n)
  (reverse (for/fold ([r '("1")]) ([n n]) (cons (encode (car r)) r))))

(for-each displayln (look-and-say-sequence 10))


Long_year(y) {
	A := Mod(y + floor(y/4) - floor(y/100) + floor(y/400), 7)
	y--, B := Mod(y + floor(y/4) - floor(y/100) + floor(y/400), 7)
	return A=4 || B=3
}


# syntax: GAWK -f LONG_YEAR.AWK
BEGIN {
    for (cc=19; cc<=21; cc++) {
      printf("%2d00-%2d99: ",cc,cc)
      for (yy=0; yy<=99; yy++) {
        ccyy = sprintf("%02d%02d",cc,yy)
        if (is_long_year(ccyy)) {
          printf("%4d ",ccyy)
        }
      }
      printf("\n")
    }
#
    printf("\n%4d-%4d: ",by=1970,ey=2037)
    for (y=by; y<=ey; y++) {
      if (strftime("%V",mktime(sprintf("%d 12 28 0 0 0",y))) == 53) {
        printf("%4d ",y)
      }
    }
    printf("\n")
    exit(0)
}
function is_long_year(year,  i) {
    for (i=0; i<=1; i++) {
      year -= i
      if ((year + int(year/4) - int(year/100) + int(year/400)) % 7 == 4-i) {
        return(1)
      }
    }
    return(0)
}


fcn longestSequence(ns){ // based on Patience sorting
   piles:=L();
   backPtr:='wrap(np){ return(np-1,if(np) piles[np-1].len()-1 else -1) }; // maybe (-1,-1)
   foreach n in (ns){ newPile:=True;   // create list of sorted lists
      foreach e,p in (piles.enumerate()){
	 if(n<p[-1][0]){
	    p.del(1,-1)  // only need the first and last elements
	    .append(T(n,backPtr(e))); newPile=False;
	    break;
	 }
      }
      if(newPile) piles.append(L(T(n,backPtr(piles.len()))));
   }
   reg r=L(),p=-1,n=0;
   do{ n,p=piles[p][n]; r.write(n); p,n=p; }while(p!=-1);
   r.reverse()
}


/*REXX program displays the sequence (and/or lengths) for the    look and say    series.*/
parse arg N ! .                                  /*obtain optional arguments from the CL*/
if N=='' | N==","  then N= 20                    /*Not specified?  Then use the default.*/
if !=='' | !==","  then !=  1                    /* "      "         "   "   "     "    */

     do j=1  for abs(N)                          /*repeat a number of times to show NUMS*/
     if j\==1  then != lookNsay(!)               /*invoke function to calculate next #. */
     if N<0    then say 'length['j"]:" length(!) /*Also,  display the sequence's length.*/
               else say '['j"]:"      !          /*display the number to the terminal.  */
     end   /*j*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
lookNsay: procedure; parse arg x,,$              /*obtain the (passed) argument  {X}.   */
          fin = '0'x                             /*use unique character to end scanning.*/
          x= x || fin                            /*append the  FIN  character to string.*/
                      do k=1  by 0               /*now,  process the given sequence.    */
                      y=  substr(x, k, 1)        /*pick off one character to examine.   */
                      if y== fin  then return $  /*if we're at the end, then we're done.*/
                      _= verify(x, y, , k) - k   /*see how many characters we have of Y.*/
                      $= $  ||  _  ||  y         /*build the  "look and say"  sequence. */
                      k= k + _                   /*now, point to the next character.    */
                      end   /*k*/


 10  DEF  FN M7(N) = N - 7 *  INT (N / 7)
 20  DEF  FN WD(Y) =  FN M7(Y +  INT (Y / 4) -  INT (Y / 100) +  INT (Y / 400))
 30  DEF  FN LY(Y) = (4 =  FN WD(Y)) OR (3 =  FN WD(Y - 1))
 40  HOME : INVERSE : PRINT "****     LIST OF ISO LONG YEARS     ****": NORMAL
 50  INPUT "START YEAR? ";S
 60  INPUT "END YEAR? ";E
 70  PRINT : FOR Y = S TO E
 80  IF  FN LY(Y) THEN  PRINT S$Y;:S$ = " "
 90  NEXT Y


get "libhdr"

let p(y) = (y + y/4 - y/100 + y/400) rem 7
let longyear(y) = p(y)=4 | p(y-1)=3

let start() be
    for y = 2000 to 2100
        if longyear(y) do writef("%N*N", y)


using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;

public static class Program
{
    public static void Main()
    {
        WriteLine("Long years in the 21st century:");
        WriteLine(string.Join(" ", 2000.To(2100).Where(y => ISOWeek.GetWeeksInYear(y) == 53)));
    }

    public static IEnumerable<int> To(this int start, int end) {
        for (int i = start; i < end; i++) yield return i;
    }

}


number = "1"
for nr = 1 to 10
    number = lookSay(number)
    see number + nl
next

func lookSay n
     i = 0 j = 0 c="" o=""
     i = 1
     while i <= len(n)
           c = substr(n,i,1)
           j = i + 1
           while substr(n,j,1) = c
                 j += 1
           end
           o += string(j-i) + c
           i = j
      end
      return o


class String
  def look_and_say
    gsub(/(.)\1*/){|s| s.size.to_s + s[0]}
  end
end

ss = '1'
12.times {puts ss; ss = ss.look_and_say}


fn next_sequence(in_seq: &[i8]) -> Vec<i8> {
    assert!(!in_seq.is_empty());

    let mut result = Vec::new();
    let mut current_number = in_seq[0];
    let mut current_runlength = 1;

    for i in &in_seq[1..] {
        if current_number == *i {
            current_runlength += 1;
        } else {
            result.push(current_runlength);
            result.push(current_number);
            current_runlength = 1;
            current_number = *i;
        }
    }
    result.push(current_runlength);
    result.push(current_number);
    result
}

fn main() {
    let mut seq = vec![1];

    for i in 0..10 {
        println!("Sequence {}: {:?}", i, seq);
        seq = next_sequence(&seq);
    }
}


#include <stdio.h>
#include <math.h>

// https://webspace.science.uu.nl/~gent0113/calendar/isocalendar.htm

int p(int year) {
	return (int)((double)year + floor(year/4) - floor(year/100) + floor(year/400)) % 7;
}

int is_long_year(int year) {
	return p(year) == 4 || p(year - 1) == 3;
}

void print_long_years(int from, int to) {
	for (int year = from; year <= to; ++year) {
		if (is_long_year(year)) {
			printf("%d ", year);
		}
	}
}

int main() {

	printf("Long (53 week) years between 1800 and 2100\n\n");
	print_long_years(1800, 2100);
	printf("\n");
	return 0;
}


// Reference:
// https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year

#include <iostream>

inline int p(int year) {
    return (year + (year/4) - (year/100) + (year/400)) % 7;
}

bool is_long_year(int year) {
    return p(year) == 4 || p(year - 1) == 3;
}

void print_long_years(int from, int to) {
    for (int year = from, count = 0; year <= to; ++year) {
        if (is_long_year(year)) {
            if (count > 0)
                std::cout << ((count % 10 == 0) ? '\n' : ' ');
            std::cout << year;
            ++count;
        }
    }
}

int main() {
    std::cout << "Long years between 1800 and 2100:\n";
    print_long_years(1800, 2100);
    std::cout << '\n';
    return 0;
}


class MAIN is
   look_and_say!: STR is
      current ::= "1";
      loop
         yield current;
         buf ::= #FSTR;
         last ::= current[0];
         count ::= 0;
         loop
            ch ::= current.elt!;
            if ch /= last then
               buf := buf + count + last;
               last := ch; count := 1;
            else
               count := count + 1;
            end;
         end;
         current := (buf + count + last).str;
      end;
   end;

   main is
      loop 12.times!;
         #OUT+ look_and_say! + "\n";
      end;
   end;
end;


import scala.annotation.tailrec

object LookAndSay extends App {

  loop(10, "1")

  @tailrec
  private def loop(n: Int, num: String): Unit = {
    println(num)
    if (n <= 0) () else loop(n - 1, lookandsay(num))
  }

  private def lookandsay(number: String): String = {
    val result = new StringBuilder

    @tailrec
    def loop(numberString: String, repeat: Char, times: Int): String =
      if (numberString.isEmpty) result.toString()
      else if (numberString.head != repeat) {
        result.append(times).append(repeat)
        loop(numberString.tail, numberString.head, 1)
      } else loop(numberString.tail, numberString.head, times + 1)

    loop(number.tail + " ", number.head, 1)
  }

}


(defn long-year? [year]
  (-> (java.time.LocalDate/of year 12 28)
      (.get (.weekOfYear (java.time.temporal.WeekFields/ISO)))
      (= 53)))

(filter long-year? (range 2000 2100))


% We can't hide one procedure inside another, but
% we can hide the helper `p' in a cluster

longyear = cluster is test
    rep = null

    p = proc (n: int) returns (int)
        return ((n + n/4 - n/100 + n/400) // 7)
    end p

    test = proc (y: int) returns (bool)
        return (p(y)=4 | p(y-1)=3)
    end test
end longyear

start_up = proc ()
    po: stream := stream$primary_output()

    for i: int in int$from_to(2000, 2100) do
        if longyear$test(i) then
            stream$putl(po, int$unparse(i))
        end
    end
end start_up


(defun december-31-weekday (year)
   (mod (+ year (floor year 4) (- (floor year 100)) (floor year 400)) 7))

(defun iso-long-year-p (year)
    (or (= 4 (december-31-weekday year)) (= 3 (december-31-weekday (1- year)))))

(format t "Long years between 1800 and 2100:~&~a~%"
    (loop for y from 1800 to 2100 if (iso-long-year-p y) collect y))


$ include "seed7_05.s7i";

const func string: lookAndSay (in integer: level, in string: stri) is func
  result
    var string: lookAndSay is "";
  local
    var integer: index is 2;
  begin
    if level = 1 then
      if stri <> "" then
        while index <= length(stri) and stri[index] = stri[1] do
          incr(index);
        end while;
        lookAndSay := str(pred(index)) & stri[1 len 1] & lookAndSay(level, stri[index ..]);
      end if;
    else
      lookAndSay := lookAndSay(1, lookAndSay(pred(level), stri));
    end if;
  end func;

const proc: main is func
  local
    var integer: level is 0;
  begin
    for level range 1 to 14 do
      writeln(lookAndSay(level, "1"));
    end for;
  end func;


func lookandsay(str) {
    str.gsub(/((.)\2*)/, {|a,b| a.len.to_s + b });
}

var num = "1";
{
  say num;
  num = lookandsay(num);
} * 10;


String extend [
  lookAndSay [ |anElement nextElement counter coll newColl|
     coll := (self asOrderedCollection).
     newColl := OrderedCollection new.
     counter := 0.
     anElement := (coll first).
     [ coll size > 0 ]
     whileTrue: [
        nextElement := coll removeFirst.
	( anElement == nextElement ) ifTrue: [
           counter := counter + 1.
        ] ifFalse: [
	  newColl add: (counter displayString).
	  newColl add: (anElement asString).
	  anElement := nextElement.
	  counter := 1.
        ]
     ].
     newColl add: (counter displayString).
     newColl add: (anElement asString).
     ^(newColl join)
  ]
].

|r|
r := '1'.
10 timesRepeat: [
  r displayNl.
  r := r lookAndSay.
]


program Long_year;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

function p(const Year: Integer): Integer;
begin
  Result := (Year + (Year div 4) - (Year div 100) + (Year div 400)) mod 7;
end;

function IsLongYear(const Year: Integer): Boolean;
begin
  Result := (p(Year) = 4) or (p(Year - 1) = 3);
end;

procedure PrintLongYears(const StartYear: Integer; const EndYear: Integer);
var
  Year, Count: Integer;
begin
  Count := 0;
  for Year := 1800 to 2100 do
    if IsLongYear(Year) then
    begin
      if Count mod 10 = 0 then
        Writeln;
      Write(Year, ' ');
      inc(Count);
    end;
end;

var
  Year: Integer;

begin
  Writeln('Long years between 1800 and 2100:');
  PrintLongYears(1800, 2100);
  Readln;
end.


defmodule ISO do
  def long_year?(y) do
    {:ok, jan1} = Date.new(y,1,1)
    {:ok, dec31} = Date.new(y,12,31)
    Date.day_of_week(jan1) == 4 or Date.day_of_week(dec31) == 4
  end
end

IO.inspect(Enum.filter(1990..2050, &ISO.long_year?/1))


*       # Encode RLE
        define('rle(str)c,n') :(rle_end)
rle     str len(1) . c :f(return)
        str span(c) @n =
        rle = rle n c :(rle)
rle_end

*       # First m members of sequence with seed n
        define('looksay(n,m)') :(looksay_end)
looksay output = n; m = gt(m,1) m - 1 :f(return)
        n = rle(n) :(looksay)
looksay_end

*       Test and display
        looksay(1,10)
end


DROP VIEW delta;
CREATE VIEW delta AS
    SELECT sequence1.v AS x,
           (sequence1.v<>sequence2.v)*sequence1.c AS v,
           sequence1.c AS c
      FROM SEQUENCE AS sequence1,
           SEQUENCE AS sequence2
     WHERE sequence1.c = sequence2.c+1;

DROP VIEW rle0;
CREATE VIEW rle0 AS
    SELECT delta2.x AS x,
           SUM(delta2.v) AS v,
           delta2.c AS c
      FROM delta AS delta1,
           delta AS delta2
     WHERE delta1.c >= delta2.c
  GROUP BY delta1.c;

DROP VIEW rle1;
CREATE VIEW rle1 AS
    SELECT SUM(x)/x AS a,
           x AS b,
           c AS c
      FROM rle0
  GROUP BY v;

DROP VIEW rle2;
CREATE VIEW rle2 AS
    SELECT a AS v, 1 AS o, 2*c+0 AS c FROM rle1 UNION
    SELECT b AS v, 1 AS o, 2*c+1 AS c FROM rle1;

DROP VIEW normed;
CREATE VIEW normed AS
    SELECT r1.v AS v, SUM(r2.o) AS c
      FROM rle2 AS r1,
           rle2 AS r2
     WHERE r1.c >= r2.c
  GROUP BY r1.c;

DROP TABLE rle;
CREATE TABLE rle(v INT, c INT);
INSERT INTO rle SELECT * FROM normed ORDER BY c;

DELETE FROM SEQUENCE;
INSERT INTO SEQUENCE VALUES(-1,0);
INSERT INTO SEQUENCE SELECT * FROM rle;


USING: calendar formatting io kernel math.ranges sequences ;

: long-year? ( n -- ? ) 12 28 <date> week-number 53 = ;

"Year  Long?\n-----------" print 1990 2021 [a,b]
[ dup long-year? "yes" "no" ? "%d  %s\n" printf ] each


: dec31wd ( year -- weekday ) dup dup 4 / swap dup 100 / swap 400 / swap - + + 7 mod ;
: long? ( year -- flag ) dup dec31wd 4 = if drop 1 else 1 - dec31wd 3 = if 1 else 0 then then ;
: demo ( startyear endyear -- ) cr swap do i long? if i . then loop cr ;


program longyear
    use iso_fortran_env, only: output_unit, input_unit
    implicit none

    integer             :: start, ende, i, counter
    integer, parameter  :: line_break=10

    write(output_unit,*) "Enter beginning of interval"
    read(input_unit,*) start
    write(output_unit,*) "Enter end of interval"
    read(input_unit,*) ende

    if (start>=ende) error stop "Last year must be after first year!"

    counter = 0
    do i = start, ende
        if (is_long_year(i)) then
            write(output_unit,'(I0,x)', advance="no") i
            counter = counter + 1
            if (modulo(counter,line_break) == 0) write(output_unit,*)
        end if
    end do
contains
    pure function p(year)
        integer, intent(in) :: year
        integer             :: p

        p = modulo(year + year/4 - year/100 + year/400, 7)
    end function p

    pure function is_long_year(year)
        integer, intent(in) :: year
        logical             :: is_long_year

        is_long_year = p(year) == 4 .or. p(year-1) == 3
    end function is_long_year
end program longyear


SET SERVEROUTPUT ON @

BEGIN
 DECLARE NMBR VARCHAR(100) DEFAULT '1';
 DECLARE J SMALLINT DEFAULT 1;

 CALL DBMS_OUTPUT.PUT_LINE(NMBR);
 WHILE (J < 10) DO
  BEGIN
  DECLARE I SMALLINT;
  DECLARE SIZE SMALLINT;
  DECLARE ACTUAL CHAR(1);
  DECLARE REPEAT CHAR(1);
  DECLARE RESULT VARCHAR(100);
  DECLARE TIMES SMALLINT;

  SET REPEAT = SUBSTR(NMBR, 1, 1);
  SET NMBR = SUBSTR(NMBR, 2) || ' ';
  SET TIMES = 1;
  SET I = 1;
  SET SIZE = LENGTH(NMBR);

  WHILE (I <= SIZE) DO
   SET ACTUAL = SUBSTR(NMBR, I, 1);
   IF (ACTUAL <> REPEAT) THEN
    SET RESULT = COALESCE(RESULT, '') || TIMES || '' || REPEAT;
    SET TIMES = 1;
    SET REPEAT = ACTUAL;
   ELSE
    SET TIMES = TIMES + 1;
   END IF;
   SET I = I + 1;
  END WHILE;

  CALL DBMS_OUTPUT.PUT_LINE(RESULT);
  SET NMBR = RESULT;
  END ;
  SET J = J + 1;
 END WHILE;
END @


func lookAndSay(_ seq: [Int]) -> [Int] {
  var result = [Int]()
  var cur = seq[0]
  var curRunLength = 1

  for i in seq.dropFirst() {
    if cur == i {
      curRunLength += 1
    } else {
      result.append(curRunLength)
      result.append(cur)
      curRunLength = 1
      cur = i
    }
  }

  result.append(curRunLength)
  result.append(cur)

  return result
}

var seq = [1]

for i in 0..<10 {
  print("Seq \(i): \(seq)")
  seq = lookAndSay(seq)
}


package main

import (
    "fmt"
    "time"
)

func main() {
    centuries := []string{"20th", "21st", "22nd"}
    starts := []int{1900, 2000, 2100}
    for i := 0; i < len(centuries); i++ {
        var longYears []int
        fmt.Printf("\nLong years in the %s century:\n", centuries[i])
        for j := starts[i]; j < starts[i] + 100; j++ {
            t := time.Date(j, time.December, 28, 0, 0, 0, 0, time.UTC)
            if _, week := t.ISOWeek(); week == 53 {
                longYears = append(longYears, j)
            }
        }
        fmt.Println(longYears)
    }
}


import Data.Time.Calendar (fromGregorian)
import Data.Time.Calendar.WeekDate (toWeekDate)

longYear :: Integer -> Bool
longYear y =
  let (_, w, _) = toWeekDate $ fromGregorian y 12 28
   in 52 < w

main :: IO ()
main = mapM_ print $ filter longYear [2000 .. 2100]


proc lookandsay n {
    set new ""
    while {[string length $n] > 0} {
        set char [string index $n 0]
        for {set count 1} {[string index $n $count] eq $char} {incr count} {}
        append new $count $char
        set n [string range $n $count end]
    }
    interp alias {} next_lookandsay {} lookandsay $new
    return $new
}

puts 1                 ;# ==> 1
puts [lookandsay 1]    ;# ==> 11
puts [next_lookandsay] ;# ==> 21
puts [next_lookandsay] ;# ==> 1211
puts [next_lookandsay] ;# ==> 111221
puts [next_lookandsay] ;# ==> 312211


$$ MODE TUSCRIPT,{}
num=1,say=""
 LOOP look
  digits=STRINGS (num," ? ")
  digitgrouped=ACCUMULATE (digits,howmany)
   LOOP/CLEAR  h=howmany,digit=digitgrouped
    say=JOIN (say,"",h,digit)
   ENDLOOP
  PRINT say
  num=VALUE(say),say=""
  IF (look==14) EXIT
 ENDLOOP


lookandsay() {
    local num=$1 char seq i
    for ((i=0; i<=${#num}; i++)); do
        char=${num:i:1}
        if [[ $char == ${seq:0:1} ]]; then
            seq+=$char
        else
            [[ -n $seq ]] && printf "%d%s" ${#seq} ${seq:0:1}
            seq=$char
        fi
    done
}

for ((num=1, i=1; i<=10; i++)); do
    echo $num
    num=$( lookandsay $num )
done


import java.time.LocalDate;
import java.time.temporal.WeekFields;

public class LongYear {

    public static void main(String[] args) {
        System.out.printf("Long years this century:%n");
        for (int year = 2000 ; year < 2100 ; year++ ) {
            if ( longYear(year) ) {
                System.out.print(year + "  ");
            }
        }
    }

    private static boolean longYear(int year) {
        return LocalDate.of(year, 12, 28).get(WeekFields.ISO.weekOfYear()) == 53;
    }

}


const isLongYear = (year) => {
  const jan1 = new Date(year, 0, 1);
  const dec31 = new Date(year, 11, 31);
  return (4 == jan1.getDay() || 4 == dec31.getDay())
}

for (let y = 1995; y <= 2045; y++) {
  if (isLongYear(y)) {
    console.log(y)
  }
}


#import std
#import nat

look_and_say "n" = ~&H\'1' next"n" rlc~&E; *= ^lhPrT\~&hNC %nP+ length

#show+

main = look_and_say 10


Public Sub LookAndSay(Optional Niter As Integer = 10)
'generate "Niter" members of the look-and-say sequence
'(argument is optional; default is 10)

Dim s As String            'look-and-say number
Dim news As String         'next number in sequence
Dim curdigit As String     'current digit in s
Dim newdigit As String     'next digit in s
Dim curlength As Integer   'length of current run
Dim p As Integer           'position in s
Dim L As Integer           'length of s

On Error GoTo Oops          'to catch overflow, i.e. number too long

'start with "1"
s = "1"
For i = 1 To Niter
  'initialise
  L = Len(s)
  p = 1
  curdigit = Left$(s, 1)
  curlength = 1
  news = ""
  For p = 2 To L
    'check next digit in s
    newdigit = Mid$(s, p, 1)
    If curdigit = newdigit Then 'extend current run
      curlength = curlength + 1
    Else ' "output" run and start new run
      news = news & CStr(curlength) & curdigit
      curdigit = newdigit
      curlength = 1
    End If
  Next p
  ' "output" last run
  news = news & CStr(curlength) & curdigit
  Debug.Print news
  s = news
Next i
Exit Sub

Oops:
  Debug.Print
  If Err.Number = 6 Then 'overflow
    Debug.Print "Oops - number too long!"
  Else
    Debug.Print "Error: "; Err.Number, Err.Description
  End If
End Sub


function looksay( n )
	dim i
	dim accum
	dim res
	dim c
	res = vbnullstring
	do
		if n = vbnullstring then exit do
		accum = 0
		c = left( n,1 )
		do while left( n, 1 ) = c
			accum = accum + 1
			n = mid(n,2)
		loop
		if accum > 0 then
			res = res & accum & c
		end if
	loop
	looksay = res
end function


# Use Zeller's Congruence to determine the day of the week, given
# year, month and day as integers in the conventional way.
# Emit 0 for Saturday, 1 for Sunday, etc.
#
def day_of_week($year; $month; $day):
  if $month == 1 or $month == 2 then
    [$month + 12, $year - 1]
  else
    [$month, $year]
  end
  | $day + (13*(.[0] + 1)/5|floor)
    +  (.[1]%100)       + ((.[1]%100)/4|floor)
    +  (.[1]/400|floor) - 2*(.[1]/100|floor)
  | . % 7 ;

def has53weeks:
  day_of_week(.; 1; 1) == 5 or day_of_week(.; 12; 31) == 5;

# To display results neatly:
def nwise($n):
  def n: if length <= $n then . else .[0:$n] , (.[$n:] | n) end;
  n;

"Long years from 1900 to 2100 inclusive:",
([range(1900;2101) | select(has53weeks)] | nwise(10) | join(", "))


using Dates

has53weeks(year) = week(Date(year, 12, 28)) == 53

println(" Year  53 weeks?\n----------------")
for year in 1990:2021
    println(year, "   ", has53weeks(year) ? "Yes" : "No")
end


fun main() {
    val has53Weeks = { year: Int -> LocalDate.of(year, 12, 28).get(WeekFields.ISO.weekOfYear()) == 53 }
    println("Long years this century:")
    (2000..2100).filter(has53Weeks)
        .forEach { year -> print("$year ")}
}


to div :x :y
  output int quotient :x :y
end

to dec31_weekday :year
   output remainder (sum :year div :year 4 div :year -100 div :year 400) 7
end

to iso_long_year? :year
   output or 4 = dec31_weekday :year 3 = dec31_weekday difference :year 1
end

for [y 1995 2045 1] [if iso_long_year? :y [print :y]]


firstyear = 2000;
lastyear = 2099;
years = Range[firstyear, lastyear];
firstday = Table[DayName[{years[[n]], 01, 01}], {n, Length[years]}];
lastday = Table[DayName[{years[[n]], 12, 31}], {n, Length[years]}];
Table[If[years[[n]] >= 1582,
  If[firstday[[n]] == Thursday || lastday[[n]] == Thursday,
   Style[years[[n]] " long year \n", Bold, Red] ,
   years[[n]] " short \n"], "error \n"], {n, Length[years]}]


Repeat(10) {
  BOL
  Reg_Empty(20)
  While (!At_EOL) {
    Match("(.)\1*", REGEXP+ADVANCE)
    Num_Str(Chars_Matched, 20, LEFT+APPEND)
    Reg_Copy_Block(20, CP-1, CP, APPEND)
  }
  Ins_Newline Reg_Ins(20)
}


fn lss(s string) string {
    mut r := ''
    mut c := s[0..1]
    mut nc := 1
    for i := 1; i < s.len; i++ {
        d := s[i..i+1]
        if d == c {
            nc++
            continue
        }
        r += nc.str() + c
        c = d
        nc = 1
    }
    return r + nc.str() + c
}

fn main() {
    mut s := "1"
    println(s)
    for i := 0; i < 8; i++ {
        s = lss(s)
        println(s)
    }
}


var lookAndSay = Fn.new { |s|
    var res = ""
    var digit = s[0]
    var count = 1
    for (i in 1...s.count) {
        if (s[i] == digit) {
            count = count + 1
        } else {
            res = res + "%(count)%(digit)"
            digit = s[i]
            count = 1
        }
    }
    return res + "%(count)%(digit)"
}

var las = "1"
for (i in 1..15) {
    System.print(las)
    las = lookAndSay.call(las)
}


MODULE LongYear;
FROM InOut IMPORT WriteCard, WriteLn;

VAR year: CARDINAL;

PROCEDURE isLongYear(year: CARDINAL): BOOLEAN;
    PROCEDURE p(year: CARDINAL): CARDINAL;
    BEGIN
        RETURN (year + year DIV 4 - year DIV 100 + year DIV 400) MOD 7;
    END p;
BEGIN
    RETURN (p(year) = 4) OR (p(year-1) = 3);
END isLongYear;

BEGIN
    FOR year := 2000 TO 2100 DO
        IF isLongYear(year) THEN
            WriteCard(year, 4);
            WriteLn;
        END;
    END;
END LongYear.


import times

proc has53weeks(year: Positive): bool =
  let dt = initDateTime(monthday = 1, month = mJan, year = year, hour = 0, minute = 0, second= 0)
  result = dt.weekday == dThu or year.isLeapYear and dt.weekday == dWed

when isMainModule:
  echo "Years with 53 weeks between 2000 and 2100:"
  for year in 2000..2100:
    if year.has53weeks:
      echo year


program long_year(input);
  var
    y: integer;

  function rd_dec31(year: integer): integer;
  begin
    { Rata Die of Dec 31, year }
    rd_dec31 := year * 365 + year div 4 - year div 100 + year div 400
  end;

  function rd_jan1(year: integer): integer;
  begin
    rd_jan1 := rd_dec31(year - 1) + 1
  end;

  function weekday(rd: integer): integer;
  begin
    weekday := rd mod 7;
  end;

  function long_year(year: integer): boolean;
  var
    jan1: integer;
    dec31: integer;
  begin
    jan1 := rd_jan1(year);
    dec31 := rd_dec31(year);
    long_year := (weekday(jan1) = 4) or (weekday(dec31) = 4)
  end;

  begin
    for y := 1990 to 2050 do
      if long_year(y) then
        writeln(y)
  end.


dim X$(2)
i = 0  // índice de cadena de entrada
X$(i) = "1"

input "Indica cuantas repeticiones: " r
print "\nSecuencia:"

print X$(i)
for n = 1 to r-1
    j = 1 - i  // índice de cadena de salida
    X$(j) = ""
    k = 1
    while k <= len(X$(i))
        k0 = k + 1
        while ((k0 <= len(X$(i))) and (mid$(X$(i), k, 1) = mid$(X$(i), k0, 1)))
            k0 = k0 + 1
        wend
        X$(j) = X$(j) + str$(k0 - k) + mid$(X$(i), k, 1)
        k = k0
    wend
    i = j
    print X$(j)
next n
print


func looksay(input) {
    // Special case: one digit
    if(strlen(input) == 1)
        return "1" + input;
    // Convert string into an array of digits
    digits = strchar(input)(:-1);
    // Find indices where each run starts
    w = where(digits(dif));
    start = numberof(w) ? grow(1, w+1) : [1];
    // Find length of each run
    len = grow(start, numberof(digits)+1)(dif);
    // Find digits for each run
    run = digits(start);
    // Construct output array
    result = array(string, numberof(start)*2);
    // Fill in lengths
    result(1::2) = swrite(format="%d", len);
    // Fill in digits; first must add trailing nulls to coerce single string
    // into an array of strings.
    run = transpose([run, array(char(0), numberof(run))])(*);
    result(2::2) = strchar(run);
    // Merge string array into single string
    return result(sum);
}

val = "1";
do {
   write, val;
   val = looksay(val);
} while(strlen(val) < 80);


fcn lookAndSay(seed){ // numeric String --> numeric String
   len,c:=[1..seed.len()-1].reduce(fcn([(len,c)]lc,index,s,sb){
      if(c!=s[index]) { sb.write(len); sb.write(c); lc.clear(1,s[index]) }
      else lc.clear(len+1,c);
   },L(1,seed[0]), seed,sb:=Sink(String));
   sb.write(len); sb.write(c);
   sb.close();
}


use strict;
use warnings;
use DateTime;

for my $century (19 .. 21) {
  for my $year ($century*100 .. ++$century*100 - 1) {
    print "$year " if DateTime->new(year => $year, month => 12, day => 28)->week_number > 52
  }
  print "\n";
}


with javascript_semantics
function week_number(integer y,m,d)
    integer doy = day_of_year(y,m,d),
            dow = day_of_week(y,m,d),
            week = floor((doy-dow+10)/7)
    return week
end function

for c=20 to 22 do
    sequence long_years = {}
    integer century = (c-1)*100
    for year=century to century+99 do
        if week_number(year,12,28)=53 then
            long_years &= year
        end if
    end for
    printf(1,"Long years in the %d%s century:%v\n", {c,ord(c),long_years})
end for


function isLongYear($year) {
  return (53 == strftime('%V', gmmktime(0,0,0,12,28,$year)));
}

for ($y=1995; $y<=2045; ++$y) {
  if (isLongYear($y)) {
    printf("%s\n", $y);
  }
}


Function Is-Long-Year {
  param([Int]$year)
  53 -eq (Get-Date -Year $year -Month 12 -Day 28 -UFormat %V)
}

For ($y=1995; $y -le 2045; $y++) {
  If (Is-Long-Year $y) {
    Write-Host $y
  }
}


% See https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year

p(Year, P):-
    P is (Year + (Year//4) - (Year//100) + (Year//400)) mod 7.

long_year(Year):-
    p(Year, 4),
    !.
long_year(Year):-
    Year_before is Year - 1,
    p(Year_before, 3).

print_long_years(From, To):-
    writef("Long years between %w and %w:\n", [From, To]),
    print_long_years(From, To, 0),
    nl.

print_long_years(From, To, _):-
    From > To,
    !.
print_long_years(From, To, Count):-
    long_year(From),
    !,
    (Count > 0 ->
        (0 is Count mod 10 -> nl ; write(' '))
        ;
        true
    ),
    write(From),
    Count1 is Count + 1,
    Next is From + 1,
    print_long_years(Next, To, Count1).
print_long_years(From, To, Count):-
    Next is From + 1,
    print_long_years(Next, To, Count).

main:-
     print_long_years(1800, 2100).


'''Long Year ?'''

from datetime import date

# longYear :: Year Int -> Bool
def longYear(y):
    '''True if the ISO year y has 53 weeks.'''
    return 52 < date(y, 12, 28).isocalendar()[1]

# --------------------------TEST---------------------------
# main :: IO ()
def main():
    '''Longer (53 week) years in the range 2000-2100'''
    for year in [
            x for x in range(2000, 1 + 2100)
            if longYear(x)
    ]:
        print(year)

# MAIN ---
if __name__ == '__main__':
    main()


  [ dup dip
      [ 1 1 rot dayofweek 4 = ]
    31 12 rot dayofweek 4 = or ] is longyear ( n --> b )

  say "Long Years in the 21st Century" cr
  cr
  100 times
    [ 2000 i^ + longyear if
      [ 2000 i^ + echo sp ] ]


sub is-long ($year) { Date.new("$year-12-28").week[1] == 53 }

# Testing
say   "Long years in the 20th century:\n", (1900..^2000).grep: &is-long;
say "\nLong years in the 21st century:\n", (2000..^2100).grep: &is-long;
say "\nLong years in the 22nd century:\n", (2100..^2200).grep: &is-long;