100 doors

There are 100 doors in a row that are all initially closed.

You make 100 passes by the doors.

The first time through, visit every door and  ''toggle''  the door  (if the door is closed,  open it;   if it is open,  close it).

The second time, only visit every 2nd door   (door #2, #4, #6, ...),   and toggle it.

The third time, visit every 3rd door   (door #3, #6, #9, ...), etc,   until you only visit the 100th door.

;Task:
Answer the question:   what state are the doors in after the last pass?   Which are open, which are closed?

'''Alternate:'''
As noted in this page's   discussion page,   the only doors that remain open are those whose numbers are perfect squares.

Opening only those doors is an   optimization   that may also be expressed;
however, as should be obvious, this defeats the intent of comparing implementations across programming languages.

Solution:
#include

#define NUM_DOORS 100

int main(int argc, char *argv[])
{
  int is_open[NUM_DOORS] = { 0 } ;
  int * doorptr, * doorlimit = is_open + NUM_DOORS ;
  int pass ;

  /* do the N passes, go backwards because the order is not important */
  for ( pass= NUM_DOORS ; ( pass ) ; -- pass ) {
    for ( doorptr= is_open + ( pass-1 ); ( doorptr < doorlimit ) ; doorptr += pass ) {
      ( * doorptr ) ^= 1 ;
    }
  }

  /* output results */
  for ( doorptr= is_open ; ( doorptr != doorlimit ) ; ++ doorptr ) {
    printf("door #%lld is %s\n", ( doorptr - is_open ) + 1, ( * doorptr ) ? "open" : "closed" ) ;
  }
}


100 doors

Solution:
(function (n) {
    "use strict";
    function finalDoors(n) {
        var lstRange = range(1, n);
        return lstRange
            .reduce(function (a, _, k) {
                var m = k + 1;
                return a.map(function (x, i) {
                    var j = i + 1;
                    return [j, j % m ? x[1] : !x[1]];
                });
            }, zip(
                lstRange,
                replicate(n, false)
            ));
    };
    function zip(xs, ys) {
        return xs.length === ys.length ? (
            xs.map(function (x, i) {
                return [x, ys[i]];
            })
        ) : undefined;
    }
    function replicate(n, a) {
        var v = [a],
            o = [];
        if (n < 1) return o;
        while (n > 1) {
            if (n & 1) o = o.concat(v);
            n >>= 1;
            v = v.concat(v);
        }
        return o.concat(v);
    }
    function range(m, n, delta) {
        var d = delta || 1,
            blnUp = n > m,
            lng = Math.floor((blnUp ? n - m : m - n) / d) + 1,
            a = Array(lng),
            i = lng;
        if (blnUp)
            while (i--) a[i] = (d * i) + m;
        else
            while (i--) a[i] = m - (d * i);
        return a;
    }
    return finalDoors(n)
        .filter(function (tuple) {
            return tuple[1];
        })
        .map(function (tuple) {
            return {
                door: tuple[0],
                open: tuple[1]
            };
        });

})(100);


100 doors

Solution:
doors = [False] * 100
for i in range(100):
   for j in range(i, 100, i+1):
       doors[j] = not doors[j]
   print("Door %d:" % (i+1), 'open' if doors[i] else 'close')


100 doors

Solution:
for i in range(1, 101):
    if i**0.5 % 1:
        state='closed'
    else:
        state='open'
    print("Door {}:{}".format(i, state))


100 prisoners

;The Problem:
* 100 prisoners are individually numbered 1 to 100
* A room having a cupboard of 100 opaque drawers numbered 1 to 100, that cannot be seen from outside.
* Cards numbered 1 to 100 are placed randomly, one to a drawer, and the drawers all closed; at the start.
* Prisoners start outside the room
:* They can decide some strategy before any enter the room.
:* Prisoners enter the room one by one, can open a drawer, inspect the card number in the drawer, then close the drawer.
:* A prisoner can open no more than 50 drawers.
:* A prisoner tries to find his own number.
:* A prisoner finding his own number is then held apart from the others.
* If '''all''' 100 prisoners find their own numbers then they will all be pardoned. If ''any'' don't then ''all'' sentences stand.

;The task:
# Simulate several thousand instances of the game where the prisoners randomly open drawers
# Simulate several thousand instances of the game where the prisoners use the optimal strategy mentioned in the Wikipedia article, of:
:* First opening the drawer whose outside number is his prisoner number.
:* If the card within has his number then he succeeds otherwise he opens the drawer with the same number as that of the revealed card. (until he opens his maximum).

Show and compare the computed probabilities of success for the two strategies, here, on this page.

;References:
# [https://www.youtube.com/watch?v=a1DUUnhk3uE The unbelievable solution to the 100 prisoner puzzle] standupmaths (Video).
# [[wp:100 prisoners problem]]
# [http://datagenetics.com/blog/december42014/index.html 100 Prisoners Escape Puzzle] DataGenetics.
# [https://en.wikipedia.org/wiki/Random_permutation_statistics#One_hundred_prisoners Random permutation statistics#One hundred prisoners] on Wikipedia.

Solution:
#include
#include
#include
#include

#define LIBERTY false
#define DEATH true

typedef struct{
	int cardNum;
	bool hasBeenOpened;
}drawer;

drawer *drawerSet;

void initialize(int prisoners){
	int i,j,card;
	bool unique;

	drawerSet = ((drawer*)malloc(prisoners * sizeof(drawer))) -1;

	card = rand()%prisoners + 1;
	drawerSet[1] = (drawer){.cardNum = card, .hasBeenOpened = false};

	for(i=1 + 1;i  ",argv[0]);

	prisoners = atoi(argv[1]);
	chances = atoi(argv[2]);
	trials = strtoull(argv[3],&end,10);

	srand(time(NULL));

	printf("Running random trials...");
	for(i=0;i

$ gcc 100prisoners.c && ./a.out 100 50 10000
Running random trials...

Games Played : 10000
Games Won : 0
Chances : 0.000000 %

Running strategic trials...

Games Played : 10000
Games Won : 3051
Chances : 30.510000 %


100 prisoners

Solution:
const _ = require('lodash');

const numPlays = 100000;

const setupSecrets = () => {
	// setup the drawers with random cards
	let secrets = [];

	for (let i = 0; i < 100; i++) {
		secrets.push(i);
	}

	return _.shuffle(secrets);
}

const playOptimal = () => {

	let secrets = setupSecrets();

	// Iterate once per prisoner
	loop1:
	for (let p = 0; p < 100; p++) {

		// whether the prisoner succeedss
		let success = false;

		// the drawer number the prisoner chose
		let choice = p;

		// The prisoner can choose up to 50 cards
		loop2:
		for (let i = 0; i < 50; i++) {

			// if the card in the drawer that the prisoner chose is his card
			if (secrets[choice] === p){
				success = true;
				break loop2;
			}

			// the next drawer the prisoner chooses will be the number of the card he has.
			choice = secrets[choice];

		}	// each prisoner gets 50 chances

		if (!success) return false;

	} // iterate for each prisoner

	return true;
}

const playRandom = () => {

	let secrets = setupSecrets();

	// iterate for each prisoner
	for (let p = 0; p < 100; p++) {

		let choices = setupSecrets();

		let success = false;

		for (let i = 0; i < 50; i++) {

			if (choices[i] === p) {
				success = true;
				break;
			}
		}

		if (!success) return false;
	}

	return true;
}

const execOptimal = () => {

	let success = 0;

	for (let i = 0; i < numPlays; i++) {

		if (playOptimal()) success++;

	}

	return 100.0 * success / 100000;
}

const execRandom = () => {

	let success = 0;

	for (let i = 0; i < numPlays; i++) {

		if (playRandom()) success++;

	}

	return 100.0 * success / 100000;
}

console.log("# of executions: " + numPlays);
console.log("Optimal Play Success Rate: " + execOptimal());
console.log("Random Play Success Rate: " + execRandom());


100 prisoners

Solution:
"use strict";

// Simulate several thousand instances of the game:
const gamesCount = 2000;

// ...where the prisoners randomly open drawers.
const randomResults = playGame(gamesCount, randomStrategy);

// ...where the prisoners use the optimal strategy mentioned in the Wikipedia article.
const optimalResults = playGame(gamesCount, optimalStrategy);

// Show and compare the computed probabilities of success for the two strategies.
console.log(`Games count: ${gamesCount}`);
console.log(`Probability of success with "random" strategy: ${computeProbability(randomResults, gamesCount)}`);
console.log(`Probability of success with "optimal" strategy: ${computeProbability(optimalResults, gamesCount)}`);

function playGame(gamesCount, strategy, prisonersCount = 100) {
    const results = new Array();

    for (let game = 1; game <= gamesCount; game++) {
        // A room having a cupboard of 100 opaque drawers numbered 1 to 100, that cannot be seen from outside.
        // Cards numbered 1 to 100 are placed randomly, one to a drawer, and the drawers all closed; at the start.
        const drawers = initDrawers(prisonersCount);

        // A prisoner tries to find his own number.
        // Prisoners start outside the room.
        // They can decide some strategy before any enter the room.
        let found = 0;
        for (let prisoner = 1; prisoner <= prisonersCount; prisoner++, found++)
            if (!find(prisoner, drawers, strategy)) break;

        // If all 100 findings find their own numbers then they will all be pardoned. If any don't then all sentences stand.
        results.push(found == prisonersCount);
    }

    return results;
}

function find(prisoner, drawers, strategy) {
    // A prisoner can open no more than 50 drawers.
    const openMax = Math.floor(drawers.length / 2);

    // Prisoners start outside the room.
    let card;
    for (let open = 0; open < openMax; open++) {
        // A prisoner tries to find his own number.
        card = strategy(prisoner, drawers, card);

        // A prisoner finding his own number is then held apart from the others.
        if (card == prisoner)
            break;
    }

    return (card == prisoner);
}

function randomStrategy(prisoner, drawers, card) {
    // Simulate the game where the prisoners randomly open drawers.

    const min = 0;
    const max = drawers.length - 1;

    return drawers[draw(min, max)];
}

function optimalStrategy(prisoner, drawers, card) {
    // Simulate the game where the prisoners use the optimal strategy mentioned in the Wikipedia article.

    // First opening the drawer whose outside number is his prisoner number.
    // If the card within has his number then he succeeds...
    if (typeof card === "undefined")
        return drawers[prisoner - 1];

    // ...otherwise he opens the drawer with the same number as that of the revealed card.
    return drawers[card - 1];
}

function initDrawers(prisonersCount) {
    const drawers = new Array();
    for (let card = 1; card <= prisonersCount; card++)
        drawers.push(card);

    return shuffle(drawers);
}

function shuffle(drawers) {
    const min = 0;
    const max = drawers.length - 1;
    for (let i = min, j; i < max; i++)     {
        j = draw(min, max);
        if (i != j)
            [drawers[i], drawers[j]] = [drawers[j], drawers[i]];
    }

    return drawers;
}

function draw(min, max) {
    // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function computeProbability(results, gamesCount) {
    return Math.round(results.filter(x => x == true).length * 10000 / gamesCount) / 100;
}


100 prisoners

Solution:
import random

def play_random(n):
    # using 0-99 instead of ranges 1-100
    pardoned = 0
    in_drawer = list(range(100))
    sampler = list(range(100))
    for _round in range(n):
        random.shuffle(in_drawer)
        found = False
        for prisoner in range(100):
            found = False
            for reveal in random.sample(sampler, 50):
                card = in_drawer[reveal]
                if card == prisoner:
                    found = True
                    break
            if not found:
                break
        if found:
            pardoned += 1
    return pardoned / n * 100   # %

def play_optimal(n):
    # using 0-99 instead of ranges 1-100
    pardoned = 0
    in_drawer = list(range(100))
    for _round in range(n):
        random.shuffle(in_drawer)
        for prisoner in range(100):
            reveal = prisoner
            found = False
            for go in range(50):
                card = in_drawer[reveal]
                if card == prisoner:
                    found = True
                    break
                reveal = card
            if not found:
                break
        if found:
            pardoned += 1
    return pardoned / n * 100   # %

if __name__ == '__main__':
    n = 100_000
    print(" Simulation count:", n)
    print(f" Random play wins: {play_random(n):4.1f}% of simulations")
    print(f"Optimal play wins: {play_optimal(n):4.1f}% of simulations")


15 puzzle game

right
[[Category:Puzzles]]
[[Category:Games]]

;Task:
Implement the Fifteen Puzzle Game.

The   '''15-puzzle'''   is also known as:
:::*   '''Fifteen Puzzle'''
:::*   '''Gem Puzzle'''
:::*   '''Boss Puzzle'''
:::*   '''Game of Fifteen'''
:::*   '''Mystic Square'''
:::*   '''14-15 Puzzle'''
:::*   and some others.

;Related Tasks:
:*   15 Puzzle Solver
:*   [[16 Puzzle Game]]

Solution:
/* RosettaCode: Fifteen puzle game, C89, plain vanillia TTY, MVC, § 22 */
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#define N 4
#define M 4
enum Move{UP,DOWN,LEFT,RIGHT};int hR;int hC;int cc[N][M];const int nS=100;int
update(enum Move m){const int dx[]={0,0,-1,1};const int dy[]={-1,1,0,0};int i=hR
+dy[m];int j=hC+dx[m];if(i>= 0&&i=0&&j

===C89, short version, TTY mode===
/*
 * RosettaCode: Fifteen puzle game, C89, plain vanillia TTY, MVC
 */

#define _CRT_SECURE_NO_WARNINGS /* unlocks printf etc. in MSVC */
#include
#include
#include

enum Move { MOVE_UP = 0, MOVE_DOWN = 1, MOVE_LEFT = 2, MOVE_RIGHT = 3 };

/* *****************************************************************************
 * Model
 */

#define NROWS     4
#define NCOLLUMNS 4
int holeRow;
int holeCollumn;
int cells[NROWS][NCOLLUMNS];
const int nShuffles = 100;

int Game_update(enum Move move){
    const int dx[] = {  0,  0, -1, +1 };
    const int dy[] = { -1, +1,  0,  0 };
    int i = holeRow     + dy[move];
    int j = holeCollumn + dx[move];
    if ( i >= 0 && i < NROWS && j >= 0 && j < NCOLLUMNS ){
        cells[holeRow][holeCollumn] = cells[i][j];
        cells[i][j] = 0; holeRow = i; holeCollumn = j;
        return 1;
    }
    return 0;
}

void Game_setup(void){
    int i,j,k;
    for ( i = 0; i < NROWS; i++ )
        for ( j = 0; j < NCOLLUMNS; j++ )
            cells[i][j] = i * NCOLLUMNS + j + 1;
    cells[NROWS-1][NCOLLUMNS-1] = 0;
    holeRow = NROWS - 1;
    holeCollumn = NCOLLUMNS - 1;
    k = 0;
    while ( k < nShuffles )
        k += Game_update((enum Move)(rand() % 4));
}

int Game_isFinished(void){
    int i,j; int k = 1;
    for ( i = 0; i < NROWS; i++ )
        for ( j = 0; j < NCOLLUMNS; j++ )
            if ( (k < NROWS*NCOLLUMNS) && (cells[i][j] != k++ ) )
                return 0;
    return 1;
}

/* *****************************************************************************
 * View
 */

void View_showBoard(){
    int i,j;
    putchar('\n');
    for ( i = 0; i < NROWS; i++ )
        for ( j = 0; j < NCOLLUMNS; j++ ){
            if ( cells[i][j] )
                printf(j != NCOLLUMNS-1 ? " %2d " : " %2d \n", cells[i][j]);
            else
                printf(j != NCOLLUMNS-1 ? " %2s " : " %2s \n", "");
        }
    putchar('\n');
}

void View_displayMessage(char* text){
    printf("\n%s\n", text);
}

/* *****************************************************************************
 * Controller
 */

enum Move Controller_getMove(void){
    int c;
    for(;;){
        printf("%s", "enter u/d/l/r : ");
        c = getchar();
        while( getchar() != '\n' )
            ;
        switch ( c ){
            case 27: exit(EXIT_SUCCESS);
            case 'd' : return MOVE_UP;
            case 'u' : return MOVE_DOWN;
            case 'r' : return MOVE_LEFT;
            case 'l' : return MOVE_RIGHT;
        }
    }
}

void Controller_pause(void){
    getchar();
}

int main(void){

    srand((unsigned)time(NULL));

    do Game_setup(); while ( Game_isFinished() );

    View_showBoard();
    while( !Game_isFinished() ){
        Game_update( Controller_getMove() );
        View_showBoard();
    }

    View_displayMessage("You win");
    Controller_pause();

    return EXIT_SUCCESS;
}


15 puzzle game

Solution:
''' Python 3.6.5 code using Tkinter graphical user interface.'''

from tkinter import *
from tkinter import messagebox
import random

# ************************************************

class Board:
    def __init__(self, playable=True):
        while True:
            # list of text for game squares:
            self.lot = [str(i) for i in range(1,16)] + ['']
            if not playable:
                break
            # list of text for game squares randomized:
            random.shuffle(self.lot)
            if self.is_solvable():
                break

        # game board is 2D array of game squares:
        self.bd = []
        i = 0
        for r in range(4):
            row = []
            for c in range(4):
                row.append(Square(r,c,self.lot[i]))
                i += 1
            self.bd.append(row)

    # How to check if an instance of a 15 puzzle
    # is solvable is explained here:
    # https://www.geeksforgeeks.org/check-instance-15-puzzle-solvable/
    # I only coded for the case where N is even.
    def is_solvable(self):
        inv = self.get_inversions()
        odd = self.is_odd_row()
        if inv % 2 == 0 and odd:
            return True
        if inv % 2 == 1 and not odd:
            return True
        return False

    def get_inversions(self):
        cnt = 0
        for i, x in enumerate(self.lot[:-1]):
            if x != '':
                for y in self.lot[i+1:]:
                    if y != '' and int(x) > int(y):
                        cnt += 1
        return cnt

    # returns True if open square is in odd row from bottom:
    def is_odd_row(self):
        idx = self.lot.index('')
        return idx in [4,5,6,7,12,13,14,15]

    # returns name, text, and button object at row & col:
    def get_item(self, r, c):
        return self.bd[r][c].get()

    def get_square(self, r, c):
        return self.bd[r][c]

    def game_won(self):
        goal = [str(i) for i in range(1,16)] + ['']
        i = 0
        for r in range(4):
            for c in range(4):
                nm, txt, btn = self.get_item(r,c)
                if txt != goal[i]:
                    return False
                i += 1
        return True

# ************************************************

class Square:       # ['btn00', '0', None]
    def __init__(self, row, col, txt):
        self.row = row
        self.col = col
        self.name = 'btn' + str(row) + str(col)
        self.txt = txt
        self.btn = None

    def get(self):
            return [self.name, self.txt, self.btn]

    def set_btn(self, btn):
        self.btn = btn

    def set_txt(self, txt):
        self.txt = txt

# ************************************************

class Game:
    def __init__(self, gw):
        self.window = gw

        # game data:
        self.bd = None
        self.playable = False

        # top frame:
        self.top_fr = Frame(gw,
                            width=600,
                            height=100,
                            bg='light green')
        self.top_fr.pack(fill=X)

        self.hdg = Label(self.top_fr,
                         text='  15 PUZZLE GAME  ',
                         font='arial 22 bold',
                         fg='Navy Blue',
                         bg='white')
        self.hdg.place(relx=0.5, rely=0.4,
                       anchor=CENTER)

        self.dir = Label(self.top_fr,
                 text="(Click 'New Game' to begin)",
                 font='arial 12 ',
                 fg='Navy Blue',
                 bg='light green')
        self.dir.place(relx=0.5, rely=0.8,
                       anchor=CENTER)

        self.play_btn = Button(self.top_fr,
                               text='New \nGame',
                               bd=5,
                               bg='PaleGreen4',
                               fg='White',
                               font='times 12 bold',
                               command=self.new_game)
        self.play_btn.place(relx=0.92, rely=0.5,
                       anchor=E)

        # bottom frame:
        self.btm_fr = Frame(gw,
                            width=600,
                            height=500,
                            bg='light steel blue')
        self.btm_fr.pack(fill=X)

        # board frame:
        self.bd_fr = Frame(self.btm_fr,
                           width=400+2,
                           height=400+2,
                           relief='solid',
                           bd=1,
                           bg='lemon chiffon')
        self.bd_fr.place(relx=0.5, rely=0.5,
                         anchor=CENTER)

        self.play_game()

# ************************************************

    def new_game(self):
        self.playable = True
        self.dir.config(text='(Click on a square to move it)')
        self.play_game()

    def play_game(self):
        # place squares on board:
        if self.playable:
            btn_state = 'normal'
        else:
            btn_state = 'disable'
        self.bd = Board(self.playable)
        objh = 100  # widget height
        objw = 100  # widget width
        objx = 0    # x-position of widget in frame
        objy = 0    # y-position of widget in frame

        for r in range(4):
            for c in range(4):
                nm, txt, btn = self.bd.get_item(r,c)
                bg_color = 'RosyBrown1'
                if txt == '':
                    bg_color = 'White'
                game_btn = Button(self.bd_fr,
                                  text=txt,
                                  relief='solid',
                                  bd=1,
                                  bg=bg_color,
                                  font='times 12 bold',
                                  state=btn_state,
                                  command=lambda x=nm: self.clicked(x))
                game_btn.place(x=objx, y=objy,
                               height=objh, width=objw)

                sq = self.bd.get_square(r,c)
                sq.set_btn(game_btn)

                objx = objx + objw
            objx = 0
            objy = objy + objh

    # processing when a square is clicked:
    def clicked(self, nm):
        r, c = int(nm[3]), int(nm[4])
        nm_fr, txt_fr, btn_fr = self.bd.get_item(r,c)

        # cannot 'move' open square to itself:
        if not txt_fr:
            messagebox.showerror(
                'Error Message',
                'Please select "square" to be moved')
            return

        # 'move' square to open square if 'adjacent' to it:
        adjs = [(r-1,c), (r, c-1), (r, c+1), (r+1, c)]
        for x, y in adjs:
            if 0 <= x <= 3 and 0 <= y <= 3:
                nm_to, txt_to, btn_to = self.bd.get_item(x,y)
                if not txt_to:
                    sq = self.bd.get_square(x,y)
                    sq.set_txt(txt_fr)
                    sq = self.bd.get_square(r,c)
                    sq.set_txt(txt_to)
                    btn_to.config(text=txt_fr,
                                  bg='RosyBrown1')
                    btn_fr.config(text=txt_to,
                                  bg='White')
                    # check if game is won:
                    if self.bd.game_won():
                        ans = messagebox.askquestion(
                            'You won!!!   Play again?')
                        if ans == 'no':
                            self.window.destroy()
                        else:
                            self.new_game()
                    return

        # cannot move 'non-adjacent' square to open square:
        messagebox.showerror(
            'Error Message',
            'Illigal move, Try again')
        return

# ************************************************

root = Tk()
root.title('15 Puzzle Game')
root.geometry('600x600+100+50')
root.resizable(False, False)
g = Game(root)
root.mainloop()


21 game

'''21''' is a two player game, the game is played by choosing
a number ('''1''', '''2''', or '''3''')  to be added to the ''running total''.

The game is won by the player whose chosen number causes the ''running total''
to reach ''exactly'' '''21'''.

The ''running total'' starts at zero.
One player will be the computer.

Players alternate supplying a number to be added to the ''running total''.

;Task:
Write a computer program that will:
::* do the prompting (or provide a button menu),
::* check for errors and display appropriate error messages,
::* do the additions (add a chosen number to the ''running total''),
::* display the ''running total'',
::* provide a mechanism for the player to quit/exit/halt/stop/close the program,
::* issue a notification when there is a winner, and
::* determine who goes first (maybe a random or user choice, or can be specified when the game begins).

Solution:
/**
 * Game 21 - an example in C language for Rosseta Code.
 *
 * A simple game program whose rules are described below
 * - see DESCRIPTION string.
 *
 * This program should be compatible with C89 and up.
 */

/*
 * Turn off MS Visual Studio panic warnings which disable to use old gold
 * library functions like printf, scanf etc. This definition should be harmless
 * for non-MS compilers.
 */
#define _CRT_SECURE_NO_WARNINGS

#include
#include
#include

/*
 * Define bool, true and false as needed. The stdbool.h is a standard header
 * in C99, therefore for older compilers we need DIY booleans. BTW, there is
 * no __STDC__VERSION__ predefined macro in MS Visual C, therefore we need
 * check also _MSC_VER.
 */
#if __STDC_VERSION__ >= 199901L || _MSC_VER >= 1800
#include
#else
#define bool int
#define true  1
#define false 0
#endif

#define GOAL               21
#define NUMBER_OF_PLAYERS   2
#define MIN_MOVE            1
#define MAX_MOVE            3
#define BUFFER_SIZE       256

#define _(STRING) STRING

/*
 * Spaces are meaningful: on some systems they can be visible.
 */
static char DESCRIPTION[] =
    "21 Game                                                          \n"
    "                                                                 \n"
    "21 is a two player game, the game is played by choosing a number \n"
    "(1, 2, or 3) to be added to the running total. The game is won by\n"
    "the player whose chosen number causes the running total to reach \n"
    "exactly 21. The running total starts at zero.                    \n\n";

static int total;

void update(char* player, int move)
{
    printf("%8s:  %d = %d + %d\n\n", player, total + move, total, move);
    total += move;
    if (total == GOAL)
        printf(_("The winner is %s.\n\n"), player);
}

int ai()
{
/*
 * There is a winning strategy for the first player. The second player can win
 * then and only then the frist player does not use the winning strategy.
 *
 * The winning strategy may be defined as best move for the given running total.
 * The running total is a number from 0 to GOAL. Therefore, for given GOAL, best
 * moves may be precomputed (and stored in a lookup table). Actually (when legal
 * moves are 1 or 2 or 3) the table may be truncated to four first elements.
 */
#if GOAL < 32 && MIN_MOVE == 1 && MAX_MOVE == 3
    static const int precomputed[] = { 1, 1, 3, 2, 1, 1, 3, 2, 1, 1, 3, 2, 1, 1,
        3, 2, 1, 1, 3, 2, 1, 1, 3, 2, 1, 1, 3, 2, 1, 1, 3 };
    update(_("ai"), precomputed[total]);
#elif MIN_MOVE == 1 && MAX_MOVE == 3
    static const int precomputed[] = { 1, 1, 3, 2};
    update(_("ai"), precomputed[total % (MAX_MOVE + 1)]);
#else
    int i;
    int move = 1;
    for (i = MIN_MOVE; i <= MAX_MOVE; i++)
        if ((total + i - 1) % (MAX_MOVE + 1) == 0)
            move = i;
    for (i = MIN_MOVE; i <= MAX_MOVE; i++)
        if (total + i == GOAL)
            move = i;
    update(_("ai"), move);
#endif
}

void human(void)
{
    char buffer[BUFFER_SIZE];
    int move;

    while ( printf(_("enter your move to play (or enter 0 to exit game): ")),
            fgets(buffer, BUFFER_SIZE, stdin),
            sscanf(buffer, "%d", &move) != 1 ||
            (move && (move < MIN_MOVE || move > MAX_MOVE || total+move > GOAL)))
        puts(_("\nYour answer is not a valid choice.\n"));
    putchar('\n');
    if (!move) exit(EXIT_SUCCESS);
    update(_("human"), move);
}

int main(int argc, char* argv[])
{
    srand(time(NULL));
    puts(_(DESCRIPTION));
    while (true)
    {
        puts(_("\n---- NEW GAME ----\n"));
        puts(_("\nThe running total is currently zero.\n"));
        total = 0;

        if (rand() % NUMBER_OF_PLAYERS)
        {
            puts(_("The first move is AI move.\n"));
            ai();
        }
        else
            puts(_("The first move is human move.\n"));

        while (total < GOAL)
        {
            human();
            ai();
        }
    }
}


21 game

Solution:
from random import randint
def start():
	game_count=0
	print("Enter q to quit at any time.\nThe computer will choose first.\nRunning total is now {}".format(game_count))
	roundno=1
	while game_count<21:
		print("\nROUND {}: \n".format(roundno))
		t = select_count(game_count)
		game_count = game_count+t
		print("Running total is now {}\n".format(game_count))
		if game_count>=21:
			print("So, commiserations, the computer has won!")
			return 0
		t = request_count()
		if not t:
			print('OK,quitting the game')
			return -1
		game_count = game_count+t
		print("Running total is now {}\n".format(game_count))
		if game_count>=21:
			print("So, congratulations, you've won!")
			return 1
		roundno+=1

def select_count(game_count):
	'''selects a random number if the game_count is less than 18. otherwise chooses the winning number'''
	if game_count<18:
		t= randint(1,3)
	else:
		t = 21-game_count
	print("The computer chooses {}".format(t))
	return t

def request_count():
	'''request user input between 1,2 and 3. It will continue till either quit(q) or one of those numbers is requested.'''
	t=""
	while True:
		try:
			t = raw_input('Your choice 1 to 3 :')
			if int(t) in [1,2,3]:
				return int(t)
			else:
				print("Out of range, try again")
		except:
			if t=="q":
				return None
			else:
				print("Invalid Entry, try again")

c=0
m=0
r=True
while r:
	o = start()
	if o==-1:
		break
	else:
		c+=1 if o==0 else 0
		m+=1 if o==1 else 0
	print("Computer wins {0} game, human wins {1} games".format(c,m))
	t = raw_input("Another game?(press y to continue):")
	r = (t=="y")


24 game

[[Category:Puzzles]]
[[Category:Games]]

The 24 Game tests one's mental arithmetic.

;Task
Write a program that displays four digits, each from 1 ──► 9 (inclusive) with repetitions allowed.

The program should prompt for the player to enter an arithmetic expression using ''just'' those, and ''all'' of those four digits, used exactly ''once'' each. The program should ''check'' then evaluate the expression.

The goal is for the player to enter an expression that (numerically) evaluates to '''24'''.
*  Only the following operators/functions are allowed: multiplication, division, addition, subtraction
*  Division should use floating point or rational arithmetic, etc, to preserve remainders.
*  Brackets are allowed, if using an infix expression evaluator.
*  Forming multiple digit numbers from the supplied digits is ''disallowed''. (So an answer of 12+12 when given 1, 2, 2, and 1 is wrong).
*  The order of the digits when given does not have to be preserved.

;Notes
* The type of expression evaluator used is not mandated. An RPN evaluator is equally acceptable for example.
* The task is not for the program to generate the expression, or test whether an expression is even possible.

;Related tasks
* [[24 game/Solve]]

;Reference
* [http://www.bbc.co.uk/dna/h2g2/A933121 The 24 Game] on h2g2.

Solution:
#include
#include
#include
#include
#include

jmp_buf ctx;
const char *msg;

enum { OP_NONE = 0, OP_NUM, OP_ADD, OP_SUB, OP_MUL, OP_DIV };

typedef struct expr_t *expr, expr_t;
struct expr_t {
	int op, val, used;
	expr left, right;
};

#define N_DIGITS 4
expr_t digits[N_DIGITS];

void gen_digits()
{
	int i;
	for (i = 0; i < N_DIGITS; i++)
		digits[i].val = 1 + rand() % 9;
}

#define MAX_INPUT 64
char str[MAX_INPUT];
int pos;

#define POOL_SIZE 8
expr_t pool[POOL_SIZE];
int pool_ptr;

void reset()
{
	int i;
	msg = 0;
	pool_ptr = pos = 0;
	for (i = 0; i < POOL_SIZE; i++) {
		pool[i].op = OP_NONE;
		pool[i].left = pool[i].right = 0;
	}
	for (i = 0; i < N_DIGITS; i++)
		digits[i].used = 0;
}

/* longish jumpish back to input cycle */
void bail(const char *s)
{
	msg = s;
	longjmp(ctx, 1);
}

expr new_expr()
{
	if (pool_ptr < POOL_SIZE)
		return pool + pool_ptr++;
	return 0;
}

/* check next input char */
int next_tok()
{
	while (isspace(str[pos])) pos++;
	return str[pos];
}

/* move input pointer forward */
int take()
{
	if (str[pos] != '\0') return ++pos;
	return 0;
}

/* BNF(ish)
expr = term { ("+")|("-") term }
term = fact { ("*")|("/") expr }
fact =	number
	| '(' expr ')'
*/

expr get_fact();
expr get_term();
expr get_expr();

expr get_expr()
{
	int c;
	expr l, r, ret;
	if (!(ret = get_term())) bail("Expected term");
	while ((c = next_tok()) == '+' || c == '-') {
		if (!take()) bail("Unexpected end of input");
		if (!(r = get_term())) bail("Expected term");

		l = ret;
		ret = new_expr();
		ret->op = (c == '+') ? OP_ADD : OP_SUB;
		ret->left = l;
		ret->right = r;
	}
	return ret;
}

expr get_term()
{
	int c;
	expr l, r, ret;
	ret = get_fact();
	while((c = next_tok()) == '*' || c == '/') {
		if (!take()) bail("Unexpected end of input");

		r = get_fact();
		l = ret;
		ret = new_expr();
		ret->op = (c == '*') ? OP_MUL : OP_DIV;
		ret->left = l;
		ret->right = r;
	}
	return ret;
}

expr get_digit()
{
	int i, c = next_tok();
	expr ret;
	if (c >= '0' && c <= '9') {
		take();
		ret = new_expr();
		ret->op = OP_NUM;
		ret->val = c - '0';
		for (i = 0; i < N_DIGITS; i++)
			if (digits[i].val == ret->val && !digits[i].used) {
				digits[i].used = 1;
				return ret;
			}
		bail("Invalid digit");
	}
	return 0;
}

expr get_fact()
{
	int c;
	expr l = get_digit();
	if (l) return l;
	if ((c = next_tok()) == '(') {
		take();
		l = get_expr();
		if (next_tok() != ')') bail("Unbalanced parens");
		take();
		return l;
	}
	return 0;
}

expr parse()
{
	int i;
	expr ret = get_expr();
	if (next_tok() != '\0')
		bail("Trailing garbage");
	for (i = 0; i < N_DIGITS; i++)
		if (!digits[i].used)
			bail("Not all digits are used");
	return ret;
}

typedef struct frac_t frac_t, *frac;
struct frac_t { int denom, num; };

int gcd(int m, int n)
{
	int t;
	while (m) {
		t = m; m = n % m; n = t;
	}
	return n;
}

/* evaluate expression tree.  result in fraction form */
void eval_tree(expr e, frac res)
{
	frac_t l, r;
	int t;
	if (e->op == OP_NUM) {
		res->num = e->val;
		res->denom = 1;
		return;
	}

	eval_tree(e->left, &l);
	eval_tree(e->right, &r);

	switch(e->op) {
	case OP_ADD:
		res->num = l.num * r.denom + l.denom * r.num;
		res->denom = l.denom * r.denom;
		break;
	case OP_SUB:
		res->num = l.num * r.denom - l.denom * r.num;
		res->denom = l.denom * r.denom;
		break;
	case OP_MUL:
		res->num = l.num * r.num;
		res->denom = l.denom * r.denom;
		break;
	case OP_DIV:
		res->num = l.num * r.denom;
		res->denom = l.denom * r.num;
		break;
	}
	if ((t = gcd(res->denom, res->num))) {
		res->denom /= t;
		res->num /= t;
	}
}

void get_input()
{
	int i;
reinput:
	reset();
	printf("\nAvailable digits are:");
	for (i = 0; i < N_DIGITS; i++)
		printf(" %d", digits[i].val);
	printf(". Type an expression and I'll check it for you, or make new numbers.\n"
		"Your choice? [Expr/n/q] ");

	while (1) {
		for (i = 0; i < MAX_INPUT; i++) str[i] = '\n';
		fgets(str, MAX_INPUT, stdin);
		if (*str == '\0') goto reinput;
		if (str[MAX_INPUT - 1] != '\n')
			bail("string too long");

		for (i = 0; i < MAX_INPUT; i++)
			if (str[i] == '\n') str[i] = '\0';
		if (str[0] == 'q') {
			printf("Bye\n");
			exit(0);
		}
		if (str[0] == 'n') {
			gen_digits();
			goto reinput;
		}
		return;
	}
}

int main()
{
	frac_t f;
	srand(time(0));

	gen_digits();
	while(1) {
		get_input();
		setjmp(ctx); /* if parse error, jump back here with err msg set */
		if (msg) {
			/* after error jump; announce, reset, redo */
			printf("%s at '%.*s'\n", msg, pos, str);
			continue;
		}

		eval_tree(parse(), &f);

		if (f.denom == 0) bail("Divide by zero");
		if (f.denom == 1 && f.num == 24)
			printf("You got 24.  Very good.\n");
		else {
			if (f.denom == 1)
				printf("Eval to: %d, ", f.num);
			else
				printf("Eval to: %d/%d, ", f.num, f.denom);
			printf("no good.  Try again.\n");
		}
	}
	return 0;
}


24 game

Solution:
function twentyfour(numbers, input) {
    var invalidChars = /[^\d\+\*\/\s-\(\)]/;

    var validNums = function(str) {
        // Create a duplicate of our input numbers, so that
        // both lists will be sorted.
        var mnums = numbers.slice();
        mnums.sort();

        // Sort after mapping to numbers, to make comparisons valid.
        return str.replace(/[^\d\s]/g, " ")
            .trim()
            .split(/\s+/)
            .map(function(n) { return parseInt(n, 10); })
            .sort()
            .every(function(v, i) { return v === mnums[i]; });
    };

    var validEval = function(input) {
        try {
            return eval(input);
        } catch (e) {
            return {error: e.toString()};
        }
    };

    if (input.trim() === "") return "You must enter a value.";
    if (input.match(invalidChars)) return "Invalid chars used, try again. Use only:\n + - * / ( )";
    if (!validNums(input)) return "Wrong numbers used, try again.";
    var calc = validEval(input);
    if (typeof calc !== 'number') return "That is not a valid input; please try again.";
    if (calc !== 24) return "Wrong answer: " + String(calc) + "; please try again.";
    return input + " == 24.  Congratulations!";
};

// I/O below.

while (true) {
    var numbers = [1, 2, 3, 4].map(function() {
        return Math.floor(Math.random() * 8 + 1);
    });

    var input = prompt(
        "Your numbers are:\n" + numbers.join(" ") +
        "\nEnter expression. (use only + - * / and parens).\n", +"'x' to exit.", "");

    if (input === 'x') {
        break;
    }
    alert(twentyfour(numbers, input));
}


24 game

Solution:
'''
 The 24 Game

 Given any four digits in the range 1 to 9, which may have repetitions,
 Using just the +, -, *, and / operators; and the possible use of
 brackets, (), show how to make an answer of 24.

 An answer of "q" will quit the game.
 An answer of "!" will generate a new set of four digits.
 Otherwise you are repeatedly asked for an expression until it evaluates to 24

 Note: you cannot form multiple digit numbers from the supplied digits,
 so an answer of 12+12 when given 1, 2, 2, and 1 would not be allowed.

'''

from __future__ import division, print_function
import random, ast, re
import sys

if sys.version_info[0] < 3: input = raw_input

def choose4():
    'four random digits >0 as characters'
    return [str(random.randint(1,9)) for i in range(4)]

def welcome(digits):
    print (__doc__)
    print ("Your four digits: " + ' '.join(digits))

def check(answer, digits):
    allowed = set('() +-*/\t'+''.join(digits))
    ok = all(ch in allowed for ch in answer) and \
         all(digits.count(dig) == answer.count(dig) for dig in set(digits)) \
         and not re.search('\d\d', answer)
    if ok:
        try:
            ast.parse(answer)
        except:
            ok = False
    return ok

def main():
    digits = choose4()
    welcome(digits)
    trial = 0
    answer = ''
    chk = ans = False
    while not (chk and ans == 24):
        trial +=1
        answer = input("Expression %i: " % trial)
        chk = check(answer, digits)
        if answer.lower() == 'q':
            break
        if answer == '!':
            digits = choose4()
            print ("New digits:", ' '.join(digits))
            continue
        if not chk:
            print ("The input '%s' was wonky!" % answer)
        else:
            ans = eval(answer)
            print (" = ", ans)
            if ans == 24:
                print ("Thats right!")
    print ("Thank you and goodbye")

if __name__ == '__main__': main()


24 game/Solve

;task:
Write a program that takes four digits, either from user input or by random generation, and computes arithmetic expressions following the rules of the [[24 game]].

Show examples of solutions generated by the program.

;Related task:
*   [[Arithmetic Evaluator]]

Solution:
#include

typedef struct {int val, op, left, right;} Node;

Node nodes[10000];
int iNodes;

int b;
float eval(Node x){
    if (x.op != -1){
        float l = eval(nodes[x.left]), r = eval(nodes[x.right]);
        switch(x.op){
            case 0: return l+r;
            case 1: return l-r;
            case 2: return r-l;
            case 3: return l*r;
            case 4: return r?l/r:(b=1,0);
            case 5: return l?r/l:(b=1,0);
        }
    }
    else return x.val*1.;
}

void show(Node x){
    if (x.op != -1){
        printf("(");
        switch(x.op){
            case 0: show(nodes[x.left]); printf(" + "); show(nodes[x.right]); break;
            case 1: show(nodes[x.left]); printf(" - "); show(nodes[x.right]); break;
            case 2: show(nodes[x.right]); printf(" - "); show(nodes[x.left]); break;
            case 3: show(nodes[x.left]); printf(" * "); show(nodes[x.right]); break;
            case 4: show(nodes[x.left]); printf(" / "); show(nodes[x.right]); break;
            case 5: show(nodes[x.right]); printf(" / "); show(nodes[x.left]); break;
        }
        printf(")");
    }
    else printf("%d", x.val);
}

int float_fix(float x){ return x < 0.00001 && x > -0.00001; }

void solutions(int a[], int n, float t, int s){
    if (s == n){
        b = 0;
        float e = eval(nodes[0]);

        if (!b && float_fix(e-t)){
            show(nodes[0]);
            printf("\n");
        }
    }
    else{
        nodes[iNodes++] = (typeof(Node)){a[s],-1,-1,-1};

        for (int op = 0; op < 6; op++){
            int k = iNodes-1;
            for (int i = 0; i < k; i++){
                nodes[iNodes++] = nodes[i];
                nodes[i] = (typeof(Node)){-1,op,iNodes-1,iNodes-2};
                solutions(a, n, t, s+1);
                nodes[i] = nodes[--iNodes];
            }
        }

        iNodes--;
    }
};

int main(){
    // define problem

    int a[4] = {8, 3, 8, 3};
    float t = 24;

    // print all solutions

    nodes[0] = (typeof(Node)){a[0],-1,-1,-1};
    iNodes = 1;

    solutions(a, sizeof(a)/sizeof(int), t, 1);

    return 0;
}


24 game/Solve

Solution:
var ar=[],order=[0,1,2],op=[],val=[];
var NOVAL=9999,oper="+-*/",out;

function rnd(n){return Math.floor(Math.random()*n)}

function say(s){
 try{document.write(s+"")}
 catch(e){WScript.Echo(s)}
}

function getvalue(x,dir){
 var r=NOVAL;
 if(dir>0)++x;
 while(1){
  if(val[x]!=NOVAL){
   r=val[x];
   val[x]=NOVAL;
   break;
  }
  x+=dir;
 }
 return r*1;
}

function calc(){
 var c=0,l,r,x;
 val=ar.join('/').split('/');
 while(c<3){
  x=order[c];
  l=getvalue(x,-1);
  r=getvalue(x,1);
  switch(op[x]){
   case 0:val[x]=l+r;break;
   case 1:val[x]=l-r;break;
   case 2:val[x]=l*r;break;
   case 3:
   if(!r||l%r)return 0;
   val[x]=l/r;
  }
  ++c;
 }
 return getvalue(-1,1);
}

function shuffle(s,n){
 var x=n,p=eval(s),r,t;
 while(x--){
  r=rnd(n);
  t=p[x];
  p[x]=p[r];
  p[r]=t;
 }
}

function parenth(n){
 while(n>0)--n,out+='(';
 while(n<0)++n,out+=')';
}

function getpriority(x){
 for(var z=3;z--;)if(order[z]==x)return 3-z;
 return 0;
}

function showsolution(){
 var x=0,p=0,lp=0,v=0;
 while(x<4){
  if(x<3){
   lp=p;
   p=getpriority(x);
   v=p-lp;
   if(v>0)parenth(v);
  }
  out+=ar[x];
  if(x<3){
   if(v<0)parenth(v);
   out+=oper.charAt(op[x]);
  }
  ++x;
 }
 parenth(-p);
 say(out);
}

function solve24(s){
 var z=4,r;
 while(z--)ar[z]=s.charCodeAt(z)-48;
 out="";
 for(z=100000;z--;){
  r=rnd(256);
  op[0]=r&3;
  op[1]=(r>>2)&3;
  op[2]=(r>>4)&3;
  shuffle("ar",4);
  shuffle("order",3);
  if(calc()!=24)continue;
  showsolution();
  break;
 }
}

solve24("1234");
solve24("6789");
solve24("1127");


4-rings or 4-squares puzzle

;Task:
Replace       '''a, b, c, d, e, f,'''   and
  '''g '''       with the decimal
digits   LOW   ───►   HIGH
such that the sum of the letters inside of each of the four large squares add up to
the same sum.

            ╔══════════════╗      ╔══════════════╗
            ║              ║      ║              ║
            ║      a       ║      ║      e       ║
            ║              ║      ║              ║
            ║          ┌───╫──────╫───┐      ┌───╫─────────┐
            ║          │   ║      ║   │      │   ║         │
            ║          │ b ║      ║ d │      │ f ║         │
            ║          │   ║      ║   │      │   ║         │
            ║          │   ║      ║   │      │   ║         │
            ╚══════════╪═══╝      ╚═══╪══════╪═══╝         │
                       │       c      │      │      g      │
                       │              │      │             │
                       │              │      │             │
                       └──────────────┘      └─────────────┘

Show all output here.

:*   Show all solutions for each letter being unique with
         LOW=1     HIGH=7
:*   Show all solutions for each letter being unique with
         LOW=3     HIGH=9
:*   Show only the   ''number''   of solutions when each letter can be non-unique
         LOW=0     HIGH=9

;Related task:
* [[Solve the no connection puzzle]]

Solution:
#include

#define TRUE 1
#define FALSE 0

int a,b,c,d,e,f,g;
int lo,hi,unique,show;
int solutions;

void
bf()
{
    for (f = lo;f <= hi; f++)
        if ((!unique) ||
           ((f != a) && (f != c) && (f != d) && (f != g) && (f != e)))
            {
            b = e + f - c;
            if ((b >= lo) && (b <= hi) &&
                   ((!unique) || ((b != a) && (b != c) &&
                   (b != d) && (b != g) && (b != e) && (b != f))))
                {
                solutions++;
                if (show)
                    printf("%d %d %d %d %d %d %d\n",a,b,c,d,e,f,g);
                }
            }
}

void
ge()
{
    for (e = lo;e <= hi; e++)
        if ((!unique) || ((e != a) && (e != c) && (e != d)))
            {
            g = d + e;
            if ((g >= lo) && (g <= hi) &&
                   ((!unique) || ((g != a) && (g != c) &&
                   (g != d) && (g != e))))
                bf();
            }
}

void
acd()
{
    for (c = lo;c <= hi; c++)
        for (d = lo;d <= hi; d++)
            if ((!unique) || (c != d))
                {
                a = c + d;
                if ((a >= lo) && (a <= hi) &&
                   ((!unique) || ((c != 0) && (d != 0))))
                    ge();
                }
}

void
foursquares(int plo,int phi, int punique,int pshow)
{
    lo = plo;
    hi = phi;
    unique = punique;
    show = pshow;
    solutions = 0;

    printf("\n");

    acd();

    if (unique)
        printf("\n%d unique solutions in %d to %d\n",solutions,lo,hi);
    else
        printf("\n%d non-unique solutions in %d to %d\n",solutions,lo,hi);
}

main()
{
    foursquares(1,7,TRUE,TRUE);
    foursquares(3,9,TRUE,TRUE);
    foursquares(0,9,FALSE,FALSE);
}


4-rings or 4-squares puzzle

Solution:
(() => {
    "use strict";

    // ----------- 4-RINGS OR 4-SQUARES PUZZLE -----------

    // rings :: noRepeatedDigits -> DigitList -> solutions
    // rings :: Bool -> [Int] -> [[Int]]
    const rings = uniq =>
        digits => Boolean(digits.length) ? (
            () => {
                const ns = digits.sort(flip(compare));

                // CENTRAL DIGIT :: d
                return ns.flatMap(
                    ringTriage(uniq)(ns)
                );
            })() : [];

    const ringTriage = uniq => ns => d => {
        const
            h = head(ns),
            ts = ns.filter(x => (x + d) <= h);

        // LEFT OF CENTRE :: c and a
        return (
            uniq ? (delete_(d)(ts)) : ns
        )
        .flatMap(c => {
            const a = c + d;

            // RIGHT OF CENTRE :: e and g
            return a > h ? (
                []
            ) : (
                uniq ? (
                    difference(ts)([d, c, a])
                ) : ns
            )
            .flatMap(subTriage(uniq)([ns, h, a, c, d]));
        });
    };

    const subTriage = uniq =>
        ([ns, h, a, c, d]) => e => {
            const g = d + e;

            return ((g > h) || (
                uniq && (g === c))
            ) ? (
                    []
                ) : (() => {
                    const
                        agDelta = a - g,
                        bfs = uniq ? (
                            difference(ns)([
                                d, c, e, g, a
                            ])
                        ) : ns;

                    // MID LEFT, MID RIGHT :: b and f
                    return bfs.flatMap(b => {
                        const f = b + agDelta;

                        return (bfs).includes(f) && (
                            !uniq || ![
                                a, b, c, d, e, g
                            ].includes(f)
                        ) ? ([
                                [a, b, c, d, e, f, g]
                            ]) : [];
                    });
                })();
        };

    // ---------------------- TEST -----------------------
    const main = () => unlines([
        "rings(true, enumFromTo(1,7))\n",
        unlines(
            rings(true)(
                enumFromTo(1)(7)
            ).map(show)
        ),

        "\nrings(true, enumFromTo(3, 9))\n",
        unlines(
            rings(true)(
                enumFromTo(3)(9)
            ).map(show)
        ),

        "\nlength(rings(false, enumFromTo(0, 9)))\n",
        rings(false)(
            enumFromTo(0)(9)
        )
        .length
        .toString(),
        ""
    ]);

    // ---------------- GENERIC FUNCTIONS ----------------

    // compare :: a -> a -> Ordering
    const compare = (a, b) =>
        a < b ? -1 : (a > b ? 1 : 0);

    // delete :: Eq a => a -> [a] -> [a]
    const delete_ = x => {
        // xs with first instance of x (if any) removed.
        const go = xs =>
            Boolean(xs.length) ? (
                (x === xs[0]) ? (
                    xs.slice(1)
                ) : [xs[0]].concat(go(xs.slice(1)))
            ) : [];

        return go;
    };

    // difference :: Eq a => [a] -> [a] -> [a]
    const difference = xs =>
        ys => {
            const s = new Set(ys);

            return xs.filter(x => !s.has(x));
        };

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m =>
        n => Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);

    // flip :: (a -> b -> c) -> b -> a -> c
    const flip = op =>
        // The binary function op with
        // its arguments reversed.
        1 !== op.length ? (
            (a, b) => op(b, a)
        ) : (a => b => op(b)(a));

    // head :: [a] -> a
    const head = xs =>
        // The first item (if any) in a list.
        Boolean(xs.length) ? (
            xs[0]
        ) : null;

    // show :: a -> String
    const show = x =>
        JSON.stringify(x);

    // unlines :: [String] -> String
    const unlines = xs =>
        // A single string formed by the intercalation
        // of a list of strings with the newline character.
        xs.join("\n");

    // MAIN ---
    return main();
})();


4-rings or 4-squares puzzle

Solution:
def foursquares(lo,hi,unique,show):

    def acd_iter():
        """
        Iterates through all the possible valid values of
        a, c, and d.

        a = c + d
        """
        for c in range(lo,hi+1):
            for d in range(lo,hi+1):
                if (not unique) or (c <> d):
                    a = c + d
                    if a >= lo and a <= hi:
                        if (not unique) or (c <> 0 and d <> 0):
                            yield (a,c,d)

    def ge_iter():
        """
        Iterates through all the possible valid values of
        g and e.

        g = d + e
        """
        for e in range(lo,hi+1):
            if (not unique) or (e not in (a,c,d)):
                g = d + e
                if g >= lo and g <= hi:
                    if (not unique) or (g not in (a,c,d,e)):
                        yield (g,e)

    def bf_iter():
        """
        Iterates through all the possible valid values of
        b and f.

        b = e + f - c
        """
        for f in range(lo,hi+1):
            if (not unique) or (f not in (a,c,d,g,e)):
                b = e + f - c
                if b >= lo and b <= hi:
                    if (not unique) or (b not in (a,c,d,g,e,f)):
                        yield (b,f)

    solutions = 0
    acd_itr = acd_iter()
    for acd in acd_itr:
        a,c,d = acd
        ge_itr = ge_iter()
        for ge in ge_itr:
            g,e = ge
            bf_itr = bf_iter()
            for bf in bf_itr:
                b,f = bf
                solutions += 1
                if show:
                    print str((a,b,c,d,e,f,g))[1:-1]
    if unique:
        uorn = "unique"
    else:
        uorn = "non-unique"

    print str(solutions)+" "+uorn+" solutions in "+str(lo)+" to "+str(hi)
    print


4-rings or 4-squares puzzle

Solution:
'''4-rings or 4-squares puzzle'''

from itertools import chain

# rings :: noRepeatedDigits -> DigitList -> Lists of solutions
# rings :: Bool -> [Int] -> [[Int]]
def rings(uniq):
    '''Sets of unique or non-unique integer values
       (drawn from the `digits` argument)
       for each of the seven names [a..g] such that:
       (a + b) == (b + c + d) == (d + e + f) == (f + g)
    '''
    def go(digits):
        ns = sorted(digits, reverse=True)
        h = ns[0]

        # CENTRAL DIGIT :: d
        def central(d):
            xs = list(filter(lambda x: h >= (d + x), ns))

            # LEFT NEIGHBOUR AND LEFTMOST :: c and a
            def left(c):
                a = c + d
                if a > h:
                    return []
                else:
                    # RIGHT NEIGHBOUR AND RIGHTMOST :: e and g
                    def right(e):
                        g = d + e
                        if ((g > h) or (uniq and (g == c))):
                            return []
                        else:
                            agDelta = a - g
                            bfs = difference(ns)(
                                [d, c, e, g, a]
                            ) if uniq else ns

                            # MID LEFT AND RIGHT :: b and f
                            def midLeftRight(b):
                                f = b + agDelta
                                return [[a, b, c, d, e, f, g]] if (
                                    (f in bfs) and (
                                        (not uniq) or (
                                            f not in [a, b, c, d, e, g]
                                        )
                                    )
                                ) else []

    # CANDIDATE DIGITS BOUND TO POSITIONS [a .. g] --------

                            return concatMap(midLeftRight)(bfs)

                    return concatMap(right)(
                        difference(xs)([d, c, a]) if uniq else ns
                    )

            return concatMap(left)(
                delete(d)(xs) if uniq else ns
            )

        return concatMap(central)(ns)

    return lambda digits: go(digits) if digits else []

# TEST ----------------------------------------------------
# main :: IO ()
def main():
    '''Testing unique digits [1..7], [3..9] and unrestricted digits'''

    print(main.__doc__ + ':\n')
    print(unlines(map(
        lambda tpl: '\nrings' + repr(tpl) + ':\n\n' + unlines(
            map(repr, uncurry(rings)(*tpl))
        ), [
            (True, enumFromTo(1)(7)),
            (True, enumFromTo(3)(9))
        ]
    )))
    tpl = (False, enumFromTo(0)(9))
    print(
        '\n\nlen(rings' + repr(tpl) + '):\n\n' +
        str(len(uncurry(rings)(*tpl)))
    )

# GENERIC -------------------------------------------------

# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
    '''A concatenated list over which a function has been mapped.
       The list monad can be derived by using a function f which
       wraps its output in a list,
       (using an empty list to represent computational failure).
    '''
    return lambda xs: list(
        chain.from_iterable(map(f, xs))
    )

# delete :: Eq a => a -> [a] -> [a]
def delete(x):
    '''xs with the first of any instances of x removed.'''
    def go(xs):
        xs.remove(x)
        return xs
    return lambda xs: go(list(xs)) if (
        x in xs
    ) else list(xs)

#  difference :: Eq a => [a] -> [a] -> [a]
def difference(xs):
    '''All elements of ys except any also found in xs'''
    def go(ys):
        s = set(ys)
        return [x for x in xs if x not in s]
    return lambda ys: go(ys)

# enumFromTo :: (Int, Int) -> [Int]
def enumFromTo(m):
    '''Integer enumeration from m to n.'''
    return lambda n: list(range(m, 1 + n))

# uncurry :: (a -> b -> c) -> ((a, b) -> c)
def uncurry(f):
    '''A function over a pair of arguments,
       derived from a vanilla or curried function.
    '''
    return lambda x, y: f(x)(y)

# unlines :: [String] -> String
def unlines(xs):
    '''A single string formed by the intercalation
       of a list of strings with the newline character.
    '''
    return '\n'.join(xs)

# MAIN ---
if __name__ == '__main__':
    main()


99 bottles of beer

;Task:
Display the complete lyrics for the song:     '''99 Bottles of Beer on the Wall'''.

;The beer song:
The lyrics follow this form:

:::              99 bottles of beer on the wall
:::              99 bottles of beer
:::              Take one down, pass it around
:::              98 bottles of beer on the wall

:::              98 bottles of beer on the wall
:::              98 bottles of beer
:::              Take one down, pass it around
:::              97 bottles of beer on the wall

... and so on, until reaching   '''0'''     (zero).

Grammatical support for   ''1 bottle of beer''   is optional.

As with any puzzle, try to do it in as creative/concise/comical a way
as possible (simple, obvious solutions allowed, too).

;See also:
*   http://99-bottles-of-beer.net/
*   [[:Category:99_Bottles_of_Beer]]
*   [[:Category:Programming language families]]
*   [https://en.wikipedia.org/wiki/99_Bottles_of_Beer Wikipedia 99 bottles of beer]

Solution:
      int b =99,u =1;
     #include
      char *d[16],y[]
      = "#:ottle/ of"
      ":eer_ a_Goy\x20some6"
      "_Take8;down4p"
      "a=1rou7_17 _<"
      "h;_ m?_nd_ on"
      "_085wal" "l_ "
      "b_e _ t_ss it"
      "_?4bu_ore_9, "
      "\060.""@, 9$";
     # define x  c  ^=
    #include
   #define or(t,z) else\
  if(c==t && !(c = 0) &&\
 (c =! z)); int p(char *t)
{ char *s = t; int c; for (
d[c = 0] = y; !t && (d[c +1
]= strchr(s = d[c], '_'));*
(d[++c]++) = 0); for(t = s?
s:t;(c= *s++); c && putchar
(c)) { if (!((( x 48)& ~0xf
) && ( x 48)) ) p(d[c]), c=
0 ; or('$', p(b - 99?".\n":
"." ) && p(b - 99? t : ""))
or ('\x40', c && p( d[!!b--
+ 2])) or('/', c && p( b^1?
"s": "")) or ('\043', b++ ?
p("So6" + --b):!printf("%d"
, b ? --b : (b += 99))) or(
'S',!(++u % 3) * 32+ 78) or
('.', puts("."))}return c;}
 int main() {return p(0);}


99 bottles of beer

Solution:
function Bottles(count) {
  this.count = count || 99;
}

Bottles.prototype.take = function() {
  var verse = [
    this.count + " bottles of beer on the wall,",
    this.count + " bottles of beer!",
    "Take one down, pass it around",
    (this.count - 1) + " bottles of beer on the wall!"
  ].join("\n");

  console.log(verse);

  this.count--;
};

Bottles.prototype.sing = function() {
  while (this.count) {
    this.take();
  }
};

var bar = new Bottles(99);
bar.sing();


99 bottles of beer

Solution: for i in range(99, 0, -1):b='bottles of beer';w=f' {b} on the wall';print(f'{i}{w}, {i} {b}\nTake one down and pass it around, {i-1}{w}.\n')


99 bottles of beer

Solution:
"""
    99 Bottles of Beer on the Wall made functional

    Main function accepts a number of parameters, so you can specify a name of
    the drink, its container and other things. English only.
"""

from functools import partial
from typing import Callable

def regular_plural(noun: str) -> str:
    """English rule to get the plural form of a word"""
    if noun[-1] == "s":
        return noun + "es"

    return noun + "s"

def beer_song(
    *,
    location: str = 'on the wall',
    distribution: str = 'Take one down, pass it around',
    solution: str = 'Better go to the store to buy some more!',
    container: str = 'bottle',
    plurifier: Callable[[str], str] = regular_plural,
    liquid: str = "beer",
    initial_count: int = 99,
) -> str:
    """
    Return the lyrics of the beer song
    :param location: initial location of the drink
    :param distribution: specifies the process of its distribution
    :param solution: what happens when we run out of drinks
    :param container: bottle/barrel/flask or other containers
    :param plurifier: function converting a word to its plural form
    :param liquid: the name of the drink in the given container
    :param initial_count: how many containers available initially
    """

    verse = partial(
        get_verse,
        initial_count = initial_count,
        location = location,
        distribution = distribution,
        solution = solution,
        container = container,
        plurifier = plurifier,
        liquid = liquid,
    )

    verses = map(verse, range(initial_count, -1, -1))
    return '\n\n'.join(verses)

def get_verse(
    count: int,
    *,
    initial_count: str,
    location: str,
    distribution: str,
    solution: str,
    container: str,
    plurifier: Callable[[str], str],
    liquid: str,
) -> str:
    """Returns the verse for the given amount of drinks"""

    asset = partial(
        get_asset,
        container = container,
        plurifier = plurifier,
        liquid = liquid,
    )

    current_asset = asset(count)
    next_number = count - 1 if count else initial_count
    next_asset = asset(next_number)
    action = distribution if count else solution

    inventory = partial(
        get_inventory,
        location = location,
    )

    return '\n'.join((
        inventory(current_asset),
        current_asset,
        action,
        inventory(next_asset),
    ))

def get_inventory(
    asset: str,
    *,
    location: str,
) -> str:
    """
    Used to return the first or the fourth line of the verse

    >>> get_inventory("10 bottles of beer", location="on the wall")
    "10 bottles of beer on the wall"
    """
    return ' '.join((asset, location))

def get_asset(
    count: int,
    *,
    container: str,
    plurifier: Callable[[str], str],
    liquid: str,
) -> str:
    """
    Quantified asset

    >>> get_asset(0, container="jar", plurifier=regular_plural, liquid='milk')
    "No more jars of milk"
    """

    containers = plurifier(container) if count != 1 else container
    spelled_out_quantity = str(count) if count else "No more"
    return ' '.join((spelled_out_quantity, containers, "of", liquid))

if __name__ == '__main__':
    print(beer_song())


99 bottles of beer

Solution:
'''99 Units of Disposable Asset'''

from itertools import chain

# main :: IO ()
def main():
    '''Modalised asset dispersal procedure.'''

    # localisation :: (String, String, String)
    localisation = (
        'on the wall',
        'Take one down, pass it around',
        'Better go to the store to buy some more'
    )

    print(unlines(map(
        incantation(localisation),
        enumFromThenTo(99)(98)(0)
    )))

# incantation :: (String, String, String) -> Int -> String
def incantation(localisation):
    '''Versification of asset disposal
       and inventory update.'''

    location, distribution, solution = localisation

    def inventory(n):
        return unwords([asset(n), location])
    return lambda n: solution if 0 == n else (
        unlines([
            inventory(n),
            asset(n),
            distribution,
            inventory(pred(n))
        ])
    )

# asset :: Int -> String
def asset(n):
    '''Quantified asset.'''
    def suffix(n):
        return [] if 1 == n else 's'
    return unwords([
        str(n),
        concat(reversed(concat(cons(suffix(n))(["elttob"]))))
    ])

# GENERIC -------------------------------------------------

# concat :: [[a]] -> [a]
# concat :: [String] -> String
def concat(xxs):
    '''The concatenation of all the elements in a list.'''
    xs = list(chain.from_iterable(xxs))
    unit = '' if isinstance(xs, str) else []
    return unit if not xs else (
        ''.join(xs) if isinstance(xs[0], str) else xs
    )

# cons :: a -> [a] -> [a]
def cons(x):
    '''Construction of a list from x as head,
       and xs as tail.'''
    return lambda xs: [x] + xs if (
        isinstance(xs, list)
    ) else chain([x], xs)

# enumFromThenTo :: Int -> Int -> Int -> [Int]
def enumFromThenTo(m):
    '''Integer values enumerated from m to n
       with a step defined by nxt-m.'''
    def go(nxt, n):
        d = nxt - m
        return list(range(m, d + n, d))
    return lambda nxt: lambda n: (
        go(nxt, n)
    )

# pred ::  Enum a => a -> a
def pred(x):
    '''The predecessor of a value. For numeric types, (- 1).'''
    return x - 1 if isinstance(x, int) else (
        chr(ord(x) - 1)
    )

# unlines :: [String] -> String
def unlines(xs):
    '''A single string derived by the intercalation
       of a list of strings with the newline character.'''
    return '\n'.join(xs)

# unwords :: [String] -> String
def unwords(xs):
    '''A space-separated string derived from
       a list of words.'''
    return ' '.join(xs)

if __name__ == '__main__':
    main()


9 billion names of God the integer

This task is a variation of the short story by Arthur C. Clarke.

(Solvers should be aware of the consequences of completing this task.)

In detail, to specify what is meant by a   “name”:
:The integer 1 has 1 name       “1”.
:The integer 2 has 2 names   “1+1”,   and   “2”.
:The integer 3 has 3 names   “1+1+1”,   “2+1”,   and   “3”.
:The integer 4 has 5 names   “1+1+1+1”,   “2+1+1”,   “2+2”,   “3+1”,   “4”.
:The integer 5 has 7 names   “1+1+1+1+1”,   “2+1+1+1”,   “2+2+1”,   “3+1+1”,   “3+2”,   “4+1”,   “5”.

;Task
Display the first 25 rows of a number triangle which begins:

                                      1
                                    1   1
                                  1   1   1
                                1   2   1   1
                              1   2   2   1   1
                            1   3   3   2   1   1

Where row   n   corresponds to integer   n,   and each column   C   in row   m   from left to right corresponds to the number of names beginning with   C.

A function   G(n)   should return the sum of the   n-th   row.

Demonstrate this function by displaying:   G(23),   G(123),   G(1234),   and   G(12345).

Optionally note that the sum of the   n-th   row   P(n)   is the    [http://mathworld.wolfram.com/PartitionFunctionP.html   integer partition function].

Demonstrate this is equivalent to   G(n)   by displaying:   P(23),   P(123),   P(1234),   and   P(12345).

;Extra credit

If your environment is able, plot   P(n)   against   n   for   n=1\ldots 999.

;Related tasks
* [[Partition function P]]

Solution:
#include
#include

#define N 100000
mpz_t p[N + 1];

void calc(int n)
{
	mpz_init_set_ui(p[n], 0);

	for (int k = 1; k <= n; k++) {
		int d = n - k * (3 * k - 1) / 2;
		if (d < 0) break;

		if (k&1)mpz_add(p[n], p[n], p[d]);
		else	mpz_sub(p[n], p[n], p[d]);

		d -= k;
		if (d < 0) break;

		if (k&1)mpz_add(p[n], p[n], p[d]);
		else	mpz_sub(p[n], p[n], p[d]);
	}
}

int main(void)
{
	int idx[] = { 23, 123, 1234, 12345, 20000, 30000, 40000, 50000, N, 0 };
	int at = 0;

	mpz_init_set_ui(p[0], 1);

	for (int i = 1; idx[at]; i++) {
		calc(i);
		if (i != idx[at]) continue;

		gmp_printf("%2d:\t%Zd\n", i, p[i]);
		at++;
	}
}


9 billion names of God the integer

Solution:
(function () {
    var cache = [
        [1]
    ];
//this was never needed.
   /* function PyRange(start, end, step) {
        step = step || 1;
        if (!end) {
            end = start;
            start = 0;
        }
        var arr = [];
        for (var i = start; i < end; i += step) arr.push(i);
        return arr;
    }*/

    function cumu(n) {
        var /*ra = PyRange(cache.length, n + 1),*/ //Seems there is a better version for this
            r, l, x, Aa, Mi;
       // for (ll in ra) { too pythony
       for (l=cache.length;l

===Solution 2===
Clean and straightforward solution

function genTriangle(n){ // O(n^3) time and O(n^2) space
    var a = new Array(n)

    for (let i = 0; i < n; i++){
        a[i] = new Array(i+1)
        for (let j = 0; j < i; j++){
            a[i][j] = 0
            let s = i-j-1, k = Math.min(s, j)
            while (k >= 0) a[i][j] += a[s][k--]
        }
        a[i][i] = 1
    }

    return a.map(x => x.join(" ")).join("\n")
}

function G(n){ // At least O(n^2) time and O(n) space
    var a = new Array(n+1)
    a[0] = 1n

    for (let i = 1; i <= n; i++){
        a[i] = 0n
        for (let k = 1, s = 1; s <= i;){
            a[i] += (k & 1 ? a[i-s]:-a[i-s])
            k > 0 ? (s += k, k = -k):(k = -k+1, s = k*(3*k-1)/2)
        }
    }

    return a[n]
}

console.log(genTriangle(25))
console.log("")

for (const x of [23, 123, 1234, 12345]){
    console.log("G(" + x + ") = " + G(x))
}


9 billion names of God the integer

Solution:
cache = [[1]]
def cumu(n):
    for l in range(len(cache), n+1):
        r = [0]
        for x in range(1, l+1):
            r.append(r[-1] + cache[l-x][min(x, l-x)])
        cache.append(r)
    return cache[n]

def row(n):
    r = cumu(n)
    return [r[i+1] - r[i] for i in range(n)]

print "rows:"
for x in range(1, 11): print "%2d:"%x, row(x)

print "\nsums:"
for x in [23, 123, 1234, 12345]: print x, cumu(x)[-1]


A+B

'''A+B'''   ─── a classic problem in programming contests,   it's given so contestants can gain familiarity with the online judging system being used.

;Task:
Given two integers,   '''A''' and '''B'''.

Their sum needs to be calculated.

;Input data:
Two integers are written in the input stream, separated by space(s):
: (-1000 \le A,B \le +1000)

;Output data:
The required output is one integer:   the sum of '''A''' and '''B'''.

;Example:
::{|class="standard"
 ! input
 ! output
 |-
 | 2 2
 | 4
 |-
 | 3 2
 | 5
 |}

Solution:
// Input file: input.txt
// Output file: output.txt
#include
int main()
{
   freopen("input.txt", "rt", stdin);
   freopen("output.txt", "wt", stdout);
   int a, b;
   scanf("%d%d", &a, &b);
   printf("%d\n", a + b);
   return 0;
}


A+B

Solution:
process.openStdin().on (
    'data',
    function (line) {
        var xs = String(line).match(/^\s*(\d+)\s+(\d+)\s*/)
        console.log (
            xs ? Number(xs[1]) + Number(xs[2]) : 'usage:  '
        )
        process.exit()
    }
)


A+B

Solution:
a = int(input("First number: "))
b = int(input("Second number: "))
print("Result:", a+b)


ABC problem

You are given a collection of ABC blocks   (maybe like the ones you had when you were a kid).

There are twenty blocks with two letters on each block.

A complete alphabet is guaranteed amongst all sides of the blocks.

The sample collection of blocks:
  (B O)
  (X K)
  (D Q)
  (C P)
  (N A)
  (G T)
  (R E)
  (T G)
  (Q D)
  (F S)
  (J W)
  (H U)
  (V I)
  (A N)
  (O B)
  (E R)
  (F S)
  (L Y)
  (P C)
  (Z M)

;Task:
Write a function that takes a string (word) and determines whether the word can be spelled with the given collection of blocks.

The rules are simple:
::#   Once a letter on a block is used that block cannot be used again
::#   The function should be case-insensitive
::#   Show the output on this page for the following 7 words in the following example

;Example:
    >>> can_make_word("A")
    True
    >>> can_make_word("BARK")
    True
    >>> can_make_word("BOOK")
    False
    >>> can_make_word("TREAT")
    True
    >>> can_make_word("COMMON")
    False
    >>> can_make_word("SQUAD")
    True
    >>> can_make_word("CONFUSE")
    True

Solution:
#include
#include

int can_make_words(char **b, char *word)
{
	int i, ret = 0, c = toupper(*word);

#define SWAP(a, b) if (a != b) { char * tmp = a; a = b; b = tmp; }

	if (!c) return 1;
	if (!b[0]) return 0;

	for (i = 0; b[i] && !ret; i++) {
		if (b[i][0] != c && b[i][1] != c) continue;
		SWAP(b[i], b[0]);
		ret = can_make_words(b + 1, word + 1);
		SWAP(b[i], b[0]);
	}

	return ret;
}

int main(void)
{
	char* blocks[] = {
		"BO", "XK", "DQ", "CP", "NA",
		"GT", "RE", "TG", "QD", "FS",
		"JW", "HU", "VI", "AN", "OB",
		"ER", "FS", "LY", "PC", "ZM",
		0 };

	char *words[] = {
		"", "A", "BARK", "BOOK", "TREAT", "COMMON", "SQUAD", "Confuse", 0
	};

	char **w;
	for (w = words; *w; w++)
		printf("%s\t%d\n", *w, can_make_words(blocks, *w));

	return 0;
}


ABC problem

Solution:
var blocks = "BO XK DQ CP NA GT RE TG QD FS JW HU VI AN OB ER FS LY PC ZM";

function CheckWord(blocks, word) {
   // Makes sure that word only contains letters.
   if(word !== /([a-z]*)/i.exec(word)[1]) return false;
   // Loops through each character to see if a block exists.
   for(var i = 0; i < word.length; ++i)
   {
      // Gets the ith character.
      var letter = word.charAt(i);
      // Stores the length of the blocks to determine if a block was removed.
      var length = blocks.length;
      // The regexp gets constructed by eval to allow more browsers to use the function.
      var reg = eval("/([a-z]"+letter+"|"+letter+"[a-z])/i");
      // This does the same as above, but some browsers do not support...
      //var reg = new RegExp("([a-z]"+letter+"|"+letter+"[a-z])", "i");
      // Removes all occurrences of the match.
      blocks = blocks.replace(reg, "");
      // If the length did not change then a block did not exist.
      if(blocks.length === length) return false;
   }
   // If every character has passed then return true.
   return true;
};

var words = [
   "A",
   "BARK",
   "BOOK",
   "TREAT",
   "COMMON",
   "SQUAD",
   "CONFUSE"
];

for(var i = 0;i

Result:

A: true
BARK: true
BOOK: false
TREAT: true
COMMON: false
SQUAD: true
CONFUSE: true

====Functional====
(function (strWords) {

    var strBlocks =
        'BO XK DQ CP NA GT RE TG QD FS JW HU VI AN OB ER FS LY PC ZM',
        blocks = strBlocks.split(' ');

    function abc(lstBlocks, strWord) {
        var lngChars = strWord.length;

        if (!lngChars) return [];

        var b = lstBlocks[0],
            c = strWord[0];

        return chain(lstBlocks, function (b) {
            return (b.indexOf(c.toUpperCase()) !== -1) ? [
                (b + ' ').concat(
                    abc(removed(b, lstBlocks), strWord.slice(1)))
            ] : [];
        })
    }

    // Monadic bind (chain) for lists
    function chain(xs, f) {
        return [].concat.apply([], xs.map(f));
    }

    // a -> [a] -> [a]
    function removed(x, xs) {
        var h = xs.length ? xs[0] : null,
            t = h ? xs.slice(1) : [];

        return h ? (
            h === x ? t : [h].concat(removed(x, t))
        ) : [];
    }

    function solution(strWord) {
        var strAttempt = abc(blocks, strWord)[0].split(',')[0];

        // two chars per block plus one space -> 3
        return strWord + ((strAttempt.length === strWord.length * 3) ?
            ' -> ' + strAttempt : ': [no solution]');
    }

    return strWords.split(' ').map(solution).join('\n');

})('A bark BooK TReAT COMMON squAD conFUSE');


ABC problem

Solution:
'''
Note that this code is broken, e.g., it won't work when
blocks = [("A", "B"), ("A","C")] and the word is "AB", where the answer
should be True, but the code returns False.
'''
blocks = [("B", "O"),
          ("X", "K"),
          ("D", "Q"),
          ("C", "P"),
          ("N", "A"),
          ("G", "T"),
          ("R", "E"),
          ("T", "G"),
          ("Q", "D"),
          ("F", "S"),
          ("J", "W"),
          ("H", "U"),
          ("V", "I"),
          ("A", "N"),
          ("O", "B"),
          ("E", "R"),
          ("F", "S"),
          ("L", "Y"),
          ("P", "C"),
          ("Z", "M")]

def can_make_word(word, block_collection=blocks):
    """
    Return True if `word` can be made from the blocks in `block_collection`.

    >>> can_make_word("")
    False
    >>> can_make_word("a")
    True
    >>> can_make_word("bark")
    True
    >>> can_make_word("book")
    False
    >>> can_make_word("treat")
    True
    >>> can_make_word("common")
    False
    >>> can_make_word("squad")
    True
    >>> can_make_word("coNFused")
    True
    """
    if not word:
        return False

    blocks_remaining = block_collection[:]
    for char in word.upper():
        for block in blocks_remaining:
            if char in block:
                blocks_remaining.remove(block)
                break
        else:
            return False
    return True

if __name__ == "__main__":
    import doctest
    doctest.testmod()
    print(", ".join("'%s': %s" % (w, can_make_word(w)) for w in
                    ["", "a", "baRk", "booK", "treat",
                     "COMMON", "squad", "Confused"]))


ASCII art diagram converter

Given the RFC 1035 message diagram from Section 4.1.1 (Header section format) as a string:
http://www.ietf.org/rfc/rfc1035.txt

 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |                      ID                       |
 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |                    QDCOUNT                    |
 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |                    ANCOUNT                    |
 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |                    NSCOUNT                    |
 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |                    ARCOUNT                    |
 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Where (every column of the table is 1 bit):

 ID is 16 bits
 QR = Query (0) or Response (1)
 Opcode = Four bits defining kind of query:
   0:    a standard query (QUERY)
   1:    an inverse query (IQUERY)
   2:    a server status request (STATUS)
   3-15: reserved for future use
 AA = Authoritative Answer bit
 TC = Truncation bit
 RD = Recursion Desired bit
 RA = Recursion Available bit
 Z = Reserved
 RCODE = Response code
 QC = Question Count
 ANC = Answer Count
 AUC = Authority Count
 ADC = Additional Count

Write a function, member function, class or template that accepts a similar multi-line string as input to define a data structure or something else able to decode or store a header with that specified bit structure.

If your language has macros, introspection, code generation, or powerful enough templates, then accept such string at compile-time to define the header data structure statically.

Such "Header" function or template should accept a table with 8, 16, 32 or 64 columns, and any number of rows. For simplicity the only allowed symbols to define the table are + - | (plus, minus, pipe), and whitespace. Lines of the input string composed just of whitespace should be ignored. Leading and trailing whitespace in the input string should be ignored, as well as  before and after each table row. The box for each bit of the diagram takes four chars "+--+". The code should perform a little of validation of the input string, but for brevity a full validation is not required.

Bonus: perform a thoroughly validation of the input string.

Solution:
#include
#include
#include
enum { MAX_ROWS=14, MAX_NAMES=20, NAME_SZ=80 };

char *Lines[MAX_ROWS] = {
   "  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+",
   "  |                      ID                       |",
   "  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+",
   "  |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |",
   "  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+",
   "  |                    QDCOUNT                    |",
   "  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+",
   "  |                    ANCOUNT                    |",
   "  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+",
   "  |                    NSCOUNT                    |",
   "  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+",
   "  |                    ARCOUNT                    |",
   "  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+"
};
typedef struct {
   unsigned bit3s;
   unsigned mask;
   unsigned data;
   char A[NAME_SZ+2];
}NAME_T;
NAME_T names[MAX_NAMES];
unsigned idx_name;
enum{ID,BITS,QDCOUNT,ANCOUNT,NSCOUNT,ARCOUNT,MAX_HDR};
unsigned header[MAX_HDR]; // for test
unsigned idx_hdr;

int  bit_hdr(char *pLine);
int  bit_names(char *pLine);
void dump_names(void);
void make_test_hdr(void);

int main(void){
   char *p1;   int rv;
   printf("Extract meta-data from bit-encoded text form\n");
   make_test_hdr();
   idx_name = 0;
   for( int i=0; i0) continue;
      if( rv = bit_names(Lines[i]),rv>0) continue;
      //printf("%s, %d\n",p1, numbits );
   }
   dump_names();
}

int  bit_hdr(char *pLine){ // count the '+--'
   char *p1 = strchr(pLine,'+');
   if( p1==NULL ) return 0;
   int numbits=0;
   for( int i=0; i ' ') tmp[k++] = p1[j];
      }
      tmp[k]= 0; sz++;
      NAME_T *pn = &names[idx_name++];
      strcpy(&pn->A[0], &tmp[0]);
      pn->bit3s = sz/3;
      if( pn->bit3s < 16 ){
	 for( int i=0; ibit3s; i++){
	    pn->mask |= 1 << maskbitcount--;
	 }
	 pn->data = header[idx_hdr] & pn->mask;
	 unsigned m2 = pn->mask;
	 while( (m2 & 1)==0 ){
	    m2>>=1;
	    pn->data >>= 1;
	 }
	 if( pn->mask == 0xf ) idx_hdr++;

      }
      else{
	 pn->data = header[idx_hdr++];
      }
   }
   return sz;
}

void dump_names(void){ // print extracted names and bits
   NAME_T *pn;
   printf("-name-bits-mask-data-\n");
   for( int i=0; ibit3s < 1 ) break;
      printf("%10s %2d X%04x = %u\n",pn->A, pn->bit3s, pn->mask, pn->data);
   }
   puts("bye..");
}

void make_test_hdr(void){
   header[ID] = 1024;
   header[QDCOUNT] = 12;
   header[ANCOUNT] = 34;
   header[NSCOUNT] = 56;
   header[ARCOUNT] = 78;
   // QR OP   AA TC RD RA Z   RCODE
   // 1  0110 1  0  1  0  000 1010
   // 1011 0101 0000 1010
   // B    5    0    A
   header[BITS] = 0xB50A;
}


ASCII art diagram converter

Solution:
// ------------------------------------------------------------[ Boilerplate ]--
const trimWhitespace = s => s.trim();
const isNotEmpty = s => s !== '';
const stringLength = s => s.length;
const hexToBin4 = s => parseInt(s, 16).toString(2).padStart(4, '0');
const concatHexToBin = (binStr, hexStr) => binStr.concat('', hexToBin4(hexStr));
const alignRight = n => s => `${s}`.padStart(n, ' ');
const alignLeft = n => s => `${s}`.padEnd(n, ' ');
const repeatChar = c => n => c.padStart(n, c);
const joinWith = c => arr => arr.join(c);
const joinNl = joinWith('\n');
const joinSp = joinWith(' ');

const printDiagramInfo = map => {
  const pName = alignLeft(8);
  const p5 = alignRight(5);
  const line = repeatChar('-');
  const res = [];
  res.push(joinSp([pName('Name'), p5('Size'), p5('Start'), p5('End')]));
  res.push(joinSp([line(8), line(5), line(5), line(5)]));
  [...map.values()].forEach(({label, bitLength, start, end}) => {
    res.push(joinSp([pName(label), p5(bitLength), p5(start), p5(end)]));
  })
  return res;
}

// -------------------------------------------------------------------[ Main ]--
const parseDiagram = dia => {

  const arr = dia.split('\n').map(trimWhitespace).filter(isNotEmpty);

  const hLine = arr[0];
  const bitTokens = hLine.split('+').map(trimWhitespace).filter(isNotEmpty);
  const bitWidth = bitTokens.length;
  const bitTokenWidth = bitTokens[0].length;

  const fields = arr.filter(e => e !== hLine);
  const allFields = fields.reduce((p, c) => [...p, ...c.split('|')], [])
      .filter(isNotEmpty);

  const lookupMap = Array(bitWidth).fill('').reduce((p, c, i) => {
    const v = i + 1;
    const stringWidth = (v * bitTokenWidth) + (v - 1);
    p.set(stringWidth, v);
    return p;
  }, new Map())

  const fieldMetaMap = allFields.reduce((p, e, i) => {
    const bitLength = lookupMap.get(e.length);
    const label = trimWhitespace(e);
    const start = i ? p.get(i - 1).end + 1 : 0;
    const end = start - 1 + bitLength;
    p.set(i, {label, bitLength, start, end})
    return p;
  }, new Map());

  const pName = alignLeft(8);
  const pBit = alignRight(5);
  const pPat = alignRight(18);
  const line = repeatChar('-');
  const nl = '\n';
  return hexStr => {
    const binString = [...hexStr].reduce(concatHexToBin, '');

    const res = printDiagramInfo(fieldMetaMap);
    res.unshift(joinNl(['Diagram:', ...arr, nl]));
    res.push(joinNl([nl, 'Test string in hex:', hexStr]));
    res.push(joinNl(['Test string in binary:', binString, nl]));
    res.push(joinSp([pName('Name'), pBit('Size'), pPat('Pattern')]));
    res.push(joinSp([line(8), line(5), line(18)]));

    [...fieldMetaMap.values()].forEach(({label, bitLength, start, end}) => {
      res.push(joinSp(
          [pName(label), pBit(bitLength),
            pPat(binString.substr(start, bitLength))]))
    })
    return joinNl(res);
  }
}

// --------------------------------------------------------------[ Run tests ]--

const dia = `
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      ID                       |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    QDCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ANCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    NSCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ARCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
`;

const parser = parseDiagram(dia);

parser('78477bbf5496e12e1bf169a4');


ASCII art diagram converter

Solution:
"""
http://rosettacode.org/wiki/ASCII_art_diagram_converter

Python example based off Go example:

http://rosettacode.org/wiki/ASCII_art_diagram_converter#Go

"""

def validate(diagram):

    # trim empty lines

    rawlines = diagram.splitlines()
    lines = []
    for line in rawlines:
        if line != '':
            lines.append(line)

    # validate non-empty lines

    if len(lines) == 0:
        print('diagram has no non-empty lines!')
        return None

    width = len(lines[0])
    cols = (width - 1) // 3

    if cols not in [8, 16, 32, 64]:
        print('number of columns should be 8, 16, 32 or 64')
        return None

    if len(lines)%2 == 0:
        print('number of non-empty lines should be odd')
        return None

    if lines[0] != (('+--' * cols)+'+'):
            print('incorrect header line')
            return None

    for i in range(len(lines)):
        line=lines[i]
        if i == 0:
            continue
        elif i%2 == 0:
            if line != lines[0]:
                print('incorrect separator line')
                return None
        elif len(line) != width:
            print('inconsistent line widths')
            return None
        elif line[0] != '|' or line[width-1] != '|':
            print("non-separator lines must begin and end with '|'")
            return None

    return lines

"""

results is list of lists like:

[[name, bits, start, end],...

"""

def decode(lines):
    print("Name     Bits  Start  End")
    print("=======  ====  =====  ===")

    startbit = 0

    results = []

    for line in lines:
        infield=False
        for c in line:
            if not infield and c == '|':
                infield = True
                spaces = 0
                name = ''
            elif infield:
                if c == ' ':
                    spaces += 1
                elif c != '|':
                    name += c
                else:
                    bits = (spaces + len(name) + 1) // 3
                    endbit = startbit + bits - 1
                    print('{0:7}    {1:2d}     {2:2d}   {3:2d}'.format(name, bits, startbit, endbit))
                    reslist = [name, bits, startbit, endbit]
                    results.append(reslist)
                    spaces = 0
                    name = ''
                    startbit += bits

    return results

def unpack(results, hex):
    print("\nTest string in hex:")
    print(hex)
    print("\nTest string in binary:")
    bin = f'{int(hex, 16):0>{4*len(hex)}b}'
    print(bin)
    print("\nUnpacked:\n")
    print("Name     Size  Bit pattern")
    print("=======  ====  ================")
    for r in results:
        name = r[0]
        size = r[1]
        startbit = r[2]
        endbit = r[3]
        bitpattern = bin[startbit:endbit+1]
        print('{0:7}    {1:2d}  {2:16}'.format(name, size, bitpattern))

diagram = """
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      ID                       |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    QDCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ANCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    NSCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ARCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

"""

lines = validate(diagram)

if lines == None:
    print("No lines returned")
else:
    print(" ")
    print("Diagram after trimming whitespace and removal of blank lines:")
    print(" ")
    for line in lines:
        print(line)

    print(" ")
    print("Decoded:")
    print(" ")

    results = decode(lines)

    # test string

    hex = "78477bbf5496e12e1bf169a4"

    unpack(results, hex)