import Data.Time.Calendar (Day, fromGregorianValid)
import Data.List.Split (chunksOf)
import Data.List (unfoldr)
import Data.Tuple (swap)
import Data.Bool (bool)
import Data.Maybe (mapMaybe)

palinDates :: [Day]
palinDates = mapMaybe palinDay [2021 .. 9999]

palinDay :: Integer -> Maybe Day
palinDay y = fromGregorianValid y m d
  where
    [m, d] = unDigits <$> chunksOf 2 (reversedDecimalDigits (fromInteger y))

reversedDecimalDigits :: Int -> [Int]
reversedDecimalDigits =
  unfoldr ((flip bool Nothing . Just . swap . flip quotRem 10) <*> (0 ==))

unDigits :: [Int] -> Int
unDigits = foldl ((+) . (10 *)) 0

main :: IO ()
main = do
  let n = length palinDates
  putStrLn $ "Count of palindromic dates [2021..9999]: " ++ show n
  putStrLn "\nFirst 15:"
  mapM_ print $ take 15 palinDates
  putStrLn "\nLast 15:"
  mapM_ print $ take 15 (drop (n - 15) palinDates)


Function parse_ip(addr)
    'ipv4 pattern
    Set ipv4_pattern = New RegExp
    ipv4_pattern.Global = True
    ipv4_pattern.Pattern = "(\d{1,3}\.){3}\d{1,3}"
    'ipv6 pattern
    Set ipv6_pattern = New RegExp
    ipv6_pattern.Global = True
    ipv6_pattern.Pattern = "([0-9a-fA-F]{0,4}:){2}[0-9a-fA-F]{0,4}"
    'test if address is ipv4
    If ipv4_pattern.Test(addr) Then
        port = Split(addr,":")
        octet = Split(port(0),".")
        ipv4_hex = ""
        For i = 0 To UBound(octet)
            If octet(i) <= 255 And octet(i) >= 0 Then
                ipv4_hex = ipv4_hex & Right("0" & Hex(octet(i)),2)
            Else
                ipv4_hex = "Erroneous Address"
                Exit For
            End If
        Next
        parse_ip = "Test Case: " & addr & vbCrLf &_
                   "Address: " & ipv4_hex & vbCrLf
        If UBound(port) = 1 Then
            If port(1) <= 65535 And port(1) >= 0 Then
                parse_ip = parse_ip & "Port: " & port(1) & vbCrLf
            Else
                parse_ip = parse_ip & "Port: Invalid" & vbCrLf
            End If
        End If
    End If
    'test if address is ipv6
    If ipv6_pattern.Test(addr) Then
        parse_ip = "Test Case: " & addr & vbCrLf
        port_v6 = "Port: "
        ipv6_hex = ""
        'check and extract port information if any
        If InStr(1,addr,"[") Then
            'extract the port
            port_v6 = port_v6 & Mid(addr,InStrRev(addr,"]")+2,Len(addr)-Len(Mid(addr,1,InStrRev(addr,"]")+1)))
            'extract the address
            addr = Mid(addr,InStrRev(addr,"[")+1,InStrRev(addr,"]")-(InStrRev(addr,"[")+1))
        End If
        word = Split(addr,":")
        word_count = 0
        For i = 0 To UBound(word)
            If word(i) = "" Then
                If i < UBound(word) Then
                    If Int((7-(i+1))/2) = 1 Then
                        k = 1
                    ElseIf UBound(word) < 6 Then
                        k = Int((7-(i+1))/2)
                    ElseIf UBound(word) >= 6 Then
                        k = Int((7-(i+1))/2)-1
                    End If
                    For j = 0 To k
                        ipv6_hex = ipv6_hex & "0000"
                        word_count = word_count + 1
                    Next
                Else
                    For j = 0 To (7-word_count)
                        ipv6_hex = ipv6_hex & "0000"
                    Next
                End If
            Else
                ipv6_hex = ipv6_hex & Right("0000" & word(i),4)
                word_count = word_count + 1
            End If
        Next
        parse_ip = parse_ip & "Address: " & ipv6_hex &_
                vbCrLf & port_v6 & vbCrLf
    End If
    'test if the address in invalid
    If ipv4_pattern.Test(addr) = False And ipv6_pattern.Test(addr) = False Then
        parse_ip = "Test Case: " & addr & vbCrLf &_
                   "Address: Invalid Address" & vbCrLf
    End If
End Function

'Testing the function
ip_arr = Array("127.0.0.1","127.0.0.1:80","::1",_
    "[::1]:80","2605:2700:0:3::4713:93e3","[2605:2700:0:3::4713:93e3]:80","RosettaCode")

For n = 0 To UBound(ip_arr)
    WScript.StdOut.Write parse_ip(ip_arr(n)) & vbCrLf
Next


import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class PalindromeDates {

    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2020, 2, 3);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        DateTimeFormatter formatterDash = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        System.out.printf("First 15 palindrome dates after 2020-02-02 are:%n");
        for ( int count = 0 ; count < 15 ; date = date.plusDays(1) ) {
            String dateFormatted = date.format(formatter);
            if ( dateFormatted.compareTo(new StringBuilder(dateFormatted).reverse().toString()) == 0 ) {
                count++;
                System.out.printf("date = %s%n", date.format(formatterDash));
            }
        }
    }

}


/**
 * Adds zeros for 1 digit days/months
 * @param date: string
 */
const addMissingZeros = date => (/^\d$/.test(date) ? `0${date}` : date);

/**
 * Formats a Date to a string. If readable is false,
 * string is only numbers (used for comparison), else
 * is a human readable date.
 * @param date: Date
 * @param readable: boolean
 */
const formatter = (date, readable) => {
  const year = date.getFullYear();
  const month = addMissingZeros(date.getMonth() + 1);
  const day = addMissingZeros(date.getDate());

  return readable ? `${year}-${month}-${day}` : `${year}${month}${day}`;
};

/**
 * Returns n (palindromesToShow) palindrome dates
 * since start (or 2020-02-02)
 * @param start: Date
 * @param palindromesToShow: number
 */
function getPalindromeDates(start, palindromesToShow = 15) {
  let date = start || new Date(2020, 3, 2);

  for (
    let i = 0;
    i < palindromesToShow;
    date = new Date(date.setDate(date.getDate() + 1))
  ) {
    const formattedDate = formatter(date);
    if (formattedDate === formattedDate.split("").reverse().join("")) {
      i++;
      console.log(formatter(date, true));
    }
  }
}

getPalindromeDates();


import "/dynamic" for Enum, Tuple
import "/big" for BigInt
import "/str" for Str
import "/fmt" for Conv, Fmt

var AddressSpace = Enum.create("AddressSpace", ["IPv4", "IPv6", "Invalid"])

// a port of -1 denotes 'not specified'
var IPAddressComponents = Tuple.create("IPAddressComponents", ["address", "addressSpace", "port"])

var INVALID = IPAddressComponents.new(BigInt.zero, AddressSpace.Invalid, 0)

var ipAddressParse = Fn.new { |ipAddress|
    var addressSpace = AddressSpace.IPv4
    var ipa = Str.lower(ipAddress)
    var port = -1
    var trans = false

    if (ipa.startsWith("::ffff:") && ipa.contains(".")) {
        addressSpace = AddressSpace.IPv6
        trans = true
        ipa = ipa[7..-1]
    } else if (ipa.startsWith("[::ffff:") && ipa.contains(".")) {
        addressSpace = AddressSpace.IPv6
        trans = true
        ipa = ipa[8..-1].replace("]", "")
    }
    var octets = ipa.split(".")[-1..0].toList
    var address = BigInt.zero
    if (octets.count == 4) {
        var split = octets[0].split(":")
        if (split.count == 2) {
            var temp = Num.fromString(split[1])
            if (!temp || temp < 0 || temp > 65535) return INVALID
            port = temp
            octets[0] = split[0]
        }
        for (i in 0..3) {
            var num = Num.fromString(octets[i])
            if (!num || num < 0 || num > 255) return INVALID
            var bigNum = BigInt.new(num)
            address = address | (bigNum << (i * 8))
        }
        if (trans) address = address + BigInt.fromBaseString("ffff00000000", 16)
    } else if (octets.count == 1) {
        addressSpace = AddressSpace.IPv6
        if (ipa[0] == "[") {
            ipa = ipa[1..-1]
            var split = ipa.split("]:")
            if (split.count != 2) return INVALID
            var temp = Num.fromString(split[1])
            if (!temp || temp < 0 || temp > 65535) return INVALID
            port = temp
            ipa = ipa[0...(-2 - split[1].count)]
        }
        var hextets = ipa.split(":")[-1..0].toList
        var len = hextets.count

        if (ipa.startsWith("::")) {
            hextets[-1] = "0"
        } else if (ipa.endsWith("::")) {
            hextets[0] = "0"
        }
        if (ipa == "::") hextets[1] = "0"
        if (len > 8 || (len == 8 && hextets.any { |h| h == "" }) || hextets.count { |h| h == "" } > 1) {
            return INVALID
        }
        if (len < 8) {
            var insertions = 8 - len
            for (i in 0..7) {
                if (hextets[i] == "") {
                    hextets[i] = "0"
                    while (insertions > 0) {
                        insertions = insertions - 1
                        hextets.insert(i, "0")
                    }
                    break
                }
            }
        }
        for (j in 0..7) {
            var num = Conv.atoi(hextets[j], 16)
            if (num > 0xFFFF) return INVALID
            var bigNum = BigInt.new(num)
            address = address | (bigNum << (j * 16))
        }
    } else return INVALID

    return IPAddressComponents.new(address, addressSpace, port)
}

var ipas = [
    "127.0.0.1",
    "127.0.0.1:80",
    "::1",
    "[::1]:80",
    "2605:2700:0:3::4713:93e3",
    "[2605:2700:0:3::4713:93e3]:80",
    "::ffff:192.168.173.22",
    "[::ffff:192.168.173.22]:80",
    "1::",
    "::",
    "256.0.0.0",
    "::ffff:127.0.0.0.1"
]
for (ipa in ipas) {
    var ipac = ipAddressParse.call(ipa)
    Fmt.print("IP address    : $s", ipa)
    Fmt.print("Address       : $s", Str.upper(ipac.address.toBaseString(16)))
    Fmt.print("Address Space : $s", AddressSpace.members[ipac.addressSpace])
    Fmt.print("Port          : $s", (ipac.port == -1) ? "not specified" : ipac.port.toString)
    System.print()
}


using Dates

function datepalindromes(nextcount=20)
    println("Date palindromes:")
    count, d = 0, Date(1000, 1, 1)
    for year in 2021:9200
        try
            dig = digits(year)
            month = 10 * dig[1] + dig[2]
            day = 10 * dig[3] + dig[4]
            d = Date(year, month, day)
        catch
            continue
        end
        println(d)
        count += 1
        if count >= nextcount
            break
        end
    end
end

datepalindromes()


today = DateList[Today];
res = {};
i = 0;
While[Length[res] < 15,
 date = DatePlus[today, i];
 ds = DateString[date, {"Year", "Month", "Day"}];
 If[PalindromeQ[ds],
  AppendTo[res, date]
  ];
 i++;
 ]
