Function min(x As Integer, y As Integer) As Integer
    If x < y Then
        min = x
    Else
        min = y
    End If
End Function

Function levenshtein(s As String, t As String) As Integer
Dim ls As Integer, lt As Integer
Dim i As Integer, j As Integer, cost As Integer
    ' degenerate cases
    ls = Len(s)
    lt = Len(t)
    If ls = lt Then
        If s = t Then
            Exit Function ' return 0
        End If
    ElseIf ls = 0 Then
        levenshtein = lt
        Exit Function
    ElseIf lt = 0 Then
        levenshtein = ls
        Exit Function
    End If

    ' create two integer arrays of distances
    ReDim v0(0 To lt) As Integer  '' previous
    ReDim v1(0 To lt) As Integer  '' current

    ' initialize v0
    For i = 0 To lt
        v0(i) = i
    Next i

    For i = 0 To ls - 1
       ' calculate v1 from v0
       v1(0) = i + 1

       For j = 0 To lt - 1
           cost = Abs(CInt(Mid$(s, i + 1, 1) <> Mid$(t, j + 1, 1)))
           v1(j + 1) = min(v1(j) + 1, min(v0(j + 1) + 1, v0(j) + cost))
       Next j

       ' copy v1 to v0 for next iteration
       For j = 0 To lt
           v0(j) = v1(j)
       Next j
    Next i

    levenshtein = v1(lt)
End Function

Sub Main()
' tests
    Debug.Print "'kitten' to 'sitting'            => "; levenshtein("kitten", "sitting")
    Debug.Print "'sitting' to 'kitten'            => "; levenshtein("sitting", "kitten")
    Debug.Print "'rosettacode' to 'raisethysword' => "; levenshtein("rosettacode", "raisethysword")
    Debug.Print "'sleep' to 'fleeting'            => "; levenshtein("sleep", "fleeting")
End Sub


 Function LevenshteinDistance(ByVal String1 As String, ByVal String2 As String) As Integer
        Dim Matrix(String1.Length, String2.Length) As Integer
        Dim Key As Integer
        For Key = 0 To String1.Length
            Matrix(Key, 0) = Key
        Next
        For Key = 0 To String2.Length
            Matrix(0, Key) = Key
        Next
        For Key1 As Integer = 1 To String2.Length
            For Key2 As Integer = 1 To String1.Length
                If String1(Key2 - 1) = String2(Key1 - 1) Then
                    Matrix(Key2, Key1) = Matrix(Key2 - 1, Key1 - 1)
                Else
                    Matrix(Key2, Key1) = Math.Min(Matrix(Key2 - 1, Key1) + 1, Math.Min(Matrix(Key2, Key1 - 1) + 1, Matrix(Key2 - 1, Key1 - 1) + 1))
                End If
            Next
        Next
        Return Matrix(String1.Length - 1, String2.Length - 1)
    End Function


var levenshtein = Fn.new { |s, t|
    var ls = s.count
    var lt = t.count
    var d = List.filled(ls + 1, null)
    for (i in 0..ls) {
        d[i] = List.filled(lt + 1, 0)
        d[i][0] = i
    }
    for (j in 0..lt) d[0][j] = j
    for (j in 1..lt) {
        for (i in 1..ls) {
            if (s[i-1] == t[j-1]) {
                d[i][j] = d[i-1][j-1]
            } else {
                var min = d[i-1][j]
                if (d[i][j-1] < min) min = d[i][j-1]
                if (d[i-1][j-1] < min) min = d[i-1][j-1]
                d[i][j] = min + 1
            }
        }
    }
    return d[-1][-1]
}

System.print(levenshtein.call("kitten", "sitting"))


fcn levenshtein(s1,s2){
   sz2,costs:=s2.len() + 1, List.createLong(sz2,0);  // -->zero filled List
   foreach i in (s1.len() + 1){
      lastValue:=i;
      foreach j in (sz2){
         if (i==0) costs[j]=j;
	 else if (j>0){
	    newValue:=costs[j-1];
	    if (s1[i-1]!=s2[j-1])
	       newValue=newValue.min(lastValue, costs[j]) + 1;
	    costs[j-1]=lastValue;
	    lastValue =newValue;
	 }
      }
      if (i>0) costs[-1]=lastValue;
   }
   costs[-1]
}


