Execute a Markov algorithm: Difference between revisions

add Ada
(Go solution)
(add Ada)
Line 130:
 
=Examples=
=={{header|Ada}}==
markov.ads:
<lang Ada>with Ada.Strings.Unbounded;
 
package Markov is
use Ada.Strings.Unbounded;
type Ruleset (Length : Natural) is private;
type String_Array is array (Positive range <>) of Unbounded_String;
function Parse (S : String_Array) return Ruleset;
function Apply (R : Ruleset; S : String) return String;
private
type Entry_Kind is (Comment, Rule);
type Set_Entry (Kind : Entry_Kind := Rule) is record
case Kind is
when Rule =>
Source : Unbounded_String;
Target : Unbounded_String;
Is_Terminating : Boolean;
when Comment =>
Text : Unbounded_String;
end case;
end record;
subtype Rule_Entry is Set_Entry (Kind => Rule);
type Entry_Array is array (Positive range <>) of Set_Entry;
type Ruleset (Length : Natural) is record
Entries : Entry_Array (1 .. Length);
end record;
end Markov;</lang>
 
markov.adb:
<lang Ada>package body Markov is
 
function Parse (S : String_Array) return Ruleset is
Result : Ruleset (Length => S'Length);
begin
for I in S'Range loop
if Length (S (I)) = 0 or else Element (S (I), 1) = '#' then
Result.Entries (I) := (Kind => Comment, Text => S (I));
else
declare
Separator : Natural;
Terminating : Boolean;
Target : Unbounded_String;
begin
Separator := Index (S (I), " -> ");
if Separator = 0 then
raise Constraint_Error;
end if;
Target :=
Unbounded_Slice
(Source => S (I),
Low => Separator + 4,
High => Length (S (I)));
Terminating := Length (Target) > 0
and then Element (Target, 1) = '.';
if Terminating then
Delete (Source => Target, From => 1, Through => 1);
end if;
Result.Entries (I) :=
(Kind => Rule,
Source => Unbounded_Slice
(Source => S (I),
Low => 1,
High => Separator - 1),
Target => Target,
Is_Terminating => Terminating);
end;
end if;
end loop;
return Result;
end Parse;
 
procedure Apply
(R : Rule_Entry;
S : in out Unbounded_String;
Modified : in out Boolean)
is
Pattern : String := To_String (R.Source);
Where : Natural := Index (S, Pattern);
begin
while Where /= 0 loop
Modified := True;
Replace_Slice
(Source => S,
Low => Where,
High => Where + Pattern'Length - 1,
By => To_String (R.Target));
Where := Index (S, Pattern, Where + Length (R.Target));
end loop;
end Apply;
 
function Apply (R : Ruleset; S : String) return String is
Result : Unbounded_String := To_Unbounded_String (S);
Current_Rule : Set_Entry;
Modified : Boolean := False;
begin
loop
Modified := False;
for I in R.Entries'Range loop
Current_Rule := R.Entries (I);
if Current_Rule.Kind = Rule then
Apply (Current_Rule, Result, Modified);
exit when Current_Rule.Is_Terminating or else Modified;
end if;
end loop;
exit when not Modified;
end loop;
return To_String (Result);
end Apply;
 
end Markov;</lang>
 
test_markov.adb:
<lang Ada>with Ada.Command_Line;
with Ada.Text_IO.Unbounded_IO;
with Ada.Strings.Unbounded;
with Markov;
 
procedure Test_Markov is
use Ada.Strings.Unbounded;
package IO renames Ada.Text_IO.Unbounded_IO;
Rule_File : Ada.Text_IO.File_Type;
Line_Count : Natural := 0;
begin
if Ada.Command_Line.Argument_Count /= 2 then
Ada.Text_IO.Put_Line ("Usage: test_markov ruleset_file source_file");
return;
end if;
Ada.Text_IO.Open
(File => Rule_File,
Mode => Ada.Text_IO.In_File,
Name => Ada.Command_Line.Argument (1));
while not Ada.Text_IO.End_Of_File (Rule_File) loop
Ada.Text_IO.Skip_Line (Rule_File);
Line_Count := Line_Count + 1;
end loop;
declare
Lines : Markov.String_Array (1 .. Line_Count);
begin
Ada.Text_IO.Reset (Rule_File);
for I in Lines'Range loop
Lines (I) := IO.Get_Line (Rule_File);
end loop;
Ada.Text_IO.Close (Rule_File);
 
declare
Ruleset : Markov.Ruleset := Markov.Parse (Lines);
Source_File : Ada.Text_IO.File_Type;
begin
Ada.Text_IO.Open
(File => Source_File,
Mode => Ada.Text_IO.In_File,
Name => Ada.Command_Line.Argument (2));
while not Ada.Text_IO.End_Of_File (Source_File) loop
Ada.Text_IO.Put_Line
(Markov.Apply (Ruleset, Ada.Text_IO.Get_Line (Source_File)));
end loop;
Ada.Text_IO.Close (Source_File);
end;
end;
end Test_Markov;</lang>
 
Output (rulesX contains the ruleset of above examples and testX the example text):
<pre>$ ./test_markov rules1 test1
I bought a bag of apples from my brother.
$ ./test_markov rules2 test2
I bought a bag of apples from T shop.
$ ./test_markov rules3 test3
I bought a bag of apples with my money from T shop.
$ ./test_markov rules4 test4
11111111111111111111
$ ./test_markov rules5 test5
00011H1111000</pre>
 
=={{header|AutoHotkey}}==
<lang autohotkey>;---------------------------------------------------------------------------
256

edits