Update all new Tasks
This commit is contained in:
parent
00a190b0a6
commit
91df62d461
5697 changed files with 93386 additions and 804 deletions
17
Task/Flipping-bits-game/00DESCRIPTION
Normal file
17
Task/Flipping-bits-game/00DESCRIPTION
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
;The game:
|
||||
Given an N by N square array of zeroes or ones in an initial
|
||||
configuration, and a target configuration of zeroes and ones
|
||||
The task is to transform one to the other in as few moves as
|
||||
possible by inverting whole numbered rows or whole lettered
|
||||
columns at once, as one move.
|
||||
|
||||
In an inversion any 1 becomes 0, and any 0 becomes 1 for that
|
||||
whole row or column.
|
||||
|
||||
;The Task:
|
||||
The task is to create a program to score for the Flipping bits game.
|
||||
# The game should create an original random target configuration and a starting configuration.
|
||||
# Ensure that the starting position is ''never'' the target position.
|
||||
# The target position must be guaranteed as reachable from the starting position. (One possible way to do this is to generate the start position by legal flips from a random target position. The flips will always be reversible back to the target from the given start position).
|
||||
# The number of moves taken so far should be shown.
|
||||
Show an example of a short game here, on this page, for a 3 by 3 array of bits.
|
||||
3
Task/Flipping-bits-game/00META.yaml
Normal file
3
Task/Flipping-bits-game/00META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
category:
|
||||
- Games
|
||||
104
Task/Flipping-bits-game/Ada/flipping-bits-game.ada
Normal file
104
Task/Flipping-bits-game/Ada/flipping-bits-game.ada
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
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;
|
||||
83
Task/Flipping-bits-game/AutoHotkey/flipping-bits-game.ahk
Normal file
83
Task/Flipping-bits-game/AutoHotkey/flipping-bits-game.ahk
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
size := 3 ; max 26
|
||||
Gui, Add, Button, , O
|
||||
Loop, %size%
|
||||
{
|
||||
x := chr(A_Index+64)
|
||||
If x = A
|
||||
Loop, %size%
|
||||
Gui, Add, Button, y+4 gFlip, % A_Index
|
||||
Gui, Add, Button, ym gFlip, % x
|
||||
Loop, %size%
|
||||
{
|
||||
y := A_Index
|
||||
Random, %x%%y%, 0, 1
|
||||
Gui, Add, Edit, v%x%%y% ReadOnly, % %x%%y%
|
||||
}
|
||||
}
|
||||
Gui, Add, Text, ym, Moves:`nTarget:
|
||||
Loop, %size%
|
||||
{
|
||||
x := chr(A_Index+64)
|
||||
Loop, %size%
|
||||
{
|
||||
y := A_Index
|
||||
Gui, Add, Edit, % y=1 ? x="A" ? "xp+0 ym+30" : "x+14 ym+30" : "" . "ReadOnly vt" x y, % t%x%%y% := %x%%y%
|
||||
}
|
||||
}Gui, Add, Text, xp-18 ym w30 Right vMoves, % Moves:=1
|
||||
|
||||
; randomize
|
||||
While (i < size)
|
||||
{
|
||||
Random, z, 1, %size%
|
||||
Random, x, 0, 1
|
||||
z := x ? chr(z+64) : z
|
||||
Solution .= z ; to cheat
|
||||
If Flip(z, size)
|
||||
i := 0 ; ensure we are not at the solution
|
||||
Else
|
||||
i++ ; count
|
||||
}
|
||||
Gui, Show, NA
|
||||
Return
|
||||
|
||||
Flip(z, size) {
|
||||
Loop, %size%
|
||||
{
|
||||
If z is alpha
|
||||
GuiControl, , %z%%A_Index%, % %z%%A_Index% := !%z%%A_Index%
|
||||
Else
|
||||
{
|
||||
AIndex := chr(A_Index+64)
|
||||
GuiControl, , %AIndex%%z%, % %AIndex%%z% := !%AIndex%%z%
|
||||
}
|
||||
}
|
||||
Loop, %size%
|
||||
{
|
||||
x := chr(A_Index+64)
|
||||
Loop, %size%
|
||||
{
|
||||
y := A_Index
|
||||
If (%x%%y% != t%x%%y%)
|
||||
Return 0
|
||||
}
|
||||
}
|
||||
Return 1
|
||||
}
|
||||
|
||||
Flip:
|
||||
GuiControl, , Moves, % Moves++
|
||||
If Flip(A_GuiControl, size)
|
||||
{
|
||||
Msgbox Success in %Moves% moves!
|
||||
Reload
|
||||
}
|
||||
Return
|
||||
|
||||
ButtonO:
|
||||
Reload
|
||||
Return
|
||||
|
||||
GuiEscape:
|
||||
GuiClose:
|
||||
ExitApp
|
||||
Return
|
||||
92
Task/Flipping-bits-game/C++/flipping-bits-game.cpp
Normal file
92
Task/Flipping-bits-game/C++/flipping-bits-game.cpp
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
#include <time.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
typedef unsigned char byte;
|
||||
using namespace std;
|
||||
|
||||
class flip
|
||||
{
|
||||
public:
|
||||
flip() { field = 0; target = 0; }
|
||||
void play( int w, int h ) { wid = w; hei = h; createField(); gameLoop(); }
|
||||
|
||||
private:
|
||||
void gameLoop()
|
||||
{
|
||||
int moves = 0;
|
||||
while( !solved() )
|
||||
{
|
||||
display(); string r; cout << "Enter rows letters and/or column numbers: "; cin >> r;
|
||||
for( string::iterator i = r.begin(); i != r.end(); i++ )
|
||||
{
|
||||
byte ii = ( *i );
|
||||
if( ii - 1 >= '0' && ii - 1 <= '9' ) { flipCol( ii - '1' ); moves++; }
|
||||
else if( ii >= 'a' && ii <= 'z' ) { flipRow( ii - 'a' ); moves++; }
|
||||
}
|
||||
}
|
||||
cout << endl << endl << "** Well done! **" << endl << "Used " << moves << " moves." << endl << endl;
|
||||
}
|
||||
|
||||
void display()
|
||||
{ system( "cls" ); output( "TARGET:", target ); output( "YOU:", field ); }
|
||||
|
||||
void output( string t, byte* f )
|
||||
{
|
||||
cout << t << endl;
|
||||
cout << " "; for( int x = 0; x < wid; x++ ) cout << " " << static_cast<char>( x + '1' ); cout << endl;
|
||||
for( int y = 0; y < hei; y++ )
|
||||
{
|
||||
cout << static_cast<char>( y + 'a' ) << " ";
|
||||
for( int x = 0; x < wid; x++ )
|
||||
cout << static_cast<char>( f[x + y * wid] + 48 ) << " ";
|
||||
cout << endl;
|
||||
}
|
||||
cout << endl << endl;
|
||||
}
|
||||
|
||||
bool solved()
|
||||
{
|
||||
for( int y = 0; y < hei; y++ )
|
||||
for( int x = 0; x < wid; x++ )
|
||||
if( target[x + y * wid] != field[x + y * wid] ) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void createTarget()
|
||||
{
|
||||
for( int y = 0; y < hei; y++ )
|
||||
for( int x = 0; x < wid; x++ )
|
||||
if( frnd() < .5f ) target[x + y * wid] = 1;
|
||||
else target[x + y * wid] = 0;
|
||||
memcpy( field, target, wid * hei );
|
||||
}
|
||||
|
||||
void flipCol( int c )
|
||||
{ for( int x = 0; x < hei; x++ ) field[c + x * wid] = !field[c + x * wid]; }
|
||||
|
||||
void flipRow( int r )
|
||||
{ for( int x = 0; x < wid; x++ ) field[x + r * wid] = !field[x + r * wid]; }
|
||||
|
||||
void calcStartPos()
|
||||
{
|
||||
int flips = ( rand() % wid + wid + rand() % hei + hei ) >> 1;
|
||||
for( int x = 0; x < flips; x++ )
|
||||
{ if( frnd() < .5f ) flipCol( rand() % wid ); else flipRow( rand() % hei ); }
|
||||
}
|
||||
|
||||
void createField()
|
||||
{
|
||||
if( field ){ delete [] field; delete [] target; }
|
||||
int t = wid * hei; field = new byte[t]; target = new byte[t];
|
||||
memset( field, 0, t ); memset( target, 0, t ); createTarget();
|
||||
while( true ) { calcStartPos(); if( !solved() ) break; }
|
||||
}
|
||||
|
||||
float frnd() { return static_cast<float>( rand() ) / static_cast<float>( RAND_MAX ); }
|
||||
|
||||
byte* field, *target; int wid, hei;
|
||||
};
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{ srand( time( NULL ) ); flip g; g.play( 3, 3 ); return system( "pause" ); }
|
||||
115
Task/Flipping-bits-game/C/flipping-bits-game.c
Normal file
115
Task/Flipping-bits-game/C/flipping-bits-game.c
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int i, j;
|
||||
|
||||
void fliprow(int **b, int sz, int n)
|
||||
{
|
||||
for(i = 0; i < sz; i++)
|
||||
b[n+1][i] = !b[n+1][i];
|
||||
}
|
||||
|
||||
void flipcol(int **b, int sz, int n)
|
||||
{
|
||||
for(i = 1; i <= sz; i++)
|
||||
b[i][n] = !b[i][n];
|
||||
}
|
||||
|
||||
void initt(int **t, int sz)
|
||||
{
|
||||
for(i = 1; i <= sz; i++)
|
||||
for(j = 0; j < sz; j++)
|
||||
t[i][j] = rand()%2;
|
||||
}
|
||||
|
||||
void initb(int **t, int **b, int sz)
|
||||
{
|
||||
for(i = 1; i <= sz; i++)
|
||||
for(j = 0; j < sz; j++)
|
||||
b[i][j] = t[i][j];
|
||||
|
||||
for(i = 1; i <= sz; i++)
|
||||
fliprow(b, sz, rand()%sz+1);
|
||||
for(i = 0; i < sz; i++)
|
||||
flipcol(b, sz, rand()%sz);
|
||||
}
|
||||
|
||||
void printb(int **b, int sz)
|
||||
{
|
||||
printf(" ");
|
||||
for(i = 0; i < sz; i++)
|
||||
printf(" %d", i);
|
||||
printf("\n");
|
||||
|
||||
for(i = 1; i <= sz; i++)
|
||||
{
|
||||
printf("%d", i-1);
|
||||
for(j = 0; j < sz; j++)
|
||||
printf(" %d", b[i][j]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int eq(int **t, int **b, int sz)
|
||||
{
|
||||
for(i = 1; i <= sz; i++)
|
||||
for(j = 0; j < sz; j++)
|
||||
if(b[i][j] != t[i][j])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int sz = 3;
|
||||
int eql = 0;
|
||||
int mov = 0;
|
||||
int **t = malloc(sz*(sizeof(int)+1));
|
||||
for(i = 1; i <= sz; i++)
|
||||
t[i] = malloc(sz*sizeof(int));
|
||||
|
||||
int **b = malloc(sz*(sizeof(int)+1));
|
||||
for(i = 1; i <= sz; i++)
|
||||
b[i] = malloc(sz*sizeof(int));
|
||||
char roc;
|
||||
int n;
|
||||
initt(t, sz);
|
||||
initb(t, b, sz);
|
||||
|
||||
while(eq(t, b, sz))
|
||||
initb(t, b, sz);
|
||||
|
||||
while(!eql)
|
||||
{
|
||||
printf("Target: \n");
|
||||
printb(t, sz);
|
||||
printf("Board: \n");
|
||||
printb(b, sz);
|
||||
printf("What to flip: ");
|
||||
scanf(" %c", &roc);
|
||||
scanf(" %d", &n);
|
||||
|
||||
switch(roc)
|
||||
{
|
||||
case 'r':
|
||||
fliprow(b, sz, n);
|
||||
break;
|
||||
case 'c':
|
||||
flipcol(b, sz, n);
|
||||
break;
|
||||
default:
|
||||
perror("Please specify r or c and an number");
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Moves Taken: %d\n", ++mov);
|
||||
|
||||
if(eq(t, b, sz))
|
||||
{
|
||||
printf("You win!\n");
|
||||
eql = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
70
Task/Flipping-bits-game/D/flipping-bits-game.d
Normal file
70
Task/Flipping-bits-game/D/flipping-bits-game.d
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import std.stdio, std.random, std.ascii, std.string, std.range,
|
||||
std.algorithm, std.conv;
|
||||
|
||||
enum N = 3; // Board side.
|
||||
static assert(N <= lowercase.length);
|
||||
enum columnIDs = lowercase[0 .. N];
|
||||
alias Board = ubyte[N][N];
|
||||
|
||||
void flipBits(ref Board board, in size_t count=1) {
|
||||
foreach (immutable _; 0 .. count)
|
||||
board[uniform(0, $)][uniform(0, $)] ^= 1;
|
||||
}
|
||||
|
||||
void notRow(ref Board board, in size_t i) pure nothrow {
|
||||
board[i][] ^= 1;
|
||||
}
|
||||
|
||||
void notColumn(ref Board board, in size_t i) pure nothrow {
|
||||
foreach (ref row; board)
|
||||
row[i] ^= 1;
|
||||
}
|
||||
|
||||
Board generateGameBoard(in ref Board target) {
|
||||
// board is generated with many flips, to keep parity unchanged.
|
||||
Board board = target;
|
||||
while (board == target)
|
||||
foreach (immutable _; 0 .. 2 * N)
|
||||
[¬Row, ¬Column][uniform(0, 2)](board, uniform(0, N));
|
||||
return board;
|
||||
}
|
||||
|
||||
void show(in ref Board board, in string comment) {
|
||||
comment.writeln;
|
||||
writefln(" %-(%c %)", columnIDs);
|
||||
foreach (immutable j, const row; board)
|
||||
writefln(" %2d %-(%d %)", j + 1, row);
|
||||
}
|
||||
|
||||
void main() {
|
||||
"T prints the target, and Q exits.\n".writeln;
|
||||
// Create target and flip some of its bits randomly.
|
||||
Board target;
|
||||
flipBits(target, uniform(0, N) + 1);
|
||||
show(target, "Target configuration is:");
|
||||
|
||||
auto board = generateGameBoard(target);
|
||||
immutable prompt = format(" 1-%d / %s-%s to flip, or T, Q: ",
|
||||
N, columnIDs[0], columnIDs.back);
|
||||
uint move = 1;
|
||||
while (board != target) {
|
||||
show(board, format("\nMove %d:", move));
|
||||
prompt.write;
|
||||
immutable ans = readln.strip;
|
||||
|
||||
if (ans.length == 1 && columnIDs.canFind(ans)) {
|
||||
board.notColumn(columnIDs.countUntil(ans));
|
||||
move++;
|
||||
} else if (iota(1, N + 1).map!text.canFind(ans)) {
|
||||
board.notRow(ans.to!uint - 1);
|
||||
move++;
|
||||
} else if (ans == "T") {
|
||||
show(target, "Target configuration is:");
|
||||
} else if (ans == "Q") {
|
||||
return "Game stopped.".writeln;
|
||||
} else
|
||||
writefln(" Wrong input '%s'. Try again.\n", ans.take(9));
|
||||
}
|
||||
|
||||
"\nWell done!".writeln;
|
||||
}
|
||||
197
Task/Flipping-bits-game/Fortran/flipping-bits-game.f
Normal file
197
Task/Flipping-bits-game/Fortran/flipping-bits-game.f
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
!Implemented by Anant Dixit (October 2014)
|
||||
program flipping_bits
|
||||
implicit none
|
||||
character(len=*), parameter :: cfmt = "(A3)", ifmt = "(I3)"
|
||||
integer :: N, i, j, io, seed(8), moves, input
|
||||
logical, allocatable :: Brd(:,:), Trgt(:,:)
|
||||
logical :: solved
|
||||
double precision :: r
|
||||
|
||||
do
|
||||
write(*,*) 'Enter the number of squares (between 1 and 10) you would like: '
|
||||
read(*,*,iostat=io) N
|
||||
if(N.gt.0 .and. N.le.10 .and. io.eq.0) exit
|
||||
write(*,*) 'Please, an integer between 1 and 10'
|
||||
end do
|
||||
|
||||
allocate(Brd(N,N),Trgt(N,N))
|
||||
call date_and_time(values=seed)
|
||||
call srand(1000*seed(7)+seed(8)+60000*seed(6))
|
||||
do i = 1,N
|
||||
do j = 1,N
|
||||
r = rand()
|
||||
if(r.gt.0.5D0) then
|
||||
Brd(i,j) = .TRUE.
|
||||
Trgt(i,j) = .TRUE.
|
||||
else
|
||||
Brd(i,j) = .FALSE.
|
||||
Trgt(i,j) = .FALSE.
|
||||
end if
|
||||
end do
|
||||
end do
|
||||
! Random moves taken by the program to `create' a target
|
||||
moves = N
|
||||
do i = 1,moves
|
||||
r = 1+2.0D0*dble(N)*rand() - 1.0D-17 !Only to make sure that the number is between 1 and 2N (less than 2N-1)
|
||||
if(floor(r).le.N) then
|
||||
do j = 1,N
|
||||
Trgt(floor(r),j) = .NOT.Trgt(floor(r),j)
|
||||
end do
|
||||
else
|
||||
r = r-N
|
||||
do j = 1,N
|
||||
Trgt(j,floor(r)) = .NOT.Trgt(j,floor(r))
|
||||
end do
|
||||
end if
|
||||
end do
|
||||
|
||||
!This part checks if the target and the starting configurations are same or not.
|
||||
do
|
||||
input = N
|
||||
call next_move(Brd,Trgt,N,input,solved)
|
||||
call next_move(Brd,Trgt,N,input,solved)
|
||||
if(solved) then
|
||||
r = 1+2.0D0*dble(N)*rand() - 1.0D-17
|
||||
if(floor(r).le.N) then
|
||||
do j = 1,N
|
||||
Trgt(floor(r),j) = .NOT.Trgt(floor(r),j)
|
||||
end do
|
||||
else
|
||||
r = r-N
|
||||
do j = 1,N
|
||||
Trgt(j,floor(r)) = .NOT.Trgt(j,floor(r))
|
||||
end do
|
||||
end if
|
||||
else
|
||||
exit
|
||||
end if
|
||||
end do
|
||||
|
||||
write(*,*) 'Welcome to the Flipping Bits game!'
|
||||
write(*,*) 'You have the current position'
|
||||
|
||||
moves = 0
|
||||
call display(Brd,Trgt,N)
|
||||
input = N
|
||||
do
|
||||
write(*,*) 'Number of moves so far:', moves
|
||||
write(*,*) 'Select the column or row you wish to flip: '
|
||||
read(*,*,iostat=io) input
|
||||
if(io.eq.0 .and. input.gt.0 .and. input.le.(2*N)) then
|
||||
moves = moves+1
|
||||
write(*,*) 'Flipping ', input
|
||||
call next_move(Brd,Trgt,N,input,solved)
|
||||
call display(Brd,Trgt,N)
|
||||
if(solved) exit
|
||||
else
|
||||
write(*,*) 'Please enter a valid column or row number. To quit, press Ctrl+C!'
|
||||
end if
|
||||
end do
|
||||
|
||||
write(*,*) 'Congratulations! You finished the game!'
|
||||
write(*,ifmt,advance='no') moves
|
||||
write(*,*) ' moves were taken by you!!'
|
||||
deallocate(Brd,Trgt)
|
||||
end program
|
||||
|
||||
subroutine display(Brd,Trgt,N)
|
||||
implicit none
|
||||
!arguments
|
||||
integer :: N
|
||||
logical :: Brd(N,N), Trgt(N,N)
|
||||
!local
|
||||
character(len=*), parameter :: cfmt = "(A3)", ifmt = "(I3)"
|
||||
integer :: i, j
|
||||
write(*,*) 'Current Configuration: '
|
||||
do i = 0,N
|
||||
if(i.eq.0) then
|
||||
write(*,cfmt,advance='no') 'R/C'
|
||||
write(*,cfmt,advance='no') ' | '
|
||||
else
|
||||
write(*,ifmt,advance='no') i
|
||||
end if
|
||||
end do
|
||||
write(*,*)
|
||||
do i = 0,N
|
||||
if(i.eq.0) then
|
||||
do j = 0,N+2
|
||||
write(*,cfmt,advance='no') '---'
|
||||
end do
|
||||
else
|
||||
write(*,ifmt,advance='no') i+N
|
||||
write(*,cfmt,advance='no') ' | '
|
||||
do j = 1,N
|
||||
if(Brd(i,j)) then
|
||||
write(*,ifmt,advance='no') 1
|
||||
else
|
||||
write(*,ifmt,advance='no') 0
|
||||
end if
|
||||
end do
|
||||
end if
|
||||
write(*,*)
|
||||
end do
|
||||
|
||||
write(*,*)
|
||||
write(*,*)
|
||||
|
||||
write(*,*) 'Target Configuration'
|
||||
do i = 0,N
|
||||
if(i.eq.0) then
|
||||
write(*,cfmt,advance='no') 'R/C'
|
||||
write(*,cfmt,advance='no') ' | '
|
||||
else
|
||||
write(*,ifmt,advance='no') i
|
||||
end if
|
||||
end do
|
||||
write(*,*)
|
||||
do i = 0,N
|
||||
if(i.eq.0) then
|
||||
do j = 0,N+2
|
||||
write(*,cfmt,advance='no') '---'
|
||||
end do
|
||||
else
|
||||
write(*,ifmt,advance='no') i+N
|
||||
write(*,cfmt,advance='no') ' | '
|
||||
do j = 1,N
|
||||
if(Trgt(i,j)) then
|
||||
write(*,ifmt,advance='no') 1
|
||||
else
|
||||
write(*,ifmt,advance='no') 0
|
||||
end if
|
||||
end do
|
||||
end if
|
||||
write(*,*)
|
||||
end do
|
||||
write(*,*)
|
||||
write(*,*)
|
||||
end subroutine
|
||||
|
||||
subroutine next_move(Brd,Trgt,N,input,solved)
|
||||
implicit none
|
||||
!arguments
|
||||
integer :: N, input
|
||||
logical :: Brd(N,N), Trgt(N,N), solved
|
||||
!others
|
||||
integer :: i,j
|
||||
|
||||
if(input.gt.N) then
|
||||
input = input-N
|
||||
do i = 1,N
|
||||
Brd(input,i) = .not.Brd(input,i)
|
||||
end do
|
||||
else
|
||||
do i = 1,N
|
||||
Brd(i,input) = .not.Brd(i,input)
|
||||
end do
|
||||
end if
|
||||
solved = .TRUE.
|
||||
do i = 1,N
|
||||
do j = 1,N
|
||||
if( (.not.Brd(i,j).and.Trgt(i,j)) .or. (Brd(i,j).and..not.Trgt(i,j)) ) then
|
||||
solved = .FALSE.
|
||||
exit
|
||||
end if
|
||||
end do
|
||||
if(.not.solved) exit
|
||||
end do
|
||||
end subroutine
|
||||
122
Task/Flipping-bits-game/Go/flipping-bits-game.go
Normal file
122
Task/Flipping-bits-game/Go/flipping-bits-game.go
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
var n int = 3 // Change to define board size
|
||||
var moves int = 0
|
||||
|
||||
a := make([][]int, n)
|
||||
for i := range a {
|
||||
a[i] = make([]int, n)
|
||||
for j := range a {
|
||||
a[i][j] = rand.Intn(2)
|
||||
}
|
||||
}
|
||||
|
||||
b := make([][]int, len(a))
|
||||
for i := range a {
|
||||
b[i] = make([]int, len(a[i]))
|
||||
copy(b[i], a[i])
|
||||
}
|
||||
|
||||
for i := rand.Intn(100); i > 0 || compareSlices(a, b) == true; i-- {
|
||||
b = flipCol(b, rand.Intn(n) + 1)
|
||||
b = flipRow(b, rand.Intn(n) + 1)
|
||||
}
|
||||
|
||||
fmt.Println("Target:")
|
||||
drawBoard(a)
|
||||
fmt.Println("\nBoard:")
|
||||
drawBoard(b)
|
||||
|
||||
var rc rune
|
||||
var num int
|
||||
|
||||
for {
|
||||
for{
|
||||
fmt.Printf("\nFlip row (r) or column (c) 1 .. %d (c1, ...): ", n)
|
||||
_, err := fmt.Scanf("%c%d", &rc, &num)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
continue
|
||||
}
|
||||
if num < 1 || num > n {
|
||||
fmt.Println("Wrong command!")
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
switch rc {
|
||||
case 'c':
|
||||
fmt.Printf("Column %v will be flipped\n", num)
|
||||
flipCol(b, num)
|
||||
case 'r':
|
||||
fmt.Printf("Row %v will be flipped\n", num)
|
||||
flipRow(b, num)
|
||||
default:
|
||||
fmt.Println("Wrong command!")
|
||||
continue
|
||||
}
|
||||
|
||||
moves++
|
||||
fmt.Println("\nMoves taken: ", moves)
|
||||
|
||||
fmt.Println("Target:")
|
||||
drawBoard(a)
|
||||
fmt.Println("\nBoard:")
|
||||
drawBoard(b)
|
||||
|
||||
if compareSlices(a, b) {
|
||||
fmt.Printf("Finished. You win with %d moves!\n", moves)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func drawBoard (m [][]int) {
|
||||
fmt.Print(" ")
|
||||
for i := range m {
|
||||
fmt.Printf("%d ", i+1)
|
||||
}
|
||||
for i := range m {
|
||||
fmt.Println()
|
||||
fmt.Printf("%d ", i+1)
|
||||
for _, val := range m[i] {
|
||||
fmt.Printf(" %d", val)
|
||||
}
|
||||
}
|
||||
fmt.Print("\n")
|
||||
}
|
||||
|
||||
func flipRow(m [][]int, row int) ([][]int) {
|
||||
for j := range m {
|
||||
m[row-1][j] ^= 1
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func flipCol(m [][]int, col int) ([][]int) {
|
||||
for j := range m {
|
||||
m[j][col-1] ^= 1
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func compareSlices(m [][]int, n[][]int) bool {
|
||||
o := true
|
||||
for i := range m {
|
||||
for j := range m {
|
||||
if m[i][j] != n[i][j] { o = false }
|
||||
}
|
||||
}
|
||||
return o
|
||||
}
|
||||
94
Task/Flipping-bits-game/Haskell/flipping-bits-game.hs
Normal file
94
Task/Flipping-bits-game/Haskell/flipping-bits-game.hs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import Data.Array
|
||||
import Data.List
|
||||
import Control.Monad
|
||||
import System.Random
|
||||
|
||||
type Board = Array (Char, Char) Int
|
||||
|
||||
flp :: Int -> Int
|
||||
flp 0 = 1
|
||||
flp 1 = 0
|
||||
|
||||
numRows, numCols :: Board -> [Char]
|
||||
numRows t = let ((a, _), (b, _)) = bounds t in [a .. b]
|
||||
|
||||
numCols t = let ((_, a), (_, b)) = bounds t in [a .. b]
|
||||
|
||||
flipRow, flipCol :: Board -> Char -> Board
|
||||
flipRow t r = let e = [ (ix, flp (t ! ix)) | ix <-
|
||||
zip (repeat r) (numCols t) ]
|
||||
in t // e
|
||||
|
||||
flipCol t c = let e = [ (ix, flp (t ! ix)) | ix <-
|
||||
zip (numRows t) (repeat c) ]
|
||||
in t // e
|
||||
|
||||
printBoard :: Board -> IO ()
|
||||
printBoard t = do
|
||||
let rows = numRows t
|
||||
cols = numCols t
|
||||
f 0 = '0'
|
||||
f 1 = '1'
|
||||
p r xs = putStrLn $ [r, ' '] ++ intersperse ' ' (map f xs)
|
||||
putStrLn $ " " ++ intersperse ' ' cols
|
||||
zipWithM_ p rows [ [ t ! (y, x) | x <- cols ] | y <- rows ]
|
||||
|
||||
-- create a random goal board, and flip rows and columns randomly
|
||||
-- to get a starting board
|
||||
setupGame :: Char -> Char -> IO (Board, Board)
|
||||
setupGame sizey sizex = do
|
||||
-- random cell value at (row, col)
|
||||
let mk rc = fmap (\v -> (rc, v)) $ randomRIO (0, 1)
|
||||
rows = ['a' .. sizey]
|
||||
cols = ['1' .. sizex]
|
||||
goal <- fmap (array (('a', '1'), (sizey, sizex))) $
|
||||
mapM mk [ (r, c) | r <- rows, c <- cols ]
|
||||
start <- do
|
||||
let change :: Board -> Int -> IO Board
|
||||
-- flip random row
|
||||
change t 0 = fmap (flipRow t) $ randomRIO ('a', sizey)
|
||||
-- flip random col
|
||||
change t 1 = fmap (flipCol t) $ randomRIO ('1', sizex)
|
||||
numMoves <- randomRIO (3, 15) -- how many flips (3 - 15)
|
||||
-- determine if rows or cols are flipped
|
||||
moves <- replicateM numMoves $ randomRIO (0, 1)
|
||||
-- make changes and get a starting board
|
||||
foldM change goal moves
|
||||
if goal /= start -- check if boards are different
|
||||
then return (goal, start) -- all ok, return both boards
|
||||
else setupGame sizey sizex -- try again
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
putStrLn "Select a board size (1 - 9).\nPress any other key to exit."
|
||||
sizec <- getChar
|
||||
when (sizec `elem` ['1' .. '9']) $ do
|
||||
let size = read [sizec] - 1
|
||||
(g, s) <- setupGame (['a'..] !! size) (['1'..] !! size)
|
||||
turns g s 0
|
||||
|
||||
where
|
||||
turns goal current moves = do
|
||||
putStrLn "\nGoal:"
|
||||
printBoard goal
|
||||
putStrLn "\nBoard:"
|
||||
printBoard current
|
||||
when (moves > 0) $
|
||||
putStrLn $ "\nYou've made " ++ show moves ++ " moves so far."
|
||||
putStrLn $ "\nFlip a row (" ++ numRows current ++
|
||||
") or a column (" ++ numCols current ++ ")"
|
||||
v <- getChar
|
||||
if v `elem` numRows current
|
||||
then check $ flipRow current v
|
||||
else if v `elem` numCols current
|
||||
then check $ flipCol current v
|
||||
else tryAgain
|
||||
|
||||
where check t = if t == goal
|
||||
then putStrLn $ "\nYou've won in " ++
|
||||
show (moves + 1) ++ " moves!"
|
||||
else turns goal t (moves + 1)
|
||||
|
||||
tryAgain = do
|
||||
putStrLn ": Invalid row or column."
|
||||
turns goal current moves
|
||||
21
Task/Flipping-bits-game/J/flipping-bits-game-1.j
Normal file
21
Task/Flipping-bits-game/J/flipping-bits-game-1.j
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
start=:3 :0
|
||||
Moves=:0
|
||||
N=:i.y
|
||||
Board=: ?2$~,~y
|
||||
'fr fc'=. (2,y)$}.#:(+?&.<:@<:)2x^2*y
|
||||
End=: fr~:fc~:"1 Board
|
||||
Board;End
|
||||
)
|
||||
|
||||
abc=:'abcdefghij'
|
||||
move=:3 :0
|
||||
fc=. N e.abc i. y ([-.-.)abc
|
||||
fr=. N e._-.~_ "."0 abc-.~":y
|
||||
Board=: fr~:fc~:"1 Board
|
||||
smoutput (":Moves=:Moves++/fr,fc),' moves'
|
||||
if. Board-:End do.
|
||||
'yes'
|
||||
else.
|
||||
Board;End
|
||||
end.
|
||||
)
|
||||
16
Task/Flipping-bits-game/J/flipping-bits-game-2.j
Normal file
16
Task/Flipping-bits-game/J/flipping-bits-game-2.j
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
start 3
|
||||
┌─────┬─────┐
|
||||
│1 1 1│1 0 1│
|
||||
│1 1 0│0 1 1│
|
||||
│1 0 0│0 0 1│
|
||||
└─────┴─────┘
|
||||
move 'b2'
|
||||
2 moves
|
||||
┌─────┬─────┐
|
||||
│1 0 1│1 0 1│
|
||||
│1 0 0│0 1 1│
|
||||
│0 0 1│0 0 1│
|
||||
└─────┴─────┘
|
||||
move '1'
|
||||
3 moves
|
||||
yes
|
||||
87
Task/Flipping-bits-game/MATLAB/flipping-bits-game.m
Normal file
87
Task/Flipping-bits-game/MATLAB/flipping-bits-game.m
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
function FlippingBitsGame(n)
|
||||
% Play the flipping bits game on an n x n array
|
||||
|
||||
% Generate random target array
|
||||
fprintf('Welcome to the Flipping Bits Game!\n')
|
||||
if nargin < 1
|
||||
n = input('What dimension array should we use? ');
|
||||
end
|
||||
Tar = logical(randi([0 1], n));
|
||||
|
||||
% Generate starting array by randomly flipping rows or columns
|
||||
Cur = Tar;
|
||||
while all(Cur(:) == Tar(:))
|
||||
nFlips = randi([3*n max(10*n, 100)]);
|
||||
randDim = randi([0 1], nFlips, 1);
|
||||
randIdx = randi([1 n], nFlips, 1);
|
||||
for k = 1:nFlips
|
||||
if randDim(k)
|
||||
Cur(randIdx(k), :) = ~Cur(randIdx(k), :);
|
||||
else
|
||||
Cur(:, randIdx(k)) = ~Cur(:, randIdx(k));
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% Print rules
|
||||
fprintf('Given a %d x %d logical array,\n', n, n)
|
||||
fprintf('and a target array configuration,\n')
|
||||
fprintf('attempt to transform the array to the target\n')
|
||||
fprintf('by inverting the bits in a whole row or column\n')
|
||||
fprintf('at once in as few moves as possible.\n')
|
||||
fprintf('Enter the corresponding letter to invert a column,\n')
|
||||
fprintf('or the corresponding number to invert a row.\n')
|
||||
fprintf('0 will reprint the target array, and no entry quits.\n\n')
|
||||
fprintf('Target:\n')
|
||||
PrintArray(Tar)
|
||||
|
||||
% Play until player wins or quits
|
||||
move = true;
|
||||
nMoves = 0;
|
||||
while ~isempty(move) && any(Cur(:) ~= Tar(:))
|
||||
fprintf('Move %d:\n', nMoves)
|
||||
PrintArray(Cur)
|
||||
move = lower(input('Enter move: ', 's'));
|
||||
if length(move) > 1
|
||||
fprintf('Invalid move, try again\n')
|
||||
elseif move
|
||||
r = str2double(move);
|
||||
if isnan(r)
|
||||
c = move-96;
|
||||
if c > n || c < 1
|
||||
fprintf('Invalid move, try again\n')
|
||||
else
|
||||
Cur(:, c) = ~Cur(:, c);
|
||||
nMoves = nMoves+1;
|
||||
end
|
||||
else
|
||||
if r > n || r < 0
|
||||
fprintf('Invalid move, try again\n')
|
||||
elseif r == 0
|
||||
fprintf('Target:\n')
|
||||
PrintArray(Tar)
|
||||
else
|
||||
Cur(r, :) = ~Cur(r, :);
|
||||
nMoves = nMoves+1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if all(Cur(:) == Tar(:))
|
||||
fprintf('You win in %d moves! Try not to flip out!\n', nMoves)
|
||||
else
|
||||
fprintf('Quitting? The challenge a bit much for you?\n')
|
||||
end
|
||||
end
|
||||
|
||||
function PrintArray(A)
|
||||
[nRows, nCols] = size(A);
|
||||
fprintf(' ')
|
||||
fprintf(' %c', (1:nCols)+96)
|
||||
fprintf('\n')
|
||||
for r = 1:nRows
|
||||
fprintf('%8d%s\n', r, sprintf(' %d', A(r, :)))
|
||||
end
|
||||
fprintf('\n')
|
||||
end
|
||||
49
Task/Flipping-bits-game/PL-I/flipping-bits-game.pli
Normal file
49
Task/Flipping-bits-game/PL-I/flipping-bits-game.pli
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
(subscriptrange, stringrange, stringsize):
|
||||
flip: procedure options (main);
|
||||
declare n fixed binary;
|
||||
|
||||
put skip list ('This is the bit-flipping game. What size of board do you want?');
|
||||
get list (n);
|
||||
put skip list
|
||||
('Your task is to change your board so as match the board on the right (the objective)');
|
||||
|
||||
begin;
|
||||
declare initial(n,n) bit (1), objective(n,n) bit (1);
|
||||
declare (i, j, k, move) fixed binary;
|
||||
declare ch character(1);
|
||||
declare alphabet character (26) initial ('abcdefghijklmnopqrstuvwxyz');
|
||||
|
||||
on subrg
|
||||
begin; put skip list ('Your row or column ' || trim(ch) || ' is out of range'); stop; end;
|
||||
|
||||
initial, objective = iand(random()*99, 1) = 1;
|
||||
|
||||
/* Set up the objective array: */
|
||||
do i = 1 to n-1;
|
||||
j = random()*n+1; objective(j,*) = ^objective(j,*);
|
||||
j = random()*n+1; objective(*,j) = ^objective(*,j);
|
||||
end;
|
||||
|
||||
do move = 0 by 1;
|
||||
put skip edit ( center('You', n*3), center('The objective', 3*n+4) ) (x(3), a);
|
||||
put skip edit ( (substr(alphabet, i, 1) do i = 1 to n) ) (x(5), (n) a(3));
|
||||
put edit ( (substr(alphabet, i, 1) do i = 1 to n) ) (x(3), (n) a(3));
|
||||
do i = 1 to n;
|
||||
put skip edit (i, initial(i,*), objective(i,*)) ((n+1) f(3), x(3), (n) F(3));
|
||||
end;
|
||||
|
||||
if all(initial = objective) then leave;
|
||||
|
||||
put skip(2) list
|
||||
('Please type a row number or column letter whose bits you want to flip: ');
|
||||
get edit (ch) (L); put edit (ch) (a);
|
||||
k = index(alphabet, ch);
|
||||
if k > 0 then
|
||||
initial(*, k) = ^initial(*,k); /* Flip column k */
|
||||
else
|
||||
initial(ch,*) = ^initial(ch,*); /* Flip row ch */
|
||||
end;
|
||||
put skip(2) list ('Congratulations. You solved it in ' || trim(move) || ' moves.');
|
||||
end;
|
||||
|
||||
end flip;
|
||||
54
Task/Flipping-bits-game/Perl-6/flipping-bits-game.pl6
Normal file
54
Task/Flipping-bits-game/Perl-6/flipping-bits-game.pl6
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
sub MAIN ($square = 4) {
|
||||
say "{$square}? Seriously?" and exit if $square < 1 or $square > 26;
|
||||
my %bits = map { $_ => %( map { $_ => 0 }, ('A' .. *)[^ $square] ) },
|
||||
(1 .. *)[^ $square];
|
||||
scramble %bits;
|
||||
my $target = build %bits;
|
||||
scramble %bits until build(%bits) ne $target;
|
||||
display($target, %bits);
|
||||
my $turns = 0;
|
||||
while my $flip = prompt "Turn {++$turns}: Flip which row / column? " {
|
||||
flip $flip.match(/\w/).uc, %bits;
|
||||
if display($target, %bits) {
|
||||
say "Hurray! You solved it in $turns turns.";
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub display($goal, %hash) {
|
||||
shell('clear');
|
||||
say "Goal\n$goal\nYou";
|
||||
my $this = build %hash;
|
||||
say $this;
|
||||
return ($goal eq $this);
|
||||
}
|
||||
|
||||
sub flip ($a, %hash) {
|
||||
given $a {
|
||||
when any(keys %hash) {
|
||||
%hash{$a}{$_} = %hash{$a}{$_} +^ 1 for %hash{$a}.keys
|
||||
};
|
||||
when any(keys %hash{'1'}) {
|
||||
%hash{$_}{$a} = %hash{$_}{$a} +^ 1 for %hash.keys
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
sub build (%hash) {
|
||||
my $string = ' ';
|
||||
$string ~= sprintf "%2s ", $_ for sort keys %hash{'1'};
|
||||
$string ~= "\n";
|
||||
for sort keys %hash -> $key {
|
||||
$string ~= sprintf "%2s ", $key;
|
||||
$string ~= sprintf "%2s ", %hash{$key}{$_} for sort keys %hash{$key};
|
||||
$string ~= "\n";
|
||||
};
|
||||
$string
|
||||
}
|
||||
|
||||
sub scramble(%hash) {
|
||||
my @keys = keys %hash;
|
||||
@keys ,= keys %hash{'1'};
|
||||
flip $_, %hash for @keys.pick( @keys/2 );
|
||||
}
|
||||
76
Task/Flipping-bits-game/Perl/flipping-bits-game.pl
Normal file
76
Task/Flipping-bits-game/Perl/flipping-bits-game.pl
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#!perl
|
||||
use strict;
|
||||
use warnings qw(FATAL all);
|
||||
|
||||
my $n = shift(@ARGV) || 4;
|
||||
if( $n < 2 or $n > 26 ) {
|
||||
die "You can't play a size $n game\n";
|
||||
}
|
||||
|
||||
my $n2 = $n*$n;
|
||||
|
||||
my (@rows, @cols);
|
||||
for my $i ( 0 .. $n-1 ) {
|
||||
my $row = my $col = "\x00" x $n2;
|
||||
vec($row, $i * $n + $_, 8) ^= 1 for 0 .. $n-1;
|
||||
vec($col, $i + $_ * $n, 8) ^= 1 for 0 .. $n-1;
|
||||
push @rows, $row;
|
||||
push @cols, $col;
|
||||
}
|
||||
|
||||
my $goal = "0" x $n2;
|
||||
int(rand(2)) or (vec($goal, $_, 8) ^= 1) for 0 .. $n2-1;
|
||||
my $start = $goal;
|
||||
{
|
||||
for(@rows, @cols) {
|
||||
$start ^= $_ if int rand 2;
|
||||
}
|
||||
redo if $start eq $goal;
|
||||
}
|
||||
|
||||
my @letters = ('a'..'z')[0..$n-1];
|
||||
sub to_strings {
|
||||
my $board = shift;
|
||||
my @result = join(" ", " ", @letters);
|
||||
for( 0 .. $n-1 ) {
|
||||
my $res = sprintf("%2d ",$_+1);
|
||||
$res .= join " ", split //, substr $board, $_*$n, $n;
|
||||
push @result, $res;
|
||||
}
|
||||
\@result;
|
||||
}
|
||||
|
||||
my $fmt;
|
||||
my ($stext, $etext) = ("Starting board", "Ending board");
|
||||
my $re = join "|", reverse 1 .. $n, @letters;
|
||||
my $moves_so_far = 0;
|
||||
while( 1 ) {
|
||||
my ($from, $to) = (to_strings($start), to_strings($goal));
|
||||
unless( $fmt ) {
|
||||
my $len = length $from->[0];
|
||||
$len = length($stext) if $len < length $stext;
|
||||
$fmt = join($len, "%", "s%", "s\n");
|
||||
}
|
||||
printf $fmt, $stext, $etext;
|
||||
printf $fmt, $from->[$_], $to->[$_] for 0 .. $n;
|
||||
last if $start eq $goal;
|
||||
INPUT_LOOP: {
|
||||
printf "Move #%s: Type one or more row numbers and/or column letters: ",
|
||||
$moves_so_far+1;
|
||||
my $input = <>;
|
||||
die unless defined $input;
|
||||
my $did_one;
|
||||
for( $input =~ /($re)/gi ) {
|
||||
$did_one = 1;
|
||||
if( /\d/ ) {
|
||||
$start ^= $rows[$_-1];
|
||||
} else {
|
||||
$_ = ord(lc) - ord('a');
|
||||
$start ^= $cols[$_];
|
||||
}
|
||||
++$moves_so_far;
|
||||
}
|
||||
redo INPUT_LOOP unless $did_one;
|
||||
}
|
||||
}
|
||||
print "You won after $moves_so_far moves.\n";
|
||||
85
Task/Flipping-bits-game/Python/flipping-bits-game.py
Normal file
85
Task/Flipping-bits-game/Python/flipping-bits-game.py
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
"""
|
||||
Given a %i by %i sqare array of zeroes or ones in an initial
|
||||
configuration, and a target configuration of zeroes and ones
|
||||
The task is to transform one to the other in as few moves as
|
||||
possible by inverting whole numbered rows or whole lettered
|
||||
columns at once.
|
||||
In an inversion any 1 becomes 0 and any 0 becomes 1 for that
|
||||
whole row or column.
|
||||
|
||||
"""
|
||||
|
||||
from random import randrange
|
||||
from copy import deepcopy
|
||||
from string import ascii_lowercase
|
||||
|
||||
|
||||
try: # 2to3 fix
|
||||
input = raw_input
|
||||
except:
|
||||
pass
|
||||
|
||||
N = 3 # N x N Square arrray
|
||||
|
||||
board = [[0]* N for i in range(N)]
|
||||
|
||||
def setbits(board, count=1):
|
||||
for i in range(count):
|
||||
board[randrange(N)][randrange(N)] ^= 1
|
||||
|
||||
def shuffle(board, count=1):
|
||||
for i in range(count):
|
||||
if randrange(0, 2):
|
||||
fliprow(randrange(N))
|
||||
else:
|
||||
flipcol(randrange(N))
|
||||
|
||||
|
||||
def pr(board, comment=''):
|
||||
print(str(comment))
|
||||
print(' ' + ' '.join(ascii_lowercase[i] for i in range(N)))
|
||||
print(' ' + '\n '.join(' '.join(['%2s' % j] + [str(i) for i in line])
|
||||
for j, line in enumerate(board, 1)))
|
||||
|
||||
def init(board):
|
||||
setbits(board, count=randrange(N)+1)
|
||||
target = deepcopy(board)
|
||||
while board == target:
|
||||
shuffle(board, count=2 * N)
|
||||
prompt = ' X, T, or 1-%i / %s-%s to flip: ' % (N, ascii_lowercase[0],
|
||||
ascii_lowercase[N-1])
|
||||
return target, prompt
|
||||
|
||||
def fliprow(i):
|
||||
board[i-1][:] = [x ^ 1 for x in board[i-1] ]
|
||||
|
||||
def flipcol(i):
|
||||
for row in board:
|
||||
row[i] ^= 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__ % (N, N))
|
||||
target, prompt = init(board)
|
||||
pr(target, 'Target configuration is:')
|
||||
print('')
|
||||
turns = 0
|
||||
while board != target:
|
||||
turns += 1
|
||||
pr(board, '%i:' % turns)
|
||||
ans = input(prompt).strip()
|
||||
if (len(ans) == 1
|
||||
and ans in ascii_lowercase and ascii_lowercase.index(ans) < N):
|
||||
flipcol(ascii_lowercase.index(ans))
|
||||
elif ans and all(ch in '0123456789' for ch in ans) and 1 <= int(ans) <= N:
|
||||
fliprow(int(ans))
|
||||
elif ans == 'T':
|
||||
pr(target, 'Target configuration is:')
|
||||
turns -= 1
|
||||
elif ans == 'X':
|
||||
break
|
||||
else:
|
||||
print(" I don't understand %r... Try again. "
|
||||
"(X to exit or T to show target)\n" % ans[:9])
|
||||
turns -= 1
|
||||
else:
|
||||
print('\nWell done!\nBye.')
|
||||
1
Task/Flipping-bits-game/README
Normal file
1
Task/Flipping-bits-game/README
Normal file
|
|
@ -0,0 +1 @@
|
|||
Data source: http://rosettacode.org/wiki/Flipping_bits_game
|
||||
86
Task/Flipping-bits-game/REXX/flipping-bits-game.rexx
Normal file
86
Task/Flipping-bits-game/REXX/flipping-bits-game.rexx
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*REXX program presents a "flipping bit" puzzle, user can solve via C.L.*/
|
||||
parse arg N u on off . /*get optional arguments. */
|
||||
if N=='' | N==',' then N=3 /*Size given? Then use default.*/
|
||||
if u=='' | u==',' then u=N /*number of bits initialized ON.*/
|
||||
if on =='' then on =1 /*character used for "on". */
|
||||
if off=='' then off=0 /*character used for "off". */
|
||||
col@='a b c d e f g h i j k l m n o p q r s t u v w x y z' /*for col id.*/
|
||||
cols=space(col@,0); upper cols /*letters to be used for columns.*/
|
||||
@.=off; !.=off /*set both arrays to "off" chars.*/
|
||||
tries=0 /*# of player's attempts used. */
|
||||
do while show(0) < u /* [↓] turn "on" U bits.*/
|
||||
r=random(1,N); c=random(1,N) /*get a random row and column.*/
|
||||
@.r.c=on ; !.r.c=on /*set (both) row & column to ON*/
|
||||
end /*while*/ /* [↑] keep going 'til U bits set*/
|
||||
oz=z /*keep the original array string.*/
|
||||
call show 1, ' ◄───target' /*show target for user to attain.*/
|
||||
|
||||
do random(1,2); call flip 'R',random(1,N) /*flip a row of bits*/
|
||||
call flip 'C',random(1,N) /* " " col " " */
|
||||
end /*random···*/ /* [↑] 1 or 2 times*/
|
||||
|
||||
if z==oz then call flip 'R',random(1,N) /*ensure it's not the target.*/
|
||||
|
||||
do until z==oz /*prompt until they get it right.*/
|
||||
call prompt /*get a row or column # from C.L.*/
|
||||
call flip left(?,1),substr(?,2) /*flip a user selected row or col*/
|
||||
call show 0 /*get image (Z) of updated array.*/
|
||||
end /*until···*/
|
||||
|
||||
call show 1, ' ◄───your array' /*display the array to the screen*/
|
||||
say '─────────Congrats! You did it in' tries "tries."
|
||||
exit tries /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────FLIP subroutine────────────────────────*/
|
||||
flip: parse arg x,# /*X is R or C, # is which one.*/
|
||||
do c=1 for N while x=='R'; if @.#.c==on then @.#.c=off; else @.#.c=on; end
|
||||
do r=1 for N while x=='C'; if @.r.#==on then @.r.#=off; else @.r.#=on; end
|
||||
return /* [↑] the bits can be ON or OFF*/
|
||||
/*──────────────────────────────────PROMPTER subroutine─────────────────*/
|
||||
prompt: if tries\==0 then say '─────────bit array after play: ' tries
|
||||
signal on halt /*another way for player to quit.*/
|
||||
!='─────────Please enter a row number or column letter, or Quit:'
|
||||
call show 1, ' ◄───your array' /*display the array to the screen*/
|
||||
|
||||
do forever; ok=1; say; say !; pull ? _ . 1 all /*prompt & get ans*/
|
||||
if abbrev('QUIT',?,1) then do; say 'quitting···'; exit 0; end
|
||||
if ?=='' then do; call show 1,' ◄───target',.; ok=0
|
||||
call show 1,' ◄───your array'
|
||||
end /* [↑] reshow targ*/
|
||||
if _\=='' then call terr 'too many args entered:' all
|
||||
if \isInt(?) & \isLet(?) then call terr 'row/column: ' ?
|
||||
if isLet(?) then a=pos(?,cols)
|
||||
if isLet(?) & (a<1 | a>N) then call terr 'column: ' ?
|
||||
if isLet(?) & length(?)>1 then call terr 'column: ' ?
|
||||
if isLet(?) then ?='C'pos(?,cols)
|
||||
if isInt(?) & (?<1 | ?>N) then call terr 'row: ' ?
|
||||
if isInt(?) then ?=?/1 /*normalize number*/
|
||||
if isInt(?) then ?='R'?
|
||||
if ok then leave /*No errors? Leave*/
|
||||
end /*forever*/ /*endeth da checks*/
|
||||
|
||||
tries=tries+1 /*bump da counter.*/
|
||||
return ? /*return response.*/
|
||||
/*──────────────────────────────────SHOW subroutine─────────────────────*/
|
||||
show: $=0; _=; z=; parse arg tell,tx,o /*$: # of ON bits.*/
|
||||
if tell then do /*are we telling? */
|
||||
say /*show blank line.*/
|
||||
say ' ' subword(col@,1,N) " column letter"
|
||||
say 'row ╔'copies('═',N+N+1) /*prepend col hdrs*/
|
||||
end /* [↑] grid hdrs.*/
|
||||
|
||||
do r=1 for N /*show grid rows.*/
|
||||
do c=1 for N /*build grid cols.*/
|
||||
if o==. then do; z=z || !.r.c; _=_ !.r.c; $=$+(!.r.c==on); end
|
||||
else do; z=z || @.r.c; _=_ @.r.c; $=$+(@.r.c==on); end
|
||||
end /*c*/ /*··· and sum ONs.*/
|
||||
if tx\=='' then tar.r=_ tx /*build da target?*/
|
||||
if tell then say right(r,2) ' ║'_ tx; _= /*show the grid? */
|
||||
end /*r*/ /*show a grid row.*/
|
||||
|
||||
if tell then say /*show blank line.*/
|
||||
return $ /*$: # of ON bits.*/
|
||||
/*──────────────────────────────────one-liner subroutines───────────────*/
|
||||
halt: say 'program was halted!'; exit /*the REXX program was halted.*/
|
||||
isInt: return datatype(arg(1),'W') /*returns 1 if arg is an int. */
|
||||
isLet: return datatype(arg(1),'M') /*returns 1 if arg is a letter*/
|
||||
terr: if ok then say '***error!***: illegal' arg(1); ok=0; return
|
||||
71
Task/Flipping-bits-game/Racket/flipping-bits-game.rkt
Normal file
71
Task/Flipping-bits-game/Racket/flipping-bits-game.rkt
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#lang racket
|
||||
(define (flip-row! pzzl r)
|
||||
(define N (integer-sqrt (bytes-length pzzl)))
|
||||
(for* ((c (in-range N)))
|
||||
(define idx (+ c (* N r)))
|
||||
(bytes-set! pzzl idx (- 1 (bytes-ref pzzl idx)))))
|
||||
|
||||
(define (flip-col! pzzl c)
|
||||
(define N (integer-sqrt (bytes-length pzzl)))
|
||||
(for* ((r (in-range N)))
|
||||
(define idx (+ c (* N r)))
|
||||
(bytes-set! pzzl idx (- 1 (bytes-ref pzzl idx)))))
|
||||
|
||||
(define (new-game N (flips 10))
|
||||
(define N2 (sqr N))
|
||||
(define targ (list->bytes (for/list ((_ N2)) (random 2))))
|
||||
(define strt (bytes-copy targ))
|
||||
(for ((_ flips))
|
||||
(case (random 2)
|
||||
((0) (flip-col! strt (random N)))
|
||||
((1) (flip-row! strt (random N)))))
|
||||
(if (equal? strt targ) (new-game N) (values targ strt)))
|
||||
|
||||
(define (show-games #:sep (pzl-sep " | ") . pzzls)
|
||||
(define N (integer-sqrt (bytes-length (first pzzls))))
|
||||
(define caption (string-join (for/list ((c (in-range N))) (~a (add1 c))) ""))
|
||||
(define ruler (string-join (for/list ((c (in-range N))) "-") ""))
|
||||
|
||||
(define ((pzzle-row r) p)
|
||||
(string-join (for/list ((c (in-range N))) (~a (bytes-ref p (+ c (* N r))))) ""))
|
||||
|
||||
(displayln
|
||||
(string-join
|
||||
(list*
|
||||
(format " ~a" (string-join (for/list ((_ pzzls)) caption) pzl-sep))
|
||||
(format " ~a" (string-join (for/list ((_ pzzls)) ruler) pzl-sep))
|
||||
(for/list ((r (in-range N)) (R (in-naturals (char->integer #\a))))
|
||||
(format "~a ~a" (integer->char R) (string-join (map (pzzle-row r) pzzls) pzl-sep))))
|
||||
"\n")))
|
||||
|
||||
(define (play N)
|
||||
(define-values (end start) (new-game N))
|
||||
(define (turn n (show? #t))
|
||||
(cond
|
||||
[(equal? end start) (printf "you won on turn #~a~%" n)]
|
||||
[else
|
||||
(when show? ;; don't show after whitespace
|
||||
(printf "turn #~a~%" n)
|
||||
(show-games start end))
|
||||
(match (read-char)
|
||||
[(? eof-object?) (printf "sad to see you go :-(~%")]
|
||||
[(? char-whitespace?) (turn n #f)]
|
||||
[(? char-numeric? c)
|
||||
(define cnum (- (char->integer c) (char->integer #\1)))
|
||||
(cond [(< -1 cnum N)
|
||||
(printf "flipping col ~a~%" (add1 cnum))
|
||||
(flip-col! start cnum)
|
||||
(turn (add1 n))]
|
||||
[else (printf "column number out of range ~a > ~a~%" (add1 cnum) N)
|
||||
(turn n)])]
|
||||
[(? char-lower-case? c)
|
||||
(define rnum (- (char->integer c) (char->integer #\a)))
|
||||
(cond [(< -1 rnum N)
|
||||
(printf "flipping row ~a~%" (add1 rnum))
|
||||
(flip-row! start rnum)
|
||||
(turn (add1 n))]
|
||||
[else (printf "row number out of range ~a > ~a~%" (add1 rnum) (sub1 N))
|
||||
(turn n)])]
|
||||
[else (printf "unrecognised character in input: ~s~%" else)
|
||||
(turn n)])]))
|
||||
(turn 0))
|
||||
104
Task/Flipping-bits-game/Ruby/flipping-bits-game.rb
Normal file
104
Task/Flipping-bits-game/Ruby/flipping-bits-game.rb
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
class FlipBoard
|
||||
def initialize(size)
|
||||
raise ArgumentError.new("Invalid board size: #{size}") if size < 2
|
||||
|
||||
@size = size
|
||||
@board = Array.new(size**2, 0)
|
||||
|
||||
randomize_board
|
||||
loop do
|
||||
@target = generate_target
|
||||
break unless solved?
|
||||
end
|
||||
|
||||
# these are used for validating user input
|
||||
@columns = [*'a'...('a'.ord+@size).chr]
|
||||
@rows = (1..@size).map(&:to_s)
|
||||
end
|
||||
|
||||
############################################################
|
||||
|
||||
def play
|
||||
moves = 0
|
||||
puts "your target:", target
|
||||
|
||||
until solved?
|
||||
puts "", "move #{moves}:", self
|
||||
print "Row/column to flip: "
|
||||
ans = $stdin.gets.strip
|
||||
|
||||
if @columns.include? ans
|
||||
flip_column @columns.index(ans)
|
||||
moves += 1
|
||||
elsif @rows.include? ans
|
||||
flip_row @rows.index(ans)
|
||||
moves += 1
|
||||
else
|
||||
puts "invalid input: " + ans
|
||||
end
|
||||
end
|
||||
|
||||
puts "", "you solved the game in #{moves} moves", self
|
||||
end
|
||||
|
||||
# the target formation as a string
|
||||
def target
|
||||
format_array @target
|
||||
end
|
||||
|
||||
# the current formation as a string
|
||||
def to_s
|
||||
format_array @board
|
||||
end
|
||||
|
||||
############################################################
|
||||
private
|
||||
|
||||
def solved?
|
||||
@board == @target
|
||||
end
|
||||
|
||||
# flip a random number of bits on the board
|
||||
def randomize_board
|
||||
(@size + rand(@size)).times do
|
||||
flip_bit rand(@size), rand(@size)
|
||||
end
|
||||
end
|
||||
|
||||
# generate a random number of flip_row/flip_column calls
|
||||
def generate_target
|
||||
orig_board = @board.clone
|
||||
(@size + rand(@size)).times do
|
||||
rand(2).zero? ? flip_row( rand(@size) ) : flip_column( rand(@size) )
|
||||
end
|
||||
target, @board = @board, orig_board
|
||||
target
|
||||
end
|
||||
|
||||
def flip_row(row)
|
||||
@size.times {|col| flip_bit(row, col)}
|
||||
end
|
||||
|
||||
def flip_column(col)
|
||||
@size.times {|row| flip_bit(row, col)}
|
||||
end
|
||||
|
||||
def flip_bit(row, col)
|
||||
@board[@size * row + col] ^= 1
|
||||
end
|
||||
|
||||
def format_array(ary)
|
||||
str = " " + @columns.join(" ") + "\n"
|
||||
@size.times do |row|
|
||||
str << "%2s " % @rows[row] + ary[@size*row, @size].join(" ") + "\n"
|
||||
end
|
||||
str
|
||||
end
|
||||
end
|
||||
|
||||
######################################################################
|
||||
begin
|
||||
FlipBoard.new(ARGV.shift.to_i).play
|
||||
rescue => e
|
||||
puts e.message
|
||||
end
|
||||
92
Task/Flipping-bits-game/Tcl/flipping-bits-game.tcl
Normal file
92
Task/Flipping-bits-game/Tcl/flipping-bits-game.tcl
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
package require Tcl 8.6
|
||||
|
||||
oo::class create Flip {
|
||||
variable board target s
|
||||
constructor {size} {
|
||||
set s $size
|
||||
set target [my RandomConfiguration]
|
||||
set board $target
|
||||
while {$board eq $target} {
|
||||
for {set i 0} {$i < $s} {incr i} {
|
||||
if {rand()<.5} {
|
||||
my SwapRow $i
|
||||
}
|
||||
if {rand()<.5} {
|
||||
my SwapColumn $i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
method RandomConfiguration {{p 0.5}} {
|
||||
for {set row 0} {$row < $s} {incr row} {
|
||||
set r {}
|
||||
for {set col 0} {$col < $s} {incr col} {
|
||||
lappend r [expr {rand() < $p}]
|
||||
}
|
||||
lappend result $r
|
||||
}
|
||||
return $result
|
||||
}
|
||||
|
||||
method SwapRow {rowId} {
|
||||
for {set i 0} {$i < $s} {incr i} {
|
||||
lset board $rowId $i [expr {![lindex $board $rowId $i]}]
|
||||
}
|
||||
}
|
||||
method SwapColumn {columnId} {
|
||||
for {set i 0} {$i < $s} {incr i} {
|
||||
lset board $i $columnId [expr {![lindex $board $i $columnId]}]
|
||||
}
|
||||
}
|
||||
|
||||
method Render {configuration {prefixes {}}} {
|
||||
join [lmap r $configuration p $prefixes {
|
||||
format %s%s $p [join [lmap c $r {string index ".X" $c}] ""]
|
||||
}] "\n"
|
||||
}
|
||||
method GetInput {prompt} {
|
||||
puts -nonewline "${prompt}: "
|
||||
flush stdout
|
||||
gets stdin
|
||||
}
|
||||
|
||||
method play {} {
|
||||
set p0 {}
|
||||
set p {}
|
||||
set top [format "%*s " [string length $s] ""]
|
||||
for {set i 1;set j 97} {$i<=$s} {incr i;incr j} {
|
||||
append top [format %c $j]
|
||||
lappend p [format "%*d " [string length $s] $i]
|
||||
lappend p0 [format "%*s " [string length $s] ""]
|
||||
}
|
||||
|
||||
set moves 0
|
||||
puts "You are trying to get to:\n[my Render $target $p0]\n"
|
||||
while true {
|
||||
puts "Current configuration (#$moves):\n$top\n[my Render $board $p]"
|
||||
|
||||
# Test for if we've won
|
||||
if {$board eq $target} break
|
||||
|
||||
# Ask the user for a move
|
||||
set i [my GetInput "Pick a column (letter) or row (number) to flip"]
|
||||
|
||||
# Parse the move and apply it
|
||||
if {[string is lower -strict $i] && [set c [expr {[scan $i "%c"] - 97}]]<$s} {
|
||||
my SwapColumn $c
|
||||
incr moves
|
||||
} elseif {[string is integer -strict $i] && $i>0 && $i<=$s} {
|
||||
my SwapRow [expr {$i - 1}]
|
||||
incr moves
|
||||
} else {
|
||||
puts "Error: bad selection"
|
||||
}
|
||||
puts ""
|
||||
}
|
||||
puts "\nYou win! (You took $moves moves.)"
|
||||
}
|
||||
}
|
||||
|
||||
Flip create flip 3
|
||||
flip play
|
||||
Loading…
Add table
Add a link
Reference in a new issue