Column[DateString[#, {"Year", "-", "Month", "-", "Day"}] & /@ res]


import strformat, times

func digits(n: int): seq[int] =
  var n = n
  while n != 0:
    result.add n mod 10
    n = n div 10

echo "First 15 palindrome dates after 2020-02-02:"
var count = 0
var year = 2021
while count != 15:
  let d = year.digits
  let monthNum = 10 * d[0] + d[1]
  let dayNum = 10 * d[2] + d[3]
  if monthNum in 1..12:
    if dayNum <= getDaysInMonth(Month(monthNum), year):
      # Date is valid.
      echo &"{year}-{monthNum:02}-{dayNum:02}"
      inc count
  inc year


use Time::Piece;
my $d = Time::Piece->strptime("2020-02-02", "%Y-%m-%d");

for (my $k = 1 ; $k <= 15 ; $d += Time::Piece::ONE_DAY) {
    my $s = $d->strftime("%Y%m%d");
    if ($s eq reverse($s) and ++$k) {
        print $d->strftime("%Y-%m-%d\n");
    }
}


with javascript_semantics
include builtins\timedate.e
sequence res = {}
for d=2021 to 9999 do
    string s = sprintf("%4d",d),
           t = reverse(s)
    s &= "-"&t[1..2]&"-"&t[3..4]
    sequence td = parse_date_string(s, {"YYYY-MM-DD"})
    if timedate(td) then res = append(res,s) end if
end for
printf(1,"Count of palindromic dates [2021..9999]: %d\n\n",length(res))
printf(1,"first 15:\n%s\n",join_by(res[1..15],3,5))
printf(1,"last 15:\n%s\n",join_by(res[-15..-1],3,5))


NewList pdates.s()

Procedure.b IsLeap(y.i)
  ProcedureReturn Bool( y % 4 = 0 ) & Bool( y % 100 <> 0 ) | Bool( y % 400 = 0 )
EndProcedure

If OpenConsole("")=0 : End 1 : EndIf

For j=2021 To 9999
  For m=1 To 12
    tm2=28+1*IsLeap(j)
    For t=1 To 31
      If m=2 And t>tm2 : Break : EndIf
      If (m=4 Or m=6 Or m=9 Or m=11) And t>30 : Break : EndIf
      s$=Str(j)+RSet(Str(m),2,"0")+RSet(Str(t),2,"0")
      If ReverseString(s$)=s$
        AddElement(pdates()) : pdates()=Mid(s$,1,4)+"-"+Mid(s$,5,2)+"-"+Mid(s$,7,2)
      EndIf
    Next t
  Next m
Next j

PrintN("Count of palindromic dates [2021..9999]: "+Str(ListSize(pdates())))
FirstElement(pdates())
t$="First 15:"
For x=1 To 2
  PrintN(~"\n"+t$)
  For y=1 To 15 : PrintN(pdates()) : NextElement(pdates()) : Next
  t$="Last 15:" : SelectElement(pdates(),ListSize(pdates())-15)
Next
Input() : End


'''Palindrome dates'''

from datetime import datetime
from itertools import chain

# palinDay :: Int -> [ISO Date]
def palinDay(y):
    '''A possibly empty list containing the palindromic
       date for the given year, if such a date exists.
    '''
    s = str(y)
    r = s[::-1]
    iso = '-'.join([s, r[0:2], r[2:]])
    try:
        datetime.strptime(iso, '%Y-%m-%d')
        return [iso]
    except ValueError:
        return []

# --------------------------TEST---------------------------
# main :: IO ()
def main():
    '''Count and samples of palindromic dates [2021..9999]
    '''
    palinDates = list(chain.from_iterable(
        map(palinDay, range(2021, 10000))
    ))
    for x in [
            'Count of palindromic dates [2021..9999]:',
            len(palinDates),
            '\nFirst 15:',
            '\n'.join(palinDates[0:15]),
            '\nLast 15:',
            '\n'.join(palinDates[-15:])
    ]:
        print(x)

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


'Task
' Write a program which calculates and shows the next 15 palindromic dates
' for those countries which express their dates in the   yyyy-mm-dd format
' and for those countries which express their dates int dd-mm-yyyy format
' the user will choose what format to use for calculating
Dim dateTest As String, Mounth As Integer, Day As Integer, Year As Integer, Pal As Integer, choice As Integer
dateTest = ""
Mounth = 0
Day = 0
Year = 0
Pal = 0
choice = 0
Print " choose date format:"
Print " press 1 for using YYYY-MM-DD format"
Print " press 2 for using DD-MM-YYYY format"

While choice < 1 Or choice > 2
    choice = Val(InKey$)
Wend
Print " Well, you have choosen format number "; choice
Sleep 2
For Year = 2020 To 2420
    dateTest = LTrim$(Str$(Year))
    For Mounth = 1 To 12
        If Mounth < 10 Then k$ = "0" Else k$ = ""

        If choice = 1 Then
            dateTest = dateTest + k$ + LTrim$(Str$(Mounth))
        Else
            dateTest = k$ + LTrim$(Str$(Mounth)) + dateTest
        End If

        For Day = 1 To 31
            If Mounth = 2 And Day > 28 Then Exit For
            If (Mounth = 4 Or Mounth = 6 Or Mounth = 9 Or Mounth = 11) And Day > 30 Then Exit For
            If Day < 10 Then k$ = "0" Else k$ = ""
            If choice = 1 Then
                dateTest = dateTest + k$ + LTrim$(Str$(Day))
            Else
                dateTest = k$ + LTrim$(Str$(Day)) + dateTest
            End If
            'Print dateTest: Sleep
            For Pal = 1 To 4
                If Mid$(dateTest, Pal, 1) <> Mid$(dateTest, 9 - Pal, 1) Then Exit For
            Next
            If Pal = 5 Then Print dateTest
            If choice = 1 Then
                dateTest = Left$(dateTest, 6)
            Else
                dateTest = Right$(dateTest, 6)
            End If
        Next
        If choice = 1 Then
            dateTest = Left$(dateTest, 4)
        Else
            dateTest = Right$(dateTest, 4)
        End If
    Next
    dateTest = ""
Next


my $start = '1000-01-01';

my @palindate = {
     state $year = $start.substr(0,4);
     ++$year;
     my $m = $year.substr(2, 2).flip;
     my $d = $year.substr(0, 2).flip;
     next if not try Date.new("$year-$m-$d");
     "$year-$m-$d"
} … *;

my $date-today = Date.today; # 2020-02-02

my $k = @palindate.first: { Date.new($_) > $date-today }, :k;

say join "\n", @palindate[$k - 1 .. $k + 14];

say "\nTotal number of four digit year palindrome dates:\n" ~
my $four = @palindate.first( { .substr(5,1) eq '-' }, :k );
say "between {@palindate[0]} and {@palindate[$four - 1]}.";

my $five = @palindate.first: { .substr(6,1) eq '-' }, :k;

say "\nTotal number of five digit year palindrome dates:\n" ~
+@palindate[$four .. $five]


/*REXX program finds & displays the next  N  palindromic dates starting after 2020─02─02*/
/*                                                                      ─────           */
parse arg n from .                               /*obtain optional argumets from the CL*/
if    n=='' |    n==","  then    n= 15           /*Not specified?  Then use the default.*/
if from=='' | from==","  then from= '2020-02-02' /* "      "         "   "   "     "    */
#= 0                                             /*the count of palindromic dates so far*/
     do j=date('Base', from, "ISO")+1 until #==n /*find palindromic dates 'til  N  found*/
     aDate= date('ISO', j, "Base")               /*convert a "base" date to ISO format. */
     $= space( translate(aDate, , '-'),  0)      /*elide the dashes  (-)  in this date. */
     if $\==reverse($)  then iterate             /*Not palindromic?  Then skip this date*/
     say 'a palindromic date: '        aDate     /*display a palindromic date ──► term. */
     #= # + 1                                    /*bump the counter of palindromic dates*/
     end   /*j*/                                 /*stick a fork in it,  we're all done. */


load "stdlib.ring"

dt		= 0
num		= 0
limit	        = 15

? "First 15 palindromic dates:" + nl

while num < limit

	dt++
	dateStr  = adddays(date(),dt)
	newDate  = substr(dateStr,7,4) + substr(dateStr,4,2) + substr(dateStr,1,2)
	newDate2 = substr(dateStr,7,4) + "-" + substr(dateStr,4,2) + "-" + substr(dateStr,1,2)
	if ispalindrome(newDate)
                num++
		? newDate2
	ok
	if num > limit
		exit
	ok

end


require 'date'

palindate = Enumerator.new do |yielder|
  ("2020"..).each do |y|
    m, d = y.reverse.scan(/../) # let the Y10K kids handle 5 digit years
    strings = [y, m, d]
    yielder << strings.join("-") if Date.valid_date?( *strings.map( &:to_i ) )
  end
end

puts palindate.take(15)


// [dependencies]
// chrono = "0.4"

fn is_palindrome(s: &str) -> bool {
    s.chars().rev().eq(s.chars())
}

fn main() {
    let mut date = chrono::Utc::today();
    let mut count = 0;
    while count < 15 {
        if is_palindrome(&date.format("%Y%m%d").to_string()) {
            println!("{}", date.format("%F"));
            count += 1;
        }
        date = date.succ();
    }
}


var palindates = gather {
    for y in (2020 .. 9999) {
        var (m, d) = Str(y).flip.last(4).split(2)...
        with ([y,m,d].join('-')) {|t|
            take(t) if Date.valid(t, "%Y-%m-%d")
        }
    }
}

say "Count of palindromic dates [2020..9999]: #{palindates.len}"

for a,b in ([
    ["First 15:", palindates.head(15)],
    ["Last 15:",  palindates.tail(15)]
]) {
    say ("\n#{a}\n", b.slices(5).map { .join("   ") }.join("\n"))
}


import Foundation

func isPalindrome(_ string: String) -> Bool {
    let chars = string.lazy
    return chars.elementsEqual(chars.reversed())
}

let format = DateFormatter()
format.dateFormat = "yyyyMMdd"

let outputFormat = DateFormatter()
outputFormat.dateFormat = "yyyy-MM-dd"

var count = 0
let limit = 15
let calendar = Calendar.current
var date = Date()

while count < limit {
    if isPalindrome(format.string(from: date)) {
        print(outputFormat.string(from: date))
        count += 1
    }
    date = calendar.date(byAdding: .day, value: 1, to: date)!
}


is_palyndrom_date() { date -d "$1" 1>/dev/null 2>&1 && echo "$1" ; }

for _H in {2..9}; do
 for _I in {0..9}; do
  for _J in {0..99}; do
   is_palyndrom_date ${_H}${_I}`printf "%02d%s" ${_J}`-`printf "%02d%s" ${_J} | rev`-`printf "%02d%s" ${_H}${_I} | rev`
  done
 done
done


Sub MainPalindromeDates()
Const FirstDate As String = "2020-02-02"
Const NumberOfDates As Integer = 15
Dim D As String, temp As String, Cpt As Integer
    temp = Format(DateAdd("d", 1, CDate(FirstDate)), "yyyy-mm-dd")
    Do
        D = Replace(temp, "-", "")
        If IsDatePalindrome(D) Then
            Debug.Print Left(D, 4) & "-" & Mid(D, 5, 2) & "-" & Right(D, 2)
            Cpt = Cpt + 1
        End If
        temp = Format(DateAdd("d", 1, CDate(temp)), "yyyy-mm-dd")
    Loop While Cpt < NumberOfDates
End Sub
Function IsDatePalindrome(strDate As String) As Boolean
    IsDatePalindrome = StrReverse(Left(strDate, 4)) = Right(strDate, 4)
End Function


import "/fmt" for Fmt
import "/date" for Date

var isPalDate = Fn.new { |date|
    date = date.format(Date.rawDate)
    return date == date[-1..0]
}

Date.default = Date.isoDate
System.print("The next 15 palindromic dates in yyyy-mm-dd format after 2020-02-02 are:")
var date = Date.new(2020, 2, 2)
var count = 0
while (count < 15) {
    date = date.addDays(1)
    if (isPalDate.call(date)) {
        System.print(date)
        count = count + 1
    }
}


func Rev(N);
int  N;
[N:= N/10;
return rem(0)*10 + N;
];

proc NumOut(N);
int  N;
[if N < 10 then ChOut(0, ^0);
IntOut(0, N);
];

int C, Y, M, D, Q, R;
[C:= 0;
for Y:= 2021 to -1>>1 do
  for M:= 1 to 12 do
    for D:= 1 to 28 do
        [Q:= Y/100;
        R:= rem(0);
        if Q = Rev(D) and R = Rev(M) then
            [IntOut(0, Y);  ChOut(0, ^-);
            NumOut(M);  ChOut(0, ^-);
            NumOut(D);  CrLf(0);
            C:= C+1;
            if C >= 15 then return;
            ];
        ];
]


dateTest$ = ""
total = 0
print "Siguientes 15 fechas palindr¢micas al 2020-02-02:"
for anno = 2021 to 9999
    dateTest$ = ltrim$(str$(anno))
    for mes = 1 to 12
        if mes < 10 then dateTest$ = dateTest$ + "0" : fi
        dateTest$ = dateTest$ + ltrim$(str$(mes))
        for dia = 1 to 31
            if mes = 2 and dia > 28 then break : fi
            if (mes = 4 or mes = 6 or mes = 9 or mes = 11) and dia > 30 then break : fi
            if dia < 10 then dateTest$ = dateTest$ + "0" : fi
            dateTest$ = dateTest$ + ltrim$(str$(dia))
            for Pal = 1 to 4
                if mid$(dateTest$, Pal, 1) <> mid$(dateTest$, 9 - Pal, 1) then break : fi
            next Pal
            if Pal = 5 then
                total = total + 1
                if total <= 15 then print left$(dateTest$,4),"-",mid$(dateTest$,5,2),"-",right$(dateTest$,2) : fi
            end if
            if total > 15 then break : break : break : fi
            dateTest$ = left$(dateTest$, 6)
        next dia
        dateTest$ = left$(dateTest$, 4)
    next mes
    dateTest$ = ""
next anno
end


TD,date,n := Time.Date, T(2020,02,02), 15;
while(n){
   ds:=TD.toYMDString(date.xplode()) - "-";
   if(ds==ds.reverse()){ n-=1; println(TD.toYMDString(date.xplode())); }
   date=TD.addYMD(date,0,0,1);
}


V pp = 1.324717957244746025960908854
V ss = 1.0453567932525329623
V Rules = [‘A’ = ‘B’, ‘B’ = ‘C’, ‘C’ = ‘AB’]

F padovan1(n)
   V r = [1] * min(n, 3)
   V (a, b, c) = (1, 1, 1)
   V count = 3
   L count < n
      (a, b, c) = (b, c, a + b)
      r [+]= c
      count++
   R r

F padovan2(n)
   V r = [1] * (n > 1)
   V p = 1.0
   V count = 1
   L count < n
      r [+]= Int(round(p / :ss))
      p *= :pp
      count++
   R r

F padovan3(n)
   [String] r
   V s = ‘A’
   V count = 0
   L count < n
      r [+]= s
      V next = ‘’
      L(ch) s
         next ‘’= Rules[ch]
      s = next
      count++
   R r

print(‘First 20 terms of the Padovan sequence:’)
print(padovan1(20).join(‘ ’))

V list1 = padovan1(64)
V list2 = padovan2(64)
print(‘The first 64 iterative and calculated values ’(I list1 == list2 {‘are the same.’} E ‘differ.’))

print()
print(‘First 10 L-system strings:’)
print(padovan3(10).join(‘ ’))
print()
print(‘Lengths of the 32 first L-system strings:’)
V list3 = padovan3(32).map(x -> x.len)
print(list3.join(‘ ’))
print(‘These lengths are’(I list3 == list1[0.<32] {‘ ’} E ‘ not ’)‘the 32 first terms of the Padovan sequence.’)


BEGIN # show members of the Padovan Sequence calculated in various ways #
    # returns the first n elements of the Padovan sequence by the       #
    #         recurance relation: P(n)=P(n-2)+P(n-3)	                #
    OP PADOVANI = ( INT n )[]INT:
       BEGIN
           [ 0 : n - 1 ]INT p; p[ 0 ] := p[ 1 ] := p[ 2 ] := 1;
           FOR i FROM 3 TO UPB p DO
               p[ i ] := p[ i - 2 ] + p[ i - 3 ]
           OD;
           p
       END; # PADOVANI #
    # returns the first n elements of the Padovan sequence by           #
    #         computing by truncation P(n)=floor(p^(n-1) / s + .5)      #
    #                where s = 1.0453567932525329623                    #
    #                  and p = the "plastic ratio"                      #
    OP PADOVANC = ( INT n )[]INT:
       BEGIN
           LONG REAL    s   = 1.0453567932525329623;
           LONG REAL    p   = 1.324717957244746025960908854;
           LONG REAL    pf := 1 / p;
           [ 0 : n - 1 ]INT result;
           FOR i FROM LWB result TO UPB result DO
               result[ i ] := SHORTEN ENTIER ( pf / s + 0.5 );
               pf         *:= p
           OD;
           result
       END; # PADOVANC #
    # returns the first n L System strings of the Padovan sequence      #
    OP PADOVANL = ( INT n )[]STRING:
       BEGIN
           [ 0 : n - 1 ]STRING l; l[ 0 ] := "A"; l[ 1 ] := "B"; l[ 2 ] := "C";
           FOR i FROM 3 TO UPB l DO
               l[ i ] := l[ i - 3 ] + l[ i - 2 ]
           OD;
           l
    END; # PADOVANC #
    # returns TRUE if a and b have the same values, FALSE otherwise     #
    OP = = ( []INT a, b )BOOL:
       IF LWB a /= LWB b OR UPB a /= UPB b
       THEN # rows are not the same size # FALSE
       ELSE
           BOOL result := TRUE;
           FOR i FROM LWB a TO UPB a WHILE result := a[ i ] = b[ i ] DO SKIP OD;
           result
       FI; # = #
    # returns the number of elements in a                               #
    OP LENGTH = ( []INT a )INT: ( UPB a - LWB a ) + 1;
    # returns the number of characters in s                             #
    OP LENGTH = ( STRING s )INT: ( UPB s - LWB s ) + 1;
    # returns a string representation of n                              #
    OP TOSTRING = ( INT n )STRING: whole( n, 0 );
    # generate 64 elements of the sequence and 32 L System values       #
    []INT    iterative  = PADOVANI 64;
    []INT    calculated = PADOVANC 64;
    []STRING l system   = PADOVANL 32;
    [ LWB l system : UPB l system ]INT l length;
    FOR i FROM LWB l length TO UPB l length DO l length[ i ] := LENGTH l system[ i ] OD;
    # first 20 terms                                                    #
    print( ( "First 20 terms of the Padovan Sequence", newline ) );
    FOR i FROM LWB iterative TO 19 DO
        print( ( " ", TOSTRING iterative[ i ] ) )
    OD;
    print( ( newline ) );
    print( ( "The first "
           , TOSTRING LENGTH iterative
           , " iterative and calculated values "
           , IF iterative = calculated THEN "are the same" ELSE "differ" FI
           , newline
           )
         );
    # print the first 10 values of the L System strings                 #
    print( ( newline, "First 10 L System strings", newline ) );
    FOR i FROM LWB l system TO 9 DO
        print( ( " ", l system[ i ] ) )
    OD;
    print( ( newline ) );
    print( ( "The first "
           , TOSTRING LENGTH l length
           , " iterative values and L System lengths "
           , IF l length = iterative[ LWB l length : UPB l length @ LWB l length ] THEN "are the same" ELSE "differ" FI
           ,  newline
           )
         )
END


--------------------- PADOVAN NUMBERS --------------------

-- padovans :: [Int]
on padovans()
    script f
        on |λ|(abc)
            set {a, b, c} to abc

            {a, {b, c, a + b}}
        end |λ|
    end script

    unfoldr(f, {1, 1, 1})
end padovans

-- padovanFloor :: [Int]
on padovanFloor()
    script f
        property p : 1.324717957245
        property s : 1.045356793253
        on |λ|(n)
            {floor(0.5 + ((p ^ (n - 1)) / s)), 1 + n}
        end |λ|
    end script

    unfoldr(f, 0)
end padovanFloor

-- padovanLSystem :: [String]
on padovanLSystem()
    script rule
        on |λ|(c)
            if "A" = c then
                "B"
            else if "B" = c then
                "C"
            else
                "AB"
            end if
        end |λ|
    end script

    script f
        on |λ|(s)
            {s, concatMap(rule, characters of s) as string}
        end |λ|
    end script

    unfoldr(f, "A")
end padovanLSystem

--------------------------- TEST -------------------------
on run
    unlines({"First 20 padovans:", ¬
        showList(take(20, padovans())), ¬
        "", ¬
        "The recurrence and floor-based functions", ¬
        "match over the first 64 terms:\n", ¬
        prefixesMatch(padovans(), padovanFloor(), 64), ¬
        "", ¬
        "First 10 L-System strings:", ¬
        showList(take(10, padovanLSystem())), ¬
        "", ¬
        "The lengths of the first 32 L-System", ¬
        "strings match the Padovan sequence:\n", ¬
        prefixesMatch(padovans(), fmap(|length|, padovanLSystem()), 32)})
end run

-- prefixesMatch :: [a] -> [a] -> Bool
on prefixesMatch(xs, ys, n)
    take(n, xs) = take(n, ys)
end prefixesMatch

------------------------- GENERIC ------------------------

-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
    set lng to length of xs
    set acc to {}
    tell mReturn(f)
        repeat with i from 1 to lng
            set acc to acc & (|λ|(item i of xs, i, xs))
        end repeat
    end tell
    return acc
end concatMap

-- floor :: Num -> Int
on floor(x)
    if class of x is record then
        set nr to properFracRatio(x)
    else
        set nr to properFraction(x)
    end if
    set n to item 1 of nr
    if 0 > item 2 of nr then
        n - 1
    else
        n
    end if
end floor

-- fmap <$> :: (a -> b) -> Gen [a] -> Gen [b]
on fmap(f, gen)
    script
        property g : mReturn(f)
        on |λ|()
            set v to gen's |λ|()
            if v is missing value then
                v
            else
                g's |λ|(v)
            end if
        end |λ|
    end script
end fmap

-- intercalate :: String -> [String] -> String
on intercalate(delim, xs)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, delim}
    set s to xs as text
    set my text item delimiters to dlm
    s
end intercalate

-- length :: [a] -> Int
on |length|(xs)
    set c to class of xs
    if list is c or string is c then
        length of xs
    else
        (2 ^ 29 - 1) -- (maxInt - simple proxy for non-finite)
    end if
end |length|

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    -- The list obtained by applying f
    -- to each element of xs.
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map

-- min :: Ord a => a -> a -> a
on min(x, y)
    if y < x then
        y
    else
        x
    end if
end min

-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
    -- 2nd class handler function lifted into 1st class script wrapper.
    if script is class of f then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn

-- properFraction :: Real -> (Int, Real)
on properFraction(n)
    set i to (n div 1)
    {i, n - i}
end properFraction

-- showList :: [a] -> String
on showList(xs)
    "[" & intercalate(",", map(my str, xs)) & "]"
end showList

-- str :: a -> String
on str(x)
    x as string
end str

-- take :: Int -> [a] -> [a]
-- take :: Int -> String -> String
on take(n, xs)
    set c to class of xs
    if list is c then
        if 0 < n then
            items 1 thru min(n, length of xs) of xs
        else
            {}
        end if
    else if string is c then
        if 0 < n then
            text 1 thru min(n, length of xs) of xs
        else
            ""
        end if
    else if script is c then
        set ys to {}
        repeat with i from 1 to n
            set v to |λ|() of xs
            if missing value is v then
                return ys
            else
                set end of ys to v
            end if
        end repeat
        return ys
    else
        missing value
    end if
end take

-- unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
on unfoldr(f, v)
    -- A lazy (generator) list unfolded from a seed value
    -- by repeated application of f to a value until no
    -- residue remains. Dual to fold/reduce.
    -- f returns either nothing (missing value),
    -- or just (value, residue).
    script
        property valueResidue : {v, v}
        property g : mReturn(f)
        on |λ|()
            set valueResidue to g's |λ|(item 2 of (valueResidue))
            if missing value ≠ valueResidue then
                item 1 of (valueResidue)
            else
                missing value
            end if
        end |λ|
    end script
end unfoldr

-- unlines :: [String] -> String
on unlines(xs)
    -- A single string formed by the intercalation
    -- of a list of strings with the newline character.
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, linefeed}
    set s to xs as text
    set my text item delimiters to dlm
    s
