#!/usr/bin/awk -f

BEGIN {
    a = "kitten";
    b = "sitting";
    d = levenshteinDistance(a, b);
    p = d == 1 ? "" : "s";
    printf("%s -> %s after %d edit%s\n", a, b, d, p);
    exit;
}

function levenshteinDistance(s1, s2,
    s1First, s2First, s1Rest, s2Rest,
    distA, distB, distC, minDist) {

    # If either string is empty,
    # then distance is insertion of the other's characters.
    if (length(s1) == 0) return length(s2);
    if (length(s2) == 0) return length(s1);

    # Rest of process uses first characters
    # and remainder of each string.
    s1First = substr(s1, 1, 1);
    s2First = substr(s2, 1, 1);
    s1Rest = substr(s1, 2, length(s1));
    s2Rest = substr(s2, 2, length(s2));

    # If leading characters are the same,
    # then distance is that between the rest of the strings.
    if (s1First == s2First) {
        return levenshteinDistance(s1Rest, s2Rest);
    }

    # Find the distances between sub strings.
    distA = levenshteinDistance(s1Rest, s2);
    distB = levenshteinDistance(s1, s2Rest);
    distC = levenshteinDistance(s1Rest, s2Rest);

    # Return the minimum distance between substrings.
    minDist = distA;
    if (distB < minDist) minDist = distB;
    if (distC < minDist) minDist = distC;
    return minDist + 1; # Include change for the first character.
}


Time.Date.isLeapYear(1988) //-->True
T(1988,1989,1900,2000).apply(Time.Date.isLeapYear)
    //-->L(True,False,False,True)


      PRINT "'kitten' -> 'sitting' has distance " ;
      PRINT ; FNlevenshtein("kitten", "sitting")
      PRINT "'rosettacode' -> 'raisethysword' has distance " ;
      PRINT ; FNlevenshtein("rosettacode", "raisethysword")
      END

      DEF FNlevenshtein(s$, t$)
      LOCAL i%, j%, m%, d%()
      DIM d%(LENs$, LENt$)
      FOR i% = 0 TO DIM(d%(),1)
        d%(i%,0) = i%
      NEXT
      FOR j% = 0 TO DIM(d%(),2)
        d%(0,j%) = j%
      NEXT
      FOR j% = 1 TO DIM(d%(),2)
        FOR i% = 1 TO DIM(d%(),1)
          IF MID$(s$,i%,1) = MID$(t$,j%,1) THEN
            d%(i%,j%) = d%(i%-1,j%-1)
          ELSE
            m% = d%(i%-1,j%-1)
            IF d%(i%,j%-1) < m% m% = d%(i%,j%-1)
            IF d%(i%-1,j%) < m% m% = d%(i%-1,j%)
            d%(i%,j%) = m% + 1
          ENDIF
        NEXT
      NEXT j%
      = d%(i%-1,j%-1)


Levenshtein ← {
  𝕨 𝕊"": ≠𝕨;
  ""𝕊 𝕩: ≠𝕩;
  𝕨 𝕊 𝕩:
    Tail←1⊸↓
    𝕨 =○⊑◶⟨1+·⌊´ 𝕊○Tail ∾ Tail⊸𝕊 ∾ 𝕊⟜Tail, 𝕊○Tail⟩ 𝕩
}


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

/* s, t: two strings; ls, lt: their respective length */
int levenshtein(const char *s, int ls, const char *t, int lt)
{
        int a, b, c;

        /* if either string is empty, difference is inserting all chars
         * from the other
         */
        if (!ls) return lt;
        if (!lt) return ls;

        /* if last letters are the same, the difference is whatever is
         * required to edit the rest of the strings
         */
        if (s[ls - 1] == t[lt - 1])
                return levenshtein(s, ls - 1, t, lt - 1);

        /* else try:
         *      changing last letter of s to that of t; or
         *      remove last letter of s; or
         *      remove last letter of t,
         * any of which is 1 edit plus editing the rest of the strings
         */
        a = levenshtein(s, ls - 1, t, lt - 1);
        b = levenshtein(s, ls,     t, lt - 1);
        c = levenshtein(s, ls - 1, t, lt    );

        if (a > b) a = b;
        if (a > c) a = c;

        return a + 1;
}

int main()
{
        const char *s1 = "rosettacode";
        const char *s2 = "raisethysword";
        printf("distance between `%s' and `%s': %d\n", s1, s2,
                levenshtein(s1, strlen(s1), s2, strlen(s2)));

        return 0;
}


using System;

namespace LevenshteinDistance
{
    class Program
    {
        static int LevenshteinDistance(string s, string t)
        {
            int n = s.Length;
            int m = t.Length;
            int[,] d = new int[n + 1, m + 1];

	    if (n == 0)
	    {
		return m;
	    }

	    if (m == 0)
	    {
		return n;
	    }

            for (int i = 0; i <= n; i++)
                d[i, 0] = i;
            for (int j = 0; j <= m; j++)
                d[0, j] = j;

            for (int j = 1; j <= m; j++)
                for (int i = 1; i <= n; i++)
                    if (s[i - 1] == t[j - 1])
                        d[i, j] = d[i - 1, j - 1];  //no operation
                    else
                        d[i, j] = Math.Min(Math.Min(
                            d[i - 1, j] + 1,    //a deletion
                            d[i, j - 1] + 1),   //an insertion
                            d[i - 1, j - 1] + 1 //a substitution
                            );
            return d[n, m];
        }

        static void Main(string[] args)
        {
            if (args.Length == 2)
                Console.WriteLine("{0} -> {1} = {2}",
                    args[0], args[1], LevenshteinDistance(args[0], args[1]));
            else
                Console.WriteLine("Usage:-\n\nLevenshteinDistance <string1> <string2>");
        }
    }
}


#include <string>
#include <iostream>
using namespace std;

// Compute Levenshtein Distance
// Martin Ettl, 2012-10-05

size_t uiLevenshteinDistance(const string &s1, const string &s2)
{
  const size_t
    m(s1.size()),
    n(s2.size());

  if( m==0 ) return n;
  if( n==0 ) return m;

  // allocation below is not ISO-compliant,
  // it won't work with -pedantic-errors.
  size_t costs[n + 1];

  for( size_t k=0; k<=n; k++ ) costs[k] = k;

  size_t i { 0 };
  for (char const &c1 : s1)
  {
    costs[0] = i+1;
    size_t corner { i },
           j      { 0 };
    for (char const &c2 : s2)
    {
      size_t upper { costs[j+1] };
      if( c1 == c2 ) costs[j+1] = corner;
      else {
        size_t t(upper<corner? upper: corner);
        costs[j+1] = (costs[j]<t?costs[j]:t)+1;
      }

      corner = upper;
      j++;
    }
    i++;
  }

  return costs[n];
}

int main()
{
  string s0 { "rosettacode" },
         s1 { "raisethysword" };
  cout << "distance between " << s0 << " and " << s1 << " : "
    << uiLevenshteinDistance(s0,s1) << endl;

  return 0;
}


(defn levenshtein [str1 str2]
  (let [len1 (count str1)
        len2 (count str2)]
    (cond (zero? len1) len2
          (zero? len2) len1
          :else
          (let [cost (if (= (first str1) (first str2)) 0 1)]
            (min (inc (levenshtein (rest str1) str2))
                 (inc (levenshtein str1 (rest str2)))
                 (+ cost
                    (levenshtein (rest str1) (rest str2))))))))

(println (levenshtein "rosettacode" "raisethysword"))


min = proc [T: type] (a, b: T) returns (T)
      where T has lt: proctype (T,T) returns (bool)
    if a<b
        then return(a)
        else return(b)
    end
end min

levenshtein = proc (s, t: string) returns (int)
    ai = array[int]
    aai = array[array[int]]
    m: int := string$size(s)
    n: int := string$size(t)

    d: aai := aai$fill_copy(0, m+1, ai$fill(0, n+1, 0))

    for i: int in int$from_to(1, m) do d[i][0] := i end
    for j: int in int$from_to(1, n) do d[0][j] := j end

    for j: int in int$from_to(1, n) do
        for i: int in int$from_to(1, m) do
            cost: int
            if s[i] = t[j]
                then cost := 0
                else cost := 1
            end
            d[i][j] := min[int]( d[i-1][j]+1,
                       min[int]( d[i][j-1]+1,
                                 d[i-1][j-1]+cost ))
        end
    end

    return (d[m][n])
end levenshtein

show = proc (s, t: string)
    po: stream := stream$primary_output()
    stream$putl(po, s || " => " || t || ": " || int$unparse(levenshtein(s,t)))
end show

start_up = proc ()
    show("kitten", "sitting")
    show("rosettacode", "raisethysword")
end start_up


       identification division.
       program-id. Levenshtein.

       environment division.
       configuration section.
       repository.
           function all intrinsic.

       data division.
       working-storage section.
       77  string-a               pic x(255).
       77  string-b               pic x(255).
       77  length-a               pic 9(3).
       77  length-b               pic 9(3).
       77  distance               pic z(3).
       77  i                      pic 9(3).
       77  j                      pic 9(3).
       01  tab.
           05 filler              occurs 256.
              10 filler           occurs 256.
                 15 costs         pic 9(3).

       procedure division.
       main.
           move "kitten" to string-a
           move "sitting" to string-b
           perform levenshtein-dist

           move "rosettacode" to string-a
           move "raisethysword" to string-b
           perform levenshtein-dist
           stop run
           .
       levenshtein-dist.
           move length(trim(string-a)) to length-a
           move length(trim(string-b)) to length-b

           initialize tab

           perform varying i from 0 by 1 until i > length-a
              move i to costs(i + 1, 1)
           end-perform

           perform varying j from 0 by 1 until j > length-b
              move j to costs(1, j + 1)
           end-perform

           perform with test after varying i from 2 by 1 until i > length-a
              perform with test after varying j from 2 by 1 until j > length-b
                 if string-a(i - 1:1) = string-b(j - 1:1)
                    move costs(i - 1, j - 1) to costs(i, j)
                 else
                    move min(min(costs(i - 1, j) + 1,     *> a deletion
                                 costs(i, j - 1) + 1),    *> an insertion
                             costs(i - 1, j - 1) + 1)     *> a substitution
                       to costs(i, j)
                 end-if
              end-perform
           end-perform
           move costs(length-a + 1, length-b + 1) to distance
           display trim(string-a) " -> " trim(string-b) " = " trim(distance)
           .


levenshtein = (str1, str2) ->
  # more of less ported simple algorithm from JS
  m = str1.length
  n = str2.length
  d = []

  return n  unless m
  return m  unless n

  d[i] = [i] for i in [0..m]
  d[0][j] = j for j in [1..n]

  for i in [1..m]
    for j in [1..n]
      if str1[i-1] is str2[j-1]
        d[i][j] = d[i-1][j-1]
      else
        d[i][j] = Math.min(
          d[i-1][j]
          d[i][j-1]
          d[i-1][j-1]
        ) + 1

  d[m][n]

console.log levenshtein("kitten", "sitting")
console.log levenshtein("rosettacode", "raisethysword")
console.log levenshtein("stop", "tops")
console.log levenshtein("yo", "")
console.log levenshtein("", "yo")


(defun levenshtein (a b)
  (let* ((la  (length a))
         (lb  (length b))
         (rec (make-array (list (1+ la) (1+ lb)) :initial-element nil)))
    (labels ((leven (x y)
               (cond
                 ((zerop x) y)
                 ((zerop y) x)
                 ((aref rec x y) (aref rec x y))
                 (t (setf (aref rec x y)
                          (+ (if (char= (char a (- la x)) (char b (- lb y))) 0 1)
                             (min (leven (1- x) y)
                                  (leven x (1- y))
                                  (leven (1- x) (1- y)))))))))
      (leven la lb))))

(print (levenshtein "rosettacode" "raisethysword"))


require "levenshtein"
puts Levenshtein.distance("kitten", "sitting")
puts Levenshtein.distance("rosettacode", "raisethysword")


void main() {
    import std.stdio, std.algorithm;

    levenshteinDistance("kitten", "sitting").writeln;
}


program Levenshtein_distanceTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Math;

function Levenshtein_distance(s, t: string): integer;
var
  d: array of array of integer;
  i, j, cost: integer;
begin
  SetLength(d, Length(s) + 1);
  for i := Low(d) to High(d) do
  begin
    SetLength(d[i], Length(t) + 1);
  end;

  for i := Low(d) to High(d) do
  begin
    d[i, 0] := i;
    for j := Low(d[i]) to High(d[i]) do
    begin
      d[0, j] := j;
    end;
  end;

  for i := Low(d) + 1 to High(d) do
  begin
    for j := Low(d[i]) + 1 to High(d[i]) do
    begin
      if s[i] = t[j] then
      begin
        cost := 0;
      end
      else
      begin
        cost := 1;
      end;

      d[i, j] := Min(Min(d[i - 1, j] + 1,      //deletion
        d[i, j - 1] + 1),     //insertion
        d[i - 1, j - 1] + cost  //substitution
      );
    end;
  end;
  Result := d[Length(s), Length(t)];
end;

