104 lines
2.9 KiB
Ada
104 lines
2.9 KiB
Ada
with Ada.Text_IO, Ada.Command_Line, Ada.Numerics.Discrete_Random;
|
|
|
|
procedure Flip_Bits is
|
|
|
|
subtype Letter is Character range 'a' .. 'z';
|
|
|
|
Last_Col: constant letter := Ada.Command_Line.Argument(1)(1);
|
|
Last_Row: constant Positive := Positive'Value(Ada.Command_Line.Argument(2));
|
|
|
|
package Boolean_Rand is new Ada.Numerics.Discrete_Random(Boolean);
|
|
Gen: Boolean_Rand.Generator;
|
|
|
|
type Matrix is array
|
|
(Letter range 'a' .. Last_Col, Positive range 1 .. Last_Row) of Boolean;
|
|
|
|
function Rand_Mat return Matrix is
|
|
M: Matrix;
|
|
begin
|
|
for I in M'Range(1) loop
|
|
for J in M'Range(2) loop
|
|
M(I,J) := Boolean_Rand.Random(Gen);
|
|
end loop;
|
|
end loop;
|
|
return M;
|
|
end Rand_Mat;
|
|
|
|
function Rand_Mat(Start: Matrix) return Matrix is
|
|
M: Matrix := Start;
|
|
begin
|
|
for I in M'Range(1) loop
|
|
if Boolean_Rand.Random(Gen) then
|
|
for J in M'Range(2) loop
|
|
M(I,J) := not M(I, J);
|
|
end loop;
|
|
end if;
|
|
end loop;
|
|
for I in M'Range(2) loop
|
|
if Boolean_Rand.Random(Gen) then
|
|
for J in M'Range(1) loop
|
|
M(J,I) := not M(J, I);
|
|
end loop;
|
|
end if;
|
|
end loop;
|
|
return M;
|
|
end Rand_Mat;
|
|
|
|
procedure Print(Message: String; Mat: Matrix) is
|
|
package NIO is new Ada.Text_IO.Integer_IO(Natural);
|
|
begin
|
|
Ada.Text_IO.New_Line;
|
|
Ada.Text_IO.Put_Line(Message);
|
|
Ada.Text_IO.Put(" ");
|
|
for Ch in Matrix'Range(1) loop
|
|
Ada.Text_IO.Put(" " & Ch);
|
|
end loop;
|
|
Ada.Text_IO.New_Line;
|
|
for I in Matrix'Range(2) loop
|
|
NIO.Put(I, Width => 3);
|
|
for Ch in Matrix'Range(1) loop
|
|
Ada.Text_IO.Put(if Mat(Ch, I) then " 1" else " 0");
|
|
end loop;
|
|
Ada.Text_IO.New_Line;
|
|
end loop;
|
|
end Print;
|
|
|
|
Current, Target: Matrix;
|
|
Moves: Natural := 0;
|
|
|
|
begin
|
|
-- choose random Target and start ("Current") matrices
|
|
Boolean_Rand.Reset(Gen);
|
|
Target := Rand_Mat;
|
|
loop
|
|
Current := Rand_Mat(Target);
|
|
exit when Current /= Target;
|
|
end loop;
|
|
Print("Target:", Target);
|
|
|
|
-- print and modify Current matrix, until it is identical to Target
|
|
while Current /= Target loop
|
|
Moves := Moves + 1;
|
|
Print("Current move #" & Natural'Image(Moves), Current);
|
|
Ada.Text_IO.Put_Line("Flip row 1 .." & Positive'Image(Last_Row) &
|
|
" or column 'a' .. '" & Last_Col & "'");
|
|
declare
|
|
S: String := Ada.Text_IO.Get_Line;
|
|
function Let(S: String) return Character is (S(S'First));
|
|
function Val(Str: String) return Positive is (Positive'Value(Str));
|
|
begin
|
|
if Let(S) in 'a' .. Last_Col then
|
|
for I in Current'Range(2) loop
|
|
Current(Let(S), I) := not Current(Let(S), I);
|
|
end loop;
|
|
else
|
|
for I in Current'Range(1) loop
|
|
Current(I, Val(S)) := not Current(I, Val(S));
|
|
end loop;
|
|
end if;
|
|
end;
|
|
end loop;
|
|
|
|
-- summarize the outcome
|
|
Ada.Text_IO.Put_Line("Done after" & Natural'Image(Moves) & " Moves.");
|
|
end Flip_Bits;
|