end unlines


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

/* Generate (and memoize) the Padovan sequence using
 * the recurrence relationship */
int pRec(int n) {
    static int *memo = NULL;
    static size_t curSize = 0;

    /* grow memoization array when necessary and fill with zeroes */
    if (curSize <= (size_t) n) {
        size_t lastSize = curSize;
        while (curSize <= (size_t) n) curSize += 1024 * sizeof(int);
        memo = realloc(memo, curSize * sizeof(int));
        memset(memo + lastSize, 0, (curSize - lastSize) * sizeof(int));
    }

    /* if we don't have the value for N yet, calculate it */
    if (memo[n] == 0) {
        if (n<=2) memo[n] = 1;
        else memo[n] = pRec(n-2) + pRec(n-3);
    }

    return memo[n];
}

/* Calculate the Nth value of the Padovan sequence
 * using the floor function */
int pFloor(int n) {
    long double p = 1.324717957244746025960908854;
    long double s = 1.0453567932525329623;
    return powl(p, n-1)/s + 0.5;
}

/* Given the previous value for the L-system, generate the
 * next value */
void nextLSystem(const char *prev, char *buf) {
    while (*prev) {
        switch (*prev++) {
            case 'A': *buf++ = 'B'; break;
            case 'B': *buf++ = 'C'; break;
            case 'C': *buf++ = 'A'; *buf++ = 'B'; break;
        }
    }
    *buf = '\0';
}

