Update all new Tasks

This commit is contained in:
Ingy döt Net 2015-02-20 09:02:09 -05:00
parent 00a190b0a6
commit 91df62d461
5697 changed files with 93386 additions and 804 deletions

View 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.

View file

@ -0,0 +1,3 @@
---
category:
- Games

View 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;

View 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

View 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" ); }

View 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;
}
}
}

View 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)
[&notRow, &notColumn][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;
}

View 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

View 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
}

View 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

View 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.
)

View 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

View 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

View 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;

View 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 );
}

View 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";

View 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.')

View file

@ -0,0 +1 @@
Data source: http://rosettacode.org/wiki/Flipping_bits_game

View 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

View 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))

View 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

View 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