10  REM ZX Spectrum Basic - Levenshtein distance
20  INPUT "first word:",n$
30  INPUT "second word:",m$
40  LET n=LEN n$:LET m=LEN m$:DIM d(m+1,n+1)
50  FOR i=1 TO m:LET d(i+1,1)=i:NEXT i
60  FOR j=1 TO n:LET d(1,j+1)=j:NEXT j
70  FOR j=1 TO n
80    FOR i=1 TO m
90       LET r=d(i,j)-(n$(j)=m$(i)):REM substitution
100      IF r>d(i,j+1) THEN LET r=r-1:REM insertion
110      LET d(i+1,j+1)=r+(r<=d(i+1,j)):REM deletion
120   NEXT i
130 NEXT j
140 PRINT "The Levenshtein distance between """;n$;""", """;m$;""" is ";d(m+1,n+1);"."


*        Last Friday of each month 17/07/2016
LASTFRI  CSECT
         USING  LASTFRI,R13        base register
         B      72(R15)            skip savearea
         DC     17F'0'             savearea
         STM    R14,R12,12(R13)    prolog
         ST     R13,4(R15)         " <-
         ST     R15,8(R13)         " ->
         LR     R13,R15            " addressability
         L      R4,YEAR            year
         SRDA   R4,32              .
         D      R4,=F'400'         year/400
         LTR    R4,R4              if year//400=0
         BZ     LEAP
         L      R4,YEAR            year
         SRDA   R4,32              .
         D      R4,=F'4'           year/4
         LTR    R4,R4              if year//4=0
         BNZ    NOTLEAP
         L      R4,YEAR            year
         SRDA   R4,32              .
         D      R4,=F'100'         year/400
         LTR    R4,R4              if year//100=0
         BZ     NOTLEAP
LEAP     MVC    DAYS+4(4),=F'29'   days(2)=29
NOTLEAP  L      R8,YEAR            year
         BCTR   R8,0               y=year-1
         LA     R7,44              44
         AR     R7,R8              +y
         LR     R3,R8              y
         SRA    R3,2               y/4
         AR     R7,R3              +y/4
         LR     R4,R8              y
         SRDA   R4,32              .
         D      R4,=F'100'         y/100
         LA     R4,0               .
         M      R4,=F'6'           *6
         AR     R7,R5              +6*(y/100)
         LR     R4,R8              y
         SRDA   R4,32              .
         D      R4,=F'400'         y/100
         AR     R7,R5              k=44+y+y/4+6*(y/100)+y/400
         LA     R6,1               m=1
LOOPM    C      R6,=F'12'          do m=1 to 12
         BH     ELOOPM
         LR     R1,R6              m
         SLA    R1,2               .
         L      R2,DAYS-4(R1)      days(m)
         AR     R7,R2              k=k+days(m)
         LR     R4,R7              k
         SRDA   R4,32              .
         D      R4,=F'7'           k/7
         SR     R2,R4              days(m)-k//7
         LR     R9,R2              d=days(m)-k//7
         L      R1,YEAR            year
         CVD    R1,DW              year: binary to packed
         OI     DW+7,X'0F'           zap sign
         UNPK   PG(4),DW             unpack (ZL4)
         CVD    R6,DW              m : binary to packed
         OI     DW+7,X'0F'           zap sign
         UNPK   PG+5(2),DW           unpack (ZL2)
         CVD    R9,DW              d: binary to packed
         OI     DW+7,X'0F'           zap sign
         UNPK   PG+8(2),DW           unpack (ZL2)
         XPRNT  PG,L'PG            print buffer
         LA     R6,1(R6)           m=m+1
         B      LOOPM
ELOOPM   L      R13,4(0,R13)       epilog
         LM     R14,R12,12(R13)    " restore
         XR     R15,R15            " rc=0
         BR     R14                exit
YEAR     DC     F'2016'            <== input year
DAYS     DC     F'31',F'28',F'31',F'30',F'31',F'30'
         DC     F'31',F'31',F'30',F'31',F'30',F'31'
PG       DC     CL80'YYYY-MM-DD'   buffer
XDEC     DS     CL12               temp
DW       DS     D                  packed (PL8) 15num
         YREGS
         END    LASTFRI


;https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Sakamoto.27s_methods
BYTE FUNC DayOfWeek(INT y BYTE m,d)	;1<=m<=12, y>1752
  BYTE ARRAY t=[0 3 2 5 0 3 5 1 4 6 2 4]
  BYTE res

  IF m<3 THEN
    y==-1
  FI
  res=(y+y/4-y/100+y/400+t(m-1)+d) MOD 7
RETURN (res)

BYTE FUNC IsLeapYear(INT y)
  IF y MOD 100=0 THEN
    IF y MOD 400=0 THEN
      RETURN (1)
    ELSE
      RETURN (0)
    FI
  FI

  IF y MOD 4=0 THEN
    RETURN (1)
  FI
RETURN (0)

INT FUNC GetMaxDay(INT y BYTE m)
  BYTE ARRAY MaxDay=[31 28 31 30 31 30 31 31 30 31 30 31]

  IF m=2 AND IsLeapYear(y)=1 THEN
    RETURN (29)
  FI
RETURN (MaxDay(m-1))

PROC PrintB2(BYTE x)
  IF x<10 THEN
    Put('0)
  FI
  PrintB(x)
RETURN

PROC Main()
  INT MinYear=[1753],MaxYear=[9999],y
  BYTE m,d,last,maxD

  DO
    PrintF("Input year in range %I...%I: ",MinYear,MaxYear)
    y=InputI()
  UNTIL y>=MinYear AND y<=MaxYear
  OD

  FOR m=1 TO 12
  DO
    last=0
    maxD=GetMaxDay(y,m)
    FOR d=1 TO maxD
    DO
      IF DayOfWeek(y,m,d)=5 THEN
        last=d
      FI
    OD
    PrintI(y) Put('-)
    PrintB2(m) Put('-)
    PrintB2(last) PutE()
  OD
RETURN


with Ada.Text_IO, GNAT.Calendar.Time_IO, Ada.Command_Line,
  Ada.Calendar.Formatting, Ada.Calendar.Arithmetic;

procedure Last_Weekday_In_Month is

   procedure Put_Line(T: Ada.Calendar.Time) is
      use GNAT.Calendar.Time_IO;
   begin
      Ada.Text_IO.Put_Line(Image(Date => T, Picture => ISO_Date));
   end Put_Line;

   use Ada.Calendar, Ada.Calendar.Arithmetic;
   subtype Day_Name is Formatting.Day_Name; use type Formatting.Day_Name;

   T, Selected : Time;
   Weekday: Day_Name  := Day_Name'Value(Ada.Command_Line.Argument (1));
   Year : Year_Number := Integer'Value (Ada.Command_Line.Argument (2));

begin
   for Month in 1 .. 12 loop
      T := Time_Of (Year => Year, Month => Month, Day => 01);
      while Ada.Calendar.Month(T) = Month loop
	 if Formatting.Day_Of_Week (T) = Weekday then
	    Selected := T;
	 end if;
	 T := T + Day_Count(1);
      end loop;
      Put_Line(Selected);
   end loop;
end Last_Weekday_In_Month;


BEGIN # find the last Friday in each month of a year             #
    # returns true if year is a leap year, false otherwise       #
    # assumes year is in the Gregorian Calendar                  #
    PROC is leap year = ( INT year )BOOL:
         year MOD 400 = 0 OR ( year MOD 4 = 0 AND year MOD 100 /= 0 );
    # returns the day of the week of the specified date (d/m/y)  #
    #         Sunday = 1                                         #
    PROC day of week = ( INT d, m, y )INT:
         BEGIN
            INT mm := m;
            INT yy := y;
            IF mm <= 2 THEN
                mm := mm + 12;
                yy := yy - 1
            FI;
            INT j = yy OVER 100;
            INT k = yy MOD  100;
            (d + ( ( mm + 1 ) * 26 ) OVER 10 + k + k OVER 4 + j OVER 4 + 5 * j ) MOD 7
         END # day of week # ;
    # returns an array of the last Friday of each month in year  #
    PROC last fridays = ( INT year )[]INT:
         BEGIN
            [ 1 : 12 ]INT last days := ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
            IF is leap year( year ) THEN last days[ 2 ] := 29 FI;
            # for each month, determine the day number of the    #
            # last Friday                                        #
            [ 1 : 12 ]INT last;
            FOR m pos TO 12 DO
                INT dow := day of week( last days[ m pos ], m pos, year );
                # dow     = 1 Sun, 2 Mon, ... , 6 Fri, 0 Sat     #
                # change to 2 Sun, 3 Mon, ... , 0 Fri, 1 Sat     #
                dow := ( dow + 1 ) MOD 7;
                # offset the last day to the last Friday         #
                last[ m pos ] := last days[ m pos ] - dow
            OD;
            last
         END # last fridays # ;
    # test the last fridays procedure                            #
    INT   year = 2021;
    []INT last = last fridays( year );
    FOR m pos TO 12 DO
        print( ( whole( year, 0 )
               , IF m pos < 10 THEN "-0" ELSE "-1" FI
               , whole( m pos MOD 10, 0 )
               , "-"
               , whole( last[ m pos ], 0 )
               , newline
               )
             )
    OD
END


begin % find the last Friday in each month of a year             %
    % returns true if year is a leap year, false otherwise       %
    % assumes year is in the Gregorian Calendar                  %
    logical procedure isLeapYear ( integer value year ) ;
        year rem 400 = 0 or ( year rem 4 = 0 and year rem 100 not = 0 );
    % returns the day of the week of the specified date (d/m/y)  %
    %         Sunday = 1, Friday = 6, Saturday = 0               %
    integer procedure Day_of_week ( integer value d, m, y );
        begin
            integer j, k, mm, yy;
            mm := m;
            yy := y;
            if mm <= 2 then begin
                mm := mm + 12;
                yy := yy - 1;
            end if_m_le_2;
            j := yy div 100;
            k := yy rem 100;
            (d + ( ( mm + 1 ) * 26 ) div 10 + k + k div 4 + j div 4 + 5 * j ) rem 7
        end Day_of_week;
    % sets the elements of last to the day of the last Friday   %
    % of each month in year                                     %
    procedure lastFridays ( integer value year
                          ; integer array last ( * )
                          ) ;
        begin
            integer array lastDays ( 1 :: 12 );
            integer m;
            % set ld to the day number od the last day of each  %
            % month in year                                     %
            m := 1;
            for ld := 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 do begin
                lastDays( m ) := ld;
                m             := m + 1
            end for_ld ;
            if isLeapYear( year ) then lastDays( 2 ) := 29;
            % for each month, determine the day number of the   %
            % last Friday                                       %
            for mPos := 1 until 12 do begin
                integer dow;
                dow := Day_of_week( lastDays( mPos ), mPos, year );
                % dow     = 1 Sun, 2 Mon, ... , 6 Fri, 0 Sat    %
                % change to 2 Sun, 3 Mon, ... , 0 Fri, 1 Sat    %
                dow := ( dow + 1 ) rem 7;
                % offset the last day to the last Friday        %
                last( mPos ) := lastDays( mPos ) - dow
            end for_mPos
        end lastFridays ;
    begin
        % test the lastFridays procedure                        %
        integer array last ( 1 :: 12 );
        integer year;
        year := 2020;
        lastFridays( year, last );
        i_w := 1; s_w := 0; % output formatting                 %
        for mPos := 1 until 12 do write( year, if mPos < 10 then "-0" else "-1", mPos rem 10, "-", last( mPos ) )
    end
end.


-- LAST FRIDAYS OF YEAR ------------------------------------------------------

--  lastFridaysOfYear :: Int -> [Date]
on lastFridaysOfYear(y)

    -- lastWeekDaysOfYear :: Int -> Int -> [Date]
    script lastWeekDaysOfYear
        on |λ|(intYear, iWeekday)

            -- lastWeekDay :: Int -> Int -> Date
            script lastWeekDay
                on |λ|(iLastDay, iMonth)
                    set iYear to intYear

                    calendarDate(iYear, iMonth, iLastDay - ¬
                        (((weekday of calendarDate(iYear, iMonth, iLastDay)) ¬
                            as integer) + (7 - (iWeekday))) mod 7)
                end |λ|
            end script

            map(lastWeekDay, lastDaysOfMonths(intYear))
        end |λ|

        -- isLeapYear :: Int -> Bool
        on isLeapYear(y)
            (0 = y mod 4) and (0 ≠ y mod 100) or (0 = y mod 400)
        end isLeapYear

        -- lastDaysOfMonths :: Int -> [Int]
        on lastDaysOfMonths(y)
            {31, cond(isLeapYear(y), 29, 28), ¬
                31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
        end lastDaysOfMonths
    end script

    lastWeekDaysOfYear's |λ|(y, Friday as integer)
end lastFridaysOfYear

-- TEST ----------------------------------------------------------------------
on run argv

    intercalate(linefeed, ¬
        map(isoRow, ¬
            transpose(map(lastFridaysOfYear, ¬
                apply(cond(class of argv is list and argv ≠ {}, ¬
                    singleYearOrRange, fiveCurrentYears), ¬
                    argIntegers(argv))))))

end run

-- ARGUMENT HANDLING ---------------------------------------------------------

-- Up to two optional command line arguments: [yearFrom], [yearTo]
-- (Default range in absence of arguments:
--  from two years ago, to two years ahead)

-- ~ $ osascript ~/Desktop/lastFridays.scpt
-- ~ $ osascript ~/Desktop/lastFridays.scpt 2013
-- ~ $ osascript ~/Desktop/lastFridays.scpt 2013 2016

-- singleYearOrRange :: [Int] -> [Int]
on singleYearOrRange(argv)
    apply(cond(length of argv > 0, my enumFromTo, my fiveCurrentYears), argv)
end singleYearOrRange

-- fiveCurrentYears :: () -> [Int]
on fiveCurrentYears(_)
    set intThisYear to year of (current date)
    enumFromTo(intThisYear - 2, intThisYear + 2)
end fiveCurrentYears

-- argIntegers :: maybe [String] -> [Int]
on argIntegers(argv)
    -- parseInt :: String -> Int
    script parseInt
        on |λ|(s)
            s as integer
        end |λ|
    end script

    if class of argv is list and argv ≠ {} then
        {map(parseInt, argv)}
    else
        {}
    end if
end argIntegers

-- GENERIC FUNCTIONS ---------------------------------------------------------

-- Dates and date strings ----------------------------------------------------

-- calendarDate :: Int -> Int -> Int -> Date
on calendarDate(intYear, intMonth, intDay)
    tell (current date)
        set {its year, its month, its day, its time} to ¬
            {intYear, intMonth, intDay, 0}
        return it
    end tell
end calendarDate

-- isoDateString :: Date -> String
on isoDateString(dte)
    (((year of dte) as string) & ¬
        "-" & text items -2 thru -1 of ¬
        ("0" & ((month of dte) as integer) as string)) & ¬
        "-" & text items -2 thru -1 of ¬
        ("0" & day of dte)
end isoDateString

-- Testing and tabulation ----------------------------------------------------

-- apply (a -> b) -> a -> b
on apply(f, a)
    mReturn(f)'s |λ|(a)
end apply

-- cond :: Bool -> (a -> b) -> (a -> b) -> (a -> b)
on cond(bool, f, g)
    if bool then
        f
    else
        g
    end if
end cond

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

-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, strText}
    set strJoined to lstText as text
    set my text item delimiters to dlm
    return strJoined
end intercalate

-- isoRow :: [Date] -> String
on isoRow(lstDate)
    intercalate(tab, map(my isoDateString, lstDate))
end isoRow

-- map :: (a -> b) -> [a] -> [b]
on map(f, 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

-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn

-- transpose :: [[a]] -> [[a]]
on transpose(xss)
    script column
        on |λ|(_, iCol)
            script row
                on |λ|(xs)
                    item iCol of xs
                end |λ|
            end script

            map(row, xss)
        end |λ|
    end script

    map(column, item 1 of xss)
end transpose


lastFridayForMonth: function [m][
    ensure -> in? m 1..12

    daysOfMonth: [0 31 27 31 30 31 30 31 31 30 31 30 31]
    loop range get daysOfMonth m 1 [d][
        dt: to :date.format:"yyyy-M-dd" ~"2012-|m|-|d|"
        if dt\Day = "Friday" -> return dt
    ]
]

loop 1..12 'month [
    print to :string.format:"yyyy-MM-dd" lastFridayForMonth month
]


if 1 = ; no parameter passed
{
	InputBox, 1, Last Fridays of year, Enter a year:, , , , , , , , %A_YYYY%
	If ErrorLevel
		ExitApp
}

YYYY = %1% ; retrieve command line parameter
Stmp = %YYYY%0101000000
count= 0

While count < 12
{
	FormatTime, ddd, %stmp%, ddd
	FormatTime, M, %stmp%, M
	If (ddd = "Fri"){
		if (M-1 = count){
			t := stmp
			stmp += 7, days
		}
		else
			 res .= SubStr(t, 1, 4) "-" SubStr(t, 5, 2) "-" SubStr(t, 7, 2) "`n"
			,count++
			,stmp := YYYY . SubStr("0" M, -1) . "01"
	}
	else
		stmp += 1, days
}
MsgBox % res


#include <Date.au3>

$iYear = InputBox('Last Friday in each month', 'Please input the year:')

_GetLastFridays($iYear)

Func _GetLastFridays($_iYear)
	Local $sResult = 'last fridays in ' & $_iYear & @LF, $iDay
	Local $aDaysInMonth[12] = [31,28,31,30,31,30,31,31,30,31,30,31]
	If _DateIsLeapYear($_iYear) Then $aDaysInMonth[1] = 29
	For $i = 1 To 12
		$iDay = $aDaysInMonth[$i-1]
		While 1
			If _DateToDayOfWeekISO($_iYear, $i, $iDay) = 5 Then
				$sResult &= StringFormat('%4d-%02d-%02d', $_iYear, $i, $iDay) & @LF
				ExitLoop
			EndIf
			$iDay -= 1
		WEnd
	Next
	ConsoleWrite($sResult)
EndFunc  ;==>_GetFridays


# syntax: GAWK -f LAST_FRIDAY_OF_EACH_MONTH.AWK year
# converted from Fortran
BEGIN {
    split("31,28,31,30,31,30,31,31,30,31,30,31",daynum_array,",") # days per month in non leap year
    year = ARGV[1]
    if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
      daynum_array[2] = 29
    }
    y = year - 1
    k = 44 + y + int(y/4) + int(6*(y/100)) + int(y/400)
    for (m=1; m<=12; m++) {
      k += daynum_array[m]
      d = daynum_array[m] - (k%7)
      printf("%04d-%02d-%02d\n",year,m,d)
    }
    exit(0)
}


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

namespace RosettaCode.LastFridaysOfYear
{
    internal static class Program
    {
        private static IEnumerable<DateTime> LastFridaysOfYear(int year)
        {
            for (var month = 1; month <= 12; month++)
            {
                var date = new DateTime(year, month, 1).AddMonths(1).AddDays(-1);
                while (date.DayOfWeek != DayOfWeek.Friday)
                {
                    date = date.AddDays(-1);
                }
                yield return date;
            }
        }

        private static void Main(string[] arguments)
        {
            int year;
            var argument = arguments.FirstOrDefault();
            if (string.IsNullOrEmpty(argument) || !int.TryParse(argument, out year))
            {
                year = DateTime.Today.Year;
            }

            foreach (var date in LastFridaysOfYear(year))
            {
                Console.WriteLine(date.ToString("d", CultureInfo.InvariantCulture));
            }
        }
    }
}


#include <boost/date_time/gregorian/gregorian.hpp>
#include <iostream>
#include <cstdlib>

int main( int argc , char* argv[ ] ) {
   using namespace boost::gregorian ;

   greg_month months[ ] = { Jan , Feb , Mar , Apr , May , Jun , Jul ,
      Aug , Sep , Oct , Nov , Dec } ;
   greg_year gy = atoi( argv[ 1 ] ) ;
   for ( int i = 0 ; i < 12 ; i++ ) {
      last_day_of_the_week_in_month lwdm ( Friday , months[ i ] ) ;
      date d = lwdm.get_date( gy ) ;
      std::cout << d << std::endl ;
   }
   return 0 ;
}


(use '[clj-time.core :only [last-day-of-the-month day-of-week minus days]]
     '[clj-time.format :only [unparse formatters]])

(defn last-fridays [year]
  (let [last-days (map #(last-day-of-the-month year %) (range 1 13 1))
        dow (map day-of-week last-days)
        relation (zipmap last-days dow)]
    (map #(minus (key %) (days (mod (+ (val %) 2) 7))) relation)))

(defn last-fridays-formatted [year]
  (sort (map #(unparse (formatters :year-month-day) %) (last-fridays year))))


       program-id. last-fri.
       data division.
       working-storage section.
       1 wk-date.
        2 yr pic 9999.
        2 mo pic 99 value 1.
        2 da pic 99 value 1.
       1 rd-date redefines wk-date pic 9(8).
       1 binary.
        2 int-date pic 9(8).
        2 dow pic 9(4).
        2 friday pic 9(4) value 5.
       procedure division.
           display "Enter a calendar year (1601 thru 9999): "
               with no advancing
           accept yr
           if yr >= 1601 and <= 9999
               continue
           else
               display "Invalid year"
               stop run
           end-if
           perform 12 times
               move 1 to da
               add 1 to mo
               if mo > 12              *> to avoid y10k in 9999
                   move 12 to mo
                   move 31 to da
               end-if
               compute int-date = function
                   integer-of-date (rd-date)
               if mo =12 and da = 31   *> to avoid y10k in 9999
                   continue
               else
                   subtract 1 from int-date
               end-if
               compute rd-date = function
                   date-of-integer (int-date)
               compute dow = function mod
                   ((int-date - 1) 7) + 1
               compute dow = function mod ((dow - friday) 7)
               subtract dow from da
               display yr "-" mo "-" da
               add 1 to mo
           end-perform
           stop run
           .
       end program last-fri.


last_friday_of_month = (year, month) ->
  # month is 1-based, JS API is 0-based, then we use
  # non-positive indexes to work backward relative to the
  # first day of the next month
  i = 0
  while true
    last_day = new Date(year, month, i)
    if last_day.getDay() == 5
      return last_day.toDateString()
    i -= 1

print_last_fridays_of_month = (year) ->
  for month in [1..12]
    console.log last_friday_of_month year, month

do ->
  year = parseInt process.argv[2]
  print_last_fridays_of_month year


(defun friday-before (year month day)
 (let*
  ((timestamp (encode-universal-time 0 0 12 day month year))
   (weekday (nth 6 (multiple-value-list (decode-universal-time timestamp))))
   (fri (- timestamp (* (+ (mod (+ weekday 2) 7) 1) 86400))))
    (multiple-value-bind (_ _ _ d m y) (decode-universal-time fri)
     (list y m d))))

(defun last-fridays (year)
  (append (loop for month from 2 to 12 collecting (friday-before year month 1))
          (list (friday-before (1+ year) 1 1))))

(let* ((year (read-from-string (car *args*))))
  (format t "~{~{~a-~2,'0d-~2,'0d~}~%~}" (last-fridays year)))


import std.stdio, std.datetime, std.traits;

void lastFridays(in uint year) {
    auto date = Date(year, 1, 1);
    foreach (_; [EnumMembers!Month]) {
        date.day(date.daysInMonth);
        date.roll!"days"(-(date.dayOfWeek + 2) % 7);
        writeln(date);
        date.add!"months"(1, AllowDayOverflow.no);
    }
}

void main() {
    lastFridays(2012);
}


program LastFridayOfMonth;

{$APPTYPE CONSOLE}

uses
  System.SysUtils, System.DateUtils;

var
  Year: Word;
  Month: Word;
  D1: TDateTime;
  D2: Word;

begin
  Write('Enter year: ');
  ReadLn(Year);

  for Month := MonthJanuary to MonthDecember do begin
    D1 := EndOfAMonth(Year, Month);
    D2 := DayOfTheWeek(D1);
    while D2 <> DayFriday do begin
      D1 := IncDay(D1, -1);
      D2 := DayOfTheWeek(D1);
    end;
    WriteLn(DateToStr(D1));
  end;
end.


defmodule RC do
  def lastFriday(year) do
    Enum.map(1..12, fn month ->
      lastday = :calendar.last_day_of_the_month(year, month)
      daynum = :calendar.day_of_the_week(year, month, lastday)
      friday = lastday - rem(daynum + 2, 7)
      {year, month, friday}
    end)
  end
end

y = String.to_integer(hd(System.argv))
Enum.each(RC.lastFriday(y), fn {year, month, day} ->
  :io.format "~4b-~2..0w-~2..0w~n", [year, month, day]
end)


import Html exposing (Html, Attribute, text, div, input)
import Html.App exposing (beginnerProgram)
import Html.Attributes exposing (placeholder, value, style)
import Html.Events exposing (onInput)
import String exposing (toInt)
import Maybe exposing (withDefault)
import List exposing (map, map2)
import List.Extra exposing (scanl1)

type Msg = SetYear String

lastFridays : Int -> List Int
lastFridays year =
  let isLeap = (year % 400) == 0 || ( (year % 4) == 0 && (year % 100) /= 0 )
      daysInMonth = [31, if isLeap then 29 else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
      y = year-1
  in scanl1 (+) daysInMonth
     |> map2 (\len day -> len - (day + 2 + y + y//4 - y//100 + y//400) % 7) daysInMonth

lastFridayStrings : String -> List String
lastFridayStrings yearString =
  let months= ["January ", "February ", "March ", "April ", "May ", "June ", "July ", "August ", "September ", "October ", "November ", "December "]
      errString = "Only years after 1752 are valid."
  in case toInt yearString of
       Ok year ->
           if (year < 1753)
           then [errString]
           else lastFridays year
                |> map2 (\m d -> m ++ toString d ++ ", " ++ toString year) months
       Err _ ->
           [errString]

view :  String -> Html Msg
view yearString =
  div []
    ([ input
        [ placeholder "Enter a year."
        , value yearString
        , onInput SetYear
        , myStyle
        ]
        []
     ] ++ (lastFridayStrings yearString
           |> map (\date -> div [ myStyle ] [ text date ]) ))

myStyle : Attribute Msg
myStyle =
  style
    [ ("width", "100%")
    , ("height", "20px")
    , ("padding", "5px 0 0 5px")
    , ("font-size", "1em")
    , ("text-align", "left")
    ]

update : Msg -> String -> String
update msg _ =
    case msg of
        SetYear yearString -> yearString

main =
    beginnerProgram
        { model = ""
        , view = view
        , update = update
        }


(require 'calendar)

(defun last-friday (year)
  "Print the last Friday in each month of year"
  (mapcar (lambda (month)
    (let*
      ((days (number-sequence 1 (calendar-last-day-of-month month year)))
       (mdy (mapcar (lambda (x) (list month x year)) days))
       (weekdays (mapcar #'calendar-day-of-week mdy))
       (lastfriday (1+ (cl-position 5 weekdays :from-end t))))
      (insert (format "%i-%02i-%02i \n" year month lastfriday))))
    (number-sequence 1 12)))

(last-friday 2012)


-module( last_date_each_month ).

-export( [monday/1, tuesday/1, wednesday/1, thursday/1, friday/1, saturday/1, sunday/1] ).

monday( Year ) -> last( Year, 1 ).
tuesday( Year ) -> last( Year, 2 ).
wednesday( Year ) -> last( Year, 3 ).
thursday( Year ) -> last( Year, 4 ).
friday( Year ) -> last( Year, 5 ).
saturday( Year ) -> last( Year, 6 ).
sunday( Year ) -> last( Year, 7 ).

last( Year, Week_day ) ->
    Months = lists:seq( 1, 12 ),
    Months_days = [{X, Y} || X <- Months, Y <- lists:seq(calendar:last_day_of_the_month(Year, X), calendar:last_day_of_the_month(Year, X) - 7, -1), calendar:valid_date(Year, X, Y), calendar:day_of_the_week(Year, X, Y) =:= Week_day],
    [{Year, X, proplists:get_value(X, Months_days)} || X <- Months].


USING: calendar calendar.format command-line io kernel math.parser sequences ;
IN: rosetta-code.last-fridays

(command-line) second string>number <year> 12 <iota>
[ months time+ last-friday-of-month ] with map
[ timestamp>ymd print ] each


' version 23-06-2015
' compile with: fbc -s console

#Ifndef TRUE        ' define true and false for older freebasic versions
    #Define FALSE 0
    #Define TRUE Not FALSE
#EndIf

Function leapyear(Year_ As Integer) As Integer
    ' from the leapyear entry
    If (Year_ Mod 4) <> 0 Then Return FALSE
    If (Year_ Mod 100) = 0 AndAlso (Year_ Mod 400) <> 0 Then Return FALSE
    Return TRUE

End Function

Function wd(m As Integer, d As Integer, y As Integer) As Integer
    ' Zellerish
    ' 0 = Sunday, 1 = Monday, 2 = Tuesday, 3 = Wednesday
    ' 4 = Thursday, 5 = Friday, 6 = Saturday

    If m < 3 Then        ' If m = 1 Or m = 2 Then
        m += 12
        y -= 1
    End If
    Return (y + (y \ 4) - (y \ 100) + (y \ 400) + d + ((153 * m + 8) \ 5)) Mod 7
End Function

' ------=< MAIN >=------

Type month_days
    m_name As String
    days As UByte
End Type

Dim As month_days arr(1 To 12)
Data "January",   31, "February", 28, "March",    31, "April",    30
Data "May",       31, "June",     30, "July",     31, "August",   31
Data "September", 30, "October",  31, "November", 30, "December", 31

Dim As Integer yr, d, i, x
Dim As String keypress

For i = 1 To 12
    With arr(i)
        Read .m_name
        Read .days
    End With
Next

Do

    Do
        Print "For what year do you want to find the last Friday of the month"
        Input "any number below 1800 stops program, year in YYYY format";yr
        ' empty input also stops
        If yr < 1800 Then
            End
        Else
            Exit Do
        End If
    Loop

    Print : Print
    Print "Last Friday of the month for"; yr

    For i = 1 To 12
        d = arr(i).days
        If i = 2 AndAlso leapyear(yr) = TRUE Then d = d + 1
        x = wd(i, d, yr)
        If x <> 5 Then d = d - IIf(x > 5, x - 5, x + 2)
        Print d; " "; arr(i).m_name
    Next

    ' empty key buffer
    While InKey <> "" : keypress = InKey : Wend
    Print : Print
    Print "Find last Friday for a other year [Y|y], anything else stops"
    keypress =""
    While keypress = "" : keypress = InKey : Wend
    If LCase(keypress) <> "y" Then Exit Do
    Print : Print

Loop
End


d = parseDate[[email protected]]
for m = 1 to 12
{
   d = beginningOfNextMonth[d]
   n = d - (((parseInt[d -> ### u ###] + 1) mod 7) + 1) days
   println[n -> ### yyyy-MM-dd ###]
}


Public Sub Form_Open()
Dim siYear As Short = InputBox("Please input a year", "Last Friday of each month")
Dim siMonth, siDay As Short
Dim dDay As Date

For siMonth = 1 To 12
  For siDay = 31 DownTo 22
    Try dDay = Date(siYear, siMonth, siDay)
    If Error Then Continue
    If WeekDay(dDay) = 5 Then
      Print Format(dDay, "yyyy-mm-dd");;
      Print Space(6) & Format(dDay, "dddd dd mmmm yyyy")
      Break
    End If
  Next
Next

Me.Close

End


package main

import (
	"fmt"
	"os"
	"strconv"
	"time"
)

func main() {
	y := time.Now().Year()
	if len(os.Args) == 2 {
		if i, err := strconv.Atoi(os.Args[1]); err == nil {
			y = i
		}
	}
	for m := time.January; m <= time.December; m++ {
		d := time.Date(y, m+1, 1, 0, 0, 0, 0, time.UTC).Add(-24 * time.Hour)
		d = d.Add(-time.Duration((d.Weekday()+7-time.Friday)%7) * 24 * time.Hour)
		fmt.Println(d.Format("2006-01-02"))
	}
}


def ymd = { it.format('yyyy-MM-dd') }
def lastFridays = lastWeekDays.curry(Day.Fri)
lastFridays(args[0] as int).each { println (ymd(it)) }


import Data.Time.Calendar
       (Day, addDays, showGregorian, fromGregorian, gregorianMonthLength)
import Data.Time.Calendar.WeekDate (toWeekDate)
import Data.List (transpose, intercalate)

-- [1 .. 7] for [Mon .. Sun]
findWeekDay :: Int -> Day -> Day
findWeekDay dayOfWeek date =
  head
    (filter
       (\x ->
           let (_, _, day) = toWeekDate x
           in day == dayOfWeek)
       ((`addDays` date) <$> [-6 .. 0]))

weekDayDates :: Int -> Integer -> [String]
weekDayDates dayOfWeek year =
  ((showGregorian . findWeekDay dayOfWeek) .
   (fromGregorian year <*> gregorianMonthLength year)) <$>
  [1 .. 12]

main :: IO ()
main =
  mapM_
    putStrLn
    (intercalate "  " <$> transpose (weekDayDates 5 <$> [2012 .. 2017]))


procedure main(A)
every write(lastfridays(!A))
end

procedure lastfridays(year)
every m := 1 to 12 do {
   d := case m of {
      2        : if IsLeapYear(year) then 29 else 28
      4|6|9|11 : 30
      default  : 31
      }                          # last day of month

   z := 0
   j := julian(m,d,year) + 1     # first day of next month
   until (j-:=1)%7 = 4 do z -:=1 # backup to last friday=4
   suspend sprintf("%d-%d-%d",year,m,d+z)
   }
end

link datetime, printf


require 'dates'
last_fridays=: 12 {. [: ({:/.~ }:"1)@(#~ 5 = weekday)@todate (i.366) + [email protected],&1 1


import java.text.*;
import java.util.*;

public class LastFridays {

    public static void main(String[] args) throws Exception {
        int year = Integer.parseInt(args[0]);
        GregorianCalendar c = new GregorianCalendar(year, 0, 1);

        for (String mon : new DateFormatSymbols(Locale.US).getShortMonths()) {
            if (!mon.isEmpty()) {
                int totalDaysOfMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);
                c.set(Calendar.DAY_OF_MONTH, totalDaysOfMonth);

                int daysToRollBack = (c.get(Calendar.DAY_OF_WEEK) + 1) % 7;

                int day = totalDaysOfMonth - daysToRollBack;
                c.set(Calendar.DAY_OF_MONTH, day);

                System.out.printf("%d %s %d\n", year, mon, day);

                c.set(year, c.get(Calendar.MONTH) + 1, 1);
            }
        }
    }
}


var last_friday_of_month, print_last_fridays_of_month;

last_friday_of_month = function(year, month) {
  var i, last_day;
  i = 0;
  while (true) {
    last_day = new Date(year, month, i);
    if (last_day.getDay() === 5) {
      return last_day.toDateString();
    }
    i -= 1;
  }
};

print_last_fridays_of_month = function(year) {
  var month, results;
  results = [];
  for (month = 1; month <= 12; ++month) {
    results.push(console.log(last_friday_of_month(year, month)));
  }
  return results;
};

(function() {
  var year;
  year = parseInt(process.argv[2]);
  return print_last_fridays_of_month(year);
})();


# In case your jq does not have "until" defined:

def until(cond; next):
  def _until:
    if cond then . else (next|_until) end;
  _until;

# Zeller's Congruence is from [[Day_of_the_week#jq]]

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


using Dates

const wday = Dates.Fri
const lo = 1
const hi = 12

print("\nThis script will print the last ", Dates.dayname(wday))
println("s of each month of the year given.")
println("(Leave input empty to quit.)")

while true
    print("\nYear> ")
    y = chomp(readline())
    0 < length(y) || break
    y = try
        parseint(y)
    catch
        println("Sorry, but \"", y, "\" does not compute as a year.")
        continue
    end
    println()
    for m in Date(y, lo):Month(1):Date(y, hi)
        println("    ", tolast(m, wday))
    end
end


// version 1.0.6

import java.util.*

fun main(args: Array<String>) {
    print("Enter a year : ")
    val year = readLine()!!.toInt()

    println("The last Fridays of each month in $year are as follows:")
    val calendar = GregorianCalendar(year, 0, 31)
    for (month in 1..12) {
        val daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
        var offset = calendar[Calendar.DAY_OF_WEEK] - Calendar.FRIDAY
        if (offset < 0) offset += 7
        val lastFriday = daysInMonth - offset
        println("$year-" + "%02d-".format(month) + "%02d".format(lastFriday))
        if (month < 12) {
            calendar.add(Calendar.DAY_OF_MONTH, 1)
            calendar.add(Calendar.MONTH, 1)
            calendar.add(Calendar.DAY_OF_MONTH, -1)
        }
    }
}


define isLeapYear(y::integer) => {
	#y % 400 == 0 ? return true
	#y % 100 == 0 ? return false
	#y % 4 == 0 ? return true
	return false
}
define fridays(y::integer) => {
	local(out = array)
	loop(12) => {
		local(last = 28)
		loop_count == 2 && isLeapYear(#y) ? #last = 29
		array(4,6,9,11) >> loop_count ? #last == 30
		#last == 28 && loop_count != 2 ? #last = 31
		local(start = date(-year=#y,-month=loop_count,-day=#last))
		while(#start->dayofweek != 6) => {
			#start->subtract(-day=1)
		}
		#out->insert(#start)
	}
	return #out
}
with f in fridays(2012) do => {^
	#f->format('%Q') + '\r'
^}


function lastFriday yyyy
    -- year,month num,day of month,hour in 24-hour time,minute,second,numeric day of week.
    convert the long date to dateitems
    put 1 into item 2 of it
    put 1 into item 3 of it
    put yyyy into item 1 of it
    put it into startDate
    convert startDate to dateItems
    repeat with m = 1 to 12
        put m into item 2 of startDate
        repeat with d = 20 to 31
            put d into item 3 of startDate
            convert startDate to dateItems
            -- 6 is friday
            if item 7 of startDate is 6 and item 1 of startDate is yyyy and item 2 of startDate is m then
                put item 3 of startDate into fridays[item 2 of startDate]
            end if
        end repeat
    end repeat
    combine fridays using cr and space
    sort fridays ascending numeric
    return fridays
end lastFriday


; Determine if a Gregorian calendar year is leap
to leap? :year
  output (and
    equal? 0 modulo :year 4
    not member? modulo :year 400 [100 200 300]
  )
end

; Convert Gregorian calendar date to a simple day count from
; RD 1 = January 1, 1 CE
to day_number :year :month :day
  local "elapsed make "elapsed difference :year 1
  output (sum  product 365 :elapsed
              int quotient :elapsed 4
              minus int quotient :elapsed 100
              int quotient :elapsed 400
              int quotient difference product 367 :month 362 12
              ifelse lessequal? :month 2 0 ifelse leap? :year -1 -2
              :day)
end

; Find the day of the week from a day number, 0 = Sunday through 6 = Saturday
to day_of_week :day_number
  output modulo :day_number 7
end

; Find the date of the last Friday of a given month
to last_friday :year :month
  local "zero make "zero day_number :year :month 0
  local "last make "last day_number :year sum 1 :month 0
  local "wday make "wday day_of_week :last
  local "friday make "friday sum :last remainder difference -2 :wday 7
  output difference :friday :zero
end

local "year
make "year ifelse empty? :command.line 2012 :command.line

repeat 12 [
  local "month make "month #
  local "day make "day last_friday :year :month
  if (less? :month 10) [make "month word "0 :month]
  print reduce [(word ?1 "- ?2)] (list :year :month :day)
]
bye


function isLeapYear (y)
    return (y % 4 == 0 and y % 100 ~=0) or y % 400 == 0
end

function dayOfWeek (y, m, d)
    local t = os.time({year = y, month = m, day = d})
    return os.date("%A", t)
end

function lastWeekdays (wday, year)
    local monthLength, day = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    if isLeapYear(year) then monthLength[2] = 29 end
    for month = 1, 12 do
        day = monthLength[month]
        while dayOfWeek(year, month, day) ~= wday do day = day - 1 end
        print(year .. "-" .. month .. "-" .. day)
    end
end

lastWeekdays("Friday", tonumber(arg[1]))


fridays := proc(year)
	local i, dt, change, last_days;
	last_days := [31,28,31,30,31,30,31,31,30,31,30,31];
	if (Calendar:-IsLeapYear(year)) then
		last_days[2] := 28;
	end if;
	for i to 12 do
		dt := Date(year, i, last_days[i]);
		change := 0;
		if not(Calendar:-DayOfWeek(dt) = 6) then
			change := -(Calendar:-DayOfWeek(dt) mod 7)-1;
		end if;
		dt := Calendar:-AdjustDateField(dt, "date", change);
		printf("%d-%d-%d\n", year, Month(dt), DayOfMonth(dt));
	end do;
end proc;

fridays(2012);


FridaysOfYear[Y_] :=
 NestWhile[(DaysPlus[#, - 1]) &, #, (DateString[#, "DayName"] != "Friday") &] & /@
  [email protected]@NestList [DaysPlus[# /. {x_, y_, X_} -> {x, y, 1}, - 1] &, {Y + 1, 1, 1}, 12]
[email protected][2012]


 function t = last_fridays_of_year(y)
  t1 = datenum([y,1,1,0,0,0]);
  t2 = datenum([y,12,31,0,0,0]);
  t  = datevec(t1:t2);
  t  = t(strmatch('Friday', datestr(t,'dddd')), :);     % find all Fridays
  t  = t([find(diff(t(:,2)) > 0); end], :);     % find Fridays before change of month
  end;

  datestr(last_fridays_of_year(2012),'yyyy-mm-dd')


import Nanoquery.Util

// a function to check if a year is a leap year
def isLeapYear(year)
	if (year % 100 = 0)
		return (year % 400 = 0)
	else
		return (year % 4 = 0)
	end
end

// a function to format 1-digit numbers as "0x"
def form(num)
	if (num > 9)
		return str(num)
	else
		return "0" + str(num)
	end
end

// get a year from the console
print "enter year: "
year = int(input())

// build a list of the expected amount of days for each month
days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
if isLeapYear($year)
	days[1] = 29
end

// loop through each month
for month in range(1, len($days))
	// loop through each day of the month
	friday = null
	for day in range(1, days[month - 1])
		// create a date object for this date
		date = new(Date)
		date.setYear(year).setMonth(month).setDay(day)

		// check if it's a friday
		if (date.getDayOfWeek() = "Friday")
			// if it is, keep it
			friday = new(Date, date)
		end
	end for

	// display the last friday found
	print   friday.getYear() + "-"
	print   form(friday.getMonth()) + "-"
	println form(friday.getDay())
end


/* NetRexx */
options replace format comments java crossref symbols nobinary

import java.text.

runSample(arg)
return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method lastFridayByLib(year) public static

  cal = GregorianCalendar(year, 0, 1)

  loop mon over DateFormatSymbols().getShortMonths()
    if \mon.isEmpty() then do
      totalDaysOfMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH)
      cal.set(Calendar.DAY_OF_MONTH, totalDaysOfMonth)

      daysToRollBack = (cal.get(Calendar.DAY_OF_WEEK) + 1) // 7

      day = totalDaysOfMonth - daysToRollBack
      cal.set(Calendar.DAY_OF_MONTH, day)

      say year.right(4, 0) mon day.right(2, 0)

      cal.set(year, cal.get(Calendar.MONTH) + 1, 1)
      end
    end mon
  return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method lastFridayCalc(year) public static binary signals BadArgumentException

  if year <= 1700 then do
    signal BadArgumentException(year 'is out of range')
    end

  wk  = int
  mth = int
  yr  = int year
  days = [int 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]  -- days in month
  days[1] = days[1] - ((yr // 4) | \(yr // 100) & (yr // 400)) -- adjust for leap year

  wk = yr * 365 + (yr - 1) % 4 - (yr - 1) % 100 + (yr - 1) % 400 + 6 -- week number

  loop mth = 0 to 11
    wk = (wk + days[mth]) // 7
    wx = int
    if wk < 5 then wx = -2
              else wx = 5
    yy = Rexx(yr)
    mm = Rexx(mth + 1)
    dd = Rexx(days[mth] + wx - wk)
    say yy.right(4, 0)'-'mm.right(2, 0)'-'dd.right(2, 0)
    end mth
  return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(arg) private static
  do
    parse arg year .
    if year = '' | year = '.' then year = 2012
    dlm = '-'
    dlm = dlm.left(60, dlm)
    say
    say 'Using Java calendar libraries'
    say dlm
    lastFridayByLib(year)
    say
    say 'Calculated'
    say dlm
    lastFridayCalc(year)
  catch ex = Exception
    ex.printStackTrace
  end
  return


import os, strutils, times

const
  DaysInMonth: array[Month, int] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  DayDiffs:  array[WeekDay, int] = [3, 4, 5, 6, 0, 1, 2]

let year = paramStr(1).parseInt

for month in mJan..mDec:
  var lastDay = DaysInMonth[month]
  if month == mFeb and year.isLeapYear: lastDay = 29
  var date = initDateTime(lastDay, month, year, 0, 0, 0)
  date = date - days(DayDiffs[date.weekday])
  echo date.format("yyyy-MM-dd")


#load "unix.cma"
open Unix

let usage() =
  Printf.eprintf "%s <year>\n" Sys.argv.(0);
  exit 1

let print_date t =
  Printf.printf "%d-%02d-%02d\n" (t.tm_year + 1900) (t.tm_mon + 1) t.tm_mday

let is_date_ok tm t =
  (tm.tm_year = t.tm_year &&
   tm.tm_mon  = t.tm_mon  &&
   tm.tm_mday = t.tm_mday)

let () =
  let _year =
    try int_of_string Sys.argv.(1)
    with _ -> usage()
  in
  let year = _year - 1900 in
  let fridays = Array.make 12 (Unix.gmtime 0.0) in
  for month = 0 to 11 do
    for day_of_month = 1 to 31 do
      let tm = { (Unix.gmtime 0.0) with
        tm_year = year;
        tm_mon = month;
        tm_mday = day_of_month;
      } in
      let _, t = Unix.mktime tm in
      if is_date_ok tm t  (* check for months that have less than 31 days *)
      && t.tm_wday = 5  (* is a friday *)
      then fridays.(month) <- t
    done;
  done;
  Array.iter print_date fridays


import: date

: lastFridays(y)
| m |
   Date.JANUARY Date.DECEMBER for: m [
      Date newDate(y, m, Date.DaysInMonth(y, m))
      while(dup dayOfWeek Date.FRIDAY <>) [ addDays(-1) ]
      println
      ] ;


program LastFriday;

{$mode objfpc}{$H+}

uses
   SysUtils;

type
  weekdays = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);

var
   m, d, y : integer;

function IsLeapYear(Year : integer) : boolean;
begin
    if Year mod 4 <> 0  { quick exit in most likely case }
        then IsLeapYear := false
    else if Year mod 400 = 0
        then IsLeapYear := true
    else if Year mod 100 = 0
        then IsLeapYear := false
    else { non-century year and divisible by 4 }
        IsLeapYear := true;
end;

function DaysInMonth(Month, Year : integer) : integer;
const
    LastDay : array[1..12] of integer =
        (31,28,31,30,31,30,31,31,30,31,30,31);
begin
    if (Month = 2) and (IsLeapYear(Year)) then
        DaysInMonth := 29
    else
        DaysInMonth := LastDay[Month];
end;

{ return day of week (Sun = 0, Mon = 1, etc.) for a }
{ given mo, da, and yr using Zeller's congruence    }
function DayOfWeek(mo, da, yr : integer) : weekdays;
var
    y, c, z : integer;
begin
    if mo < 3 then
        begin
            mo := mo + 10;
            yr := yr - 1
        end
    else mo := mo - 2;
    y := yr mod 100;
    c := yr div 100;
    z := (26 * mo - 2) div 10;
    z := z + da + y + (y div 4) + (c div 4) - 2 * c + 777;
    DayOfWeek := weekdays(z mod 7);
end;

{ return the calendar day of the last occurrence of the }
{ specified weekday in the given month and year         }
function LastWeekday(k : weekdays; m, y : integer) : integer;
var
  d : integer;
  w : weekdays;
begin
  { determine weekday for the last day of the month }
  d := DaysInMonth(m, y);
  w := DayOfWeek(m, d, y);
  { back up as needed to desired weekday }
  if w >= k then
    LastWeekday := d - (ord(w) - ord(k))
  else
    LastWeekday := d - (7 - ord(k)) - ord(w);
end;

begin { main program }
  write('Find last Fridays in what year? ');
  readln(y);
  writeln;
  writeln('Month  Last Fri');
  for m := 1 to 12 do
    begin
      d  := LastWeekday(Fri, m, y);
      writeln(m:5,'   ',d:5);
    end;
end.


#!/usr/bin/perl -w
use strict ;
use DateTime ;
use feature qw( say ) ;

foreach my $month ( 1..12 ) {
   my $dt = DateTime->last_day_of_month( year => $ARGV[ 0 ] , month => $month ) ;
   while ( $dt->day_of_week != 5 ) {
      $dt->subtract( days => 1 ) ;
   }
   say $dt->ymd ;
}


with javascript_semantics
procedure last_day_of_month(integer y, dow)
    for m=1 to 12 do
        integer d = days_in_month(y,m),
                a = dow-day_of_week(y,m,d)
        printf(1,"%4d-%02d-%02d\n",{y,m,d+a-7*(a>0)})
    end for
end procedure
constant FRIDAY=5
--prompt_number() is not compatible with pwa/p2js
--last_day_of_month(prompt_number("Year:",{1752,9999}),FRIDAY)
last_day_of_month(2012,FRIDAY)


<?php
function last_friday_of_month($year, $month) {
  $day = 0;
  while(True) {
    $last_day = mktime(0, 0, 0, $month+1, $day, $year);
    if (date("w", $last_day) == 5) {
      return date("Y-m-d", $last_day);
    }
    $day -= 1;
  }
}

function print_last_fridays_of_month($year) {
  foreach(range(1, 12) as $month) {
    echo last_friday_of_month($year, $month), "<br>";
  }
}

date_default_timezone_set("GMT");
$year = 2012;
print_last_fridays_of_month($year);
?>


% for command line argument
main(ARGV) =>
  if ARGV.length > 0 then
    Year = ARGV[1].to_integer(),
    show_year(Year),
    nl
  end.

% Without command line argument
main => go.

go =>
  show_year(2022),
  nl.

% Show the months
show_year(Year) =>
  foreach(Date in get_months(Year))
    println(format_date(Date))
  end,
  nl.

% Format date to YYYY-DD-MM
format_date(Date) = to_fstring("%4d-%02d-%02d",Date[1],Date[2],Date[3]).

% Return the last Fridays of each month for year Year
get_months(Year) =
  [ [ [Year,Month,Day] : Day in 1..max_days_in_month(Year,Month),
                         dow(Year, Month, Day) == 5].last() : Month in 1..12].

% Day of week, Sakamoto's method
dow(Y, M, D) = R =>
  T = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4],
  if M < 3 then
     Y := Y - 1
  end,
  R = (Y + Y // 4 - Y // 100 + Y // 400 + T[M] + D) mod 7.

% Maximum days in month
max_days_in_month(Year,Month) = Days =>
  if member(Month, [1,3,5,7,8,10,12]) then
    Days = 31
  elseif member(Month,[4,6,9,11]) then
    Days = 30
  else
    if leap_year(Year) then
     Days = 29
   else
     Days = 28
   end
  end.

% Is Year a leap year?
leap_year(Year) =>
  (Year mod 4 == 0, Year mod 100 != 0)
  ;
  Year mod 400 == 0.


(de lastFridays (Y)
   (for M 12
      (prinl
         (dat$
            (find '((D) (= "Friday" (day D)))
               (mapcar '((D) (date Y M D)) `(range 31 22)) )
            "-" ) ) ) )


int(0..1) last_friday(object day)
{
   return day->week_day() == 5 &&
          day->month_day() > day->month()->number_of_days()-7;
}

int main(int argc, array argv)
{
    array days = filter(Calendar.Year((int)argv[1])->months()->days()[*], last_friday);
    write("%{%s\n%}", days->format_ymd());
    return 0;
}


Fridays: procedure (year) options (main); /* 8 January 2013 */
   declare year character (4) varying;
   declare start fixed binary (31);
   declare months fixed decimal (2) initial (0);
   declare (current_month, month_one_week_hence) character (2);

   put list ('Last Fridays in each month for the year ' || year || ':' );
   start = days('0101' || year, 'DDMMYYYY');
   /* Find first Friday */
   do while (weekday(start) ^= 6); start = start + 1; end;

   do until (months=12);
      current_month = substr (daystodate(start, 'MMDDYYYY'), 1, 2 );
      month_one_week_hence = substr (daystodate(start+7, 'MMDDYYYY'), 1, 2 );
      if current_month ^= month_one_week_hence then
         do;
            months = months + 1;
            put skip list (daystodate(start, 'DDMmmYYYY'));
         end;
      start = start + 7;
   end;
end Fridays;


function last-dayofweek {
    param(
     [Int][ValidatePattern("[1-9][0-9][0-9][0-9]")]$year,
     [String][validateset('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday')]$dayofweek
    )
    $date = (Get-Date -Year $year -Month 1 -Day 1)
    while($date.DayOfWeek -ne $dayofweek) {$date = $date.AddDays(1)}
    while($date.year -eq $year) {
        if($date.Month -ne $date.AddDays(7).Month) {$date.ToString("yyyy-dd-MM")}
        $date = $date.AddDays(7)
    }
}
last-dayofweek 2012 "Friday"


Procedure LastFridayOfEachMonth(yyyy.i,List lfem.i())
  Define dv.i=ParseDate("%yyyy",Str(yyyy)), mv.i=1
  NewList d.i()
  For d=1 To 365
    dv=AddDate(dv,#PB_Date_Day,1)
    If DayOfWeek(dv)=5
      AddElement(d()) : d()=dv
    EndIf
  Next
  dv=0
  For mv=1 To 12
    ForEach d()
      If dv<d() And Month(d())=mv
        dv=d()
      EndIf
    Next
    AddElement(lfem()) : lfem()=dv
  Next
EndProcedure

NewList lf.i()
Define y.i
OpenConsole("Last Friday of each month")
Print("Input Year [ 1971 < y < 2038 ]: ")
y=Val(Input())
If y>1971 And y<2038
  PrintN("Last Friday of each month...")
  LastFridayOfEachMonth(y,lf())
  ForEach lf()
    PrintN(FormatDate("%dd.%mm.%yyyy",lf()))
  Next
EndIf
Print("...End")
Input()


import calendar

def last_fridays(year):
    for month in range(1, 13):
        last_friday = max(week[calendar.FRIDAY]
            for week in calendar.monthcalendar(year, month))
        print('{:4d}-{:02d}-{:02d}'.format(year, month, last_friday))


  [ over 3 < if [ 1 - ]
    dup 4 / over +
    over 100 / -
    swap 400 / +
    swap 1 -
    [ table
      0 3 2 5 0 3
      5 1 4 6 2 4 ]
    + + 7 mod ]                     is dayofweek  ( day month year --> weekday )

  [ dup 400 mod 0 = iff
      [ drop true ]  done
    dup 100 mod 0 = iff
      [ drop false ] done
    4 mod 0 = ]                     is leap       (           year --> b       )

  [ swap 1 -
    [ table
      31 [ dup leap 28 + ]
      31 30 31 30 31 31 30
      31 30 31 ]
    do nip ]                        is monthdays  (     month year --> n       )

  [ number$
    2 times
      [ char - join
        over 10 < if
          [ char 0 join ]
        swap number$ join ]
      echo$ ]                       is echoymd    ( day month year -->         )

  [ dip
      [ 2dup monthdays
        dup temp put
        unrot dayofweek ]
    - dup 0 < if [ 7 + ]
    temp take swap - ]              is lastwkday  ( month year wkd --> n       )

  [ temp put
    12 times
      [ i^ 1+ over
        2dup temp share lastwkday
        unrot echoymd cr ]
    drop temp release ]            is lastwkdays  (       year wkd -->        )

  [ 5 lastwkdays ]                 is lastfridays (           year -->        )

  2012 lastfridays


year = commandArgs(T)
d = as.Date(paste0(year, "-01-01"))
fridays = d + seq(by = 7,
    (5 - as.POSIXlt(d)$wday) %% 7,
    364 + (months(d + 30 + 29) == "February"))
message(paste(collapse = "\n", fridays[tapply(
    seq_along(fridays), as.POSIXlt(fridays)$mon, max)]))


#lang racket
(require srfi/19 math)

(define (days-in-month m y)
  (define lengths #(0 31 #f 31 30 31 30 31 31 30 31 30 31))
  (define d (vector-ref lengths m))
  (or d (days-in-feb y)))

(define (leap-year? y)
  (and (divides? 4 y)
       (or (not (divides? 100 y))
           (divides? 400 y))))

(define (days-in-feb y)
  (if (leap-year? y) 29 28))

(define (last-day-in-month m y)
  (make-date 0 0 0 0 (days-in-month m y) m y 0))

(define (week-day date)
  (define days #(sun mon tue wed thu fri sat))
  (vector-ref days (date-week-day date)))

(define (last-fridays y)
  (for/list ([m (in-range 1 13)])
    (prev-friday (last-day-in-month m y))))

(define 24hours (make-time time-duration 0 (* 24 60 60)))

(define (prev-day d)
  (time-utc->date
   (subtract-duration
    (date->time-utc d) 24hours)))

(define (prev-friday d)
  (if (eq? (week-day d) 'fri)
      d
      (prev-friday (prev-day d))))

(for ([d (last-fridays 2012)])
  (displayln (~a (date->string d "~a ~d ~b ~Y"))))


sub MAIN (Int $year = Date.today.year) {
    my @fri;
    for Date.new("$year-01-01") .. Date.new("$year-12-31") {
        @fri[.month] = .Str if .day-of-week == 5;
    }
    .say for @fri[1..12];
}


leap-year?:  function [year] [to-logic attempt [to-date reduce [29 2 year]]]

days-in-feb: function [year] [either leap-year? year [29] [28]]

days-in-month: function [month year] [
    do pick [31 (days-in-feb year) 31 30 31 30 31 31 30 31 30 31] month
]

last-day-of-month: function [month year] [
    to-date reduce [year month  days-in-month month year]
]

last-weekday-of-month: function [weekday month year] [
    d: last-day-of-month month year
    while [d/weekday != weekday] [d/day: d/day - 1]
    d
]

last-friday-of-month: function [month year] [last-weekday-of-month 5 month year]

year: to-integer input
repeat month 12 [print last-friday-of-month month year]


 ╔════════════════════════════════════════════════════════════════════════════════════════════════╗
 ║ lastDOW:  procedure to return the date of the  last day─of─week of any particular month of any ║
 ║           particular year.                                                                     ║
 ║                                                                                ║
 ║ The  day─of─week  must be specified  (it can be in any case, (lower─/mixed─/upper─case)  as an ║
 ║ English name of the spelled day of the week,  with a minimum length that causes no ambiguity.  ║
 ║                                                                                ║
 ║ I.E.:    TU  for Tuesday.    W  for Wednesday,     Sa  for Saturday,     Su  for Sunday ...    ║
 ║                                                                                ║
 ║ The month can be specified as an integer  1 ──► 12                                             ║
 ║    1=January     2=February     3=March     4=April     5=May     6=June    ...   12=December  ║
 ║ or the English  name  of the month,  with a minimum length that causes no ambiguity.           ║
 ║ I.E.:    JA  for January,   AP  for April,   JUN  for June,   JUL  for July,   D  for December.║
 ║ If omitted  [or an asterisk(*)],  the current month is used.                                   ║
 ║                                                                                ║
 ║ The year is specified as an integer or just the last two digits  (two digit years are assumed  ║
 ║ to be in the current century,  and there is no windowing for a two─digit year).  If omitted    ║
 ║ [or an asterisk(*)],  the current year is used.     Years < 100   must be specified with  (at  ║
 ║ least 2)  leading zeroes.                                                                      ║
 ║                                                                                ║
 ║ The method used is:  find the "day number" of the 1st of the next month and then subtract one  ║
 ║ (this gives the "day number" of the last day of the month,  bypassing the leapday mess).  The  ║
 ║ last day─of─week is then obtained straightforwardly,   or  via subtraction.                    ║
 ╚════════════════════════════════════════════════════════════════════════════════════════════════╝


see "What year to calculate (yyyy) : "
give year
see "Last Friday in " + year + " are on :" + nl
month = list(12)
mo = [4,0,0,3,5,1,3,6,2,4,0,2]
mon = [31,28,31,30,31,30,31,31,30,31,30,31]
if year < 2100 leap = year - 1900 else leap = year - 1904 ok
m = ((year-1900)%7) + floor(leap/4) % 7
for n = 1 to 12
    month[n] = (mo[n] + m) % 7
next
for n = 1 to 12
     for i = (mon[n] - 6) to mon[n]
         if year%4 = 0 and n<3
            x = (month[n] + i) % 7 - 1
         else x = (month[n] + i) % 7 ok
         if  n < 10 strn = "0" + string(n) else strn = string(n) ok
         if x = 2 see year + "-" + strn + "-" + string(i) + nl ok
     next
next


require 'date'

def last_friday(year, month)
  # Last day of month: Date.new interprets a negative number as a relative month/day from the end of year/month.
  d = Date.new(year, month, -1)
  d -= (d.wday - 5) % 7  # Subtract days after Friday.
end

year = Integer(ARGV.shift)
(1..12).each {|month| puts last_friday(year, month)}


input "Year:";yr
dayOne$ = "01-01-";yr
n1	= date$(dayOne$)
for i = 1 to 12
  n1  = n1 + 26
  m1$ = left$(date$(n1),2)
  while  m1$ = left$(date$(n1),2) ' find end of month
    n1 = n1 + 1
  wend
  n1 = n1 -1
  while (n1 Mod 7) <> 3 	  ' find Friday
    n1 = n1 - 1
  wend
  print date$(n1)		  ' print last Friday's date
next i


use std::env::args;
use time::{Date, Duration};

fn main() {
    let year = args().nth(1).unwrap().parse::<i32>().unwrap();
    (1..=12)
        .map(|month| Date::try_from_ymd(year + month / 12, ((month % 12) + 1) as u8, 1))
        .filter_map(|date| date.ok())
        .for_each(|date| {
            let days_back =
                Duration::days(((date.weekday().number_from_sunday() as i64) % 7) + 1);
            println!("{}", date - days_back);
        });
}


import java.util.Calendar
import java.text.SimpleDateFormat

object Fridays {

  def lastFridayOfMonth(year:Int, month:Int)={
    val cal=Calendar.getInstance
    cal.set(Calendar.YEAR, year)
    cal.set(Calendar.MONTH, month)
    cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY)
    cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, -1)
    cal.getTime
  }

  def fridaysOfYear(year:Int)=for(month <- 0 to 11) yield lastFridayOfMonth(year, month)

  def main(args:Array[String]){
    val year=args(0).toInt
    val formatter=new SimpleDateFormat("yyyy-MMM-dd")
    fridaysOfYear(year).foreach{date=>
      println(formatter.format(date))
    }
  }
}


$ include "seed7_05.s7i";
  include "time.s7i";
  include "duration.s7i";

const proc: main is func
  local
    var integer: weekday is 1; # 1 for monday, 2 for tuesday, and so on up to 7 for sunday.
    var integer: year is 0;
    var integer: month is 1;
    var time: aDate is time.value;
    var time: selected is time.value;
  begin
    if length(argv(PROGRAM)) <> 2 then
      writeln("usage: lastWeekdayInMonth weekday year");
      writeln("  weekday: 1 for monday, 2 for tuesday, and so on up to 7 for sunday.");
    else
      weekday := integer parse (argv(PROGRAM)[1]);
      year := integer parse (argv(PROGRAM)[2]);
      for month range 1 to 12 do
        aDate := date(year, month, 1);
        while aDate.month = month do
          if dayOfWeek(aDate) = weekday then
            selected := aDate;
          end if;
          aDate +:= 1 . DAYS;
        end while;
        writeln(strDate(selected));
      end for;
    end if;
  end func;


ask "What year?"
put it into year

put !"The last Fridays of each month in [[year]] are:"

set lastDayOfMonth to year & "-01-31" -- start with January 31 of the year

repeat 12 times
	set lastFriday to lastDayOfMonth
	repeat until weekdayName of lastFriday is "Friday"
		subtract a day from lastFriday -- work back to Friday
	end repeat

	put the monthName of lastFriday && ordinalWords of the day of lastFriday

	add a month to lastDayOfMonth -- advance to last day of next month
end repeat


require('DateTime')
var (year=2016) = ARGV.map{.to_i}...

for month (1..12) {
   var dt = %O<DateTime>.last_day_of_month(year => year, month => month)
   while (dt.day_of_week != 5) {
      dt.subtract(days => 1)
   }
   say dt.ymd
}


Pharo Smalltalk

[ :yr | | firstDay firstFriday |
  firstDay := Date year: yr month: 1 day: 1.
  firstFriday := firstDay addDays: (6 - firstDay dayOfWeek).
  (0 to: 53)
    collect: [ :each | firstFriday addDays: (each * 7) ]
    thenSelect: [ :each |
      (((Date daysInMonth: each monthIndex forYear: yr) - each dayOfMonth) <= 6) and: [	each year = yr ] ] ]


SELECT to_char( next_day( last_day( add_months( to_date(
        :yr||'01','yyyymm' ),level-1))-7,'Fri') ,'yyyy-mm-dd Dy') lastfriday
FROM dual
CONNECT BY level <= 12;


import Foundation

func lastFridays(of year: Int) -> [Date] {

	let calendar = Calendar.current
	var dates = [Date]()

	for month in 2...13 {

		let lastDayOfMonth = DateComponents(calendar: calendar,
		                                    year: year,
		                                    month: month,
		                                    day: 0,
		                                    hour: 12)

		let date = calendar.date(from: lastDayOfMonth)!

		let isFriday = calendar.component(.weekday, from: date) == 6

		if isFriday {

			dates.append(calendar.date(from: lastDayOfMonth)!)

		} else {

			let lastWeekofMonth = calendar.ordinality(of: .weekOfMonth,
			                                          in: .month,
			                                          for: date)!

			let lastWithFriday = lastWeekofMonth - (calendar.component(.weekday, from: date) > 6 ? 0 : 1)

			let lastFridayOfMonth = DateComponents(calendar: calendar,
			                                       year: year,
			                                       month: month - 1,
			                                       hour: 12,
			                                       weekday: 6,
			                                       weekOfMonth: lastWithFriday)

			dates.append(calendar.date(from: lastFridayOfMonth)!)
		}
	}
	return dates
}

var dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short

print(lastFridays(of: 2013).map(dateFormatter.string).joined(separator: "\n"))


package require Tcl 8.5
set year [lindex $argv 0]
foreach dm {02/1 03/1 04/1 05/1 06/1 07/1 08/1 09/1 10/1 11/1 12/1 12/32} {
    # The [clock scan] code is unhealthily clever; use it for our own evil purposes
    set t [clock scan "last friday" -base [clock scan $dm/$year -gmt 1] -gmt 1]
    # Print the interesting part
    puts [clock format $t -format "%Y-%m-%d" -gmt 1]
}


$$ MODE TUSCRIPT
year=2012
LOOP month=1,12
 LOOP day=31,22,-1
  dayofweek=DATE (number,day,month,year,nummer)
  IF (dayofweek==5) THEN
  PRINT year,"-",month,"-",day
  EXIT
  ENDIF
 ENDLOOP
ENDLOOP


#!/bin/sh

if [ -z $1 ]; then exit 1; fi

# weed out multiple erros due to bad year
ncal 1 $1 > /dev/null && \
for m in 01 02 03 04 05 06 07 08 09 10 11 12; do
	echo $1-$m-`ncal $m $1 | grep Fr | sed 's/.* \([0-9]\)/\1/'`
done


*!* OOP implementaion
LOCAL lnYear As Integer, oCalc As fricalc
CLEAR
lnYear = VAL(INPUTBOX("Year", "Year"))
oCalc = NEWOBJECT("fricalc")
oCalc.LastFriday(lnYear)

DEFINE CLASS fricalc As Session
DataSession = 2	&& Private

PROCEDURE Init
*!* These date settings are private to this class
SET DATE YMD
SET CENTURY ON
SET MARK TO "-"
ENDPROC

FUNCTION LastFriday(tnYear As Integer) As VOID
LOCAL i As Integer, ldDate As Date
CLEAR
? "Last Fridays in the year " + TRANSFORM(tnYear)
FOR i = 1 TO 12
	ldDate = DATE(tnYear, i, 1)	&& 1st of month
	ldDate = GOMONTH(ldDate, 1) - 1	&& last day of month
	*!* Use the built in function to return the day of the week
	*!* 6 is Friday
	DO WHILE DOW(ldDate) # 6
		ldDate = ldDate - 1
	ENDDO
	? ldDate
ENDFOR
ENDFUNC

ENDDEFINE


import time
import os

fn main() {

    mut year := 0
    mut t := time.now()

    year = os.input("Please select a year: ").int()

    println("Last Fridays of each month of $year")
    println("==================================")

    for i in 1..13 {
        mut j := time.month_days[i-1]
        if i == 2 {
            if time.is_leap_year(year) {
                j = 29
            }
        }
        for {
            t = time.parse('$year-${i:02}-$j 12:30:00')?
            if t.weekday_str() == 'Fri' {
                println("${time.long_months[i-1]}: $j")
                break
            }
            j --
        }
    }
}


import "os" for Process
import "/date" for Date

var args = Process.arguments
if (args.count != 1) {
    Fiber.abort("Please pass just the year to be processed.")
}

var year = Num.fromString(args[0])
System.print("The dates of the last Fridays in the month for %(year) are:")
Date.default = Date.isoDate
for (m in 1..12) {
    var d = Date.monthLength(year, m)
    var dt = Date.new(year, m, d)
    var wd = dt.dayOfWeek
    if (wd == 5) {
        System.print(dt)
    } else if (wd > 5) {
        System.print(dt.addDays(-wd + 5))
    } else {
        System.print(dt.addDays(-wd - 2))
    }
}


include c:\cxpl\codes; \intrinsic 'code' declarations

func WeekDay(Year, Month, Day);   \Return day of week (0=Sun, 1=Mon ... 6=Sat)
int  Year, Month, Day;            \works for years from 1583 onward
[if Month<=2 then [Month:= Month+12;  Year:= Year-1];
return rem((Day-1 + (Month+1)*26/10 + Year + Year/4 + Year/100*6 + Year/400)/7);
];

int Year, Month, LastDay, WD;
[Year:= IntIn(8);               \from command line
for Month:= 1 to 12 do
    [LastDay:= WeekDay(Year, Month+1, 1) - WeekDay(Year, Month, 28);
    if LastDay < 0 then LastDay:= LastDay + 7;
    LastDay:= LastDay + 27;     \ = number of days in Month
    WD:= WeekDay(Year, Month, LastDay);
    WD:= WD - 5;
    if WD < 0 then WD:= WD + 7;
    LastDay:= LastDay - WD;
    IntOut(0, Year);  ChOut(0, ^-);
    if Month < 10 then ChOut(0, ^0);  IntOut(0, Month);  ChOut(0, ^-);
    IntOut(0, LastDay);  CrLf(0);
    ];
]


var [const] D=Time.Date;
fcn lastDay(y,d){
   [1..12].pump(List,'wrap(m){  // 12 months, closure for y & d
      [D.daysInMonth(y,m)..1,-1].pump(Void,'wrap(_d){  // work backwards
         D.weekDay(y,m,_d) :
         if (_==d) return(Void.Stop,D.toYMDString(y,m,_d))
      })
   })
}
lastDay(2012,D.Friday).concat("\n").println();


F check_dec(num)
   Set[Int] st
   L(c) String(num)
      V d = Int(c)
      I d == 0 | num % d != 0 | d C st
         R 0B
      st.add(d)
   R 1B

L(i) (98764321 .< 0).step(-1)
   I check_dec(i)
      print(i)
      L.break


*        Largest number divisible by its digits - base10 - 05/05/2020
LANUDIDO CSECT
         USING  LANUDIDO,R13       base register
         B      72(R15)            skip savearea
         DC     17F'0'             savearea
         SAVE   (14,12)            save previous context
         ST     R13,4(R15)         link backward
         ST     R15,8(R13)         link forward
         LR     R13,R15            set addressability
         L      R6,KM              i=km
       DO WHILE=(C,R6,GE,=F'1')    do i=km to 1 by -ks
         CVD    R6,DBLI              binary to packed decimal
         MVC    CI,MAK               load mask for edit
         EDMK   CI,DBLI+2            ci=cstr(i)
         S      R1,=A(CI)            number of blanks
         LA     R2,L'CI              length(ci)
         SR     R2,R1                length of the number
         ST     R2,LCI               lci=length(ci)
         MVC    CIL,=CL12' '         cil=' '
         LA     R4,CI                @ci
         AR     R4,R1                @ci[k]
         LA     R3,CIL               @cil
         LR     R5,R2                length(ci)
         BCTR   R5,0                 ~
         EX     R5,MVCR3R4           cil=ltrim(ci)
         LA     R8,CIL               @ci
         LA     R7,1                 j=1
       DO WHILE=(C,R7,LE,LCI)        do j=1 to length(ci)
         CLI    0(R8),C'5'             if ci[j]='5'
         BE     ITERI                  then cycle i ! 5 impossible
         CLI    0(R8),C'0'             if ci[j]='0'
         BE     ITERI                  then cycle i ! 0 impossible
         LA     R8,1(R8)               @ci++
         LA     R7,1(R7)               j++
       ENDDO    ,                    enddo j
         L      R2,LCI               length(ci)
         BCTR   R2,0                 length(ci)-1
         LA     R7,1                 j=1
       DO WHILE=(CR,R7,LE,R2)        do j=1 to length(ci)-1
         LA     R3,CIL-1               @cil
         AR     R3,R7                  @cil[j]
         IC     R1,0(R3)               cil[j]
         STC    R1,CK                  ck=substr(cil,j,1)
         SR     R0,R0                  index=0
         LR     R8,R7                  j
         LA     R8,1(R8)               k=j+1
         LA     R9,CIL                 @ci
         AR     R9,R8                  +i
         BCTR   R9,0                   -1
       DO WHILE=(C,R8,LE,LCI)          do k=j+1 to length(ci)
       IF   CLC,0(0,R9),EQ,CK THEN       if substr(ci,k,1)=ck then
         LR     R0,R8                      index=k
         B      EXITK                      exit do k
       ENDIF    ,                        endif
         LA     R9,1(R9)                 @ci++
         LA     R8,1(R8)                 k++
       ENDDO    ,                      enddo k
EXITK    LTR    R0,R0                  if index(ci,ck,j+1)<>0
         BNZ    ITERI                  then cycle i ! no dup digit
         LA     R7,1(R7)               j++
       ENDDO    ,                    enddo j
         LA     R7,1                 j=1
       DO WHILE=(C,R7,LE,LCI)        do j=1 to length(ci)
         LA     R3,CIL-1               @cil
         AR     R3,R7                  @cil[j]
         IC     R1,0(R3)               cil[j]
         SLL    R1,28                  ~
         SRL    R1,28                  kk=int(substr(ci,j,1))
         XR     R4,R4                  ~
         LR     R5,R6                  i
         DR     R4,R1                  r5=i/kk r4=mod(i,kk)
         LTR    R4,R4                  if mod(i,kk)<>0
         BNZ    ITERI                  then cycle i ! div by all digit
         LA     R7,1(R7)               j++
       ENDDO    ,                    enddo j
         B      EXITI                exit do i ! found
ITERI    S      R6,KS                i-=ks
       ENDDO    ,                  enddo i
EXITI    XPRNT  CIL,L'CIL          print cil
         L      R13,4(0,R13)       restore previous savearea pointer
         RETURN (14,12),RC=0       restore registers from calling save
MVCR3R4  MVC    0(0,R3),0(R4)      move: %R3 <- %R4
KS       DC     F'504'             ks=504=7*8*9  magic number
KM       DC     F'9876384'         km=9876384    mod(km,ks)=0
DBLI     DS     PL8                double word 15num
MAK      DC     X'402020202020202020202020'  mask CL12 11num
CI       DS     CL12               12num - i right justify
CIL      DS     CL12               12num - i left  justify
LCI      DS     F                  length(i)
CK       DS     C                  ck
         REGEQU
         END    LANUDIDO


BEGIN # find the largest decimal integer with unique digits, divisible by its digits #
    INT magic   = 9 * 8 * 7; # see analysis in the Raku sample #
    INT high    = 9876432 OVER magic * magic;
    BOOL found := FALSE;
    FOR i FROM high BY - magic TO magic WHILE NOT found DO
        IF   INT d1 = i MOD 10;
             d1 = 0
        THEN SKIP # can't end in '0' #
        ELIF [ 0 : 9 ]BOOL digits := []BOOL( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE )[ @ 0 ];
             BOOL unique  := TRUE;
             INT  v       := i OVER 10;
             digits[ d1 ] := TRUE;
             WHILE v > 0 AND unique DO
                 INT d = v MOD 10;
                 v OVERAB 10;
                 unique      := NOT digits[ d ];
                 digits[ d ] := TRUE
             OD;
             NOT unique
        THEN SKIP # digits must be unique #
        ELIF digits[ 0 ] OR digits[ 5 ]
        THEN SKIP # can't contain 0 or 5 #
        ELIF found := TRUE;
             FOR d TO UPB digits WHILE found DO
                 IF digits[ d ] THEN found := i MOD d = 0 FI
             OD;
             found
        THEN
             print( ( "Largest decimal number is ", whole( i, 0 ), newline ) )
        FI
    OD
END


lynchBell?: function [num][
    hset: new []
    loop digits num 'd [
        if d=0 -> return false
        if or? [0 <> mod num d]
               [contains? hset d] -> return false
        'hset ++ d
        unique 'hset
    ]
    return true
]

Magic: 9 * 8 * 7
High: ((from.hex "9876432") / Magic) * Magic

loop range High .step: Magic Magic 'n [
    if lynchBell? n [
        print n
        break
    ]
]


# Usage: gawk -f LARGEST_NUMBER_DIVISIBLE_BY_ITS_DIGITS_10.AWK
BEGIN {
    base = 10
    comdiv = 12
    startn = 9876543
    stopn = 1000000
    solve(startn, stopn)
}
function solve(startn, stopn,    n, d) {
    for (n = startn - startn % comdiv; n > stopn; n -= comdiv) {
        if (hasuniqedigits(n)) {
            # Check divisibility of n by all its digits
            for (d = 2; d < base; d++) {
                if ((dcount[d]) && (n % d)) {
                    break
                }
            }
            if (d == base) {
                printf("%d\n", n)
                return
            }
        }
    }
}
function hasuniqedigits(n,    d) {
    # Returns 1, if n consists of unique digits in range 1..(base-1)
    # The array dcount stores the count (up to 1) of those digits
    for (d = 1; d < base; d++)
        dcount[d] = 0
    while (n) {
        d = n % base
        if ((d == 0) || (++dcount[d] > 1))
            return 0
        n = int(n / base)
    }
    return 1
}


arraybase 1
for n = 9867000  to 9867400
	dim numbers(9) fill 0

	flag = true : flag2 = true : flag3 = true
	cadena = string(n)

	for m = 1 to length(cadena)
		if int(mid(cadena,m,1)) > 0 then
			numbers[int(mid(cadena,m,1))] += 1
		else
			flag2 = false
		end if
	next m

	if flag2 = true then
		for p = 1 to 9
			if not (numbers[p] = 0 or numbers[p] = 1) then flag = false
		next p
		if flag = true then
			for x = 1 to length(cadena)
				if n mod (int(mid(cadena,x,1))) <> 0 then flag3 = false
			next x
			if flag3 = true then print "El mayor número decimal es: "; n
		end if
	end if
next n
end


#include<stdio.h>

int main()
{
	int num = 9876432,diff[] = {4,2,2,2},i,j,k=0;
	char str[10];

		start:snprintf(str,10,"%d",num);

		for(i=0;str[i+1]!=00;i++){
			if(str[i]=='0'||str[i]=='5'||num%(str[i]-'0')!=0){
				num -= diff[k];
				k = (k+1)%4;
				goto start;
			}
			for(j=i+1;str[j]!=00;j++)
				if(str[i]==str[j]){
					num -= diff[k];
					k = (k+1)%4;
					goto start;
			}
		}

	printf("Number found : %d",num);
	return 0;
}


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

namespace LargestNumber {
    class Program {
        static bool ChkDec(int num) {
            HashSet<int> set = new HashSet<int>();

            return num.ToString()
                .Select(c => c - '0')
                .All(d => (d != 0) && (num % d == 0) && set.Add(d));
        }

        static void Main() {
            int result = Enumerable.Range(0, 98764321)
                .Reverse()
                .Where(ChkDec)
                .First();
            Console.WriteLine(result);
        }
    }
}


#include <iostream>
#include <sstream>
#include <set>

bool checkDec(int num) {
    std::set<int> set;

    std::stringstream ss;
    ss << num;
    auto str = ss.str();

    for (int i = 0; i < str.size(); ++i) {
        char c = str[i];
        int d = c - '0';
        if (d == 0) return false;
        if (num % d != 0) return false;
        if (set.find(d) != set.end()) {
            return false;
        }
        set.insert(d);
    }

    return true;
}

int main() {
    for (int i = 98764321; i > 0; i--) {
        if (checkDec(i)) {
            std::cout << i << "\n";
            break;
        }
    }

    return 0;
}


(require '[clojure.string :as str]) ;'
(def the_base 16)

;A sequence named digits containing the non-zero digits for the current number base.
(def digits (rest (range the_base)))

;A container for the digits which are prime.
(def primes [])

;Populate the primes sequence with the primes less than the current base.
(for [n digits] (if (= 1 (count (filter (fn[m] (and (< m n) (= 0 (mod n m)))) digits)) ) (def primes (conj primes n))))

;Determines the highest power of a given prime p that divides a given integer n.
(defn duplicity [n p partial] (if (= 0 (mod n p)) (duplicity (/ n p) p (conj partial p)) partial))

;Constructs the prime factorization of a given integer.
(defn factorize [n] (let [a (flatten (for [p (filter #(< % n) primes)]
  (remove #(= 1 %) (duplicity n p [1]))))] (if (= 0 (count a)) (lazy-seq [n]) a) ))

;Determines the number of times a given number appears in a given sequence of numbers.
(defn multiplicity [s n] (count (filter #(= n %) s)))

;Combines two sequence two create their "union" in the sense that in the resulting sequence
;each element from each sequence is uniquely represented and no smaller sequence would suffice.
;For example if one sequence contains two A's and other contains three A's, then the result will contain three A's.
;This is used to generate representations of prime factorizations and to construct least common multiples from them.
(defn combine [x y] (concat x (flatten (for [w (dedupe y)] (repeat (- (multiplicity y w) (multiplicity x w)) w) ))))

;deterimes the lcm least common multiple for a set of digits.
(defn lcm [s] (reduce * (reduce combine (map factorize s))))

;Retuns x^n.
(defn exp [x n] (reduce * (repeat n x)))

;Generates all non-empty subsequences for a sequence.
(defn non_empty_subsets [s] (for [x (reverse (rest (range (exp 2 (count s)))))]
  (remove nil? (for [i (range (count s))] (if (bit-test x i) (nth s i))))))

;Generates from a given sequence of digits in the current base the number that is s[0]s[1]s[2]...s[n].
;More generally, produces s[0]*the_base^n + s[1]*the_base^(n-1) + ... + s[n-1]*the_base^1 + s[n]*the_base^0
;for an arbitrary sequence of numbers.
(defn power_up [s] (reduce + (loop [idx (- (count s) 1) s_next s]
  (if (zero? idx) s_next (recur (dec idx) (map-indexed #(if (< %1 idx) (* %2 the_base) %2) s_next))))))

;Here is an alternative version of power_up that could be more efficient as it does not repeatedly recalculate powers of the base.
;Instead it calculates the dot product of s with a pre-populated sequence of powers of the base.
;Calculates the dot product of two vectors/sequences
;(defn dot [xs ys] (reduce + (map * xs ys)))
;(def places (map #(exp the_base %) (range the_base)))
;(defn power_up [s] (dot s (reverse (take (count s) places))))

;Returns the largest integer which contains each item from a given sequence exactly once as a digit.
(defn max_for_digits [s] (power_up (sort #(> %1 %2) s)))

;Returns the smallest non-negative integer which contains each item from a given sequence exactly once as a digit.
(defn min_for_digits [s] (power_up (sort #(< %1 %2) s)))

;calculate the logarithm of the input in the current base.
(defn log_base [x] (/ (Math/log x) (Math/log the_base)))

;Removes the zeros from a sequence
(defn remove_zeros [s] (remove #(= % 0) s))

;Returns the largest integer that is a multiple of a given integer and does not exceed another given integer.
(defn first_multiple_not_after [n ub] (loop [m ub] (if (= 0 (mod m n)) m (recur (dec m)))))

;creates a representation in the current base of a positive integer as a sequence listing the digits for the number in the base.
(defn representation [n] (let [full_power (int (log_base n))]
  (loop [power full_power place (exp the_base full_power) rep [] rem n ] (if (= power -1) rep
    (recur (dec power) (/ place the_base) (conj rep (int (/ rem place))) (- rem (* place (int (/ rem place)))))))))

;determines if a given number is exactly comprised of a given set of digits.
(defn digit_qualifies [m s] (let [rep_m (representation m)] (= (sort s) (sort rep_m))))

;Returns a sequence containing the largest Lynch-Bell number for the current base and a given sequence of digits
;or an empty sequence if there is none.
(defn find_s_largest_lb [s] (let [lb (min_for_digits s)] (let [m (lcm s)]
  (loop [v (first_multiple_not_after m (max_for_digits s))] (if (< v lb) []
    (if (digit_qualifies v s) (representation v) (recur (- v m))))))))

;Finds the largest Lynch-Bell number for the current base by looking for the largest for all subsets of a given size
;and picking the largest from those working from the largest size (most digits) to the smallest.
(defn find_largest_lb [] (let [subsets (non_empty_subsets (reverse digits))]
  (loop [s_size (- the_base 1)] (let [hits (remove #(= (count %) 0) (map find_s_largest_lb (filter #(= (count %) s_size) subsets)))]
    (if (pos? (count hits)) (first (sort #(first (remove_zeros (map - %2 %1))) hits)) (recur (dec s_size)))))))

;Converts small integers to hexidecimal digits.
;This isn't being used but could be leveraged to make output that looks normal for base 16.
(defn hex_digit [v] (case v 15 "F" 14 "E" 13 "D" 12 "C" 11 "B" 10 "A" (str v)))

(find_largest_lb)


magic_number = 9*8*7
div          = (9876432 // magic_number) * magic_number
candidates   = div.step(to: 0, by: -magic_number)

res = candidates.find do |c|
  digits = c.to_s.chars.map(&.to_i)
  (digits & [0,5]).empty? && digits == digits.uniq
end

puts "Largest decimal number is #{res}"


import std.algorithm.iteration : filter, map;
import std.algorithm.searching : all;
import std.conv : to;
import std.range : iota;
import std.stdio : writeln;

bool chkDec(int num) {
    int[int] set;

    return num
        .to!string
        .map!(c => c.to!int - '0')
        .all!(d => (d != 0) && (num % d == 0) && set[d]++ < 1);
}

auto lcm(R)(R r) {
    return r.reduce!((a,b) => a * b / gcd(a,b));
}

void main() {
    // base 10
    iota(98764321, 0, -1)
        .filter!chkDec
        .front
        .writeln;
}


program Largest_number_divisible_by_its_digits;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type
  TSetAnsiChar = set of AnsiChar;

function DivByAll(num: Integer; digits: TSetAnsiChar): Boolean;
var
  offset: byte;
begin
  offset := ord('0');
  for var d in digits do
  begin
    if (num mod (ord(d) - offset)) <> 0 then
      exit(false);
  end;
  Result := true;
end;

begin
  var magic: Cardinal := 9 * 8 * 7;
  var h: Cardinal := 9876432 div magic * magic;
  for var i := h downto magic do
  begin
    if i mod 10 = 0 then
      Continue;

    var s := i.tostring;
    if (s.indexOf('0') > -1) or (s.indexOf('5') > -1) then
      Continue;
    var digits: TSetAnsiChar := [];
    var isUnic := true;
    for var b in ansistring(s) do
      if not (b in digits) then
        Include(digits, b)
      else
      begin
        isUnic := false;
        break;
      end;

    if not isUnic then
      Continue;

    if DivByAll(i, digits) then
    begin
      writeln('Largest decimal number is ', i);
      Break;
    end;
  end;
  readln;
end.


USING: io kernel math math.combinatorics math.parser math.ranges
sequences tools.time ;
IN: rosetta-code.largest-divisible

: all-div? ( seq -- ? )
    [ string>number ] [ string>digits ] bi [ mod ] with map
    sum 0 = ;

: n-digit-all-div ( n -- seq )
    "12346789" swap <combinations>
    [ [ all-div? ] filter-permutations ] map concat ;

: largest-divisible ( -- str )
    8 [ dup n-digit-all-div dup empty? ] [ drop 1 - ] while
    nip supremum ;

: largest-divisible-demo ( -- )
    [ largest-divisible print ] time ;

MAIN: largest-divisible-demo


For n As Integer = 9867000  To 9867400
    Dim As Integer numbers(9)
    For t As Byte = 1 To 9
        numbers(t) = 0
    Next t

    Dim As Boolean flag = true, flag2 = true, flag3 = true
    Dim As String cadena = Str(n)
    For m As Byte = 1 To Len(cadena)
        If Val(Mid(cadena,m,1)) > 0 Then
            numbers(Val(Mid(cadena,m,1))) += 1
        Else
            flag2 = false
        End If
    Next m
    If flag2 = true Then
        For p As Byte = 1 To 9
            If Not (numbers(p) = 0 Or numbers(p) = 1) Then flag = false
        Next p
        If flag = true Then
            For x As Byte = 1 To Len(cadena)
                If n Mod (Val(Mid(cadena,x,1))) <> 0 Then flag3 = false
            Next x
            If flag3 = true Then Print "El mayor n£mero decimal es:"; n
        End If
    End If
Next n
Sleep


package main

import (
    "fmt"
    "strconv"
    "strings"
)

func divByAll(num int, digits []byte) bool {
    for _, digit := range digits {
        if num%int(digit-'0') != 0 {
            return false
        }
    }
    return true
}

func main() {
    magic := 9 * 8 * 7
    high := 9876432 / magic * magic
    for i := high; i >= magic; i -= magic {
        if i%10 == 0 {
            continue // can't end in '0'
        }
        s := strconv.Itoa(i)
        if strings.ContainsAny(s, "05") {
            continue // can't contain '0'or '5'
        }
        var set = make(map[byte]bool)
        var sd []byte // distinct digits
        for _, b := range []byte(s) {
            if !set[b] {
                set[b] = true
                sd = append(sd, b)
            }
        }
        if len(sd) != len(s) {
            continue // digits must be unique
        }
        if divByAll(i, sd) {
            fmt.Println("Largest decimal number is", i)
            return
        }
    }
}


import Data.List (maximumBy, permutations, delete)
import Data.Ord (comparing)
import Data.Bool (bool)

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

ds :: [Int]
ds = [1, 2, 3, 4, 6, 7, 8, 9] -- 0 (and thus 5) are both unworkable

lcmDigits :: Int
lcmDigits = foldr1 lcm ds -- 504

sevenDigits :: [[Int]]
sevenDigits = (`delete` ds) <$> [1, 4, 7] -- Dropping any one of these three

main :: IO ()
main =
  print $
  maximumBy
  -- Checking for divisibility by all digits
    (comparing (bool 0 <*> (0 ==) . (`rem` lcmDigits)))
    (unDigits <$> concat (permutations <$> sevenDigits))


public class LynchBell {

    static String s = "";

    public static void main(String args[]) {
        //Highest number with unique digits (no 0 or 5)
        int i = 98764321;
        boolean isUnique = true;
        boolean canBeDivided = true;
        while (i>0) {
            s = String.valueOf(i);
            isUnique = uniqueDigits(i);
            if (isUnique) {
                //Number has unique digits
                canBeDivided = testNumber(i);
                if(canBeDivided) {
                    System.out.println("Number found: " + i);
                    i=0;
                }
            }
            i--;
        }
    }

    public static boolean uniqueDigits(int i) {
        //returns true, if unique digits, false otherwise
        for (int k = 0; k<s.length();k++) {
            for(int l=k+1; l<s.length();l++) {
                if(s.charAt(l)=='0' || s.charAt(l)=='5') {
                    //0 or 5 is a digit
                    return false;
                }
                if(s.charAt(k) == s.charAt(l)) {
                    //non-unique digit
                    return false;
                }
            }
        }
        return true;
    }

    public static boolean testNumber(int i) {
        //Tests, if i is divisible by all its digits (0 is not a digit already)
        int j = 0;
        boolean divisible = true;
        // TODO: divisible by all its digits
        for (char ch: s.toCharArray()) {
            j = Character.getNumericValue(ch);
            divisible = ((i%j)==0);
            if (!divisible) {
                return false;
            }
        }
        return true;
    }
}


def has_unique_digits:
  tostring
  | explode
  | label $out
  | (foreach map([.] | implode)[] as $d ({};
      .[$d] += 1;
      select(.[$d] > 1) | (0, break $out)))
    // true
    | . == true;

# exclude numbers with a 0
def is_divisible_by_all_its_digits:
  . as $n
  | tostring
  | explode
  | map([.] | implode | tonumber) as $digits
  | all($digits[]; . != 0) and
    all($digits[]; $n % . == 0);

def task:
  def solve($startn; $stopn; $comdiv):
    ($startn - ($startn % $comdiv))
    | while (. >= $stopn; . - $comdiv)
    | select(has_unique_digits and is_divisible_by_all_its_digits);
  first(solve(9876543; 1000000; 12));

task


function main()
    num = 9876432
    dif = [4, 2, 2, 2]
    local k = 1
    @label start
    local str = dec(num)
    for (i, ch) in enumerate(str)
        if ch in ('0', '5') || num % (ch - '0') != 0
            num -= dif[k]
            k = (k + 1) % 4 + 1
            @goto start
        end
        for j in i+1:endof(str)
            if str[i] == str[j]
                num -= dif[k]
                k = (k + 1) % 4 + 1
                @goto start
            end
        end
    end

    return num
end

println("Number found: ", main())


// version 1.1.4-3

fun Int.divByAll(digits: List<Char>) = digits.all { this % (it - '0') == 0 }

fun main(args: Array<String>) {
    val magic = 9 * 8 * 7
    val high = 9876432 / magic * magic
    for (i in high downTo magic step magic) {
        if (i % 10 == 0) continue            // can't end in '0'
        val s = i.toString()
        if ('0' in s || '5' in s) continue   // can't contain '0' or '5'
        val sd = s.toCharArray().distinct()
        if (sd.size != s.length) continue    // digits must be unique
        if (i.divByAll(sd)) {
            println("Largest decimal number is $i")
            return
        }
    }
}


function isDivisible(n)
    local t = n
    local a = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

    while t ~= 0 do
        local r = t % 10
        if r == 0 then
            return false
        end
        if n % r ~= 0 then
            return false
        end
        if a[r + 1] > 0 then
            return false
        end
        a[r + 1] = 1
        t = math.floor(t / 10)
    end

    return true
end

for i=9999999999,0,-1 do
    if isDivisible(i) then
        print(i)
        break
    end
end


s = ""

def uniqueDigits(i)
        global s

        // returns true, if unique digits, false otherwise
        for k in range(0, len(s) - 2)
                for l in range(k + 1, len(s) - 1)
                        if (s[l] = "0") || (s[l] = "5")
                                //0 or 5 digit
                                return false
                        end

                        if s[k] = s[l]
                                //non-unique digit
                                return false
                        end
                end
        end

        return true
end

def testNumber(i)
        global s

        //Tests, if i is divisible by all its digits (0 is not a digit already)
        j = 0
        divisible = true
        for ch in s
                j = int(ch)
                divisible = (i % j) = 0
                if not divisible
                        return false
                end
        end

        return true
end

i = 98764321
isUnique = true
canBeDivided = true

while i > 0
        s = str(i)
        isUnique = uniqueDigits(i)
        if isUnique
                //Number has unique digits
                canBeDivided = testNumber(i)
                if canBeDivided
                        println "Number found: " + i
                        i = 0
                end
        end
        i -= 1
end


type Digit = range[0..9]

iterator digits(n: int64): Digit =
  var n = n
  while true:
    yield n mod 10
    n = n div 10
    if n == 0: break

func isLynchBell(num: int64): bool =
  var hSet: set[Digit]
  for d in num.digits:
    if d == 0 or num mod d != 0 or d in hSet:
      return false
    hSet.incl(d)
  return true

const
  Magic = 9 * 8 * 7
  High = 0x9876432 div Magic * Magic

for n in countdown(High, Magic, Magic):
  if n.isLynchBell:
    echo n
    break


my $step = 9 * 8 * 7;                               # 504, interval between tests

my $initial = int(9876432 / $step) * $step;         # largest 7 digit multiple of 504 < 9876432

for($test = $initial; $test > 0 ; $test -= $step) { # decrement by 504
    next if $test =~ /[05]/;                        # skip numbers containing 0 or 5
    next if $test =~ /(.).*\1/;                     # skip numbers with non unique digits

    for (split '', $test) {                         # skip numbers that don't divide evenly by all digits
        next unless ($test / $_) % 1;
    }

    printf "Found $test after %d steps\n", ($initial-$test)/$step;
    for (split '', $test) {
       printf "%s / %s = %s\n", $test, $_, $test / $_;
    }
    last
}


with javascript_semantics
integer magic = 9*8*7,
        high  = 9876432,
        n = high-mod(high,magic)
sequence seen
while true do
    string s = sprintf("%d",n)
    seen = {1,0,0,0,0,1,0,0,0,0}
    for j=1 to length(s) do
        seen[s[j]-'0'+1] += 1
    end for
    if max(seen)=1 then exit end if
    n -= magic
end while
-- may as well quickly verify...
seen[5+1] = 0   -- (skipping 5)
for i=1 to 9 do --  ( and 0 )
    if seen[i+1] then
        if mod(n,i)!=0 then ?9/0 end if
    end if
end for
printf(1,"%d (%d iterations)\n",{n,(high-n)/magic})