int main() {
    // 8192 is enough up to P_33.
    #define BUFSZ 8192
    char buf1[BUFSZ], buf2[BUFSZ];
    int i;

    /* Print P_0..P_19 */
    printf("P_0 .. P_19: ");
    for (i=0; i<20; i++) printf("%d ", pRec(i));
    printf("\n");

    /* Check that functions match up to P_63 */
    printf("The floor- and recurrence-based functions ");
    for (i=0; i<64; i++) {
        if (pRec(i) != pFloor(i)) {
            printf("do not match at %d: %d != %d.\n",
                i, pRec(i), pFloor(i));
            break;
        }
    }
    if (i == 64) {
        printf("match from P_0 to P_63.\n");
    }

    /* Show first 10 L-system strings */
    printf("\nThe first 10 L-system strings are:\n");
    for (strcpy(buf1, "A"), i=0; i<10; i++) {
        printf("%s\n", buf1);
        strcpy(buf2, buf1);
        nextLSystem(buf2, buf1);
    }

    /* Check lengths of strings against pFloor up to P_31 */
    printf("\nThe floor- and L-system-based functions ");
    for (strcpy(buf1, "A"), i=0; i<32; i++) {
        if ((int)strlen(buf1) != pFloor(i)) {
            printf("do not match at %d: %d != %d\n",
                i, (int)strlen(buf1), pFloor(i));
            break;
        }
        strcpy(buf2, buf1);
        nextLSystem(buf2, buf1);
    }
    if (i == 32) {
        printf("match from P_0 to P_31.\n");
    }

    return 0;
}


#include <iostream>
#include <map>
#include <cmath>

// Generate the Padovan sequence using the recurrence
// relationship.
int pRec(int n) {
    static std::map<int,int> memo;
    auto it = memo.find(n);
    if (it != memo.end()) return it->second;

    if (n <= 2) memo[n] = 1;
    else memo[n] = pRec(n-2) + pRec(n-3);
    return memo[n];
}

// Calculate the N'th Padovan sequence using the
// floor function.
int pFloor(int n) {
    long const double p = 1.324717957244746025960908854;
    long const double s = 1.0453567932525329623;
    return std::pow(p, n-1)/s + 0.5;
}

// Return the N'th L-system string
std::string& lSystem(int n) {
    static std::map<int,std::string> memo;
    auto it = memo.find(n);
    if (it != memo.end()) return it->second;

    if (n == 0) memo[n] = "A";
    else {
        memo[n] = "";
        for (char ch : memo[n-1]) {
            switch(ch) {
                case 'A': memo[n].push_back('B'); break;
                case 'B': memo[n].push_back('C'); break;
                case 'C': memo[n].append("AB"); break;
            }
        }
    }
    return memo[n];
}

// Compare two functions up to p_N
using pFn = int(*)(int);
void compare(pFn f1, pFn f2, const char* descr, int stop) {
    std::cout << "The " << descr << " functions ";
    int i;
    for (i=0; i<stop; i++) {
        int n1 = f1(i);
        int n2 = f2(i);
        if (n1 != n2) {
            std::cout << "do not match at " << i
                      << ": " << n1 << " != " << n2 << ".\n";
            break;
        }
    }
    if (i == stop) {
        std::cout << "match from P_0 to P_" << stop << ".\n";
    }
}

int main() {
    /* Print P_0 to P_19 */
    std::cout << "P_0 .. P_19: ";
    for (int i=0; i<20; i++) std::cout << pRec(i) << " ";
    std::cout << "\n";

    /* Check that floor and recurrence match up to P_64 */
    compare(pFloor, pRec, "floor- and recurrence-based", 64);

    /* Show first 10 L-system strings */
    std::cout << "\nThe first 10 L-system strings are:\n";
    for (int i=0; i<10; i++) std::cout << lSystem(i) << "\n";
    std::cout << "\n";

    /* Check lengths of strings against pFloor up to P_31 */
    compare(pFloor, [](int n){return (int)lSystem(n).length();},
                            "floor- and L-system-based", 32);
    return 0;
}


(def padovan (map first (iterate (fn [[a b c]] [b c (+ a b)]) [1 1 1])))

(def pad-floor
  (let [p 1.324717957244746025960908854
        s 1.0453567932525329623]
    (map (fn [n] (int (Math/floor (+ (/ (Math/pow p (dec n)) s) 0.5)))) (range))))

(def pad-l
  (iterate (fn f [[c & s]]
             (case c
               \A (str "B" (f s))
               \B (str "C" (f s))
               \C (str "AB" (f s))
               (str "")))
           "A"))

(defn comp-seq [n seqa seqb]
  (= (take n seqa) (take n seqb)))

(defn comp-all [n]
  (= (map count (vec (take n pad-l)))
     (take n padovan)
     (take n pad-floor)))

(defn padovan-print [& args]
  ((print "The first 20 items with recursion relation are: ")
   (println (take 20 padovan))
   (println)
   (println (str
             "The recurrence and floor based algorithms "
             (if (comp-seq 64 padovan pad-floor) "match" "not match")
             " to n=64"))
   (println)
   (println "The first 10 L-system strings are:")
   (println (take 10 pad-l))
   (println)
   (println (str
             "The L-system, recurrence and floor based algorithms "
             (if (comp-all 32) "match" "not match")
             " to n=32"))))


program Padovan_sequence;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Velthuis.BigDecimals,
  Boost.Generics.Collection;

type
  TpFn = TFunc<Integer, Integer>;

var
  RecMemo: TDictionary<Integer, Integer>;
  lSystemMemo: TDictionary<Integer, string>;

function pRec(n: Integer): Integer;
begin
  if RecMemo.HasKey(n) then
    exit(RecMemo[n]);

  if (n <= 2) then
    RecMemo[n] := 1
  else
    RecMemo[n] := pRec(n - 2) + pRec(n - 3);
  Result := RecMemo[n];
end;

function pFloor(n: Integer): Integer;
var
  p, s, a: BigDecimal;
begin
  p := '1.324717957244746025960908854';
  s := '1.0453567932525329623';
  a := p.IntPower(n - 1, 64);
  Result := Round(BigDecimal.Divide(a, s));
end;

function lSystem(n: Integer): string;
begin
  if n = 0 then
    lSystemMemo[n] := 'A'
  else
  begin
    lSystemMemo[n] := '';
    for var ch in lSystemMemo[n - 1] do
    begin
      case ch of
        'A':
          lSystemMemo[n] := lSystemMemo[n] + 'B';
        'B':
          lSystemMemo[n] := lSystemMemo[n] + 'C';
        'C':
          lSystemMemo[n] := lSystemMemo[n] + 'AB';
      end;
    end;
  end;
  Result := lSystemMemo[n];
end;

procedure Compare(f1, f2: TpFn; descr: string; stop: Integer);
begin
  write('The ', descr, ' functions ');
  var i := 0;
  while i < stop do
  begin
    var n1 := f1(i);
    var n2 := f2(i);
    if n1 <> n2 then
    begin
      write('do not match at ', i);
      writeln(': ', n1, ' != ', n2, '.');
      break;
    end;
    inc(i);
  end;
  if i = stop then
    writeln('match from P_0 to P_', stop, '.');
end;