procedure Println(s, t: string);
begin
  Writeln('> LevenshteinDistance "', s, '" "', t, '"');
  Writeln(s, ' -> ', t, ' = ', Levenshtein_distance(s, t), #10);
end;

begin
  Println('kitten', 'sitting');
  Println('rosettacode', 'raisethysword');
  readln;
end.


function LevenshteinDistance(s, t : String) : Integer;
var
   i, j : Integer;
begin
   var d:=new Integer[Length(s)+1, Length(t)+1];
   for i:=0 to Length(s) do
      d[i, 0] := i;
   for j:=0 to Length(t) do
      d[0, j] := j;

   for j:=1 to Length(t) do
      for i:=1 to Length(s) do
         if s[i]=t[j] then
            d[i, j] := d[i-1, j-1] // no operation
         else d[i,j]:=MinInt(MinInt(
               d[i-1, j] +1 ,    // a deletion
               d[i, j-1] +1 ),   // an insertion
               d[i- 1,j-1] +1    // a substitution
               );
   Result:=d[Length(s), Length(t)];
end;

PrintLn(LevenshteinDistance('kitten', 'sitting'));


func levenshtein(s, t) {
    var n = s.Length()
    var m = t.Length()
    var d = Array.Empty(n + 1, () => Array.Empty(m + 1))

    if n == 0 {
        return m
    }

    if (m == 0) {
        return n
    }

    for i in 0..n {
        d[i][0] = i
    }

    for j in 0..m {
        d[0][j] = j
    }

    for j in 1..m {
        for i in 1..n {
            if s[i - 1] == t[j - 1] {
                d[i][j] = d[i - 1][j - 1] //no operation
            }
            else {
                d[i][j] = min(min(
                    d[i - 1][j] + 1,    //a deletion
                    d[i][j - 1] + 1),   //an insertion
                    d[i - 1][j - 1] + 1 //a substitution
                    )
            }
        }
    }

    d[n][m]
}

func run(x, y) {
    print("\(x) -> \(y) = \(levenshtein(x, y))")
}

run("rosettacode", "raisethysword")


;; Recursive version adapted from Clojure
;; Added necessary memoization

(define (levenshtein str1 str2 (cost 0) (rest1 0) (rest2 0) (key null))
(set! key (string-append str1 "|" str2))
(if (get 'mem key) ;; memoized ?
    (get 'mem key)
;; else memoize
(putprop 'mem
  (let [(len1 (string-length str1))
        (len2 (string-length str2))]
    (cond ((zero? len1) len2)
          ((zero? len2) len1)
          (else
          (set! cost (if (= (string-first str1) (string-first str2)) 0 1))
          (set! rest1 (string-rest str1))
          (set! rest2 (string-rest str2))
            (min (1+ (levenshtein rest1 str2))
                 (1+ (levenshtein str1 rest2))
                 (+ cost
                    (levenshtein rest1 rest2 ))))))
    key)))

;; 😛 127 calls with memoization
;; 😰 29737 calls without memoization
(levenshtein "kitten" "sitting") → 3

(levenshtein "rosettacode" "raisethysword") → 8


open list

levenshtein s1 s2 = last <| foldl transform [0 .. length s1] s2
            where transform (n::ns')@ns c = scanl calc (n+1) <| zip3 s1 ns ns'
                        where calc z (c', x, y) = minimum [y+1, z+1, x + toInt (c' <> c)]


defmodule Levenshtein do
  def distance(a, b) do
    ta = String.downcase(a) |> to_charlist |> List.to_tuple
    tb = String.downcase(b) |> to_charlist |> List.to_tuple
    m = tuple_size(ta)
    n = tuple_size(tb)
    costs = Enum.reduce(0..m, %{},   fn i,acc -> Map.put(acc, {i,0}, i) end)
    costs = Enum.reduce(0..n, costs, fn j,acc -> Map.put(acc, {0,j}, j) end)
    Enum.reduce(0..n-1, costs, fn j, acc ->
      Enum.reduce(0..m-1, acc, fn i, map ->
        d = if elem(ta, i) == elem(tb, j) do
              map[ {i,j} ]
            else
              Enum.min([ map[ {i  , j+1} ] + 1,         # deletion
                         map[ {i+1, j  } ] + 1,         # insertion
                         map[ {i  , j  } ] + 1 ])       # substitution
            end
        Map.put(map, {i+1, j+1}, d)
      end)
    end)
    |> Map.get({m,n})
  end
end

words = ~w(kitten sitting saturday sunday rosettacode raisethysword)
Enum.each(Enum.chunk(words, 2), fn [a,b] ->
  IO.puts "distance(#{a}, #{b}) = #{Levenshtein.distance(a,b)}"
end)


-module(levenshtein).
-compile(export_all).

distance_cached(S,T) ->
    {L,_} = ld(S,T,dict:new()),
    L.

distance(S,T) ->
    ld(S,T).

ld([],T) ->
    length(T);
ld(S,[]) ->
    length(S);
ld([X|S],[X|T]) ->
    ld(S,T);
ld([_SH|ST]=S,[_TH|TT]=T) ->
    1 + lists:min([ld(S,TT),ld(ST,T),ld(ST,TT)]).

ld([]=S,T,Cache) ->
    {length(T),dict:store({S,T},length(T),Cache)};
ld(S,[]=T,Cache) ->
    {length(S),dict:store({S,T},length(S),Cache)};
ld([X|S],[X|T],Cache) ->
    ld(S,T,Cache);
ld([_SH|ST]=S,[_TH|TT]=T,Cache) ->
    case dict:is_key({S,T},Cache) of
        true -> {dict:fetch({S,T},Cache),Cache};
        false ->
            {L1,C1} = ld(S,TT,Cache),
            {L2,C2} = ld(ST,T,C1),
            {L3,C3} = ld(ST,TT,C2),
            L = 1+lists:min([L1,L2,L3]),
            {L,dict:store({S,T},L,C3)}
    end.


PROGRAM LEVENSHTEIN

!$DYNAMIC
  DIM D%[0,0]

PROCEDURE LEVENSHTEIN(S$,T$->RES%)
      LOCAL I%,J%,M%
      FOR I%=0 TO LEN(S$) DO
        D%[I%,0]=I%
      END FOR
      FOR J%=0 TO LEN(T$) DO
        D%[0,J%]=J%
      END FOR
      FOR J%=1 TO LEN(T$) DO
        FOR I%=1 TO LEN(S$) DO
          IF MID$(S$,I%,1)=MID$(T$,J%,1) THEN
            D%[I%,J%]=D%[I%-1,J%-1]
          ELSE
            M%=D%[I%-1,J%-1]
            IF D%[I%,J%-1]<M% THEN M%=D%[I%,J%-1] END IF
            IF D%[I%-1,J%]<M% THEN M%=D%[I%-1,J%] END IF
            D%[I%,J%]=M%+1
          END IF
        END FOR
      END FOR
      RES%=D%[I%-1,J%-1]
END PROCEDURE

BEGIN
   S$="kitten"  T$="sitting"
   PRINT("'";S$;"' -> '";T$;"' has distance ";)
   !$DIM D%[LEN(S$),LEN(T$)]
   LEVENSHTEIN(S$,T$->RES%)
   PRINT(RES%)
   !$ERASE D%

   S$="rosettacode" T$="raisethysword"
   PRINT("'";S$;"' -> '";T$;"' has distance ";)
   !$DIM D%[LEN(S$),LEN(T$)]
   LEVENSHTEIN(S$,T$->RES%)
   PRINT(RES%)
   !$ERASE D%
END PROGRAM


function min(sequence s)
    atom m
    m = s[1]
    for i = 2 to length(s) do
        if s[i] < m then
            m = s[i]
        end if
    end for
    return m
end function

function levenshtein(sequence s1, sequence s2)
    integer n, m
    sequence d
    n = length(s1) + 1
    m = length(s2) + 1

    if n = 1  then
        return m-1
    elsif m = 1 then
        return n-1
    end if

    d = repeat(repeat(0, m), n)
    for i = 1 to n do
        d[i][1] = i-1
    end for

    for j = 1 to m do
        d[1][j] = j-1
    end for

    for i = 2 to n do
        for j = 2 to m do
            d[i][j] = min({
                d[i-1][j] + 1,
                d[i][j-1] + 1,
                d[i-1][j-1] + (s1[i-1] != s2[j-1])
            })
        end for
    end for

    return d[n][m]
end function

? levenshtein("kitten", "sitting")
? levenshtein("rosettacode", "raisethysword")


open System

let getInput (name : string) =
    Console.Write ("String {0}: ", name)
    Console.ReadLine ()

let levDist (strOne : string) (strTwo : string) =
    let strOne = strOne.ToCharArray ()
    let strTwo = strTwo.ToCharArray ()

    let (distArray : int[,]) = Array2D.zeroCreate (strOne.Length + 1) (strTwo.Length + 1)

    for i = 0 to strOne.Length do distArray.[i, 0] <- i
    for j = 0 to strTwo.Length do distArray.[0, j] <- j

    for j = 1 to strTwo.Length do
        for i = 1 to strOne.Length do
            if strOne.[i - 1] = strTwo.[j - 1] then distArray.[i, j] <- distArray.[i - 1, j - 1]
            else
                distArray.[i, j] <- List.min (
                    [distArray.[i-1, j] + 1;
                    distArray.[i, j-1] + 1;
                    distArray.[i-1, j-1] + 1]
                )
    distArray.[strOne.Length, strTwo.Length]

let stringOne = getInput "One"
let stringTwo = getInput "Two"
printf "%A" (levDist stringOne stringTwo)

Console.ReadKey () |> ignore


USING: lcs prettyprint ;
"kitten" "sitting" levenshtein .


: levenshtein                          ( a1 n1 a2 n2 -- n3)
  dup                                  \ if either string is empty, difference
  if                                   \ is inserting all chars from the other
    2>r dup
    if
      2dup 1- chars + [email protected] [email protected] 1- chars + [email protected] =
      if
        1- 2r> 1- recurse exit
      else                             \ else try:
        2dup 1- [email protected] 1- recurse -rot    \   changing first letter of s to t;
        2dup    [email protected] 1- recurse -rot    \   remove first letter of s;
        1- 2r> recurse min min 1+      \   remove first letter of t,
      then                             \ any of which is 1 edit plus
    else                               \ editing the rest of the strings
      2drop 2r> nip
    then
  else
    2drop nip
  then
;

s" kitten"      s" sitting"       levenshtein . cr
s" rosettacode" s" raisethysword" levenshtein . cr


program demo_edit_distance
character(len=:),allocatable :: sources(:),targets(:)
integer,allocatable          :: answers(:),expected(:)

sources=[character(len=20)   :: "kitten",  "rosettacode",   "Saturday", "sleep",    "qwerty", "Fortran" ]
targets=[character(len=20)   :: "sitting", "raisethysword", "Sunday",   "fleeting", "qweryt", "Fortran" ]
expected=[                       3,         8,               3,          5,          2,        0        ]
! calculate answers
answers=edit_distance(sources,targets)
! print inputs, answers, and confirmation
do i=1, size(sources)
   write(*,'(*(g0,1x))') sources(i), targets(i), answers(i), answers(i) == expected(i)
enddo
! a longer test
write(*,*)edit_distance("here's a bunch of words", "to wring out this code")==18

contains

pure elemental integer function edit_distance (source,target)
!! The Levenshtein distance function returns how many edits (deletions,
!! insertions, transposition) are required to turn one string into another.
character(len=*), intent(in) :: source, target
integer                      :: len_source, len_target, i, j, cost
integer                      :: matrix(0:len_trim(source), 0:len_trim(target))
   len_source = len_trim(source)
   len_target = len_trim(target)
   matrix(:,0) = [(i,i=0,len_source)]
   matrix(0,:) = [(j,j=0,len_target)]
   do i = 1, len_source
      do j = 1, len_target
         cost=merge(0,1,source(i:i)==target(j:j))
         matrix(i,j) = min(matrix(i-1,j)+1, matrix(i,j-1)+1, matrix(i-1,j-1)+cost)
      enddo
   enddo
   edit_distance = matrix(len_source,len_target)
end function edit_distance

end program demo_edit_distance


' FB 1.05.0 Win64

' Uses the "iterative with two matrix rows" algorithm
' referred to in the Wikipedia article.

Function min(x As Integer, y As Integer) As Integer
   Return IIf(x < y, x, y)
End Function

Function levenshtein(s As String, t As String) As Integer
    ' degenerate cases
    If s = t Then Return 0
    If s = "" Then Return Len(t)
    If t = "" Then Return Len(s)

    ' create two integer arrays of distances
    Dim v0(0 To Len(t)) As Integer  '' previous
    Dim v1(0 To Len(t)) As Integer  '' current

    ' initialize v0
    For i As Integer = 0 To Len(t)
      v0(i) = i
    Next

    Dim cost As Integer
    For i As Integer = 0 To Len(s) - 1
      ' calculate v1 from v0
      v1(0) = i + 1

      For j As Integer = 0 To Len(t) - 1
        cost = IIf(s[i] = t[j], 0, 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 As Integer = 0 To Len(t)
        v0(j) = v1(j)
      Next  j
    Next i

    Return v1(Len(t))
End Function

Print "'kitten' to 'sitting'            => "; levenshtein("kitten", "sitting")
Print "'rosettacode' to 'raisethysword' => "; levenshtein("rosettacode", "raisethysword")
Print "'sleep' to 'fleeting'            => "; levenshtein("sleep", "fleeting")
Print
Print "Press any key to quit"
Sleep


window 1

local fn LevenshteinDistance( aStr as Str255, bStr as Str255 ) as long
  dim as long m, n, i, j, min, k, l
  dim as long distance( 255, 255 )

  m = len$(aStr)
  n = len$(bStr)

  for i = 0 to m
    distance( i, 0 ) = i
  next

  for j = 0 to n
    distance( 0, j ) = j
  next

  for j = 1 to n
    for i = 1 to m
      if mid$( aStr, i, 1 ) == mid$( bStr, j, 1 )
        distance( i, j ) = distance( i-1, j-1 )
      else
        min = distance( i-1, j   ) + 1
        k   = distance( i, j - 1 ) + 1
        l   = distance( i-1, j-1 ) + 1
        if k < min then min = k
        if l < min then min = l
        distance( i, j ) = min
      end if
    next
  next
end fn = distance( m, n )

dim as long i
dim as Str255 testStr( 5, 2 )

testStr( 0, 0 ) = "kitten"      : testStr( 0, 1 ) = "sitting"
testStr( 1, 0 ) = "rosettacode" : testStr( 1, 1 ) = "raisethysword"
testStr( 2, 0 ) = "Saturday"    : testStr( 2, 1 ) = "Sunday"
testStr( 3, 0 ) = "FutureBasic" : testStr( 3, 1 ) = "FutureBasic"
testStr( 4, 0 ) = "here's a bunch of words"
testStr( 4, 1 ) = "to wring out this code"

for i = 0 to 4
  print "1st string = "; testStr( i, 0 )
  print "2nd string = "; testStr( i, 1 )
  print "Levenshtein distance ="; fn LevenshteinDistance( testStr( i, 0 ), testStr( i, 1 ) )
  print
next

HandleEvents


package main

import "fmt"

func main() {
    fmt.Println(ld("kitten", "sitting"))
}

func ld(s, t string) int {
    d := make([][]int, len(s)+1)
    for i := range d {
        d[i] = make([]int, len(t)+1)
    }
    for i := range d {
        d[i][0] = i
    }
    for j := range d[0] {
        d[0][j] = j
    }
    for j := 1; j <= len(t); j++ {
        for i := 1; i <= len(s); i++ {
            if s[i-1] == t[j-1] {
                d[i][j] = d[i-1][j-1]
            } else {
                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[len(s)][len(t)]
}


def distance(String str1, String str2) {
    def dist = new int[str1.size() + 1][str2.size() + 1]
    (0..str1.size()).each { dist[it][0] = it }
    (0..str2.size()).each { dist[0][it] = it }

    (1..str1.size()).each { i ->
        (1..str2.size()).each { j ->
            dist[i][j] = [dist[i - 1][j] + 1, dist[i][j - 1] + 1, dist[i - 1][j - 1] + ((str1[i - 1] == str2[j - 1]) ? 0 : 1)].min()
        }
    }
    return dist[str1.size()][str2.size()]
}

[ ['kitten', 'sitting']: 3,
  ['rosettacode', 'raisethysword']: 8,
  ['edocattesor', 'drowsyhtesiar']: 8 ].each { key, dist ->
    println "Checking distance(${key[0]}, ${key[1]}) == $dist"
    assert distance(key[0], key[1]) == dist
}


levenshtein :: Eq a => [a] -> [a] -> Int
levenshtein s1 s2 = last $ foldl transform [0 .. length s1] s2
  where
    transform ns@(n:ns1) c = scanl calc (n + 1) $ zip3 s1 ns ns1
      where
        calc z (c1, x, y) = minimum [y + 1, z + 1, x + fromEnum (c1 /= c)]

main :: IO ()
main = print (levenshtein "kitten" "sitting")


procedure main()
    every process(!&input)
end

procedure process(s)
    s ? (s1 := tab(upto(' \t')), s2 := (tab(many(' \t')), tab(0))) | fail
    write("'",s1,"' -> '",s2,"' = ", levenshtein(s1,s2))
end

procedure levenshtein(s, t)
    if (n := *s+1) = 1 then return *t
    if (m := *t+1) = 1 then return *s

    every !(d := list(n,0)) := list(m, 0)
    every i := 1 to max(n,m) do d[i,1] := d[1,i] := i
    every d[1(i := 2 to n, s_i := s[iM1 := i-1]), j := 2 to m] :=
             min(d[iM1,j], d[i,jM1:=j-1],
                 d[iM1,jM1] + if s_i == t[jM1] then -1 else 0) + 1

    return d[n,m]-1
end


Io 20110905
Io> Range ; "kitten" levenshtein("sitting")
==> 3
Io> "rosettacode" levenshtein("raisethysword")
==> 8
Io>


public class Levenshtein {

    public static int distance(String a, String b) {
        a = a.toLowerCase();
        b = b.toLowerCase();
        // i == 0
        int [] costs = new int [b.length() + 1];
        for (int j = 0; j < costs.length; j++)
            costs[j] = j;
        for (int i = 1; i <= a.length(); i++) {
            // j == 0; nw = lev(i - 1, j)
            costs[0] = i;
            int nw = i - 1;
            for (int j = 1; j <= b.length(); j++) {
                int cj = Math.min(1 + Math.min(costs[j], costs[j - 1]), a.charAt(i - 1) == b.charAt(j - 1) ? nw : nw + 1);
                nw = costs[j];
                costs[j] = cj;
            }
        }
        return costs[b.length()];
    }

    public static void main(String [] args) {
        String [] data = { "kitten", "sitting", "saturday", "sunday", "rosettacode", "raisethysword" };
        for (int i = 0; i < data.length; i += 2)
            System.out.println("distance(" + data[i] + ", " + data[i+1] + ") = " + distance(data[i], data[i+1]));
    }
}


function levenshtein(a, b) {
  var t = [], u, i, j, m = a.length, n = b.length;
  if (!m) { return n; }
  if (!n) { return m; }
  for (j = 0; j <= n; j++) { t[j] = j; }
  for (i = 1; i <= m; i++) {
    for (u = [i], j = 1; j <= n; j++) {
      u[j] = a[i - 1] === b[j - 1] ? t[j - 1] : Math.min(t[j - 1], t[j], u[j - 1]) + 1;
    } t = u;
  } return u[n];
}

// tests
[ ['', '', 0],
  ['yo', '', 2],
  ['', 'yo', 2],
  ['yo', 'yo', 0],
  ['tier', 'tor', 2],
  ['saturday', 'sunday', 3],
  ['mist', 'dist', 1],
  ['tier', 'tor', 2],
  ['kitten', 'sitting', 3],
  ['stop', 'tops', 2],
  ['rosettacode', 'raisethysword', 8],
  ['mississippi', 'swiss miss', 8]
].forEach(function(v) {
  var a = v[0], b = v[1], t = v[2], d = levenshtein(a, b);
  if (d !== t) {
    console.log('levenstein("' + a + '","' + b + '") was ' + d + ' should be ' + t);
  }
});


  9ms overhead (invoking jq and compiling the program)
 17ms for kitten/sitting
 67ms for rosettacode/raisethysword
 71ms for edocattesor/drowsyhtesiar


/* Levenshtein Distance, in Jsish */

function levenshtein(a, b) {
  var t = [], u, i, j, m = a.length, n = b.length;
  if (!m) { return n; }
  if (!n) { return m; }
  for (j = 0; j <= n; j++) { t[j] = j; }
  for (i = 1; i <= m; i++) {
    for (u = [i], j = 1; j <= n; j++) {
      u[j] = a[i - 1] === b[j - 1] ? t[j - 1] : Math.min(t[j - 1], t[j], u[j - 1]) + 1;
    } t = u;
  } return u[n];
}

provide('levenshtein', 1);

;levenshtein('', '');
;levenshtein('yo', '');
;levenshtein('', 'yo');
;levenshtein('yo', 'yo');
;levenshtein('tier', 'tor');
;levenshtein('saturday', 'sunday');
;levenshtein('mist', 'dist');
;levenshtein('tier', 'tor');
;levenshtein('kitten', 'sitting');
;levenshtein('stop', 'tops');
;levenshtein('rosettacode', 'raisethysword');
;levenshtein('mississippi', 'swiss miss');

/*
=!EXPECTSTART!=
levenshtein('', '') ==> 0
levenshtein('yo', '') ==> 2
levenshtein('', 'yo') ==> 2
levenshtein('yo', 'yo') ==> 0
levenshtein('tier', 'tor') ==> 2
levenshtein('saturday', 'sunday') ==> 3
levenshtein('mist', 'dist') ==> 1
levenshtein('tier', 'tor') ==> 2
levenshtein('kitten', 'sitting') ==> 3
levenshtein('stop', 'tops') ==> 2
levenshtein('rosettacode', 'raisethysword') ==> 8
levenshtein('mississippi', 'swiss miss') ==> 8
=!EXPECTEND!=
*/


function levendist(s::AbstractString, t::AbstractString)
    ls, lt = length.((s, t))
    ls == 0 && return lt
    lt == 0 && return ls

    s₁, t₁ = s[2:end], t[2:end]
    ld₁ = levendist(s₁, t₁)
    s[1] == t[1] ? ld₁ : 1 + min(ld₁, levendist(s, t₁), levendist(s₁, t))
end

@show levendist("kitten", "sitting") # 3
@show levendist("rosettacode", "raisethysword") # 8


// version 1.0.6

// Uses the "iterative with two matrix rows" algorithm referred to in the Wikipedia article.

fun levenshtein(s: String, t: String): Int {
    // degenerate cases
    if (s == t)  return 0
    if (s == "") return t.length
    if (t == "") return s.length

    // create two integer arrays of distances and initialize the first one
    val v0 = IntArray(t.length + 1) { it }  // previous
    val v1 = IntArray(t.length + 1)         // current

    var cost: Int
    for (i in 0 until s.length) {
        // calculate v1 from v0
        v1[0] = i + 1
        for (j in 0 until t.length) {
            cost = if (s[i] == t[j]) 0 else 1
            v1[j + 1] = Math.min(v1[j] + 1, Math.min(v0[j + 1] + 1, v0[j] + cost))
        }
        // copy v1 to v0 for next iteration
        for (j in 0 .. t.length) v0[j] = v1[j]
    }
    return v1[t.length]
}

fun main(args: Array<String>) {
    println("'kitten' to 'sitting'            => ${levenshtein("kitten", "sitting")}")
    println("'rosettacode' to 'raisethysword' => ${levenshtein("rosettacode", "raisethysword")}")
    println("'sleep' to 'fleeting'            => ${levenshtein("sleep", "fleeting")}")
}


(defun levenshtein-simple
  (('() str)
    (length str))
  ((str '())
    (length str))
  (((cons a str1) (cons b str2)) (when (== a b))
    (levenshtein-simple str1 str2))
  (((= (cons _ str1-tail) str1) (= (cons _ str2-tail) str2))
    (+ 1 (lists:min
          (list
           (levenshtein-simple str1 str2-tail)
           (levenshtein-simple str1-tail str2)
           (levenshtein-simple str1-tail str2-tail))))))


'Levenshtein Distance translated by Brandon Parker
'08/19/10
'from http://www.merriampark.com/ld.htm#VB
'No credit was given to the Visual Basic Author on the site :-(

Print LevenshteinDistance("kitten", "sitting")
End

'Get the minum of three values
Function Minimum(a, b, c)
    Minimum = Min(a, Min(b, c))
End Function

'Compute the Levenshtein Distance
Function LevenshteinDistance(string1$, string2$)
    n = Len(string1$)
    m = Len(string2$)
    If n = 0 Then
        LevenshteinDistance = m
        Exit Function
    End If
    If m = 0 Then
        LevenshteinDistance = n
        Exit Function
    End If
    Dim d(n, m)
    For i = 0 To n
        d(i, 0) = i
    Next i
    For i = 0 To m
        d(0, i) = i
    Next i
    For i = 1 To n
        si$ = Mid$(string1$, i, 1)
        For ii = 1 To m
            tj$ = Mid$(string2$, ii, 1)
            If si$ = tj$ Then
                cost = 0
            Else
                cost = 1
            End If
            d(i, ii) = Minimum((d(i - 1, ii) + 1), (d(i, ii - 1) + 1), (d(i - 1, ii - 1) + cost))
        Next ii
    Next i
    LevenshteinDistance = d(n, m)
End Function


implement Levenshtein;

include "sys.m"; sys: Sys;
	print: import sys;
include "draw.m";

Levenshtein: module {
	init: fn(nil: ref Draw->Context, args: list of string);
	# Export distance so that this module can be used as either a
	# standalone program or as a library:
	distance: fn(s, t: string): int;
};

init(nil: ref Draw->Context, args: list of string)
{
	sys = load Sys Sys->PATH;
	if(!(len args % 2)) {
		sys->fprint(sys->fildes(2), "Provide an even number of arguments!\n");
		raise "fail:usage";
	}
	args = tl args;

	while(args != nil) {
		(s, t) := (hd args, hd tl args);
		args = tl tl args;
		print("%s <-> %s => %d\n", s, t, distance(s, t));
	}
}

distance(s, t: string): int
{
	if(s == "")
		return len t;
	if(t == "")
		return len s;
	if(s[0] == t[0])
		return distance(s[1:], t[1:]);
	a := distance(s[1:], t);
	b := distance(s, t[1:]);
	c := distance(s[1:], t[1:]);
	if(a > b)
		a = b;
	if(a > c)
		a = c;
	return a + 1;
}


//Code By Neurox66
function Levenshtein pString1 pString2
   put 0 into tPosChar1
   repeat for each char tChar1 in pString1
      add 1 to tPosChar1
      put tPosChar1 into tDistance[tPosChar1][0]
      put 0 into tPosChar2
      repeat for each char tChar2 in pString2
         add 1 to tPosChar2
         put tPosChar2 into tDistance[0][tPosChar2]
         put 1 into tCost
         if tChar1 = tChar2 then
            put 0 into tCost
         end if
         put min((tDistance[tPosChar1-1][tPosChar2] + 1),(tDistance[tPosChar1][tPosChar2-1] + 1),(tDistance[tPosChar1-1][tPosChar2-1] + tCost)) into tDistance[tPosChar1][tPosChar2]
      end repeat
   end repeat
   return tDistance[tPosChar1][tPosChar2]
end Levenshtein

put Levenshtein("kitten","sitting")
put Levenshtein("rosettacode","raisethysword")


with Ada.Text_IO;         use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Main is
   subtype param_type is Integer range 1 .. 100;
   function lpd (n : in param_type) return param_type is
      result : param_type := 1;
   begin
      for divisor in reverse 1 .. n / 2 loop
         if n rem divisor = 0 then
            result := divisor;
            exit;
         end if;
      end loop;
      return result;
   end lpd;

begin
   for I in param_type loop
      Put (Item => lpd (I), Width => 3);
      if I rem 10 = 0 then
         New_Line;
      end if;
   end loop;
end Main;


FOR n TO 100 DO # show the largest proper divisors for n = 1..100 #
    INT largest proper divisor := 1;
    FOR j FROM ( n OVER 2 ) BY -1 TO 2 WHILE largest proper divisor = 1 DO
        IF n MOD j = 0 THEN
            largest proper divisor := j
        FI
    OD;
    print( ( whole( largest proper divisor, -3 ) ) );
    IF n MOD 10 = 0 THEN print( ( newline ) ) FI
OD


for n := 1 until 100 do begin % show the largest proper divisors for n = 1..100 %
    for j := n div 2 step -1 until 2 do begin
        if n rem j = 0 then begin
            writeon( i_w := 3, s_w := 0, j );
            goto foundLargestProperDivisor
        end if_n_rem_j_eq_0
    end for_j;
    writeon( i_w := 3, s_w := 0, 1 );
foundLargestProperDivisor:
    if n rem 10 = 0 then write()
end for_n.


def levenshtein(s: string, t: string) -> int:

    def makeNxM(n: int, m: int, v: int) -> [[int]]:
        let d:[[int]] = vector_reserve(typeof return, n)
        for(n) i:
            push(d, vector_reserve(typeof return, m))
            for(m) j:
                push(d[i], v)
        return d

    let ls = s.length
    let lt = t.length
    let d = makeNxM(ls + 1, lt + 1, -1)

    def dist (i: int, j: int) -> int:
        if d[i][j] >= 0:
            return d[i][j]
        var x = 0
        if i == ls:
            x = lt - j
        else: if j == lt:
            x = ls - i
        else: if s[i] == t[j]:
            x = dist(i + 1, j + 1)
        else:
            x = dist(i + 1, j + 1)
            x = min(x, dist(i, j + 1))
            x = min(x, dist(i + 1, j))
            x += 1
        d[i][j] = x
        return x

    return dist(0,0)

assert 3 == levenshtein("kitten", "sitting")
assert 8 == levenshtein("rosettacode", "raisethysword")


function leven(s,t)
    if s == '' then return t:len() end
    if t == '' then return s:len() end

    local s1 = s:sub(2, -1)
    local t1 = t:sub(2, -1)

    if s:sub(0, 1) == t:sub(0, 1) then
        return leven(s1, t1)
    end

    return 1 + math.min(
        leven(s1, t1),
        leven(s,  t1),
        leven(s1, t )
      )
end

print(leven("kitten", "sitting"))
print(leven("rosettacode", "raisethysword"))


on largestProperDivisor(n)
    if (n mod 2 = 0) then return n div 2
    if (n mod 3 = 0) then return n div 3
    if (n < 5) then return missing value
    repeat with i from 5 to (n ^ 0.5 div 1) by 6
        if (n mod i = 0) then return n div i
        if (n mod (i + 2) = 0) then return n div (i + 2)
    end repeat
    return 1
end largestProperDivisor

on task(max)
    script o
        property LPDs : {}
        property output : {}
    end script

    set w to (count (max as text)) * 2 + 3
    set padding to text 1 thru (w - 2) of "          "
    set end of o's LPDs to "1:1" & padding
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to ""
    set c to 1
    repeat with n from 2 to max
        set end of o's LPDs to text 1 thru w of ((n as text) & ":" & largestProperDivisor(n) & padding)
        set c to c + 1
        if (c mod 10 is 0) then
            set end of o's output to o's LPDs as text
            set o's LPDs to {}
        end if
    end repeat
    if (c mod 10 > 0) then set end of o's output to o's LPDs as text
    set AppleScript's text item delimiters to linefeed
    set o's output to o's output as text
    set AppleScript's text item delimiters to astid

    return o's output
end task

task(100)


loop split.every:10 [1] ++ map 2..100 'x -> last chop factors x 'row [
    print map to [:string] row 'r -> pad r 5
]


Module Checkit {
	\\ Iterative with two matrix rows
	function LevenshteinDistance(s$,t$) {
		if len(s$)<len(t$) then swap s$, t$
		n=len(t$)
		m=len(s$)
		dim base 0, v0(n+1), v1(n+1)
Rem		dim sw()  ' we can use stack of values to make the swap.
		for i=0 to n : v0(i)=i:next
		for i=0 to m-1
			v1(0)=i+1
			for j=0 to n-1
				deletioncost=v0(j+1)+1
				insertioncost=v1(j)+1
				if mid$(s$,i+1,1)=mid$(t$,j+1,1) then
					substitutionCost=v0(j)
				else
					substitutionCost=v0(j)+1
				end if
				v1(j+1)=min.data(deletionCost, insertionCost, substitutionCost)
			next
Rem			sw()=v0():v0()=v1():v1()=sw()
			\\ when we push arrays, we only push a pointer to
			\\ when we read array (identifier with parenthesis) then we get a copy
			\\ between Push and Read any change on arrays included in copies
			Push v0(),v1(): Read v0(),v1()
		next
		=v0(n)
	}
	Print LevenshteinDistance("kitten","sitting")=3  ' true
	Print LevenshteinDistance("Sunday","Saturday")=3  ' true
	Print LevenshteinDistance("rosettacode","raisethysword")=8  ' true
}
Checkit

Module Checkit2 {
	\\ Iterative with two matrix rows, using pointers to arrays
	function LevenshteinDistance(s$,t$) {
		if len(s$)<len(t$) then swap s$, t$
		n=len(t$)
		m=len(s$)
		dim base 0, v0(n+1), v1(n+1)
		v0=v0()  ' v0 is pointer to v0()
		v1=v1() ' v1 is pointer to v1()
		for i=0 to n : v0(i)=i:next
		for i=0 to m-1
			return v1, 0:=i+1
			for j=0 to n-1
				deletioncost=Array(v0,j+1)+1
				insertioncost=Array(v1,j)+1
				if mid$(s$,i+1,1)=mid$(t$,j+1,1) then
					substitutionCost=Array(v0,j)
				else
					substitutionCost=Array(v0,j)+1
				end if
				return v1, j+1:=min.data(deletionCost, insertionCost, substitutionCost)
			next
			swap v0, v1  ' just swap pointers
		next
		=Array(v0,n)
	}
	Print LevenshteinDistance("kitten","sitting")=3
	Print LevenshteinDistance("Sunday","Saturday")=3
	Print LevenshteinDistance("rosettacode","raisethysword")=8
}
Checkit2


> with(StringTools):
> Levenshtein("kitten","sitting");
                                   3

> Levenshtein("rosettacode","raisethysword");
                                   8


# syntax: GAWK -f LARGEST_PROPER_DIVISOR_OF_N.AWK
# converted from C
BEGIN {
    start = 1
    stop = 100
    for (i=start; i<=stop; i++) {
      printf("%3d%1s",largest_proper_divisor(i),++count%10?"":"\n")
    }
    printf("\nLargest proper divisor of n %d-%d\n",start,stop)
    exit(0)
}
function largest_proper_divisor(n,  i) {
    if (n <= 1) {
      return(1)
    }
    for (i=n-1; i>0; i--) {
      if (n % i == 0) {
        return(i)
      }
    }
}


10 DEFINT A-Z
20 FOR I=1 TO 100
30 IF I=1 THEN PRINT "  1";: GOTO 70
40 FOR J=I-1 TO 1 STEP -1
50 IF I MOD J=0 THEN PRINT USING "###";J;: GOTO 70
60 NEXT J
70 IF I MOD 10=0 THEN PRINT
80 NEXT I


print "El mayor divisor propio de n es:\n"
print " 1  1 ";
for i = 3 to 100
	for j = i-1 to 1 step -1
		If i % j = 0 then
			print " "; j; " ";
			exit for
		end if
	next  j
	if i % 10 = 0 then print
next i
end


get "libhdr"

let lpd(n) = valof
    for i = n<=1 -> 1, n-1 to 1 by -1
        if n rem i=0 resultis i

let start() be
    for i=1 to 100
    $(  writed(lpd(i), 3)
        if i rem 10=0 then wrch('*N')
    $)


function score = levenshtein(s1, s2)
% score = levenshtein(s1, s2)
%
% Calculates the area under the ROC for a given set
% of posterior predictions and labels. Currently limited to two classes.
%
% s1: string
% s2: string
% score: levenshtein distance
%
% Author: Ben Hamner ([email protected])
if length(s1) < length(s2)
score = levenshtein(s2, s1);
elseif isempty(s2)
score = length(s1);
else
previous_row = 0:length(s2);
for i=1:length(s1)
current_row = 0*previous_row;
current_row(1) = i;
for j=1:length(s2)
insertions = previous_row(j+1) + 1;
deletions = current_row(j) + 1;
substitutions = previous_row(j) + (s1(i) ~= s2(j));
current_row(j+1) = min([insertions, deletions, substitutions]);
end
previous_row = current_row;
end
score = current_row(end);
end


import "stringUtil"
print "kitten".editDistance("sitting")


#include <stdio.h>

unsigned int lpd(unsigned int n) {
    if (n<=1) return 1;
    int i;
    for (i=n-1; i>0; i--)
        if (n%i == 0) return i;
}

int main() {
    int i;
    for (i=1; i<=100; i++) {
        printf("%3d", lpd(i));
        if (i % 10 == 0) printf("\n");
    }
    return 0;
}


#include <cassert>
#include <iomanip>
#include <iostream>

int largest_proper_divisor(int n) {
    assert(n > 0);
    if ((n & 1) == 0)
        return n >> 1;
    for (int p = 3; p * p <= n; p += 2) {
        if (n % p == 0)
            return n / p;
    }
    return 1;
}

int main() {
    for (int n = 1; n < 101; ++n) {
        std::cout << std::setw(2) << largest_proper_divisor(n)
            << (n % 10 == 0 ? '\n' : ' ');
    }
}


include "cowgol.coh";

sub print3(n: uint8) is
    print_char(' ');
    if n>9 then
        print_char('0' + n/10);
    else
        print_char(' ');
    end if;
    print_char('0' + n%10);
end sub;

sub lpd(n: uint8): (r: uint8) is
    if n <= 1 then
        r := 1;
    else
        r := n - 1;
        while r > 0 loop
            if n % r == 0 then
                break;
            end if;
            r := r - 1;
        end loop;
    end if;
end sub;

var i: uint8 := 1;
while i <= 100 loop
    print3(lpd(i));
    if i%10 == 0 then
        print_nl();
    end if;
    i := i + 1;
end loop;


MODULE LevenshteinDistance;
FROM InOut IMPORT WriteString, WriteCard, WriteLn;
FROM Strings IMPORT Length;

PROCEDURE levenshtein(s, t: ARRAY OF CHAR): CARDINAL;
    CONST MaxLen = 15;
    VAR d: ARRAY [0..MaxLen],[0..MaxLen] OF CARDINAL;
        lenS, lenT, i, j: CARDINAL;

    PROCEDURE min(a, b: CARDINAL): CARDINAL;
    BEGIN
        IF a<b THEN RETURN a;
        ELSE RETURN b;
        END;
    END min;
BEGIN
    lenS := Length(s);
    lenT := Length(t);

    IF lenS = 0 THEN RETURN lenT;
    ELSIF lenT = 0 THEN RETURN lenS;
    ELSE
        FOR i := 0 TO lenS DO d[i,0] := i; END;
        FOR j := 0 TO lenT DO d[0,j] := j; END;
        FOR i := 1 TO lenS DO
            FOR j := 1 TO lenT DO
                IF s[i-1] = t[j-1] THEN
                    d[i,j] := d[i-1,j-1];
                ELSE
                    d[i,j] :=
                      min(d[i-1,j] + 1,
                      min(d[i,j-1] + 1, d[i-1,j-1]+1));
                END;
            END;
        END;
        RETURN d[lenS,lenT];
    END;
END levenshtein;

PROCEDURE ShowDistance(s, t: ARRAY OF CHAR);
BEGIN
    WriteString(s);
    WriteString(" -> ");
    WriteString(t);
    WriteString(": ");
    WriteCard(levenshtein(s, t), 0);
    WriteLn();
END ShowDistance;

BEGIN
    ShowDistance("kitten", "sitting");
    ShowDistance("rosettacode", "raisethysword");
END LevenshteinDistance.


proc nonrec lpd(word n) word:
    word d;
    if n=1 then
        1
    else
        d := n-1;
        while n % d /= 0 do d := d-1 od;
        d
    fi
corp

proc nonrec main() void:
    word n;
    for n from 1 upto 100 do
        write(lpd(n):3);
        if n%10 = 0 then writeln() fi
    od
corp


// Largest proper divisor of n: Nigel Galloway. June 2nd., 2021
let fN g=let rec fN n=let i=Seq.head n in match(g/i,g%i) with (1,_)->1 |(n,0)->n |_->fN(Seq.tail n) in fN(Seq.initInfinite((+)2))
seq{yield 1; yield! seq{2..100}|>Seq.map fN}|>Seq.iter(printf "%d "); printfn ""


USING: grouping kernel math math.bitwise math.functions
math.ranges prettyprint sequences ;

: odd ( m -- n )
    dup 3 /i 1 - next-odd 1 -2 <range>
    [ divisor? ] with find nip ;

: largest ( m -- n ) dup odd? [ odd ] [ 2/ ] if ;

100 [1,b] [ largest ] map 10 group simple-table.


Func Lpd(n) =
    if n = 1 then Return(1) fi;
    for i = n\2 to 1 by -1 do
        if n|i = 0 then Return(i) fi;
    od.;

for m = 1 to 100 do
    !(Lpd(m):4);
    if m|10=0 then ! fi;
od;


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

n = 0
w = ''
n = n + 1; w[0] = n; w[n] = "kitten sitting"
n = n + 1; w[0] = n; w[n] = "rosettacode raisethysword"

loop n = 1 to w[0]
  say w[n].word(1) "->" w[n].word(2)":" levenshteinDistance(w[n].word(1), w[n].word(2))
  end n
return

method levenshteinDistance(s, t) private static
  s = s.lower
  t = t.lower

  m = s.length
  n = t.length

  -- for all i and j, d[i,j] will hold the Levenshtein distance between
  -- the first i characters of s and the first j characters of t;
  -- note that d has (m+1)x(n+1) values
  d = 0

  -- source prefixes can be transformed into empty string by
  -- dropping all characters (Note, ooRexx arrays are 1-based)
  loop i = 2 to m + 1
    d[i, 1] = 1
  end i

  -- target prefixes can be reached from empty source prefix
  -- by inserting every characters
  loop j = 2 to n + 1
    d[1, j] = 1
  end j

  loop j = 2 to n + 1
    loop i = 2 to m + 1
      if s.substr(i - 1, 1) == t.substr(j - 1, 1) then do
        d[i, j] = d[i - 1, j - 1]   -- no operation required
        end
      else do
        d[i, j] =                 -
          (d[i - 1, j] + 1).min(  - -- a deletion
          (d[i, j - 1] + 1)).min( - -- an insertion
          (d[i - 1, j - 1] + 1))    -- a substitution
        end
    end i
  end j

  return d[m + 1, n + 1]


import std/editdistance

echo editDistanceAscii("kitten", "sitting")
echo editDistanceAscii("rosettacode", "raisethysword")


: largest-proper-divisor { n -- n }
  n 1 and 0= if n 2/ exit then
  3
  begin
    dup dup * n <=
  while
    dup n swap /mod swap
    0= if nip exit else drop then
    2 +
  repeat drop 1 ;

: main
  101 1 do
    i largest-proper-divisor 2 .r
    i 10 mod 0= if cr else space then
  loop ;

main
bye


       program LargestProperDivisors
       implicit none
       integer i, lpd
       do 10 i=1, 100
           write (*,'(I3)',advance='no') lpd(i)
 10        if (i/10*10 .eq. i) write (*,*)
       end program

       integer function lpd(n)
       implicit none
       integer n, i
       if (n .le. 1) then
           lpd = 1
       else
           do 10 i=n-1, 1, -1
 10            if (n/i*i .eq. n) goto 20
 20        lpd = i
       end if
       end function


Print !"El mayor divisor propio de n es:\n"
Print "  1  1";
For i As Byte = 3 To 100
    For j As Byte = i-1 To 1 Step -1
        If i Mod j = 0 Then Print Using "###"; j; : Exit For
    Next  j
    If i Mod 10 = 0 Then Print
Next i
Sleep


for n = 1 to 100
   println[last[allFactors[n,true,false]]]


package main

import "fmt"

func largestProperDivisor(n int) int {
    for i := 2; i*i <= n; i++ {
        if n%i == 0 {
            return n / i
        }
    }
    return 1
}

func main() {
    fmt.Println("The largest proper divisors for numbers in the interval [1, 100] are:")
    fmt.Print(" 1  ")
    for n := 2; n <= 100; n++ {
        if n%2 == 0 {
            fmt.Printf("%2d  ", n/2)
        } else {
            fmt.Printf("%2d  ", largestProperDivisor(n))
        }
        if n%10 == 0 {
            fmt.Println()
        }
    }
}


10 PRINT 1;
20 FOR I = 1 TO 101
30 FOR D = I\2 TO 1 STEP -1
40 IF I MOD D = 0 THEN PRINT D; : GOTO 60
50 NEXT D
60 NEXT I


import Data.List.Split (chunksOf)
import Text.Printf (printf)

lpd :: Int -> Int
lpd 1 = 1
lpd n = head [x | x <- [n -1, n -2 .. 1], n `mod` x == 0]

main :: IO ()
main =
  (putStr . unlines . map concat . chunksOf 10) $
     printf "%3d" . lpd <$> [1 .. 100]


@interface NSString (levenshteinDistance)
- (NSUInteger)levenshteinDistanceToString:(NSString *)string;
@end

@implementation NSString (levenshteinDistance)
- (NSUInteger)levenshteinDistanceToString:(NSString *)string {
    NSUInteger sl = [self length];
    NSUInteger tl = [string length];
    NSUInteger *d = calloc(sizeof(*d), (sl+1) * (tl+1));

#define d(i, j) d[((j) * sl) + (i)]
    for (NSUInteger i = 0; i <= sl; i++) {
        d(i, 0) = i;
    }
    for (NSUInteger j = 0; j <= tl; j++) {
        d(0, j) = j;
    }
    for (NSUInteger j = 1; j <= tl; j++) {
        for (NSUInteger i = 1; i <= sl; i++) {
            if ([self characterAtIndex:i-1] == [string characterAtIndex:j-1]) {
                d(i, j) = d(i-1, j-1);
            } else {
                d(i, j) = MIN(d(i-1, j), MIN(d(i, j-1), d(i-1, j-1))) + 1;
            }
        }
    }

    NSUInteger r = d(sl, tl);
#undef d

    free(d);

    return r;
}
@end


# (1|largestpd) is 1 as per the task definition
def largestpd:
  if . == 1 then 1
  else . as $n
  | first( range( ($n - ($n % 2)) /2; 0; -1) | (select($n % . == 0) ))
  end;


largestpd(n) = (for i in n÷2:-1:1 (n % i == 0) && return i; end; 1)

foreach(n -> print(rpad(largestpd(n), 3), n % 10 == 0 ? "\n" : ""), 1:100)


            NORMAL MODE IS INTEGER

            INTERNAL FUNCTION(N)
            ENTRY TO LPD.
            WHENEVER N.LE.1, FUNCTION RETURN 1
            THROUGH TEST, FOR D=N-1, -1, D.L.1
TEST        WHENEVER N/D*D.E.N, FUNCTION RETURN D
            END OF FUNCTION

            THROUGH SHOW, FOR I=1, 10, I.GE.100
SHOW        PRINT FORMAT TABLE,
          0     LPD.(I), LPD.(I+1), LPD.(I+2), LPD.(I+3),
          1     LPD.(I+4), LPD.(I+5), LPD.(I+6), LPD.(I+7),
          2     LPD.(I+8), LPD.(I+9)

            VECTOR VALUES TABLE = $10(I3)*$
            END OF PROGRAM


Last[Prepend[DeleteCases[Divisors[#], #], 1]] & /@ Range[100]


MODULE LargestProperDivisor;
FROM InOut IMPORT WriteCard, WriteLn;

VAR i: CARDINAL;

PROCEDURE lpd(n: CARDINAL): CARDINAL;
    VAR i: CARDINAL;
BEGIN
    IF n=1 THEN
        RETURN 1;
    END;

    FOR i := n DIV 2 TO 1 BY -1 DO
        IF n MOD i = 0 THEN
            RETURN i;
        END;
    END;
END lpd;

BEGIN
    FOR i := 1 TO 100 DO
        WriteCard(lpd(i), 3);
        IF i MOD 10 = 0 THEN
            WriteLn();
        END;
    END;
END LargestProperDivisor.


let minimum a b c =
  min a (min b c)

let levenshtein_distance s t =
  let m = String.length s
  and n = String.length t in
  (* for all i and j, d.(i).(j) will hold the Levenshtein distance between
     the first i characters of s and the first j characters of t *)
  let d = Array.make_matrix (m+1) (n+1) 0 in

  for i = 0 to m do
    d.(i).(0) <- i  (* the distance of any first string to an empty second string *)
  done;
  for j = 0 to n do
    d.(0).(j) <- j  (* the distance of any second string to an empty first string *)
  done;

  for j = 1 to n do
    for i = 1 to m do

      if s.[i-1] = t.[j-1] then
        d.(i).(j) <- d.(i-1).(j-1)  (* no operation required *)
      else
        d.(i).(j) <- minimum
                       (d.(i-1).(j) + 1)   (* a deletion *)
                       (d.(i).(j-1) + 1)   (* an insertion *)
                       (d.(i-1).(j-1) + 1) (* a substitution *)
    done;
  done;

  d.(m).(n)
;;

let test s t =
  Printf.printf " %s -> %s = %d\n" s t (levenshtein_distance s t);
;;

let () =
  test "kitten" "sitting";
  test "rosettacode" "raisethysword";
;;


import math, strutils

func largestProperDivisor(n: Positive): int =
  for d in 2..sqrt(float(n)).int:
    if n mod d == 0: return n div d
  result = 1

for n in 1..100:
  stdout.write ($n.largestProperDivisor).align(2), if n mod 10 == 0: '\n' else: ' '


program LarPropDiv;

function LargestProperDivisor(n:NativeInt):NativeInt;
//searching upwards to save time for example 100
//2..sqrt(n) aka 1..10 instead downwards n..sqrt(n) 100..10
var
  i,j: NativeInt;
Begin
  i := 2;
  repeat
    If n Mod i = 0 then
    Begin
      LargestProperDivisor := n DIV i;
      EXIT;
    end;
    inc(i);
  until i*i > n;
  LargestProperDivisor := 1;
end;
var
  n : Uint32;
begin
  for n := 1 to 100 do
  Begin
    write(LargestProperDivisor(n):4);
    if n mod 10 = 0 then
      Writeln;
  end;
end.


use strict;
use warnings;
use ntheory 'divisors';
use List::AllUtils <max natatime>;

sub proper_divisors {
  my $n = shift;
  return 1 if $n == 0;
  my @d = divisors($n);
  pop @d;
  @d;
}

my @range = 1 .. 100;
print "GPD for $range[0] through $range[-1]:\n";
my $iter = natatime 10, @range;
while( my @batch = $iter->() ) {
    printf '%3d', $_ == 1 ? 1 : max proper_divisors($_) for @batch; print "\n";
}


say "kitten -> sitting:" levenshteinDistance("kitten", "sitting")
say "rosettacode -> raisethysword:" levenshteinDistance("rosettacode", "raisethysword")

::routine levenshteinDistance
  use arg s, t
  s = s~lower
  t = t~lower

  m = s~length
  n = t~length

  -- for all i and j, d[i,j] will hold the Levenshtein distance between
  -- the first i characters of s and the first j characters of t;
  -- note that d has (m+1)x(n+1) values
  d = .array~new(m + 1, n + 1)

  -- clear all elements in d
  loop i = 1 to d~dimension(1)
      loop j = 1 to d~dimension(2)
          d[i, j] = 0
      end
  end

  -- source prefixes can be transformed into empty string by
  -- dropping all characters (Note, ooRexx arrays are 1-based)
  loop i = 2 to m + 1
      d[i, 1] = 1
  end

  -- target prefixes can be reached from empty source prefix
  -- by inserting every characters
  loop j = 2 to n + 1
      d[1, j] = 1
  end

  loop j = 2 to n + 1
      loop i = 2 to m + 1
          if s~subchar(i - 1) == t~subchar(j - 1) then
              d[i, j] = d[i - 1, j - 1]   -- no operation required
          else d[i, j] = min(d[i - 1, j] + 1,    - -- a deletion
                             d[i, j-1] + 1,      - -- an insertion
                             d[i - 1, j - 1] + 1)  -- a substitution
      end
  end

  return d[m + 1, n + 1 ]


\\ Levenshtein distance between two words
\\ 6/21/16 aev
levensDist(s1,s2)={
my(n1=#s1,n2=#s2,v1=Vecsmall(s1),v2=Vecsmall(s2),c,
   n11=n1+1,n21=n2+1,t=vector(n21,z,z-1),u0=vector(n21),u=u0);
if(s1==s2, return(0)); if(!n1, return(n2)); if(!n2, return(n1));
for(i=2,n11, u=u0; u[1]=i-1;
  for(j=2,n21,
    if(v1[i-1]==v2[j-1], c=t[j-1], c=vecmin([t[j-1],t[j],u[j-1]])+1);
    u[j]=c;
  );\\fend j
  t=u;
);\\fend i
print(" *** Levenshtein distance = ",t[n21]," for strings: ",s1,", ",s2);
return(t[n21]);
}
{ \\ Testing:
levensDist("kitten","sitting");
levensDist("rosettacode","raisethysword");
levensDist("Saturday","Sunday");
levensDist("oX","X");
levensDist("X","oX");
}


largestProperDivisor: procedure options(main);
    lpd: procedure(n) returns(fixed);
        declare (n, i) fixed;
        if n <= 1 then return(1);
        do i=n-1 repeat(i-1) while(i>=1);
            if mod(n,i)=0 then return(i);
        end;
    end lpd;

    declare i fixed;
    do i=1 to 100;
        put edit(lpd(i)) (F(3));
        if mod(i,10)=0 then put skip;
    end;
end largestProperDivisor;


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

PRINT$3: PROCEDURE (N);
    DECLARE N BYTE;
    CALL PUT$CHAR(' ');
    IF N>9
        THEN CALL PUT$CHAR('0' + N/10);
        ELSE CALL PUT$CHAR(' ');
    CALL PUT$CHAR('0' + N MOD 10);
END PRINT$3;

LPD: PROCEDURE (N) BYTE;
    DECLARE (N, I) BYTE;
    IF N <= 1 THEN RETURN 1;
    I = N-1;
    DO WHILE I >= 1;
        IF N MOD I = 0 THEN RETURN I;
        I = I - 1;
    END;
END LPD;

DECLARE I BYTE;
DO I=1 TO 100;
    CALL PRINT$3(LPD(I));
    IF I MOD 10 = 0 THEN CALL PRINT(.(13,10,'$'));
END;
CALL EXIT;
EOF


Program LevenshteinDistanceDemo(output);

uses
  Math;

function LevenshteinDistance(s, t: string): longint;
  var
    d: array of array of integer;
    i, j, n, m: integer;
  begin
    n := length(t);
    m := length(s);
    setlength(d, m+1, n+1);

    for i := 0 to m do
      d[i,0] := i;
    for j := 0 to n do
      d[0,j] := j;
    for j := 1 to n do
      for i := 1 to m do
        if s[i] = t[j] then
          d[i,j] := d[i-1,j-1]
        else
          d[i,j] := min(d[i-1,j] + 1, min(d[i,j-1] + 1, d[i-1,j-1] + 1));
    LevenshteinDistance := d[m,n];
  end;

var
  s1, s2: string;

begin
  s1 := 'kitten';
  s2 := 'sitting';
  writeln('The Levenshtein distance between "', s1, '" and "', s2, '" is: ', LevenshteinDistance(s1, s2));
  s1 := 'rosettacode';
  s2 := 'raisethysword';
  writeln('The Levenshtein distance between "', s1, '" and "', s2, '" is: ', LevenshteinDistance(s1, s2));
end.


Procedure.i lpd(v.i)
  For i=v/2 To 1 Step -1
    If v%i=0 : ProcedureReturn i : EndIf
  Next
  ProcedureReturn 1
EndProcedure

If OpenConsole("")
  For i=1 To 100
    Print(RSet(Str(lpd(i)),3))
    If i%10=0 : PrintN("") : EndIf
  Next
  Input()
EndIf


def lpd(n):
    for i in range(n-1,0,-1):
        if n%i==0: return i
    return 1

for i in range(1,101):
    print("{:3}".format(lpd(i)), end=i%10==0 and '\n' or '')


' [ 1 ] 99 times
  [ i^ 2 + factors
    -2 peek join ]
echo


largest_proper_divisor <- function(n){
  if(n == 1) return(1)

  lpd = 1

  for(i in seq(1, n-1, 1)){
    if(n %% i == 0)
      lpd = i
  }

  message(paste0("The largest proper divisor of ", n, " is ", lpd))
  return(lpd)
}

#Verify
for (i in 1:100){       #about 10 seconds to calculate until 10000
  largest_proper_divisor(i)
}


use Prime::Factor;

for 0, 2**67 - 1 -> $add {
    my $start = now;

    my $range = $add + 1 .. $add + 100;

    say "GPD for {$range.min} through {$range.max}:";

    say ( $range.hyper(:14batch).map: {$_ == 1 ?? 1 !! $_ %% 2 ?? $_ / 2 !! .&proper-divisors.max} )\
        .batch(10)».fmt("%{$add.chars + 1}d").join: "\n";

    say (now - $start).fmt("%0.3f seconds\n");
}


use List::Util qw(min);

my %cache;

sub leven {
    my ($s, $t) = @_;

    return length($t) if $s eq '';
    return length($s) if $t eq '';

    $cache{$s}{$t} //=    # try commenting out this line
      do {
        my ($s1, $t1) = (substr($s, 1), substr($t, 1));

        (substr($s, 0, 1) eq substr($t, 0, 1))
          ? leven($s1, $t1)
          : 1 + min(
                    leven($s1, $t1),
                    leven($s,  $t1),
                    leven($s1, $t ),
            );
      };
}

print leven('rosettacode', 'raisethysword'), "\n";


/*REXX program finds the largest proper divisors of all numbers  (up to a given limit). */
parse arg n cols .                               /*obtain optional argument from the CL.*/
if    n=='' |    n==","  then    n= 101          /*Not specified?  Then use the default.*/
if cols=='' | cols==","  then cols=  10          /* "      "         "   "   "     "    */
w= length(n)  +  1                               /*W:  the length of any output column. */
@LPD = "largest proper divisor of  N,  where  N  < "       n
idx = 1                                          /*initialize the index (output counter)*/
say ' index │'center(@LPD,  1 + cols*(w+1)     ) /*display the title for the output.    */
say '───────┼'center(""  ,  1 + cols*(w+1), '─') /*   "     "   sep   "   "     "       */
$=                                               /*a list of largest proper divs so far.*/
     do j=1  for n-1;  $= $ right(LPDIV(j), w)   /*add a largest proper divisor ──► list*/
     if j//cols\==0  then iterate                /*have we populated a line of output?  */
     say center(idx, 7)'│'  substr($, 2);   $=   /*display what we have so far  (cols). */
     idx= idx + cols                             /*bump the  index  count for the output*/
     end   /*j*/

if $\==''  then say center(idx, 7)"│"  substr($, 2)  /*possible display residual output.*/
say '───────┴'center(""  ,  1 + cols*(w+1), '─') /*display the foot separator.          */
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
LPDIV:  procedure; parse arg x;  if x<4  then return 1   /*obtain  X;  test if  X < 4.  */
        odd= x // 2;    beg= x % 2                       /*use BEG as the first divisor.*/
        if odd  then if beg//2==0  then beg= beg -  1    /*Is X odd?  Then make BEG odd.*/
                   do k=beg  by -1-odd           /*begin at halfway point and decrease. */
                   if x//k==0  then return k     /*Remainder=0?  Got largest proper div.*/
                   end   /*k*/
                                    return 1     /*If we get here,  then  X  is a prime.*/


? "working..."
limit = 100
? "Largest proper divisor up to " + limit + " are:"
see " 1 "
col = 1

for n = 2 to limit
    for m = 1 to n >> 1
        if n % m = 0 div = m ok
    next
    if div < 10 see " " ok
    see "" + div + " "
    if col++ % 10 = 0 ? "" ok
next
? "done..."


require 'prime'

def a(n)
  return 1 if n == 1 || n.prime?
  (n/2).downto(1).detect{|d| n.remainder(d) == 0}
end

(1..100).map{|n| a(n).to_s.rjust(3)}.each_slice(10){|slice| puts slice.join}


with javascript_semantics

requires("0.8.2") -- (just the use of papply() at the end)

function levenshtein(string a, b)
    integer n = length(a),
            m = length(b)
    if n=0 then return m end if
    if m=0 then return n end if
    sequence d = repeat(repeat(0, m+1), n+1)
    for i=1 to n do
        d[i+1][1] = i
        for j=1 to m do
            d[1][j+1] = j
            --   next  := min({ prev  +substitution,  deletion, or insertion }):
            d[i+1][j+1] = min({d[i][j]+(a[i]!=b[j]), d[i][j+1]+1, d[i+1][j]+1})
        end for
    end for
    return d[$][$]
end function

procedure test(string s1, s2, integer expected)
    integer actual = levenshtein(s1,s2)
    if actual!=expected
    or actual!=levenshtein(s2,s1)
    or actual!=levenshtein(reverse(s1),reverse(s2))
    or actual!=levenshtein(reverse(s2),reverse(s1)) then
        crash("oh dear...")
    end if
    printf(1,"%14q <== %d ==> %q\n",{s1,actual,s2})
end procedure

constant tests = {{"kitten", "sitting", 3},
                  {"rosettacode", "raisethysword", 8},
                  {"abcdefgh", "defghabc", 6},
                  {"saturday", "sunday", 3},
                  {"sleep", "fleeting", 5},
                  {"", "four", 4},
                  {"", "", 0}}
papply(false,test,tests)


$ include "seed7_05.s7i";

const func integer: largestProperDivisor (in integer: number) is func
  result
    var integer: divisor is 0;
  begin
    if not odd(number) then
      divisor := number >> 1;
    else
      divisor := number div 3 - 1;
      if odd(divisor) then
        divisor +:= 2;
      else
        incr(divisor);
      end if;
      while number rem divisor <> 0 do
        divisor -:= 2;
      end while;
    end if;
  end func;

const proc: main is func
  local
    var integer: n is 0;
  begin
    for n range 1 to 100 do
      write(largestProperDivisor(n) lpad 3);
      if n rem 10 = 0 then
        writeln;
      end if;
    end for;
  end func;


import Foundation

func largestProperDivisor(_ n : Int) -> Int? {
    guard n > 0 else {
        return nil
    }
    if (n & 1) == 0 {
        return n >> 1
    }
    var p = 3
    while p * p <= n {
        if n % p == 0 {
            return n / p
        }
        p += 2
    }
    return 1
}

for n in (1..<101) {
    print(String(format: "%2d", largestProperDivisor(n)!),
          terminator: n % 10 == 0 ? "\n" : " ")
}


PRINT "El mayor divisor propio de n es:"
PRINT
PRINT "  1  1";
FOR i = 3 TO 100
    FOR j = i-1 TO 1 STEP -1
        IF remainder(i, j) = 0 THEN
           PRINT USING$("###", j);
           EXIT FOR
        END IF
    NEXT  j
    IF remainder(i, 10) = 0 THEN PRINT
NEXT i
END


fn largest_proper_divisor(n int) int {
    for i := 2; i*i <= n; i++ {
        if n%i == 0 {
            return n / i
        }
    }
    return 1
}

fn main() {
    println("The largest proper divisors for numbers in the interval [1, 100] are:")
    print(" 1  ")
    for n := 2; n <= 100; n++ {
        if n%2 == 0 {
            print("${n/2:2}  ")
        } else {
            print("${largest_proper_divisor(n):2}  ")
        }
        if n%10 == 0 {
            println('')
        }
    }
}


import "/math" for Int
import "/fmt" for Fmt

System.print("The largest proper divisors for numbers in the interval [1, 100] are:")
System.write(" 1  ")
for (n in 2..100) {
    if (n % 2 == 0) {
        Fmt.write("$2d  ", n / 2)
    } else {
        Fmt.write("$2d  ", Int.properDivisors(n)[-1])
    }
    if (n % 10 == 0) System.print()
}


echo levenshtein('kitten','sitting');
echo levenshtein('rosettacode', 'raisethysword');


levenshtein(S,T) = Dist =>
  M = 1+S.length,
  N = 1+T.length,

  D = new_array(M,N),

  foreach(I in 1..M)
    D[I,1] := I-1
  end,

  foreach(J in 1..N)
    D[1,J] := J-1
  end,

  foreach(J in 2..N, I in 2..M)
    if S[I-1] == T[J-1] then
      D[I,J] := D[I-1,J-1]            % no operation required
    else
      D[I,J] := min([D[I-1,J  ] + 1,  % a deletion
                     D[I  ,J-1] + 1,  % an insertion
                     D[I-1,J-1] + 1]  % a substitution
                    )
    end
  end,

  Dist = D[M,N].


print "El mayor divisor propio de n es:\n"
print " 1  1 ";
for i = 3 to 100
	for j = i-1 to 1 step -1
		If mod(i, j) = 0 then print j using "##"; : break : fi
	next  j
    if mod(i, 10) = 0 then print : fi
next i
print
end


      1                              ;Assemble with: tasm, tlink /t
      2 0000                                 .model  tiny
      3 0000                                 .code
      4                                      org     100h            ;.com program starts here
      5
      6                              ;bl = D = divisor
      7                              ;bh = N
      8
      9 0100  B7 01                  start:  mov     bh, 1           ;for N:= 1 to 100 do
     10 0102  8A DF                  d10:    mov     bl, bh          ;D:= if N=1 then 1 else N/2
     11 0104  D0 EB                          shr     bl, 1
     12 0106  75 02                          jne     d15
     13 0108  FE C3                           inc    bl
     14 010A                         d15:
     15 010A  8A C7                  d20:    mov     al, bh          ;while rem(N/D) # 0 do
     16 010C  98                             cbw                     ; ah:= 0 (extend sign of al into ah)
     17 010D  F6 FB                          idiv    bl              ; al:= ax/bl; ah:= remainder
     18 010F  84 E4                          test    ah, ah
     19 0111  74 04                          je      d30
     20 0113  FE CB                           dec    bl              ; D--
     21 0115  EB F3                           jmp    d20
     22 0117                         d30:
     23 0117  8A C3                          mov     al, bl          ;output number in D
     24 0119  D4 0A                          aam     10              ;ah:= al/10; al:= remainder
     25 011B  50                             push    ax              ;save low digit in remainder
     26 011C  8A C4                          mov     al, ah          ;get high digit
     27 011E  04 20                          add     al, 20h         ;if zero make it a space char
     28 0120  84 E4                          test    ah, ah
     29 0122  74 02                          je      d50
     30 0124  04 10                           add    al, 10h         ;else make it into ASCII digit
     31 0126  CD 29                  d50:    int     29h             ;output high digit or space
     32 0128  58                             pop     ax              ;get low digit
     33 0129  04 30                          add     al, 30h         ;make it ASCII
     34 012B  CD 29                          int     29h             ;output low digit
     35
     36 012D  B0 20                          mov     al, 20h         ;output space char
     37 012F  CD 29                          int     29h
     38
     39 0131  8A C7                          mov     al, bh          ;if remainder(N/10) = 0 then CR LF
     40 0133  D4 0A                          aam     10              ;ah:= al/10; al:= remainder
     41 0135  3C 00                          cmp     al, 0
     42 0137  75 08                          jne     next
     43 0139  B0 0D                           mov    al, 0Dh         ;CR
     44 013B  CD 29                           int    29h
     45 013D  B0 0A                           mov    al, 0Ah         ;LF
     46 013F  CD 29                           int    29h
     47
     48 0141  FE C7                  next:   inc     bh              ;next N
     49 0143  80 FF 64                       cmp     bh, 100
     50 0146  7E BA                          jle     d10
     51 0148  C3                             ret
     52
     53                                      end     start


(de levenshtein (A B)
   (let D
      (cons
         (range 0 (length A))
         (mapcar
            '((I) (cons I (copy A)))
            (range 1 (length B)) ) )
      (for (J . Y) B
         (for (I . X) A
            (set
               (nth D (inc J) (inc I))
               (if (= X Y)
                  (get D J I)
                  (inc
                     (min
                        (get D J (inc I))
                        (get D (inc J) I)
                        (get D J I) ) ) ) ) ) ) ) )


*process source xref attributes or(!);
 lsht: Proc Options(main);
 Call test('kitten'      ,'sitting');
 Call test('rosettacode' ,'raisethysword');
 Call test('Sunday'      ,'Saturday');
 Call test('Vladimir_Levenshtein[1965]',
           'Vladimir_Levenshtein[1965]');
 Call test('this_algorithm_is_similar_to',
            'Damerau-Levenshtein_distance');
 Call test('','abc');

 test: Proc(s,t);
 Dcl (s,t) Char(*) Var;
 Put Edit('          1st string  = >'!!s!!'<')(Skip,a);
 Put Edit('          2nd string  = >'!!t!!'<')(Skip,a);
 Put Edit('Levenshtein distance  =',LevenshteinDistance(s,t))
         (Skip,a,f(3));
 Put Edit('')(Skip,a);
 End;

 LevenshteinDistance: Proc(s,t) Returns(Bin Fixed(31));
 Dcl (s,t) Char(*) Var;
 Dcl (sl,tl) Bin Fixed(31);
 Dcl ld      Bin Fixed(31);
 /* for all i and j, d[i,j] will hold the Levenshtein distance between
 *  the first i characters of s and the first j characters of t;
 *  note that d has (m+1)*(n+1) values                               */
 sl=length(s);
 tl=length(t);
 Begin;
   Dcl d(0:sl,0:tl) Bin Fixed(31);
   Dcl (i,j,ii,jj)  Bin Fixed(31);
   d=0;
   Do i=1 To sl;  /* source prefixes can be transformed into         */
     d(i,0)=i;    /* empty string by dropping all characters         */
     End;
   Do j=1 To tl;  /* target prefixes can be reached from             */
     d(0,j)=j;    /* empty source prefix by inserting every character*/
     End;
   Do j=1 To tl;
     jj=j-1;
     Do i=1 To sl;
       ii=i-1;
       If substr(s,i,1)=substr(t,j,1) Then
         d(i,j)=d(ii,jj);                  /* no operation required  */
       Else
         d(i,j)=1+min(d(ii,j),             /* a deletion             */
                      d(i,jj),             /* an insertion           */
                      d(ii,jj));           /* a substitution         */
       End;
     End;
   ld=d(sl,tl);
   End;
 Return(ld);
 End;
 End;


int N, D;
[for N:= 1 to 100 do
    [D:= if N=1 then 1 else N/2;
    while rem(N/D) do D:= D-1;
    if D<10 then ChOut(0, ^ );
    IntOut(0, D);
    if rem(N/10) = 0 then CrLf(0) else ChOut(0, ^ );
    ];
]


function Get-LevenshteinDistance
{
    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    Param
    (
        [Parameter(Mandatory=$true, Position=0)]
        [ValidateNotNullOrEmpty()]
        [Alias("s")]
        [string]
        $ReferenceObject,

        [Parameter(Mandatory=$true, Position=1)]
        [ValidateNotNullOrEmpty()]
        [Alias("t")]
        [string]
        $DifferenceObject
    )

    [int]$n = $ReferenceObject.Length
    [int]$m = $DifferenceObject.Length

    $d = New-Object -TypeName 'System.Object[,]' -ArgumentList ($n + 1),($m + 1)

    $outputObject = [PSCustomObject]@{
        ReferenceObject  = $ReferenceObject
        DifferenceObject = $DifferenceObject
        Distance         = $null
    }

    for ($i = 0; $i -le $n; $i++)
    {
        $d[$i, 0] = $i
    }

    for ($i = 0; $i -le $m; $i++)
    {
        $d[0, $i] = $i
    }

    for ($i = 1; $i -le $m; $i++)
    {
        for ($j = 1; $j -le $n; $j++)
        {
            if ($ReferenceObject[$j - 1] -eq $DifferenceObject[$i - 1])
            {
                $d[$j, $i] = $d[($j - 1), ($i - 1)]
            }
            else
            {
                $d[$j, $i] = [Math]::Min([Math]::Min(($d[($j - 1), $i] + 1), ($d[$j, ($i - 1)] + 1)), ($d[($j - 1), ($i - 1)] + 1))
            }
        }
    }

    $outputObject.Distance = $d[$n, $m]

    $outputObject
}


void setup() {
  println(distance("kitten", "sitting"));
}
int distance(String a, String b) {
  int [] costs = new int [b.length() + 1];
  for (int j = 0; j < costs.length; j++)
    costs[j] = j;
  for (int i = 1; i <= a.length(); i++) {
    costs[0] = i;
    int nw = i - 1;
    for (int j = 1; j <= b.length(); j++) {
      int cj = min(1 + min(costs[j], costs[j - 1]), a.charAt(i - 1) == b.charAt(j - 1) ? nw : nw + 1);
      nw = costs[j];
      costs[j] = cj;
    }
  }
  return costs[b.length()];
}


levenshtein(S, T, R) :-
	length(S, M),
	M1 is M+1,
	length(T, N),
	N1 is N+1,
	length(Lev, N1),
	maplist(init(M1), Lev),
	numlist(0, N, LN),
	maplist(init_n, LN, Lev),
	nth0(0, Lev, Lev0),
	numlist(0, M, Lev0),

	% compute_levenshtein distance
	numlist(1, N, LN1),
	maplist(work_on_T(Lev, S), LN1, T),
	last(Lev, LevLast),
	last(LevLast, R).

work_on_T(Lev, S, J, TJ) :-
	length(S, M),
	numlist(1, M, LM),
	maplist(work_on_S(Lev, J, TJ), LM, S).

work_on_S(Lev, J, C, I, C) :-
	% same char
	!,
	I1 is I-1, J1 is J-1,
	nth0(J1, Lev, LevJ1),
	nth0(I1, LevJ1, V),
	nth0(J, Lev, LevJ),
	nth0(I, LevJ, V).

work_on_S(Lev, J, _C1, I, _C2) :-
	I1 is I-1, J1 is J - 1,
	% compute the value for deletion
	nth0(J, Lev, LevJ),
	nth0(I1, LevJ, VD0),
	VD is VD0 + 1,

	% compute the value for insertion
	nth0(J1, Lev, LevJ1),
	nth0(I, LevJ1, VI0),
	VI is VI0 + 1,

	% compute the value for substitution
	nth0(I1, LevJ1, VS0),
	VS is VS0 + 1,

	% set the minimum value to cell(I,J)
	sort([VD, VI, VS], [V|_]),

	nth0(I, LevJ, V).

init(Len, C) :-
	length(C, Len).

init_n(N, L) :-
	nth0(0, L, N).


Procedure LevenshteinDistance(A_string$, B_String$)
  Protected m, n, i, j, min, k, l
  m = Len(A_string$)
  n = Len(B_String$)
  Dim D(m, n)

  For i=0 To m: D(i,0)=i: Next
  For j=0 To n: D(0,j)=j: Next

  For j=1 To n
    For i=1 To m
      If Mid(A_string$,i,1) = Mid(B_String$,j,1)
        D(i,j) = D(i-1, j-1); no operation required
      Else
        min = D(i-1, j)+1   ; a deletion
        k   = D(i, j-1)+1   ; an insertion
        l   = D(i-1, j-1)+1 ; a substitution
        If k < min: min=k: EndIf
        If l < min: min=l: EndIf
        D(i,j) = min
      EndIf
    Next
  Next
  ProcedureReturn D(m,n)
EndProcedure

;- Testing
n = LevenshteinDistance("kitten", "sitting")
MessageRequester("Info","Levenshtein Distance= "+Str(n))


def levenshteinDistance(str1, str2):
    m = len(str1)
    n = len(str2)
    d = [[i] for i in range(1, m + 1)]   # d matrix rows
    d.insert(0, list(range(0, n + 1)))   # d matrix columns
    for j in range(1, n + 1):
        for i in range(1, m + 1):
            if str1[i - 1] == str2[j - 1]:   # Python (string) is 0-based
                substitutionCost = 0
            else:
                substitutionCost = 1
            d[i].insert(j, min(d[i - 1][j] + 1,
                               d[i][j - 1] + 1,
                               d[i - 1][j - 1] + substitutionCost))
    return d[-1][-1]

print(levenshteinDistance("kitten","sitting"))
print(levenshteinDistance("rosettacode","raisethysword"))


#lang racket

(define (levenshtein a b)
  (define (ls0 a-index b-index)
    (cond [(or (= a-index -1) (= b-index -1)) (abs (- a-index b-index))]
          [else
           (define a-char (string-ref a a-index))
           (define b-char (string-ref b b-index))
           (if (equal? a-char b-char)
               (ls (sub1 a-index) (sub1 b-index))
               (min (add1 (ls (sub1 a-index) b-index))
                    (add1 (ls a-index (sub1 b-index)))
                    (add1 (ls (sub1 a-index) (sub1 b-index)))))]))
  (define memo (make-hash))
  (define (ls a-i b-i)
    (hash-ref! memo (cons a-i b-i) (λ() (ls0 a-i b-i))))
  (ls (sub1 (string-length a)) (sub1 (string-length b))))

(levenshtein "kitten" "sitting")
(levenshtein "rosettacode" "raisethysword")


sub levenshtein-distance ( Str $s, Str $t --> Int ) {
    my @s = *, |$s.comb;
    my @t = *, |$t.comb;

    my @d;
    @d[$_;  0] = $_ for ^@s.end;
    @d[ 0; $_] = $_ for ^@t.end;

    for 1..@s.end X 1..@t.end -> ($i, $j) {
        @d[$i; $j] = @s[$i] eq @t[$j]
            ??   @d[$i-1; $j-1]    # No operation required when eq
            !! ( @d[$i-1; $j  ],   # Deletion
                 @d[$i  ; $j-1],   # Insertion
                 @d[$i-1; $j-1],   # Substitution
               ).min + 1;
    }

    return @d[*-1][*-1];
}

my @a = [<kitten sitting>], [<saturday sunday>], [<rosettacode raisethysword>];

for @a -> [$s, $t] {
    say "Levenshtein distance('$s', '$t') == ", levenshtein-distance($s, $t);
}


/*REXX program  calculates and displays the  Levenshtein distance  between two strings. */
call Levenshtein   'kitten'                        ,     "sitting"
call Levenshtein   'rosettacode'                   ,     "raisethysword"
call Levenshtein   'Sunday'                        ,     "Saturday"
call Levenshtein   'Vladimir Levenshtein[1965]'    ,     "Vladimir Levenshtein[1965]"
call Levenshtein   'this algorithm is similar to'  ,     "Damerau─Levenshtein distance"
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
Levenshtein: procedure; parse arg o,t;  oL= length(o);   tL= length(t);     @.= 0
    say '        original string  = '    o                          /*show   old  string*/
    say '          target string  = '    t                          /*  "   target   "  */
                     do #=1  for tL;   @.0.#= #;   end  /*#*/       /*the   drop  array.*/
                     do #=1  for oL;   @.#.0= #;   end  /*#*/       /* "   insert   "   */
         do    j=1  for tL;   jm= j-1;    q= substr(t, j, 1)        /*obtain character. */
            do k=1  for oL;   km= k-1
            if q==substr(o, k, 1)  then @.k.j= @.km.jm              /*use previous char.*/
                                   else @.k.j= 1   +   min(@.km.j,  @.k.jm,  @.km.jm)
            end   /*k*/
         end      /*j*/                                             /* [↑]  best choice.*/
    say '   Levenshtein distance  = '  @.oL.tL;    say;      return


# Project : Levenshtein distance

load "stdlib.ring"
see "" + "distance(kitten, sitting) = " + levenshteindistance("kitten", "sitting") + nl
see "" + "distance(saturday, sunday) = " + levenshteindistance("saturday", "sunday") + nl
see "" + "distance(rosettacode, raisethysword) = " + levenshteindistance("rosettacode", "raisethysword") + nl

func levenshteindistance(s1, s2)
        n = len(s1)
        m = len(s2)
        if n = 0
            levenshteindistance = m
            return
        ok
        if m = 0
            levenshteindistance = n
            return
        ok
        d = newlist(n, m)
        for i = 1 to n
             d[i][1] = i
        next i
        for i = 1 to m
             d[1][i] = i
        next
        for i = 2 to n
             si = substr(s1, i, 1)
             for j = 2 to m
                  tj = substr(s2, j, 1)
                  if si = tj
                     cost = 0
                  else
                     cost = 1
                  ok
                  d[i][ j] = min((d[i - 1][ j]), min((d[i][j - 1] + 1), (d[i - 1][j - 1] + cost)))
             next
        next
        levenshteindistance = d[n][m]
        return levenshteindistance


module Levenshtein

  def self.distance(a, b)
    a, b = a.downcase, b.downcase
    costs = Array(0..b.length) # i == 0
    (1..a.length).each do |i|
      costs[0], nw = i, i - 1  # j == 0; nw is lev(i-1, j)
      (1..b.length).each do |j|
        costs[j], nw = [costs[j] + 1, costs[j-1] + 1, a[i-1] == b[j-1] ? nw : nw + 1].min, costs[j]
      end
    end
    costs[b.length]
  end

  def self.test
    %w{kitten sitting saturday sunday rosettacode raisethysword}.each_slice(2) do |a, b|
      puts "distance(#{a}, #{b}) = #{distance(a, b)}"
    end
  end

end

Levenshtein.test


print levenshteinDistance("kitten", "sitting")
print levenshteinDistance("rosettacode", "raisethysword")
end
function levenshteinDistance(s1$, s2$)
    n = len(s1$)
    m = len(s2$)
    if n = 0 then
        levenshteinDistance = m
        goto [ex]
    end if
    if m = 0 then
        levenshteinDistance = n
        goto [ex]
    end if
    dim d(n, m)
    for i = 0 to n
        d(i, 0) = i
    next i
    for i = 0 to m
        d(0, i) = i
    next i
    for i = 1 to n
        si$ = mid$(s1$, i, 1)
        for j = 1 to m
            tj$ = mid$(s2$, j, 1)
            if si$ = tj$ then cost = 0 else cost = 1
            d(i, j) = min((d(i - 1, j) + 1),min((d(i, j - 1) + 1),(d(i - 1, j - 1) + cost)))
        next j
    next i
    levenshteinDistance = d(n, m)
[ex]
end function


fn main() {
    println!("{}", levenshtein_distance("kitten", "sitting"));
    println!("{}", levenshtein_distance("saturday", "sunday"));
    println!("{}", levenshtein_distance("rosettacode", "raisethysword"));
}

fn levenshtein_distance(word1: &str, word2: &str) -> usize {
    let w1 = word1.chars().collect::<Vec<_>>();
    let w2 = word2.chars().collect::<Vec<_>>();

    let word1_length = w1.len() + 1;
    let word2_length = w2.len() + 1;

    let mut matrix = vec![vec![0; word1_length]; word2_length];

    for i in 1..word1_length { matrix[0][i] = i; }
    for j in 1..word2_length { matrix[j][0] = j; }

    for j in 1..word2_length {
        for i in 1..word1_length {
            let x: usize = if w1[i-1] == w2[j-1] {
                matrix[j-1][i-1]
            } else {
                1 + std::cmp::min(
                        std::cmp::min(matrix[j][i-1], matrix[j-1][i])
                        , matrix[j-1][i-1])
            };
            matrix[j][i] = x;
        }
    }
    matrix[word2_length-1][word1_length-1]
}


object Levenshtein0 extends App {

  def distance(s1: String, s2: String): Int = {
    val dist = Array.tabulate(s2.length + 1, s1.length + 1) { (j, i) => if (j == 0) i else if (i == 0) j else 0 }

    @inline
    def minimum(i: Int*): Int = i.min

    for {j <- dist.indices.tail
         i <- dist(0).indices.tail} dist(j)(i) =
        if (s2(j - 1) == s1(i - 1)) dist(j - 1)(i - 1)
        else minimum(dist(j - 1)(i) + 1, dist(j)(i - 1) + 1, dist(j - 1)(i - 1) + 1)

    dist(s2.length)(s1.length)
  }

  def printDistance(s1: String, s2: String) {
    println("%s -> %s : %d".format(s1, s2, distance(s1, s2)))
  }

  printDistance("kitten", "sitting")
  printDistance("rosettacode", "raisethysword")

}


(define (levenshtein s t)
  (define (%levenshtein s sl t tl)
    (cond ((zero? sl) tl)
          ((zero? tl) sl)
          (else
	    (min (+ (%levenshtein (cdr s) (- sl 1) t tl) 1)
                 (+ (%levenshtein s sl (cdr t) (- tl 1)) 1)
                 (+ (%levenshtein (cdr s) (- sl 1) (cdr t) (- tl 1))
		    (if (char=? (car s) (car t)) 0 1))))))
  (%levenshtein (string->list s)
		(string-length s)
		(string->list t)
		(string-length t)))


$ include "seed7_05.s7i";

const func integer: levenshteinDistance (in string: s, in string: t) is func
  result
    var integer: distance is 0;
  local
    var array array integer: d is 0 times 0 times 0;
    var integer: i is 0;
    var integer: j is 0;
  begin
    d := [0 .. length(s)] times [0 .. length(t)] times 0;
    for key i range s do
      d[i][0] := i;
    end for;
    for key j range t do
      d[0][j] := j;
      for key i range s do
        if s[i] = t[j] then
          d[i][j] := d[pred(i)][pred(j)];
        else
          d[i][j] := min(min(succ(d[pred(i)][j]), succ(d[i][pred(j)])), succ(d[pred(i)][pred(j)]));
        end if;
      end for;
    end for;
    distance := d[length(s)][length(t)];
  end func;

const proc: main is func
  begin
    writeln("kitten -> sitting: " <& levenshteinDistance("kitten", "sitting"));
    writeln("rosettacode -> raisethysword: " <& levenshteinDistance("rosettacode", "raisethysword"));
  end func;


put textDifference("kitten", "sitting") // --> 3
put textDifference("rosettacode", "raisethysword") // --> 8


import <Utilities/Sequence.sl>;
import <Utilities/Math.sl>;

main(args(2)) := LenenshteinDistance(args[1], args[2]);

LenenshteinDistance(s(1), t(1)) :=
	0 when equalList(s,t) else
	size(t) when size(s) = 0 else
	size(s) when size(t) = 0 else
	LenenshteinDistanceIterative(s, t, 0 ... size(t), duplicate(0, size(t) + 1), 1);

LenenshteinDistanceIterative(s(1), t(1), v0(1), v1(1), n) :=
	v0[size(t) + 1] when n > size(s) else
	LenenshteinDistanceIterative(s, t, iterate(s[n], t, v0, setElementAt(v1, 1, n + 0), 1), v0, n + 1);

iterate(s, t(1), v0(1), v1(1), n) :=
	v1 when n > size(t) else
	iterate(s, t, v0,
		setElementAt(v1, n + 1,
			min(min(v1[n] + 1, v0[n + 1] + 1), v0[n] + (0 when s = t[n] else 1))),
		n + 1);


func lev(s, t) is cached {

    s || return t.len
    t || return s.len

    var s1 = s.ft(1)
    var t1 = t.ft(1)

    s[0] == t[0] ? __FUNC__(s1, t1)
                 : 1+Math.min(
                        __FUNC__(s1, t1),
                        __FUNC__(s,  t1),
                        __FUNC__(s1, t )
                     )
}


BEGIN

    INTEGER PROCEDURE LEVENSHTEINDISTANCE(S1, S2); TEXT S1, S2;
    BEGIN
        INTEGER N, M;
        N := S1.LENGTH;
        M := S2.LENGTH;
        IF N = 0 THEN LEVENSHTEINDISTANCE := M ELSE
        IF M = 0 THEN LEVENSHTEINDISTANCE := N ELSE
        BEGIN
            INTEGER ARRAY D(0:N, 0:M);
            INTEGER I, J;
            FOR I := 0 STEP 1 UNTIL N DO D(I, 0) := I;
            FOR I := 0 STEP 1 UNTIL M DO D(0, I) := I;
            S1.SETPOS(1);
            FOR I := 1 STEP 1 UNTIL N DO
            BEGIN
                CHARACTER SI, TJ;
                SI := S1.GETCHAR;
                S2.SETPOS(1);
                FOR J := 1 STEP 1 UNTIL M DO
                BEGIN
                    INTEGER COST;
                    TJ := S2.GETCHAR;
                    COST := IF SI = TJ THEN 0 ELSE 1;
                    D(I, J) := MIN(D(I - 1, J) + 1, MIN(D(I, J - 1) + 1, D(I - 1, J - 1) + COST));
                END;
            END;
            LEVENSHTEINDISTANCE := D(N, M);
        END;
    END LEVENSHTEINDISTANCE;

    OUTINT(LEVENSHTEINDISTANCE("kitten", "sitting"), 0); OUTIMAGE;
    OUTINT(LEVENSHTEINDISTANCE("rosettacode", "raisethysword"), 0); OUTIMAGE;

END


'kitten' levenshteinTo: 'sitting' s:1 k:1 c:1 i:1 d:1 -> 3
'rosettacode' levenshteinTo: 'raisethysword' s:1 k:1 c:1 i:1 d:1 -> 8


func levDis(w1: String, w2: String) -> Int {

  let (t, s) = (w1.characters, w2.characters)

  let empty = Repeat(count: s.count, repeatedValue: 0)
  var mat = [[Int](0...s.count)] + (1...t.count).map{[$0] + empty}

  for (i, tLett) in t.enumerate() {
    for (j, sLett) in s.enumerate() {
      mat[i + 1][j + 1] = tLett == sLett ?
        mat[i][j] : min(mat[i][j], mat[i][j + 1], mat[i + 1][j]).successor()
    }
  }
  return mat.last!.last!
}


proc levenshteinDistance {s t} {
    # Edge cases
    if {![set n [string length $t]]} {
	return [string length $s]
    } elseif {![set m [string length $s]]} {
	return $n
    }
    # Fastest way to initialize
    for {set i 0} {$i <= $m} {incr i} {
	lappend d 0
	lappend p $i
    }
    # Loop, computing the distance table (well, a moving section)
    for {set j 0} {$j < $n} {} {
	set tj [string index $t $j]
	lset d 0 [incr j]
	for {set i 0} {$i < $m} {} {
	    set a [expr {[lindex $d $i]+1}]
	    set b [expr {[lindex $p $i]+([string index $s $i] ne $tj)}]
	    set c [expr {[lindex $p [incr i]]+1}]
	    # Faster than min($a,$b,$c)
	    lset d $i [expr {$a<$b ? $c<$a ? $c : $a : $c<$b ? $c : $b}]
	}
	# Swap
	set nd $p; set p $d; set d $nd
    }
    # The score is at the end of the last-computed row
    return [lindex $p end]
}


// library: math: get: damerau: levenshtein <description></description> <version>1.0.0.0.23</version> <version control></version control> (filenamemacro=getmadle.s) [kn, ri, th, 08-09-2011 23:04:55]
INTEGER PROC FNMathGetDamerauLevenshteinDistanceI( STRING s1, STRING s2 )
 INTEGER L1 = Length( s1 )
 INTEGER L2 = Length( s2 )
 INTEGER substitutionCostI = 0
 STRING h1[255] = ""
 STRING h2[255] = ""
 IF ( ( L1 == 0 ) OR ( L2 == 0 ) )
  // Trivial case: one string is 0-length
  RETURN( Max( L1, L2 ) )
 ELSE
  // The cost of substituting the last character
  IF   ( ( s1[ L1 ] ) == ( s2[ L2 ] ) )
   substitutionCostI = 0
  ELSE
   substitutionCostI = 1
  ENDIF
  // h1 and h2 are s1 and s2 with the last character chopped off
  h1 = SubStr( s1, 1,  L1 - 1 )
  h2 = SubStr( s2, 1,  L2 - 1 )
  IF ( ( L1 > 1 ) AND  ( L2 > 1 ) AND  ( s1[ L1 - 0 ] == s2[ L2 - 1 ] ) AND ( s1[ L1 - 1 ] == s2[ L2 - 0 ] ) )
   RETURN( Min( Min( FNMathGetDamerauLevenshteinDistanceI( h1, s2 ) + 1, FNMathGetDamerauLevenshteinDistanceI( s1, h2 ) + 1 ), Min( FNMathGetDamerauLevenshteinDistanceI( h1 , h2 ) + substitutionCostI, FNMathGetDamerauLevenshteinDistanceI( SubStr( s1, 1,  L1 - 2 ), SubStr( s2, 1, L2 - 2 ) ) + 1 ) ) )
  ENDIF
  RETURN( Min( Min( FNMathGetDamerauLevenshteinDistanceI( h1, s2 ) + 1, FNMathGetDamerauLevenshteinDistanceI( s1, h2 ) + 1 ), FNMathGetDamerauLevenshteinDistanceI( h1 ,  h2 ) + substitutionCostI ) )
 ENDIF
END

PROC Main()
STRING s1[255] = "arcain"
STRING s2[255] = "arcane"
Warn( "Minimum amount of steps to convert ", s1, " to ", s2, " = ", FNMathGetDamerauLevenshteinDistanceI( s1, s2 ) ) // gives e.g. 2
s1 = "algorithm"
s2 = "altruistic"
Warn( "Minimum amount of steps to convert ", s1, " to ", s2, " = ", FNMathGetDamerauLevenshteinDistanceI( s1, s2 ) ) // gives e.g. 6
END


10 DIM Word_1$(20), Word_2$(20), DLDm(21, 21)
11 CLS
20 Word_1$="kitten" : Word_2$="sitting" : ? Word_1$;" - ";Word_2$ : EXEC _DLD_ : ?
30 Word_1$="rosettacode" : Word_2$="raisethysword" : ? Word_1$;" - ";Word_2$ : EXEC _DLD_ : ?

11000 END
11600 REM DamerauLevenshteinDistance INPUT(Word_1$, Word_2$, DLDm[]) USE(I, J, K, L, M, N, Min) RETURN(INT Result)
11600 PROC _DLD_
11610   Result=0 : M=LEN(Word_1$) : N=LEN(Word_2$)
11620   FOR I=0 TO M : DLDm(I,0)=I : NEXT I
11630   FOR J=0 TO N : DLDm(0,J)=J : NEXT J
11640   FOR J=1 TO N
11650     FOR I=1 TO M
11660       IF Word_1$(I,I) = Word_2$(J,J)
11670         DLDm(I,J) = DLDm(I-1, J-1) : REM no operation required
11680       ELSE
11690         Min = DLDm(I-1, J)+1 : REM delete
11700         K = DLDm(I, J-1)+1   : REM insert
11710         L = DLDm(I-1, J-1)+1 : REM substitution
11720         IF K < Min THEN Min=K
11730         IF L < Min THEN Min=L
11740         DLDm(I,J) = Min
11750 REM     IF I>1 AND J>1
11760 REM          IF Word_1$(I,I) = Word_2$(J-1,J-1) AND Word_1$(I-1,I-1) = Word_2$(J,J)
11770 REM              Min=DLDm(I,J) : IF Min>(DLDm(I-2,J-2)+1) THEN Min=(DLDm(I-2,J-2)+1)
11780 REM              DLDm(I,J) = Min : REM transposition
11790 REM          ENDIF
11800 REM     ENDIF
11810       ENDIF
11820     NEXT I
11830   NEXT J
11840   Result=DLDm(M,N)
11845   REM ? "Damerau Levenshtein Distance=";Result
11846   ? "Damerau Distance=";Result
11850 ENDPROC


$$ MODE TUSCRIPT
distance=DISTANCE ("kitten", "sitting")
PRINT distance


  function levenshtein(a: string, b: string): number {
    const m: number = a.length,
      n: number = b.length;
    let t: number[] = [...Array(n + 1).keys()],
      u: number[] = [];
    for (let i: number = 0; i < m; i++) {
      u = [i + 1];
      for (let j: number = 0; j < n; j++) {
        u[j + 1] = a[i] === b[j] ? t[j] : Math.min(t[j], t[j + 1], u[j]) + 1;
      }
      t = u;
    }
    return u[n];
  }


class LevenshteinDistance : Object {
    public static int compute (owned string s, owned string t, bool case_sensitive = false) {
        var n = s.length;
        var m = t.length;
        var d = new int[n + 1, m + 1];
        if (case_sensitive == false) {
            s = s.down ();
            t = t.down ();
        }
        if (n == 0) {
            return m;
        }
        if (m == 0) {
            return n;
        }
        for (var i = 0; i <= n; d[i, 0] = i++) {}
        for (var j = 0; j <= m; d[0, j] = j++) {}
        for (var i = 1; i <= n; i++) {
            for (var j = 1; j <= m; j++) {
                var cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
                d[i, j] = int.min (int.min (d[i - 1, j] + 1, d[i, j - 1] + 1), d[i - 1, j - 1] + cost);
            }
        }
        return d[n, m];
    }
}


Option Base 1
Function levenshtein(s1 As String, s2 As String) As Integer
    Dim n As Integer: n = Len(s1) + 1
    Dim m As Integer: m = Len(s2) + 1
    Dim d() As Integer, i As Integer, j As Integer
    ReDim d(n, m)

    If n = 1 Then
        levenshtein = m - 1
        Exit Function
    Else
        If m = 1 Then
            levenshtein = n - 1
            Exit Function
        End If
    End If

    For i = 1 To n
        d(i, 1) = i - 1
    Next i

    For j = 1 To m
        d(1, j) = j - 1
    Next j

    For i = 2 To n
        For j = 2 To m
            d(i, j) = WorksheetFunction.Min( _
                           d(i - 1, j) + 1, _
                           d(i, j - 1) + 1, _
                           (d(i - 1, j - 1) - (Mid(s1, i - 1, 1) <> Mid(s2, j - 1, 1))) _
                           )
        Next j
    Next i

    levenshtein = d(n, m)
End Function
Public Sub main()
    Debug.Print levenshtein("kitten", "sitting")
    Debug.Print levenshtein("rosettacode", "raisethysword")
End Sub


' Levenshtein distance - 23/04/2020

Function Min(a,b)
    If a < b then Min = a : Else  Min = b
End Function 'Min

Function Levenshtein(s1, s2)
    Dim d(), i, j, n1, n2, d1, d2, d3
    n1 = Len(s1) + 1
    n2 = Len(s2) + 1
    ReDim d(n1, n2)
    If n1 = 1 Then
        Levenshtein = n2 - 1
        Exit Function
    End If
    If n2 = 1 Then
        Levenshtein = n1 - 1
        Exit Function
    End If
    For i = 1 To n1
        d(i, 1) = i - 1
    Next
    For j = 1 To n2
        d(1, j) = j - 1
    Next
    For i = 2 To n1
        For j = 2 To n2
            d1 = d(i - 1, j    ) + 1
            d2 = d(i,     j - 1) + 1
            d3 = d(i - 1, j - 1) + Abs(Mid(s1, i - 1, 1) <> Mid(s2, j - 1, 1))
            d(i, j) = Min(d1, Min(d2, d3))
        Next
    Next
    Levenshtein = d(n1, n2)
End Function 'Levenshtein

Sub PrintLevenshtein(c1, c2)
	WScript.StdOut.WriteLine c1&" "& c2&" "& Levenshtein(c1, c2)
End Sub 'PrintLevenshtein

PrintLevenshtein "kitten", "sitting"
PrintLevenshtein "rosettacode", "raisethysword"
PrintLevenshtein "saturday", "sunday"
PrintLevenshtein "sleep", "fleeting"