begin
  RecMemo := TDictionary<Integer, Integer>.Create([], []);
  lSystemMemo := TDictionary<Integer, string>.Create([], []);

  write('P_0 .. P_19: ');
  for var i := 0 to 19 do
    write(pRec(i), ' ');
  writeln;

  Compare(pFloor, pRec, 'floor- and recurrence-based', 64);
  writeln(#10'The first 10 L-system strings are:');

  for var i := 0 to 9 do
    writeln(lSystem(i));
  writeln;

  Compare(pFloor,
    function(n: Integer): Integer
    begin
      Result := length(lSystem(n));
    end, 'floor- and L-system-based', 32);
  readln;
end.


USING: L-system accessors io kernel make math math.functions
memoize prettyprint qw sequences ;

CONSTANT: p 1.324717957244746025960908854
CONSTANT: s 1.0453567932525329623

: pfloor ( m -- n ) 1 - p swap ^ s /f .5 + >integer ;

MEMO: precur ( m -- n )
    dup 3 < [ drop 1 ]
    [ [ 2 - precur ] [ 3 - precur ] bi + ] if ;

: plsys, ( L-system -- )
    [ iterate-L-system-string ] [ string>> , ] bi ;

: plsys ( n -- seq )
    <L-system>
    "A" >>axiom
    { qw{ A B } qw{ B C } qw{ C AB } } >>rules
    swap 1 - '[ "A" , _ [ dup plsys, ] times ] { } make nip ;

"First 20 terms of the Padovan sequence:" print
20 [ pfloor pprint bl ] each-integer nl nl

64 [ [ pfloor ] [ precur ] bi assert= ] each-integer
"Recurrence and floor based algorithms match to n=63." print nl

"First 10 L-system strings:" print
10 plsys . nl

32 <iota> [ pfloor ] map 32 plsys [ length ] map assert=
"The L-system, recurrence and floor based algorithms match to n=31." print


package main

import (
    "fmt"
    "math"
    "math/big"
    "strings"
)

func padovanRecur(n int) []int {
    p := make([]int, n)
    p[0], p[1], p[2] = 1, 1, 1
    for i := 3; i < n; i++ {
        p[i] = p[i-2] + p[i-3]
    }
    return p
}

func padovanFloor(n int) []int {
    var p, s, t, u = new(big.Rat), new(big.Rat), new(big.Rat), new(big.Rat)
    p, _ = p.SetString("1.324717957244746025960908854")
    s, _ = s.SetString("1.0453567932525329623")
    f := make([]int, n)
    pow := new(big.Rat).SetInt64(1)
    u = u.SetFrac64(1, 2)
    t.Quo(pow, p)
    t.Quo(t, s)
    t.Add(t, u)
    v, _ := t.Float64()
    f[0] = int(math.Floor(v))
    for i := 1; i < n; i++ {
        t.Quo(pow, s)
        t.Add(t, u)
        v, _ = t.Float64()
        f[i] = int(math.Floor(v))
        pow.Mul(pow, p)
    }
    return f
}

type LSystem struct {
    rules         map[string]string
    init, current string
}

func step(lsys *LSystem) string {
    var sb strings.Builder
    if lsys.current == "" {
        lsys.current = lsys.init
    } else {
        for _, c := range lsys.current {
            sb.WriteString(lsys.rules[string(c)])
        }
        lsys.current = sb.String()
    }
    return lsys.current
}

func padovanLSys(n int) []string {
    rules := map[string]string{"A": "B", "B": "C", "C": "AB"}
    lsys := &LSystem{rules, "A", ""}
    p := make([]string, n)
    for i := 0; i < n; i++ {
        p[i] = step(lsys)
    }
    return p
}

// assumes lists are same length
func areSame(l1, l2 []int) bool {
    for i := 0; i < len(l1); i++ {
        if l1[i] != l2[i] {
            return false
        }
    }
    return true
}

func main() {
    fmt.Println("First 20 members of the Padovan sequence:")
    fmt.Println(padovanRecur(20))
    recur := padovanRecur(64)
    floor := padovanFloor(64)
    same := areSame(recur, floor)
    s := "give"
    if !same {
        s = "do not give"
    }
    fmt.Println("\nThe recurrence and floor based functions", s, "the same results for 64 terms.")

    p := padovanLSys(32)
    lsyst := make([]int, 32)
    for i := 0; i < 32; i++ {
        lsyst[i] = len(p[i])
    }
    fmt.Println("\nFirst 10 members of the Padovan L-System:")
    fmt.Println(p[:10])
    fmt.Println("\nand their lengths:")
    fmt.Println(lsyst[:10])

    same = areSame(recur[:32], lsyst)
    s = "give"
    if !same {
        s = "do not give"
    }
    fmt.Println("\nThe recurrence and L-system based functions", s, "the same results for 32 terms.")


-- list of Padovan numbers using recurrence
pRec = map (\(a,_,_) -> a) $ iterate (\(a,b,c) -> (b,c,a+b)) (1,1,1)

-- list of Padovan numbers using self-referential lazy lists
pSelfRef = 1 : 1 : 1 : zipWith (+) pSelfRef (tail pSelfRef)

-- list of Padovan numbers generated from floor function
pFloor = map f [0..]
    where f n = floor $ p**fromInteger (pred n) / s + 0.5
          p   = 1.324717957244746025960908854
          s   = 1.0453567932525329623

-- list of L-system strings
lSystem = iterate f "A"
    where f []      = []
          f ('A':s) = 'B':f s
          f ('B':s) = 'C':f s
          f ('C':s) = 'A':'B':f s

-- check if first N elements match
checkN n as bs = take n as == take n bs

main = do
    putStr "P_0 .. P_19: "
    putStrLn $ unwords $ map show $ take 20 pRec

    putStr "The floor- and recurrence-based functions "
    putStr $ if checkN 64 pRec pFloor then "match" else "do not match"
    putStr " from P_0 to P_63.\n"

    putStr "The self-referential- and recurrence-based functions "
    putStr $ if checkN 64 pRec pSelfRef then "match" else "do not match"
    putStr " from P_0 to P_63.\n\n"

    putStr "The first 10 L-system strings are:\n"
    putStrLn $ unwords $ take 10 lSystem

    putStr "\nThe floor- and L-system-based functions "
    putStr $ if checkN 32 pFloor (map length lSystem)
             then "match" else "do not match"
    putStr " from P_0 to P_31.\n"


(() => {
    "use strict";

    // ----------------- PADOVAN NUMBERS -----------------

    // padovans :: [Int]
    const padovans = () => {
        // Non-finite series of Padovan numbers,
        // defined in terms of recurrence relations.
        const f = ([a, b, c]) => [
            a,
            [b, c, a + b]
        ];

        return unfoldr(f)([1, 1, 1]);
    };

    // padovanFloor :: [Int]
    const padovanFloor = () => {
        // The Padovan series, defined in terms
        // of a floor function.
        const
            // NB JavaScript loses some of this
            // precision at run-time.
            p = 1.324717957244746025960908854,
            s = 1.0453567932525329623;

        const f = n => [
            Math.floor(((p ** (n - 1)) / s) + 0.5),
            1 + n
        ];

        return unfoldr(f)(0);
    };

    // padovanLSystem : [Int]
    const padovanLSystem = () => {
        // An L-system generating terms whose lengths
        // are the values of the Padovan integer series.
        const rule = c =>
            "A" === c ? (
                "B"
            ) : "B" === c ? (
                "C"
            ) : "AB";

        const f = s => [
            s,
            chars(s).flatMap(rule)
            .join("")
        ];

        return unfoldr(f)("A");
    };

    // ---------------------- TEST -----------------------
    // main :: IO ()
    const main = () => {
        // prefixesMatch :: [a] -> [a] -> Bool
        const prefixesMatch = xs =>
            ys => n => and(
                zipWith(a => b => a === b)(
                    take(n)(xs)
                )(
                    take(n)(ys)
                )
            );

        return [
                "First 20 padovans:",
                take(20)(padovans()),

                "\nThe recurrence and floor-based functions",
                "match over the first 64 terms:\n",
                prefixesMatch(
                    padovans()
                )(
                    padovanFloor()
                )(64),

                "\nFirst 10 L-System strings:",
                take(10)(padovanLSystem()),

                "\nThe lengths of the first 32 L-System",
                "strings match the Padovan sequence:\n",
                prefixesMatch(
                    padovans()
                )(
                    fmap(length)(padovanLSystem())
                )(32)
            ]
            .map(str)
            .join("\n");
    };

    // --------------------- GENERIC ---------------------

    // and :: [Bool] -> Bool
    const and = xs =>
        // True unless any value in xs is false.
        [...xs].every(Boolean);

    // chars :: String -> [Char]
    const chars = s =>
        s.split("");

    // fmap <$> :: (a -> b) -> Gen [a] -> Gen [b]
    const fmap = f =>
        function* (gen) {
            let v = take(1)(gen);

            while (0 < v.length) {
                yield f(v[0]);
                v = take(1)(gen);
            }
        };

    // length :: [a] -> Int
    const length = xs =>
        // Returns Infinity over objects without finite
        // length. This enables zip and zipWith to choose
        // the shorter argument when one is non-finite,
        // like cycle, repeat etc
        "GeneratorFunction" !== xs.constructor
        .constructor.name ? (
            xs.length
        ) : Infinity;

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = n =>
        // The first n elements of a list,
        // string of characters, or stream.
        xs => "GeneratorFunction" !== xs
        .constructor.constructor.name ? (
            xs.slice(0, n)
        ) : [].concat(...Array.from({
            length: n
        }, () => {
            const x = xs.next();

            return x.done ? [] : [x.value];
        }));

    // str :: a -> String
    const str = x =>
        "string" !== typeof x ? (
            JSON.stringify(x)
        ) : x;

    // unfoldr :: (b -> Maybe (a, b)) -> b -> Gen [a]
    const unfoldr = f =>
        // A lazy (generator) list unfolded from a seed value
        // by repeated application of f to a value until no
        // residue remains. Dual to fold/reduce.
        // f returns either Null or just (value, residue).
        // For a strict output list,
        // wrap with `list` or Array.from
        x => (
            function* () {
                let valueResidue = f(x);

                while (null !== valueResidue) {
                    yield valueResidue[0];
                    valueResidue = f(valueResidue[1]);
                }
            }()
        );

    // zipWithList :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f =>
        // A list constructed by zipping with a
        // custom function, rather than with the
        // default tuple constructor.
        xs => ys => ((xs_, ys_) => {
            const lng = Math.min(length(xs_), length(ys_));

            return take(lng)(xs_).map(
                (x, i) => f(x)(ys_[i])
            );
        })([...xs], [...ys]);

    // MAIN ---
    return main();
})();


# Output: first $n Padovans
def padovanRecur($n):
  [range(0;$n) | 1] as $p
  | if $n < 3 then $p
    else reduce range(3;$n) as $i ($p; .[$i] = .[$i-2] + .[$i-3])
    end;

# Output: first $n Padovans
def padovanFloor($n):
  { p: 1.324717957244746025960908854,
    s: 1.0453567932525329623,
    pow: 1 }
  | reduce range (1;$n) as $i ( .f = [ ((.pow/.p/.s) + 0.5)|floor];
      .f[$i] = (((.pow/.s) + 0.5)|floor)
      | .pow *= .p)
  | .f ;

# Output: a stream of the L-System Padovan strings
def padovanStrings:
  {A: "B", B: "C", C: "AB", "": "A"} as $rules
  | $rules[""]
  | while(true;
      ascii_downcase
      | gsub("a"; $rules["A"]) | gsub("b"; $rules["B"]) | gsub("c"; $rules["C"]) ) ;

# Output: a stream of the Padovan numbers using the L-System strings
def padovanNumbers:
  padovanStrings | length;

def task:
  def s1($n):
    if padovanFloor($n) == padovanRecur($n) then "give" else "do not give" end;

  def s2($n):
    if [limit($n; padovanNumbers)] == padovanRecur($n) then "give" else "do not give" end;

  "The first 20 members of the Padovan sequence:", padovanRecur(20),
  "",
  "The recurrence and floor-based functions \(s1(64)) the same results for 64 terms.",
  "",
  ([limit(10; padovanStrings)]
     | "First 10 members of the Padovan L-System:", .,
        "and their lengths:",
         map(length)),
  "",
  "The recurrence and L-system based functions \(s2(32)) the same results for 32 terms."
;

task


""" Recursive Padovan """
rPadovan(n) = (n < 4) ? one(n) : rPadovan(n - 3) + rPadovan(n - 2)

""" Floor function calculation Padovan """
function fPadovan(n)::Int
    p, s = big"1.324717957244746025960908854", big"1.0453567932525329623"
    return Int(floor(p^(n-2) / s + .5))
end

""" LSystem Padovan """
function list_LsysPadovan(N)
    rules = Dict("A" => "B", "B" => "C", "C" => "AB")
    seq, lens = ["A"], [1]
    for i in 1:N
        str = prod([rules[string(c)] for c in seq[end]])
        push!(seq, str)
        push!(lens, length(str))
    end
    return seq, lens
end

const lr, lf = [rPadovan(i) for i in 1:64], [fPadovan(i) for i in 1:64]
const sL, lL = list_LsysPadovan(32)
println("N  Recursive  Floor      LSystem      String\n=============================================")
foreach(i -> println(rpad(i, 4), rpad(lr[i], 12), rpad(lf[i], 12),
    rpad(i < 33 ? lL[i] : "", 12), (i < 11 ? sL[i] : "")), 1:64)


import sequtils, strutils, tables

const
  P = 1.324717957244746025960908854
  S = 1.0453567932525329623

  Rules = {'A': "B", 'B': "C", 'C': "AB"}.toTable

iterator padovan1(n: Natural): int {.closure.} =
  ## Yield the first "n" Padovan values using recurrence relation.
  for _ in 1..min(n, 3): yield 1
  var a, b, c = 1
  var count = 3
  while count < n:
    (a, b, c) = (b, c, a + b)
    yield c
    inc count

iterator padovan2(n: Natural): int {.closure.} =
  ## Yield the first "n" Padovan values using formula.
  if n > 1: yield 1
  var p = 1.0
  var count = 1
  while count < n:
    yield (p / S).toInt
    p *= P
    inc count

iterator padovan3(n: Natural): string {.closure.} =
  ## Yield the strings produced by the L-system.
  var s = "A"
  var count = 0
  while count < n:
    yield s
    var next: string
    for ch in s:
      next.add Rules[ch]
    s = move(next)
    inc count

echo "First 20 terms of the Padovan sequence:"
echo toSeq(padovan1(20)).join(" ")

let list1 = toSeq(padovan1(64))
let list2 = toSeq(padovan2(64))
echo "The first 64 iterative and calculated values ",
     if list1 == list2: "are the same." else: "differ."

echo ""
echo "First 10 L-system strings:"
echo toSeq(padovan3(10)).join(" ")
echo ""
echo "Lengths of the 32 first L-system strings:"
let list3 = toSeq(padovan3(32)).mapIt(it.len)
echo list3.join(" ")
echo "These lengths are",
     if list3 == list1[0..31]: " " else: " not ",
     "the 32 first terms of the Padovan sequence."


with javascript_semantics
sequence padovan = {1,1,1}
function padovanr(integer n)
    while length(padovan)<n do
        padovan &= padovan[$-2]+padovan[$-1]
    end while
    return padovan[n]
end function

constant p = 1.324717957244746025960908854,
         s = 1.0453567932525329623
function padovana(integer n)
    return floor(power(p,n-2)/s + 0.5)
end function

constant l = {"B","C","AB"}
function padovanl(string prev)
    string res = ""
    for i=1 to length(prev) do
        res &= l[prev[i]-64]
    end for
    return res
end function

sequence pl = "A", l10 = {}
for n=1 to 64 do
    integer pn = padovanr(n)
    if padovana(n)!=pn or length(pl)!=pn then crash("oops") end if
    if n<=10 then l10 = append(l10,pl) end if
    pl = padovanl(pl)
end for
printf(1,"The first 20 terms of the Padovan sequence: %v\n\n",{padovan[1..20]})
printf(1,"The first 10 L-system strings: %v\n\n",{l10})
printf(1,"recursive, algorithmic, and l-system agree to n=64\n")


from math import floor
from collections import deque
from typing import Dict, Generator

def padovan_r() -> Generator[int, None, None]:
    last = deque([1, 1, 1], 4)
    while True:
        last.append(last[-2] + last[-3])
        yield last.popleft()

_p, _s = 1.324717957244746025960908854, 1.0453567932525329623

def padovan_f(n: int) -> int:
    return floor(_p**(n-1) / _s + .5)

def padovan_l(start: str='A',
             rules: Dict[str, str]=dict(A='B', B='C', C='AB')
             ) -> Generator[str, None, None]:
    axiom = start
    while True:
        yield axiom
        axiom = ''.join(rules[ch] for ch in axiom)

if __name__ == "__main__":
    from itertools import islice

    print("The first twenty terms of the sequence.")
    print(str([padovan_f(n) for n in range(20)])[1:-1])

    r_generator = padovan_r()
    if all(next(r_generator) == padovan_f(n) for n in range(64)):
        print("\nThe recurrence and floor based algorithms match to n=63 .")
    else:
        print("\nThe recurrence and floor based algorithms DIFFER!")

    print("\nThe first 10 L-system string-lengths and strings")
    l_generator = padovan_l(start='A', rules=dict(A='B', B='C', C='AB'))
    print('\n'.join(f"  {len(string):3} {repr(string)}"
                    for string in islice(l_generator, 10)))

    r_generator = padovan_r()
    l_generator = padovan_l(start='A', rules=dict(A='B', B='C', C='AB'))
    if all(len(next(l_generator)) == padovan_f(n) == next(r_generator)
           for n in range(32)):
        print("\nThe L-system, recurrence and floor based algorithms match to n=31 .")
    else:
        print("\nThe L-system, recurrence and floor based algorithms DIFFER!")


( --------------------- Recurrence -------------------- )

  [ dup 0 = iff
     [ drop ' [ ] ] done
    dup 1 = iff
      [ drop ' [ 1 ] ] done
   dip [ [] 0 1 1 ]
   2 - times
       [ dip [ 2dup + ] swap
         3 pack dip join
         unpack ]
     3 times join behead drop ] is padovan1 ( n --> [   )

  say "With recurrence:     " 20 padovan1 echo cr cr

( ------------------- Floor Function ------------------ )

  $ "bigrat.qky" loadfile

  [ [ $ "1.324717957244746025960908854"
      $->v drop join ] constant
    do ]                        is p        (   --> n/d )

  [ [ $ "1.0453567932525329623"
      $->v drop join ] constant
    do ]                        is s        (   --> n/d )

  [ 1 -
    p rot v** s v/ 1 2 v+ / ]   is padovan2 ( n --> n   )

  say "With floor function: "
  []
  20 times [ i^ padovan2 join ]
  echo cr cr

( ---------------------- L-System --------------------- )

  [ $ "" swap witheach
      [ nested quackery join ] ]    is expand ( $ --> $ )

  [ $ "B" ]                         is A      ( $ --> $ )

  [ $ "C" ]                         is B      ( $ --> $ )

  [ $ "AB" ]                        is C      ( $ --> $ )

  $ "A"

  say "First 10 L System strings: "
  9 times
    [ dup echo$ sp
      expand ]
  echo$ cr cr

  [] $ "A"
  31 times
    [ dup size
      swap dip join
      expand ]
  size join

  32 padovan1 = iff
    [ say "The first 32 recurrence terms and L System lengths are the same." ]
  else [ say "Oh no! It's all gone pear-shaped!" ]


constant p = 1.32471795724474602596;
constant s = 1.0453567932525329623;
constant %rules = A => 'B', B => 'C', C => 'AB';

my @pad-recur = 1, 1, 1, -> $c, $b, $ { $b + $c }  … *;

my @pad-floor = { floor 1/2 + p ** ($++ - 1) / s } … *;

my @pad-L-sys = 'A', { %rules{$^axiom.comb}.join } … *;
my @pad-L-len = @pad-L-sys.map: *.chars;

say @pad-recur.head(20);
say @pad-L-sys.head(10);

say "Recurrence == Floor to N=64" if (@pad-recur Z== @pad-floor).head(64).all;
say "Recurrence == L-len to N=32" if (@pad-recur Z== @pad-L-len).head(32).all;


/*REXX pgm computes the Padovan seq. (using 2 methods), and also computes the L─strings.*/
numeric digits 40                                /*better precision for Plastic ratio.  */
parse arg n nF Ln cL .                           /*obtain optional arguments from the CL*/
if  n=='' |  n==","  then  n= 20                 /*Not specified?  Then use the default.*/
if nF=='' | nF==","  then nF= 64                 /* "      "         "   "   "     "    */
if Ln=='' | Ln==","  then Ln= 10                 /* "      "         "   "   "     "    */
if cL=='' | cL==","  then cL= 32                 /* "      "         "   "   "     "    */
PR= 1.324717957244746025960908854                /*the plastic ratio  (constant).       */
 s= 1.0453567932525329623                        /*tge  "s"  constant.                  */
    @.= .;      @.0= 1;      @.1= 1;      @.2= 1 /*initialize 3 terms of the Padovan seq*/
    !.= .;      !.0= 1;      !.1= 1;      !.2= 1 /*     "     "   "    "  "     "     " */
call req1;   call req2;   call req3;   call req4 /*invoke the four task's requirements. */
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
floor: procedure; parse arg x;      t= trunc(x);               return t  -  (x<0) * (x\=t)
pF:    procedure expose !. PR s; parse arg x;  !.x= floor(PR**(x-1)/s + .5);    return !.x
th:    parse arg th; return th||word('th st nd rd',1+(th//10)*(th//100%10\==1)*(th//10<4))
/*──────────────────────────────────────────────────────────────────────────────────────*/
L_sys: procedure: arg x; q=; a.A= 'B'; a.B= 'C'; a.C= 'AB';      if x==''  then return 'A'
                                do k=1  for length(x);  _= substr(x, k, 1);  q= q  ||  a._
                                end   /*k*/;                           return q
/*──────────────────────────────────────────────────────────────────────────────────────*/
p:     procedure expose @.; parse arg x;  if @.x\==.  then return @.x     /*@.X defined?*/
       xm2= x - 2;    xm3= x - 3;    @.x= @.xm2 + @.xm3;   return @.x
/*──────────────────────────────────────────────────────────────────────────────────────*/
req1:                   say 'The first '    n    " terms of the Pandovan sequence:";
       $= @.0;  do j=1  for n-1;   $= $  p(j)
                end   /*j*/
       say $;                                                          return
/*──────────────────────────────────────────────────────────────────────────────────────*/
req2:  ok= 1;           what= ' terms match for  recurrence  and  floor─based  functions.'
                do j=0  for nF;  if p(j)==pF(j)  then iterate
                say 'the '   th(j)   " terms don't match:"   p(j)  pF(j);   ok= 0
                end   /*j*/
       say
       if ok  then say 'all '    nF    what;                           return
/*──────────────────────────────────────────────────────────────────────────────────────*/
req3:                               y=;             $= 'A'
                do j=1  for Ln-1;   y= L_sys(y);    $= $  L_sys(y)
                end   /*j*/
       say
       say 'L_sys:'  $;                                                return
/*──────────────────────────────────────────────────────────────────────────────────────*/
req4:  y=;              what=' terms match for Padovan terms and lengths of L_sys terms.'
       ok= 1;   do j=1  for cL;  y= L_sys(y);   L= length(y)
       if       L==p(j-1)  then iterate
                say 'the '    th(j)    " Padovan term doesn't match the length of the",
                                       'L_sys term:'   p(j-1)  L;           ok= 0
                end   /*j*/
       say
       if ok  then say 'all '    cL    what;                           return


padovan = Enumerator.new do |y|
  ar = [1, 1, 1]
  loop do
    ar << ar.first(2).sum
    y  << ar.shift
  end
end

P, S = 1.324717957244746025960908854, 1.0453567932525329623
def padovan_f(n) = (P**(n-1) / S + 0.5).floor

puts "Recurrence Padovan: #{padovan.take(20)}"
puts "Floor function:     #{(0...20).map{|n| padovan_f(n)}}"

n = 63
bool =  (0...n).map{|n| padovan_f(n)} == padovan.take(n)
puts "Recurrence and floor function are equal upto #{n}: #{bool}."
puts

def l_system(axiom = "A", rules = {"A" => "B", "B" => "C", "C" => "AB"} )
  return enum_for(__method__,  axiom, rules) unless block_given?
  loop do
    yield axiom
    axiom = axiom.chars.map{|c| rules[c] }.join
  end
end

puts "First 10 elements of L-system: #{l_system.take(10).join(", ")} "
n = 32
bool = l_system.take(n).map(&:size) == padovan.take(n)
puts "Sizes of first #{n} l_system strings equal to recurrence padovan? #{bool}."


fn padovan_recur() -> impl std::iter::Iterator<Item = usize> {
    let mut p = vec![1, 1, 1];
    let mut n = 0;
    std::iter::from_fn(move || {
        let pn = if n < 3 { p[n] } else { p[0] + p[1] };
        p[0] = p[1];
        p[1] = p[2];
        p[2] = pn;
        n += 1;
        Some(pn)
    })
}

fn padovan_floor() -> impl std::iter::Iterator<Item = usize> {
    const P: f64 = 1.324717957244746025960908854;
    const S: f64 = 1.0453567932525329623;
    (0..).map(|x| (P.powf((x - 1) as f64) / S + 0.5).floor() as usize)
}

fn padovan_lsystem() -> impl std::iter::Iterator<Item = String> {
    let mut str = String::from("A");
    std::iter::from_fn(move || {
        let result = str.clone();
        let mut next = String::new();
        for ch in str.chars() {
            match ch {
                'A' => next.push('B'),
                'B' => next.push('C'),
                _ => next.push_str("AB"),
            }
        }
        str = next;
        Some(result)
    })
}

fn main() {
    println!("First 20 terms of the Padovan sequence:");
    for p in padovan_recur().take(20) {
        print!("{} ", p);
    }
    println!();

    println!(
        "\nRecurrence and floor functions agree for first 64 terms? {}",
        padovan_recur().take(64).eq(padovan_floor().take(64))
    );

    println!("\nFirst 10 strings produced from the L-system:");
    for p in padovan_lsystem().take(10) {
        print!("{} ", p);
    }
    println!();

    println!(
        "\nLength of first 32 strings produced from the L-system = Padovan sequence? {}",
        padovan_lsystem()
            .map(|x| x.len())
            .take(32)
            .eq(padovan_recur().take(32))
    );
}


import Foundation

class PadovanRecurrence: Sequence, IteratorProtocol {
    private var p = [1, 1, 1]
    private var n = 0

    func next() -> Int? {
        let pn = n < 3 ? p[n] : p[0] + p[1]
        p[0] = p[1]
        p[1] = p[2]
        p[2] = pn
        n += 1
        return pn
    }
}

class PadovanFloor: Sequence, IteratorProtocol {
    private let P = 1.324717957244746025960908854
    private let S = 1.0453567932525329623
    private var n = 0

    func next() -> Int? {
        let p = Int(floor(pow(P, Double(n - 1)) / S + 0.5))
        n += 1
        return p
    }
}

class PadovanLSystem: Sequence, IteratorProtocol {
    private var str = "A"

    func next() -> String? {
        let result = str
        var next = ""
        for ch in str {
            switch (ch) {
            case "A": next.append("B")
            case "B": next.append("C")
            default: next.append("AB")
            }
        }
        str = next
        return result
    }
}

print("First 20 terms of the Padovan sequence:")
for p in PadovanRecurrence().prefix(20) {
    print("\(p)", terminator: " ")
}
print()

var b = PadovanRecurrence().prefix(64)
    .elementsEqual(PadovanFloor().prefix(64))
print("\nRecurrence and floor functions agree for first 64 terms? \(b)")

print("\nFirst 10 strings produced from the L-system:");
for p in PadovanLSystem().prefix(10) {
    print(p, terminator: " ")
}
print()

b = PadovanLSystem().prefix(32).map{$0.count}
    .elementsEqual(PadovanRecurrence().prefix(32))
print("\nLength of first 32 strings produced from the L-system = Padovan sequence? \(b)")


import "/big" for BigRat
import "/dynamic" for Struct

var padovanRecur = Fn.new { |n|
    var p = List.filled(n, 1)
    if (n < 3) return p
    for (i in 3...n) p[i] = p[i-2] + p[i-3]
    return p
}

var padovanFloor = Fn.new { |n|
    var p = BigRat.fromDecimal("1.324717957244746025960908854")
    var s = BigRat.fromDecimal("1.0453567932525329623")
    var f = List.filled(n, 0)
    var pow = BigRat.one
    f[0] = (pow/p/s + 0.5).floor.toInt
    for (i in 1...n) {
        f[i] = (pow/s + 0.5).floor.toInt
        pow = pow * p
    }
    return f
}

var LSystem = Struct.create("LSystem", ["rules", "init", "current"])

var step = Fn.new { |lsys|
    var s = ""
    if (lsys.current == "") {
        lsys.current = lsys.init
    } else {
        for (c in lsys.current) s = s + lsys.rules[c]
        lsys.current = s
    }
    return lsys.current
}

var padovanLSys = Fn.new { |n|
    var rules = {"A": "B", "B": "C", "C": "AB"}
    var lsys = LSystem.new(rules, "A", "")
    var p = List.filled(n, null)
    for (i in 0...n) p[i] = step.call(lsys)
    return p
}

System.print("First 20 members of the Padovan sequence:")
System.print(padovanRecur.call(20))

var recur = padovanRecur.call(64)
var floor = padovanFloor.call(64)
var areSame = (0...64).all { |i| recur[i] == floor[i] }
var s = areSame ? "give" : "do not give"
System.print("\nThe recurrence and floor based functions %(s) the same results for 64 terms.")

var p = padovanLSys.call(32)
var lsyst = p.map { |e| e.count }.toList
System.print("\nFirst 10 members of the Padovan L-System:")
System.print(p.take(10).toList)
System.print("\nand their lengths:")
System.print(lsyst.take(10).toList)

recur = recur.take(32).toList
areSame = (0...32).all { |i| recur[i] == lsyst[i] }
s = areSame ? "give" : "do not give"
System.print("\nThe recurrence and L-system based functions %(s) the same results for 32 terms.")


F rn(n, k) -> [Int]
   assert(k >= 2)
   V result = I n == 2 {[1, 1, 1]} E rn(n - 1, n + 1)
   L result.len != k
      result.append(sum(result[(len)-n-1 .< (len)-1]))
   R result

L(n) 2..8
   print(n‘: ’rn(n, 15).map(it -> ‘#3’.format(it)).join(‘ ’))


BEGIN # show some valuies of the Padovan n-step number sequences  #
    # returns an array with the elements set to the elements of   #
    # the Padovan sequences from 2 to max s & elements 1 to max e #
    # max s must be >= 2                                          #
    PROC padovan sequences = ( INT max s, max e )[,]INT:
         BEGIN
            PRIO MIN = 1;
            OP   MIN = ( INT a, b )INT: IF a < b THEN a ELSE b FI;
            # sequence 2                                          #
            [ 2 : max s, 1 : max e ]INT r;
            FOR x TO max e MIN 3 DO r[ 2, x ] := 1 OD;
            FOR x FROM 4 TO max e DO r[ 2, x ] := r[ 2, x - 2 ] + r[ 2, x - 3 ] OD;
            # sequences 3 and above                               #
            FOR n FROM 3 TO max s DO
                FOR x TO max e MIN n + 1 DO r[ n, x ] := r[ n - 1, x ] OD;
                FOR x FROM n + 2 TO max e DO
                    r[ n, x ] := 0;
                    FOR p FROM x - n - 1 TO x - 2 DO r[ n, x ] +:= r[ n, p ] OD
                OD
            OD;
            r
         END # padovan sequences # ;
    # calculate and show the sequences                            #
    [,]INT r = padovan sequences( 8, 15 );
    print( ( "Padovan n-step sequences:", newline ) );
    FOR n FROM 1 LWB r TO 1 UPB r DO
        print( ( whole( n, 0 ), " |" ) );
        FOR x FROM 2 LWB r TO 2 UPB r DO print( ( " ", whole( r[ n, x ], -3 ) ) ) OD;
        print( ( newline ) )
    OD
END


begin % show some valuies of the Padovan n-step number sequences  %
    % sets R(i,j) to the jth element of the ith padovan sequence  %
    % maxS is the number of sequences to generate and maxE is the %
    % maximum number of elements for each sequence                %
    % maxS must be >= 2                                           %
    procedure PadovanSequences ( integer array R ( *, * )
                               ; integer value maxS, maxE
                               ) ;
    begin
        integer procedure min( integer value a, b ) ; if a < b then a else b;
        % sequence 2                                              %
        for x := 1 until min( maxE, 3 ) do R( 2, x ) := 1;
        for x := 4 until maxE do R( 2, x ) := R( 2, x - 2 ) + R( 2, x - 3 );
        % sequences 3 and above                                   %
        for N := 3 until maxS do begin
            for x := 1 until min( maxE, N + 1 ) do R( N, x ) := R( N - 1, x );
            for x := N + 2 until maxE do begin
                R( N, x ) := 0;
                for p := x - N - 1 until x - 2 do R( N, x ) := R( N, x ) + R( N, p )
            end for_x
        end for_N
    end PadovanSequences ;
    integer MAX_SEQUENCES, MAX_ELEMENTS;
    MAX_SEQUENCES :=  8;
    MAX_ELEMENTS  := 15;
    begin % calculate and show the sequences                      %
        % array to hold the Padovan Sequences                     %
        integer array R ( 2 :: MAX_SEQUENCES, 1 :: MAX_ELEMENTS );
        % construct the sequences                                 %
        PadovanSequences( R, MAX_SEQUENCES, MAX_ELEMENTS );
        % show the sequences                                      %
        write( "Padovan n-step sequences:" );
        for n := 2 until MAX_SEQUENCES do begin
            write( i_w := 1, s_w := 0, n, " |" );
            for x := 1 until MAX_ELEMENTS do writeon( i_w := 3, s_w := 0, " ", R( n, x ) )
        end for_n
    end
end.


use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

------------------ PADOVAN N-STEP NUMBERS ----------------

-- padovans :: [Int]
on padovans(n)
    script recurrence
        on |λ|(xs)
            {item 1 of xs, ¬
                rest of xs & {sum(take(n, xs)) as integer}}
        end |λ|
    end script

    if 3 > n then
        set seed to |repeat|(1)
    else
        set seed to padovans(n - 1)
    end if

    if 0 > n then
        {}
    else
        unfoldr(recurrence, take(1 + n, seed))
    end if
end padovans

--------------------------- TEST -------------------------
on run
    script nSample
        on |λ|(n)
            take(15, padovans(n))
        end |λ|
    end script

    script justified
        on |λ|(ns)
            concatMap(justifyRight(4, space), ns)
        end |λ|
    end script

    fTable("Padovan N-step Series:", str, justified, ¬
        nSample, enumFromTo(2, 8))
end run

------------------------ FORMATTING ----------------------

-- fTable :: String -> (a -> String) -> (b -> String) ->
-- (a -> b) -> [a] -> String
on fTable(s, xShow, fxShow, f, xs)
    set ys to map(xShow, xs)
    set w to maximum(map(my |length|, ys))
    script arrowed
        on |λ|(a, b)
            |λ|(a) of justifyRight(w, space) & " ->" & b
        end |λ|
    end script
    s & linefeed & unlines(zipWith(arrowed, ¬
        ys, map(compose(fxShow, f), xs)))
end fTable

------------------------- GENERIC ------------------------

-- compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
on compose(f, g)
    script
        property mf : mReturn(f)
        property mg : mReturn(g)
        on |λ|(x)
            mf's |λ|(mg's |λ|(x))
        end |λ|
    end script
end compose

-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
    set lng to length of xs
    set acc to {}
    tell mReturn(f)
        repeat with i from 1 to lng
            set acc to acc & (|λ|(item i of xs, i, xs))
        end repeat
    end tell
    if {text, string} contains class of xs then
        acc as text
    else
        acc
    end if
end concatMap

-- enumFromTo :: Int -> Int -> [Int]
on enumFromTo(m, n)
    if m ≤ n then
        set lst to {}
        repeat with i from m to n
            set end of lst to i
        end repeat
        lst
    else
        {}
    end if
end enumFromTo

-- intercalate :: String -> [String] -> String
on intercalate(delim, xs)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, delim}
    set s to xs as text
    set my text item delimiters to dlm
    s
end intercalate

-- justifyRight :: Int -> Char -> String -> String
on justifyRight(n, cFiller)
    script
        on |λ|(v)
            set strText to v as text
            if n > length of strText then
                text -n thru -1 of ¬
                    ((replicate(n, cFiller) as text) & strText)
            else
                strText
            end if
        end |λ|
    end script
end justifyRight

-- length :: [a] -> Int
on |length|(xs)
    set c to class of xs
    if list is c or string is c then
        length of xs
    else
        (2 ^ 29 - 1) -- (maxInt - simple proxy for non-finite)
    end if
end |length|

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    -- The list obtained by applying f
    -- to each element of xs.
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map

-- maximum :: Ord a => [a] -> a
on maximum(xs)
    set ca to current application
    unwrap((ca's NSArray's arrayWithArray:xs)'s ¬
        valueForKeyPath:"@max.self")
end maximum

-- min :: Ord a => a -> a -> a
on min(x, y)
    if y < x then
        y
    else
        x
    end if
end min

-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
    -- 2nd class handler function lifted
    -- into 1st class script wrapper.
    if script is class of f then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn

-- repeat :: a -> Generator [a]
on |repeat|(x)
    script
        on |λ|()
            return x
        end |λ|
    end script
end |repeat|

-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary
-- assembly of a target length
-- replicate :: Int -> String -> String
on replicate(n, s)
    -- Egyptian multiplication - progressively doubling a list,
    -- appending stages of doubling to an accumulator where needed
    -- for binary assembly of a target length
    script p
        on |λ|({n})
            n ≤ 1
        end |λ|
    end script

    script f
        on |λ|({n, dbl, out})
            if (n mod 2) > 0 then
                set d to out & dbl
            else
                set d to out
            end if
            {n div 2, dbl & dbl, d}
        end |λ|
    end script

    set xs to |until|(p, f, {n, s, ""})
    item 2 of xs & item 3 of xs
end replicate

-- str :: a -> String
on str(x)
    x as string
end str

-- sum :: [Num] -> Num
on sum(xs)
    set ca to current application
    ((ca's NSArray's arrayWithArray:xs)'s ¬
        valueForKeyPath:"@sum.self") as real
end sum

-- take :: Int -> [a] -> [a]
-- take :: Int -> String -> String
on take(n, xs)
    set c to class of xs
    if list is c then
        set lng to length of xs
        if 0 < n and 0 < lng then
            items 1 thru min(n, lng) of xs
        else
            {}
        end if
    else if string is c then
        if 0 < n then
            text 1 thru min(n, length of xs) of xs
        else
            ""
        end if
    else if script is c then
        set ys to {}
        repeat with i from 1 to n
            set v to |λ|() of xs
            if missing value is v then
                return ys
            else
                set end of ys to v
            end if
        end repeat
        return ys
    else
        missing value
    end if
end take

-- unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
on unfoldr(f, v)
    -- A lazy (generator) list unfolded from a seed value
    -- by repeated application of f to a value until no
    -- residue remains. Dual to fold/reduce.
    -- f returns either nothing (missing value),
    -- or just (value, residue).
    script
        property valueResidue : {v, v}
        property g : mReturn(f)
        on |λ|()
            set valueResidue to g's |λ|(item 2 of (valueResidue))
            if missing value ≠ valueResidue then
                item 1 of (valueResidue)
            else
                missing value
            end if
        end |λ|
    end script
end unfoldr

-- unlines :: [String] -> String
on unlines(xs)
    -- A single string formed by the intercalation
    -- of a list of strings with the newline character.
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, linefeed}
    set s to xs as text
    set my text item delimiters to dlm
    s
end unlines

-- until :: (a -> Bool) -> (a -> a) -> a -> a
on |until|(p, f, x)
    set v to x
    set mp to mReturn(p)
    set mf to mReturn(f)
    repeat until mp's |λ|(v)
        set v to mf's |λ|(v)
    end repeat
    v
end |until|

-- unwrap :: NSValue -> a
on unwrap(nsValue)
    if nsValue is missing value then
        missing value
    else
        set ca to current application
        item 1 of ((ca's NSArray's arrayWithObject:nsValue) as list)
    end if
end unwrap

-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
on zipWith(f, xs, ys)
    set lng to min(length of xs, length of ys)
    set lst to {}
    if 1 > lng then
        return {}
    else
        tell mReturn(f)
            repeat with i from 1 to lng
                set end of lst to |λ|(item i of xs, item i of ys)
            end repeat
            return lst
        end tell
    end if
end zipWith


#include <stdio.h>

void padovanN(int n, size_t t, int *p) {
    int i, j;
    if (n < 2 || t < 3) {
        for (i = 0; i < t; ++i) p[i] = 1;
        return;
    }
    padovanN(n-1, t, p);
    for (i = n + 1; i < t; ++i) {
        p[i] = 0;
        for (j = i - 2; j >= i - n - 1; --j) p[i] += p[j];
    }
}

int main() {
    int n, i;
    const size_t t = 15;
    int p[t];
    printf("First %ld terms of the Padovan n-step number sequences:\n", t);
    for (n = 2; n <= 8; ++n) {
        for (i = 0; i < t; ++i) p[i] = 0;
        padovanN(n, t, p);
        printf("%d: ", n);
        for (i = 0; i < t; ++i) printf("%3d ", p[i]);
        printf("\n");
    }
    return 0;
}


// Padovan n-step number sequences. Nigel Galloway: July 28th., 2021
let rec pad=function 2->Seq.unfold(fun(n:int[])->Some(n.[0],Array.append n.[1..2] [|Array.sum n.[0..1]|]))[|1;1;1|]
                    |g->Seq.unfold(fun(n:int[])->Some(n.[0],Array.append n.[1..g] [|Array.sum n.[0..g-1]|]))(Array.ofSeq(pad(g-1)|>Seq.take(g+1)))
[2..8]|>List.iter(fun n->pad n|>Seq.take 15|>Seq.iter(printf "%d "); printfn "")


USING: compiler.tree.propagation.call-effect io kernel math
math.ranges prettyprint sequences ;

: padn ( m n -- seq )
    V{ "|" 1 1 1 } over prefix clone over 2 -
    [ dup last2 + suffix! ] times rot pick 1 + -
    [ dup length 1 - pick [ - ] keepd pick <slice> sum suffix! ]
    times nip ;

"Padovan n-step sequences" print
2 8 [a..b] [ 15 swap padn ] map simple-table.


package main

import "fmt"

func padovanN(n, t int) []int {
    if n < 2 || t < 3 {
        ones := make([]int, t)
        for i := 0; i < t; i++ {
            ones[i] = 1
        }
        return ones
    }
    p := padovanN(n-1, t)
    for i := n + 1; i < t; i++ {
        p[i] = 0
        for j := i - 2; j >= i-n-1; j-- {
            p[i] += p[j]
        }
    }
    return p
}

func main() {
    t := 15
    fmt.Println("First", t, "terms of the Padovan n-step number sequences:")
    for n := 2; n <= 8; n++ {
        fmt.Printf("%d: %3d\n", n, padovanN(n, t))
    }
}


import Data.Bifunctor (second)
import Data.List (transpose, uncons, unfoldr)

------------------ PADOVAN N-STEP SERIES -----------------

padovans :: Int -> [Int]
padovans n
  | 0 > n = []
  | otherwise = unfoldr (recurrence n) $ take (succ n) xs
  where
    xs
      | 3 > n = repeat 1
      | otherwise = padovans $ pred n

recurrence :: Int -> [Int] -> Maybe (Int, [Int])
recurrence n =
  ( fmap
      . second
      . flip (<>)
      . pure
      . sum
      . take n
  )
    <*> uncons

--------------------------- TEST -------------------------
main :: IO ()
main =
  putStrLn $
    "Padovan N-step series:\n\n"
      <> spacedTable
        justifyRight
        ( fmap
            ( \n ->
                [show n <> " -> "]
                  <> fmap show (take 15 $ padovans n)
            )
            [2 .. 8]
        )

------------------------ FORMATTING ----------------------

spacedTable ::
  (Int -> Char -> String -> String) -> [[String]] -> String
spacedTable aligned rows =
  unlines $
    fmap
      (unwords . zipWith (`aligned` ' ') columnWidths)
      rows
  where
    columnWidths =
      fmap
        (maximum . fmap length)
        (transpose rows)

justifyRight :: Int -> a -> [a] -> [a]
justifyRight n c = drop . length <*> (replicate n c <>)


(() => {
    "use strict";

    // ---------- PADOVAN N-STEP NUMBER SERIES -----------

    // padovans :: Int -> [Int]
    const padovans = n => {
        // Padovan number series of step N
        const recurrence = ns => [
            ns[0],
            ns.slice(1).concat(
                sum(take(n)(ns))
            )
        ];

        return 0 > n ? (
            []
        ) : unfoldr(recurrence)(
            take(1 + n)(
                3 > n ? (
                    repeat(1)
                ) : padovans(n - 1)
            )
        );
    };

    // ---------------------- TEST -----------------------
    // main :: IO ()
    const main = () =>
        fTable("Padovan N-step series:")(str)(
            xs => xs.map(
                compose(justifyRight(4)(" "), str)
            )
            .join("")
        )(
            compose(take(15), padovans)
        )(
            enumFromTo(2)(8)
        );

    // --------------------- GENERIC ---------------------

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (...fs) =>
        // A function defined by the right-to-left
        // composition of all the functions in fs.
        fs.reduce(
            (f, g) => x => f(g(x)),
            x => x
        );

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m =>
        n => Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);

    // repeat :: a -> Generator [a]
    const repeat = function* (x) {
        while (true) {
            yield x;
        }
    };

    // sum :: [Num] -> Num
    const sum = xs =>
        // The numeric sum of all values in xs.
        xs.reduce((a, x) => a + x, 0);

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = n =>
        // The first n elements of a list,
        // string of characters, or stream.
        xs => "GeneratorFunction" !== xs
        .constructor.constructor.name ? (
            xs.slice(0, n)
        ) : [].concat(...Array.from({
            length: n
        }, () => {
            const x = xs.next();

            return x.done ? [] : [x.value];
        }));

    // unfoldr :: (b -> Maybe (a, b)) -> b -> Gen [a]
    const unfoldr = f =>
        // A lazy (generator) list unfolded from a seed value
        // by repeated application of f to a value until no
        // residue remains. Dual to fold/reduce.
        // f returns either Nothing or Just (value, residue).
        // For a strict output list,
        // wrap with `list` or Array.from
        x => (
            function* () {
                let valueResidue = f(x);

                while (null !== valueResidue) {
                    yield valueResidue[0];
                    valueResidue = f(valueResidue[1]);
                }
            }()
        );

    // ------------------- FORMATTING --------------------

    // fTable :: String -> (a -> String) ->
    // (b -> String) -> (a -> b) -> [a] -> String
    const fTable = s =>
        // Heading -> x display function ->
        //           fx display function ->
        //    f -> values -> tabular string
        xShow => fxShow => f => xs => {
            const
                ys = xs.map(xShow),
                w = Math.max(...ys.map(y => [...y].length)),
                table = zipWith(
                    a => b => `${a.padStart(w, " ")} ->${b}`
                )(ys)(
                    xs.map(x => fxShow(f(x)))
                ).join("\n");

            return `${s}\n${table}`;
        };

    // justifyRight :: Int -> Char -> String -> String
    const justifyRight = n =>
        // The string s, preceded by enough padding (with
        // the character c) to reach the string length n.
        c => s => n > s.length ? (
            s.padStart(n, c)
        ) : s;

    // str :: a -> String
    const str = x => `${x}`;

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f =>
        // A list constructed by zipping with a
        // custom function, rather than with the
        // default tuple constructor.
        xs => ys => take(
            Math.min(xs.length, ys.length)
        )(
            xs.map((x, i) => f(x)(ys[i]))
        );

    // MAIN ---
    return main();
})();


"""
    First nterms terms of the first 2..max_nstep -step Padovan sequences.
"""
function nstep_Padovan(max_nstep=8, nterms=15)
    start = [[], [1, 1, 1]]     # for n=0 and n=1 (hidden).
    for n in 2:max_nstep
        this = start[n][1:n+1]     # Initialise from last
        while length(this) < nterms
            push!(this, sum(this[end - i] for i in 1:n))
        end
        push!(start, this)
    end
    return start[3:end]
end

function print_Padovan_seq(p)
    println(strip("""
:::: {| style="text-align: left;" border="4" cellpadding="2" cellspacing="2"
|+ Padovan <math>n</math>-step sequences
|- style="background-color: rgb(255, 204, 255);"
! <math>n</math> !! Values
|-
          """))
    for (n, seq) in enumerate(p)
        println("| $n || $(replace(string(seq[2:end]), r"[ a-zA-Z\[\]]+" => "")), ...\n|-")
    end
    println("|}")
end

print_Padovan_seq(nstep_Padovan())


ClearAll[Padovan]
Padovan[2,tmax_]:=Module[{start,a,m},
 start={1,1,1};
 start=MapIndexed[a[#2[[1]]]==#1&,start];
 RecurrenceTable[{a[m]==a[m-2]+a[m-3]}~Join~start,a,  {m,tmax}]
]
Padovan[n_,tmax_]:=Module[{start,eq,a,m},
 start=Padovan[n-1,n+1];
 start=MapIndexed[a[#2[[1]]]==#1&,start];
 eq=Range[2,n+1];
 eq=Append[start,a[m]==Total[a[m-#]&/@eq]];
 RecurrenceTable[eq,a, {m,tmax}]
]
Padovan[2,15]
Padovan[3,15]
Padovan[4,15]
Padovan[5,15]
Padovan[6,15]
Padovan[7,15]
Padovan[8,15]


import math, sequtils, strutils

proc rn(n, k: Positive): seq[int] =
  assert k >= 2
  result = if n == 2: @[1, 1, 1] else: rn(n - 1, n + 1)
  while result.len != k:
    result.add sum(result[^(n + 1)..^2])

for n in 2..8:
  echo n, ": ", rn(n, 15).mapIt(($it).align(3)).join(" ")


use strict;
use warnings;
use feature <state say>;
use List::Util 'sum';
use List::Lazy 'lazy_list';

say 'Padovan N-step sequences; first 25 terms:';
for our $N (2..8) {

    my $pad_n = lazy_list {
        state $n  = 2;
        state @pn = (1, 1, 1);
        push @pn, sum @pn[ grep { $_ >= 0 } $n-$N .. $n++ - 1 ];
        $pn[-4]
    };

    print "N = $N |";
    print ' ' . $pad_n->next() for 1..25;
    print "\n"
}


with javascript_semantics
function padovann(integer n,t)
    if n<2 or t<3 then return repeat(1,t) end if
    sequence p = padovann(n-1, t)
    for i=n+2 to t do
        p[i] = sum(p[i-n-1..i-2])
    end for
    return p
end function

constant t = 15,
 fmt = "%d: %d %d %d %d %d %d %d %2d %2d %2d %2d %2d %3d %3d %3d\n"
printf(1,"First %d terms of the Padovan n-step number sequences:\n",t)
for n=2 to 8 do
    printf(1,fmt,n&padovann(n,t))
end for


def pad_like(max_n=8, t=15):
    """
    First t terms of the first 2..max_n-step Padovan sequences.
    """
    start = [[], [1, 1, 1]]     # for n=0 and n=1 (hidden).
    for n in range(2, max_n+1):
        this = start[n-1][:n+1]     # Initialise from last
        while len(this) < t:
            this.append(sum(this[i] for i in range(-2, -n - 2, -1)))
        start.append(this)
    return start[2:]

def pr(p):
    print('''
:::: {| style="text-align: left;" border="4" cellpadding="2" cellspacing="2"
|+ Padovan <math>n</math>-step sequences
|- style="background-color: rgb(255, 204, 255);"
! <math>n</math> !! Values
|-
          '''.strip())
    for n, seq in enumerate(p, 2):
        print(f"| {n:2} || {str(seq)[1:-1].replace(' ', '')+', ...'}\n|-")
    print('|}')

if __name__ == '__main__':
    p = pad_like()
    pr(p)


say 'Padovan N-step sequences; first 25 terms:';

for 2..8 -> \N {
    my @n-step = 1, 1, 1, { state $n = 2; @n-step[ ($n - N .. $n++ - 1).grep: * >= 0 ].sum } … *;
    put "N = {N} |" ~ @n-step[^25]».fmt: "%5d";
}


/*REXX program computes and shows the Padovan sequences for  M  steps  for  N  numbers. */
parse arg n m .                                  /*obtain optional arguments from the CL*/
if  n=='' |  n==","  then  n= 15                 /*Not specified?  Then use the default.*/
if  m=='' |  m==","  then  m=  8                 /* "      "         "   "   "     "    */
w.= 1                                            /*W.c:  the maximum width of a column. */
        do #=2  for m-1
        @.= 0;    @.0= 1;    @.1= 1;    @.2= 1   /*initialize 3 terms of the Padovan seq*/
        $= @.0                                   /*initials the list with the zeroth #. */
               do k=2  for  n-1;      z= pd(k-1)
               w.k= max(w.k, length(z));  $= $ z /*find maximum width for a specific col*/
               end   /*k*/
        $.#= $                                   /*save each unaligned line for later.  */
        end          /*#*/
oW= 1
        do col=1  for n;  oW= oW + w.col + 1     /*add up the width of each column.     */
        end   /*col*/
                    iW= length(m) + 2;       pad= left('', 20*(n<21))    /*maybe indent.*/
say pad center('M', iW, " ")"│"center('first ' n " Padovan sequence with step  M", oW)
say pad center('',  iW, "─")"┼"center('',  oW,  "─")

        do out=2  for m-1;   $=                  /*align columnar elements for outputs. */
             do j=1  for n;  $= $ right(word($.out, j),  w.j)      /*align the columns. */
             end     /*j*/
        say pad center(out,length(m)+2)'│'$      /*display a line of columnar elements. */
        end          /*out*/

say pad center('',  length(m)+2, "─")"┴"center('',  oW,  "─")
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
pd:    procedure expose @. #; parse arg x;  if @.x\==0  then return @.x   /*@.x defined?*/
                    do k=1  for  #;   _= x-1-k;    @.x= @.x + @._;    end;      return @.x


func padovan(N) {
    Enumerator({|callback|
        var n = 2
        var pn = [1, 1, 1]
        loop {
            pn << sum(pn[n-N .. (n++-1) -> grep { _ >= 0 }])
            callback(pn[-4])
        }
    })
}

for n in (2..8) {
    say "n = #{n} | #{padovan(n).first(25).join(' ')}"
}


import "/fmt" for Fmt

var padovanN // recursive
padovanN = Fn.new { |n, t|
    if (n < 2 || t < 3) return [1] * t
    var p = padovanN.call(n-1, t)
    if (n + 1 >= t) return p
    for (i in n+1...t) {
        p[i] = 0
        for (j in i-2..i-n-1) p[i] = p[i] + p[j]
    }
    return p
}

var t = 15
System.print("First %(t) terms of the Padovan n-step number sequences:")
for (n in 2..8) Fmt.print("$d: $3d" , n, padovanN.call(n, t))