<|start_filename|>resource.h<|end_filename|>

#define IDR_MENUBAR1                    101

#define ID_GAME                         40005
#define ID_TYPE                         40006

#define IDS_CAP_GAME                    40105
#define IDS_CAP_TYPE                    40106

#define IDD_ABOUT			2000
#define IDC_ABOUT_CAPTION		2001
#define IDC_ABOUT_LINE			2002
#define IDC_ABOUT_GAME			2003
#define IDC_ABOUT_VERSION		2004

#define IDD_CONFIG			2100
#define IDC_CONFIG_CAPTION		2101
#define IDC_CONFIG_LINE			2102

#define IDR_PADTOOLBAR                  4000


<|start_filename|>html/samegame.html<|end_filename|>
Same Game
<p>
Try to empty the playing area completely, by removing connected
groups of two or more squares of the same colour. Then try to score
as much as possible, by removing large groups at a time instead of
small ones.
<p>
Click on a coloured square to highlight the rest of its connected
group. The status line will print the number of squares selected,
and the score you would gain by removing them. Click again to remove
the group; other squares will fall down to fill the space, and if
you empty a whole column then the other columns will move up. You
cannot remove a single isolated square: try to avoid dead-end
positions where all remaining squares are isolated.


<|start_filename|>html/tents.html<|end_filename|>
Tents
<p>
Place tents in the empty squares in such a way that:
<ul>
<li>no two tents are adjacent, even diagonally
<li>the number of tents in each row and column matches the numbers
around the edge of the grid
<li>it is possible to match tents to trees so that each tree is
orthogonally adjacent to its own tent (but may also be adjacent to
other tents).
</ul>
<p>
Click in a square to place or remove a tent. Right-click to mark a
square as empty (not a tent). Right-click and drag along a row or
column to mark many squares at once as empty.
<p>
Warning '!' marks appear to indicate adjacent tents. Numbers round
the edge of the grid light up red to indicate they do not match the
number of tents in the row. Groups of tents light up red to indicate
that they have too few trees between them, and vice versa.


<|start_filename|>PSTCollectionView/Examples/FlowLayoutHorizontal/CollectionExample/ViewController.h<|end_filename|>
//
//  ViewController.h
//  CollectionExample
//
//  Created by <NAME> on 19-10-12.
//  Copyright (c) 2012 Haanstra. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "PSTCollectionView.h"

@interface ViewController : UIViewController <PSUICollectionViewDataSource, PSUICollectionViewDelegate>

@property (weak, nonatomic) IBOutlet PSUICollectionView *collectionView;

@end


<|start_filename|>html/dominosa.html<|end_filename|>
Dominosa
<p>
Tile the rectangle with dominoes (1&times;2 rectangles) so that
every possible domino appears exactly once (that is, every possible
pair of numbers, including doubles).
<p>
Click between two adjacent numbers to place or remove a domino.
Right-click to place a line between numbers if you think a domino
definitely cannot go there. Dominoes light up red if two identical
ones appear on the grid.


<|start_filename|>loopgen.h<|end_filename|>
/*
 * loopgen.h: interface file for loop generation functions for grid.[ch].
 */

#ifndef _LOOPGEN_H
#define _LOOPGEN_H

#include "puzzles.h"
#include "grid.h"

enum face_colour { FACE_WHITE, FACE_GREY, FACE_BLACK };

/* face should be of type grid_face* here. */
#define FACE_COLOUR(face) \
    ( (face) == NULL ? FACE_BLACK : \
	  board[(face) - g->faces] )

typedef int (*loopgen_bias_fn_t)(void *ctx, char *board, int face);

/* 'board' should be a char array whose length is the same as
 * g->num_faces: this will be filled in with FACE_WHITE or FACE_BLACK
 * after loop generation.
 *
 * If 'bias' is non-null, it should be a user-provided function which
 * rates a half-finished board (i.e. may include some FACE_GREYs) for
 * desirability; this will cause the loop generator to bias in favour
 * of loops with a high return value from that function. The 'face'
 * parameter to the bias function indicates which face of the grid has
 * been modified since the last call; it is guaranteed that only one
 * will have been (so that bias functions can work incrementally
 * rather than re-scanning the whole grid on every call). */
extern void generate_loop(grid *g, char *board, random_state *rs,
                          loopgen_bias_fn_t bias, void *biasctx);

#endif


<|start_filename|>PSTCollectionView/Examples/BatchUpdate/BatchUpdate/AppDelegate.h<|end_filename|>
//
//  AppDelegate.h
//  BatchUpdate
//
//  Created by <NAME> on 4/17/13.
//
//

@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) ViewController *viewController;

@end


<|start_filename|>html/netslide.html<|end_filename|>
Netslide
<p>
Slide the grid squares around so that they all join up into a single
connected network with no loops.
<p>
Click on the arrows at the edges of the grid to move a row or column
left, right, up or down. The square that falls off the end of the
row comes back on the other end.
<p>
Squares connected to the middle square are lit up. Aim to light up
every square in the grid (not just the endpoint blobs).
<p>
Connecting across a red barrier line is forbidden. On harder levels,
there are fewer barriers, which makes it harder rather than easier!


<|start_filename|>tdq.c<|end_filename|>
/*
 * tdq.c: implement a 'to-do queue', a simple de-duplicating to-do
 * list mechanism.
 */

#include <assert.h>

#include "puzzles.h"

/*
 * Implementation: a tdq consists of a circular buffer of size n
 * storing the integers currently in the queue, plus an array of n
 * booleans indicating whether each integer is already there.
 *
 * Using a circular buffer of size n to store between 0 and n items
 * inclusive has an obvious failure mode: if the input and output
 * pointers are the same, how do you know whether that means the
 * buffer is full or empty?
 *
 * In this application we have a simple way to tell: in the former
 * case, the flags array is all 1s, and in the latter case it's all
 * 0s. So we could spot that case and check, say, flags[0].
 *
 * However, it's even easier to simply determine whether the queue is
 * non-empty by testing flags[buffer[op]] - that way we don't even
 * _have_ to compare ip against op.
 */

struct tdq {
    int n;
    int *queue;
    int ip, op;                        /* in pointer, out pointer */
    bool *flags;
};

tdq *tdq_new(int n)
{
    int i;
    tdq *tdq = snew(struct tdq);
    tdq->queue = snewn(n, int);
    tdq->flags = snewn(n, bool);
    for (i = 0; i < n; i++) {
        tdq->queue[i] = 0;
        tdq->flags[i] = false;
    }
    tdq->n = n;
    tdq->ip = tdq->op = 0;
    return tdq;
}

void tdq_free(tdq *tdq)
{
    sfree(tdq->queue);
    sfree(tdq->flags);
    sfree(tdq);
}

void tdq_add(tdq *tdq, int k)
{
    assert((unsigned)k < (unsigned)tdq->n);
    if (!tdq->flags[k]) {
        tdq->queue[tdq->ip] = k;
        tdq->flags[k] = true;
        if (++tdq->ip == tdq->n)
            tdq->ip = 0;
    }
}

int tdq_remove(tdq *tdq)
{
    int ret = tdq->queue[tdq->op];

    if (!tdq->flags[ret])
        return -1;

    tdq->flags[ret] = false;
    if (++tdq->op == tdq->n)
        tdq->op = 0;

    return ret;
}

void tdq_fill(tdq *tdq)
{
    int i;
    for (i = 0; i < tdq->n; i++)
        tdq_add(tdq, i);
}


<|start_filename|>html/pattern.html<|end_filename|>
Pattern
<p>
Fill in the grid with a pattern of black and white squares, so that
the numbers in each row and column match the lengths of consecutive
runs of black squares.
<p>
Left-click in a square to mark it black; right-click (or hold Ctrl
while left-clicking) to mark it white. Click and drag along a row or
column to mark multiple squares black or white at once. Middle-click
(or hold Shift while left-clicking) to return a square to grey
(meaning undecided): dragging like that can erase a whole rectangle,
not just a row or column.


<|start_filename|>html/pearl.html<|end_filename|>
Pearl
<p>
Draw a single closed loop by connecting together the centres of
adjacent grid squares, so that some squares end up as corners, some as
straights (horizontal or vertical), and some may be empty. Every
square containing a black circle must be a corner not connected
directly to another corner; every square containing a white circle
must be a straight which is connected to <em>at least one</em> corner.
<p>
Drag between squares to draw or undraw pieces of the loop.
Alternatively, left-click the edge between two squares to turn it on
or off. Right-click an edge to mark it with a cross indicating that
you are sure the loop does not go through it.


<|start_filename|>html/filling.html<|end_filename|>
Filling
<p>
Write a number in every blank square of the grid. When the grid is
full, every orthogonally connected group of identical numbers should
have an area equal to that number: so 1s always appear alone, 2s in
pairs, and so on.
<p>
To place a number, click the mouse in a blank square to select it,
then type the number you want on the keyboard. You can also drag to
select multiple squares, and then type a number to place it in all
of them. To erase numbers, select one or more squares in the same
way and then press Backspace.


<|start_filename|>no-icon.c<|end_filename|>

/*
 * Dummy source file which replaces the files generated in the
 * `icons' subdirectory, when they're absent.
 */

const char *const *const xpm_icons[] = { 0 };
const int n_xpm_icons = 0;


<|start_filename|>html/fifteen.html<|end_filename|>
Fifteen
<p>
Slide the tiles around the box until they appear in numerical order
from the top left, with the hole in the bottom right corner.
<p>
Click on a tile to slide it towards the hole.


<|start_filename|>html/unequal.html<|end_filename|>
Unequal
<p>
Fill in the grid with numbers from 1 to the grid size, so that every
number appears exactly once in each row and column, and so that all
the <code>&lt;</code> signs represent true inequalities (i.e. the
number at the pointed end is smaller than the number at the open end).
<p>
To place a number, click in a square to select it, then type the
number on the keyboard. To erase a number, click to select a square
and then press Backspace.
<p>
Right-click in a square and then type a number to add or remove the
number as a pencil mark, indicating numbers that you think
<em>might</em> go in that square.


<|start_filename|>html/bridges.html<|end_filename|>
Bridges
<p>
Draw horizontal or vertical bridges to link up all the islands.
Bridges may be single or double; they may not cross; the islands
must all end up connected to each other; the number in each island
must match the number of bridges that end at that island (counting
double bridges as two). Note that loops of bridges are permitted.
<p>
Click on an island and drag left, right, up or down to draw a bridge
to the next island in that direction. Do the same again to create a
double bridge, and again to remove the bridge if you change your
mind. Click on an island without dragging to mark the island as
completed once you think you have placed all its bridges.


<|start_filename|>matching.c<|end_filename|>
/*
 * Implementation of matching.h.
 */

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

#include "puzzles.h"
#include "matching.h"

struct scratch {
    /*
     * Current contents of the in-progress matching. LtoR is an array
     * of nl integers, each of which holds a value in {0,1,...,nr-1},
     * or -1 for no current assignment. RtoL is exactly the reverse.
     *
     * Invariant: LtoR[i] is non-empty and equal to j if and only if
     * RtoL[j] is non-empty and equal to i.
     */
    int *LtoR, *RtoL;

    /*
     * Arrays of nl and nr integer respectively, giving the layer
     * assigned to each integer in the breadth-first search step of
     * the algorithm.
     */
    int *Llayer, *Rlayer;

    /*
     * Arrays of nl and nr integers respectively, used to hold the
     * to-do queues in the breadth-first search.
     */
    int *Lqueue, *Rqueue;

    /*
     * An augmenting path of vertices, alternating between L vertices
     * (in the even-numbered positions, starting at 0) and R (in the
     * odd positions). Must be long enough to hold any such path that
     * never repeats a vertex, i.e. must be at least 2*min(nl,nr) in
     * size.
     */
    int *augpath;

    /*
     * Track the progress of the depth-first search at each
     * even-numbered layer. Has one element for each even-numbered
     * position in augpath.
     */
    int *dfsstate;

    /*
     * Store a random permutation of the L vertex indices, if we're
     * randomising the dfs phase.
     */
    int *Lorder;
};

size_t matching_scratch_size(int nl, int nr)
{
    size_t n;
    int nmin = (nl < nr ? nl : nr);

    n = (sizeof(struct scratch) + sizeof(int)-1)/sizeof(int);
    n += nl;                           /* LtoR */
    n += nr;                           /* RtoL */
    n += nl;                           /* Llayer */
    n += nr;                           /* Rlayer */
    n += nl;                           /* Lqueue */
    n += nr;                           /* Rqueue */
    n += 2*nmin;                       /* augpath */
    n += nmin;                         /* dfsstate */
    n += nl;                           /* Lorder */
    return n * sizeof(int);
}

int matching_with_scratch(void *scratchv,
                          int nl, int nr, int **adjlists, int *adjsizes,
                          random_state *rs, int *outl, int *outr)
{
    struct scratch *s = (struct scratch *)scratchv;
    int L, R, i, j;

    /*
     * Set up the various array pointers in the scratch space.
     */
    {
        int *p = scratchv;
        int nmin = (nl < nr ? nl : nr);

        p += (sizeof(struct scratch) + sizeof(int)-1)/sizeof(int);
        s->LtoR = p; p += nl;
        s->RtoL = p; p += nr;
        s->Llayer = p; p += nl;
        s->Rlayer = p; p += nr;
        s->Lqueue = p; p += nl;
        s->Rqueue = p; p += nr;
        s->augpath = p; p += 2*nmin;
        s->dfsstate = p; p += nmin;
        s->Lorder = p; p += nl;
    }

    /*
     * Set up the initial matching, which is empty.
     */
    for (L = 0; L < nl; L++)
        s->LtoR[L] = -1;
    for (R = 0; R < nr; R++)
        s->RtoL[R] = -1;

    while (1) {
        /*
         * Breadth-first search starting from the unassigned left
         * vertices, traversing edges from left to right only if they
         * are _not_ part of the matching, and from right to left only
         * if they _are_. We assign a 'layer number' to all vertices
         * visited by this search, with the starting vertices being
         * layer 0 and every successor of a layer-n node being layer
         * n+1.
         */
        int Lqs, Rqs, layer, target_layer;

        for (L = 0; L < nl; L++)
            s->Llayer[L] = -1;
        for (R = 0; R < nr; R++)
            s->Rlayer[R] = -1;

        Lqs = 0;
        for (L = 0; L < nl; L++) {
            if (s->LtoR[L] == -1) {
                s->Llayer[L] = 0;
                s->Lqueue[Lqs++] = L;
            }
        }

        layer = 0;
        while (1) {
            bool found_free_R_vertex = false;

            Rqs = 0;
            for (i = 0; i < Lqs; i++) {
                L = s->Lqueue[i];
                assert(s->Llayer[L] == layer);

                for (j = 0; j < adjsizes[L]; j++) {
                    R = adjlists[L][j];
                    if (R != s->LtoR[L] && s->Rlayer[R] == -1) {
                        s->Rlayer[R] = layer+1;
                        s->Rqueue[Rqs++] = R;
                        if (s->RtoL[R] == -1)
                            found_free_R_vertex = true;
                    }
                }
            }
            layer++;

            if (found_free_R_vertex)
                break;

            if (Rqs == 0)
                goto done;

            Lqs = 0;
            for (j = 0; j < Rqs; j++) {
                R = s->Rqueue[j];
                assert(s->Rlayer[R] == layer);
                if ((L = s->RtoL[R]) != -1 && s->Llayer[L] == -1) {
                    s->Llayer[L] = layer+1;
                    s->Lqueue[Lqs++] = L;
                }
            }
            layer++;

            if (Lqs == 0)
                goto done;
        }

        target_layer = layer;

        /*
         * Vertices in the target layer are only interesting if
         * they're actually unassigned. Blanking out the others here
         * will save us a special case in the dfs loop below.
         */
        for (R = 0; R < nr; R++)
            if (s->Rlayer[R] == target_layer && s->RtoL[R] != -1)
                s->Rlayer[R] = -1;

        /*
         * Choose an ordering in which to try the L vertices at the
         * start of the next pass.
         */
        for (L = 0; L < nl; L++)
            s->Lorder[L] = L;
        if (rs)
            shuffle(s->Lorder, nl, sizeof(*s->Lorder), rs);

        /*
         * Now depth-first search through that layered set of vertices
         * to find as many (vertex-)disjoint augmenting paths as we
         * can, and for each one we find, augment the matching.
         */
        s->dfsstate[0] = 0;
        i = 0;
        while (1) {
            /*
             * Find the next vertex to go on the end of augpath.
             */
            if (i == 0) {
                /* In this special case, we're just looking for L
                 * vertices that are not yet assigned. */
                if (s->dfsstate[i] == nl)
                    break;             /* entire DFS has finished */

                L = s->Lorder[s->dfsstate[i]++];

                if (s->Llayer[L] != 2*i)
                    continue;          /* skip this vertex */
            } else {
                /* In the more usual case, we're going through the
                 * adjacency list for the previous L vertex. */
                L = s->augpath[2*i-2];
                j = s->dfsstate[i]++;
                if (j == adjsizes[L]) {
                    /* Run out of neighbours of the previous vertex. */
                    i--;
                    continue;
                }
                if (rs && adjsizes[L] - j > 1) {
                    int which = j + random_upto(rs, adjsizes[L] - j);
                    int tmp = adjlists[L][which];
                    adjlists[L][which] = adjlists[L][j];
                    adjlists[L][j] = tmp;
                }
                R = adjlists[L][j];

                if (s->Rlayer[R] != 2*i-1)
                    continue;          /* skip this vertex */

                s->augpath[2*i-1] = R;
                s->Rlayer[R] = -1;     /* mark vertex as visited */

                if (2*i-1 == target_layer) {
                    /*
                     * We've found an augmenting path, in the form of
                     * an even-sized list of vertices alternating
                     * L,R,...,L,R, with the initial L and final R
                     * vertex free and otherwise each R currently
                     * connected to the next L. Adjust so that each L
                     * connects to the next R, increasing the edge
                     * count in the matching by 1.
                     */
                    for (j = 0; j < 2*i; j += 2) {
                        s->LtoR[s->augpath[j]] = s->augpath[j+1];
                        s->RtoL[s->augpath[j+1]] = s->augpath[j];
                    }

                    /*
                     * Having dealt with that path, and already marked
                     * all its vertices as visited, rewind right to
                     * the start and resume our DFS from a new
                     * starting L-vertex.
                     */
                    i = 0;
                    continue;
                }

                L = s->RtoL[R];
                if (s->Llayer[L] != 2*i)
                    continue;          /* skip this vertex */
            }

            s->augpath[2*i] = L;
            s->Llayer[L] = -1;         /* mark vertex as visited */
            i++;
            s->dfsstate[i] = 0;
        }
    }

  done:
    /*
     * Fill in the output arrays.
     */
    if (outl) {
        for (i = 0; i < nl; i++)
            outl[i] = s->LtoR[i];
    }
    if (outr) {
        for (j = 0; j < nr; j++)
            outr[j] = s->RtoL[j];
    }

    /*
     * Return the number of matching edges.
     */
    for (i = j = 0; i < nl; i++)
        if (s->LtoR[i] != -1)
            j++;
    return j;
}

int matching(int nl, int nr, int **adjlists, int *adjsizes,
             random_state *rs, int *outl, int *outr)
{
    void *scratch;
    int size;
    int ret;

    size = matching_scratch_size(nl, nr);
    scratch = malloc(size);
    if (!scratch)
	return -1;

    ret = matching_with_scratch(scratch, nl, nr, adjlists, adjsizes,
                                rs, outl, outr);

    free(scratch);

    return ret;
}

#ifdef STANDALONE_MATCHING_TEST

/*
 * Diagnostic routine used in testing this algorithm. It is passed a
 * pointer to a piece of scratch space that's just been used by
 * matching_with_scratch, and extracts from it a labelling of the
 * input graph that acts as a 'witness' to the maximality of the
 * returned matching.
 *
 * The output parameter 'witness' should be an array of (nl+nr)
 * integers, indexed such that witness[L] corresponds to an L-vertex (for
 * L=0,1,...,nl-1) and witness[nl+R] corresponds to an R-vertex (for
 * R=0,1,...,nr-1). On return, this array will assign each vertex a
 * label which is either 0 or 1, and the following properties will
 * hold:
 *
 *  + all vertices not paired up by the matching are type L0 or R1
 *  + every L0->R1 edge is used by the matching
 *  + no L1->R0 edge is used by the matching.
 *
 * The mere existence of such a labelling is enough to prove the
 * maximality of the matching, because if there is any larger matching
 * then its symmetric difference with this one must include at least
 * one 'augmenting path', which starts at a free L-vertex and ends at
 * a free R-vertex, traversing only unused L->R edges and only used
 * R->L edges. But that would mean it starts at an L0, ends at an R1,
 * and never follows an edge that can get from an 0 to a 1.
 */
static void matching_witness(void *scratchv, int nl, int nr, int *witness)
{
    struct scratch *s = (struct scratch *)scratchv;
    int i, j;

    for (i = 0; i < nl; i++)
        witness[i] = s->Llayer[i] == -1;
    for (j = 0; j < nr; j++)
        witness[nl + j] = s->Rlayer[j] == -1;
}

/*
 * Standalone tool to run the matching algorithm.
 */

#include <string.h>
#include <ctype.h>
#include <time.h>

#include "tree234.h"

int nl, nr, count;
int **adjlists, *adjsizes;
int *adjdata, *outl, *outr, *witness;
void *scratch;
random_state *rs;

void allocate(int nl_, int nr_, int maxedges)
{
    nl = nl_;
    nr = nr_;
    adjdata = snewn(maxedges, int);
    adjlists = snewn(nl, int *);
    adjsizes = snewn(nl, int);
    outl = snewn(nl, int);
    outr = snewn(nr, int);
    witness = snewn(nl+nr, int);
    scratch = smalloc(matching_scratch_size(nl, nr));
}

void deallocate(void)
{
    sfree(adjlists);
    sfree(adjsizes);
    sfree(adjdata);
    sfree(outl);
    sfree(outr);
    sfree(witness);
    sfree(scratch);
}

void find_and_check_matching(void)
{
    int i, j, k;

    count = matching_with_scratch(scratch, nl, nr, adjlists, adjsizes,
                                  rs, outl, outr);
    matching_witness(scratch, nl, nr, witness);

    for (i = j = 0; i < nl; i++) {
        if (outl[i] != -1) {
            assert(0 <= outl[i] && outl[i] < nr);
            assert(outr[outl[i]] == i);
            j++;

            for (k = 0; k < adjsizes[i]; k++)
                if (adjlists[i][k] == outl[i])
                    break;
            assert(k < adjsizes[i]);
        }
    }
    assert(j == count);

    for (i = j = 0; i < nr; i++) {
        if (outr[i] != -1) {
            assert(0 <= outr[i] && outr[i] < nl);
            assert(outl[outr[i]] == i);
            j++;
        }
    }
    assert(j == count);

    for (i = 0; i < nl; i++) {
        if (outl[i] == -1)
            assert(witness[i] == 0);
    }
    for (i = 0; i < nr; i++) {
        if (outr[i] == -1)
            assert(witness[nl+i] == 1);
    }
    for (i = 0; i < nl; i++) {
        for (j = 0; j < adjsizes[i]; j++) {
            k = adjlists[i][j];

            if (outl[i] == k)
                assert(!(witness[i] == 1 && witness[nl+k] == 0));
            else
                assert(!(witness[i] == 0 && witness[nl+k] == 1));
        }
    }
}

struct nodename {
    const char *name;
    int index;
};

int compare_nodes(void *av, void *bv)
{
    const struct nodename *a = (const struct nodename *)av;
    const struct nodename *b = (const struct nodename *)bv;
    return strcmp(a->name, b->name);
}

int node_index(tree234 *n2i, tree234 *i2n, const char *name)
{
    struct nodename *nn, *nn_prev;
    char *namedup = dupstr(name);

    nn = snew(struct nodename);
    nn->name = namedup;
    nn->index = count234(n2i);

    nn_prev = add234(n2i, nn);
    if (nn_prev != nn) {
        sfree(nn);
        sfree(namedup);
    } else {
        addpos234(i2n, nn, nn->index);
    }

    return nn_prev->index;
}

struct edge {
    int L, R;
};

int compare_edges(void *av, void *bv)
{
    const struct edge *a = (const struct edge *)av;
    const struct edge *b = (const struct edge *)bv;
    if (a->L < b->L) return -1;
    if (a->L > b->L) return +1;
    if (a->R < b->R) return -1;
    if (a->R > b->R) return +1;
    return 0;
}

void matching_from_user_input(FILE *fp, const char *filename)
{
    tree234 *Ln2i, *Li2n, *Rn2i, *Ri2n, *edges;
    char *line = NULL;
    struct edge *e;
    int i, lineno = 0;
    int *adjptr;

    Ln2i = newtree234(compare_nodes);
    Rn2i = newtree234(compare_nodes);
    Li2n = newtree234(NULL);
    Ri2n = newtree234(NULL);
    edges = newtree234(compare_edges);

    while (sfree(line), lineno++, (line = fgetline(fp)) != NULL) {
        char *p, *Lname, *Rname;

        p = line;
        while (*p && isspace((unsigned char)*p)) p++;
        if (!*p)
            continue;

        Lname = p;
        while (*p && !isspace((unsigned char)*p)) p++;
        if (*p)
            *p++ = '\0';
        while (*p && isspace((unsigned char)*p)) p++;

        if (!*p) {
            fprintf(stderr, "%s:%d: expected 2 words, found 1\n",
                    filename, lineno);
            exit(1);
        }

        Rname = p;
        while (*p && !isspace((unsigned char)*p)) p++;
        if (*p)
            *p++ = '\0';
        while (*p && isspace((unsigned char)*p)) p++;

        if (*p) {
            fprintf(stderr, "%s:%d: expected 2 words, found more\n",
                    filename, lineno);
            exit(1);
        }

        e = snew(struct edge);
        e->L = node_index(Ln2i, Li2n, Lname);
        e->R = node_index(Rn2i, Ri2n, Rname);
        if (add234(edges, e) != e) {
            fprintf(stderr, "%s:%d: duplicate edge\n",
                    filename, lineno);
            exit(1);
        }
    }

    allocate(count234(Ln2i), count234(Rn2i), count234(edges));

    adjptr = adjdata;
    for (i = 0; i < nl; i++)
        adjlists[i] = NULL;
    for (i = 0; (e = index234(edges, i)) != NULL; i++) {
        if (!adjlists[e->L])
            adjlists[e->L] = adjptr;
        *adjptr++ = e->R;
        adjsizes[e->L] = adjptr - adjlists[e->L];
    }

    find_and_check_matching();

    for (i = 0; i < nl; i++) {
        if (outl[i] != -1) {
            struct nodename *Lnn = index234(Li2n, i);
            struct nodename *Rnn = index234(Ri2n, outl[i]);
            printf("%s %s\n", Lnn->name, Rnn->name);
        }
    }
}

void test_subsets(void)
{
    int b = 8;
    int n = 1 << b;
    int i, j, nruns, expected_size;
    int *adjptr;
    int *edgecounts;
    struct stats {
        int min, max;
        double n, sx, sxx;
    } *stats;
    static const char seed[] = "fixed random seed for repeatability";

    /*
     * Generate a graph in which every subset of [b] = {1,...,b}
     * (represented as a b-bit integer 0 <= i < n) has an edge going
     * to every subset obtained by removing exactly one element.
     *
     * This graph is the disjoint union of the corresponding graph for
     * each layer (collection of same-sized subset) of the power set
     * of [b]. Each of those graphs has a matching of size equal to
     * the smaller of its vertex sets. So we expect the overall size
     * of the output matching to be less than n by the size of the
     * largest layer, that is, to be n - binomial(n, floor(n/2)).
     *
     * We run the generation repeatedly, randomising it every time,
     * and we expect to see every possible edge appear sooner or
     * later.
     */

    rs = random_new(seed, strlen(seed));

    allocate(n, n, n*b);
    adjptr = adjdata;
    expected_size = 0;
    for (i = 0; i < n; i++) {
        adjlists[i] = adjptr;
        for (j = 0; j < b; j++) {
            if (i & (1 << j))
                *adjptr++ = i & ~(1 << j);
        }
        adjsizes[i] = adjptr - adjlists[i];
        if (adjsizes[i] != b/2)
            expected_size++;
    }

    edgecounts = snewn(n*b, int);
    for (i = 0; i < n*b; i++)
        edgecounts[i] = 0;

    stats = snewn(b, struct stats);

    nruns = 0;
    while (nruns < 10000) {
        nruns++;
        find_and_check_matching();
        assert(count == expected_size);

        for (i = 0; i < n; i++)
            for (j = 0; j < b; j++)
                if ((i ^ outl[i]) == (1 << j))
                    edgecounts[b*i+j]++;

        if (nruns % 1000 == 0) {
            for (i = 0; i < b; i++) {
                struct stats *st = &stats[i];
                st->min = st->max = -1;
                st->n = st->sx = st->sxx = 0;
            }

            for (i = 0; i < n; i++) {
                int pop = 0;
                for (j = 0; j < b; j++)
                    if (i & (1 << j))
                        pop++;
                pop--;

                for (j = 0; j < b; j++) {
                    if (i & (1 << j)) {
                        struct stats *st = &stats[pop];
                        int x = edgecounts[b*i+j];
                        if (st->max == -1 || st->max < x)
                            st->max = x;
                        if (st->min == -1 || st->min > x)
                            st->min = x;
                        st->n++;
                        st->sx += x;
                        st->sxx += (double)x*x;
                    } else {
                        assert(edgecounts[b*i+j] == 0);
                    }
                }
            }
        }
    }

    printf("after %d runs:\n", nruns);
    for (j = 0; j < b; j++) {
        struct stats *st = &stats[j];
        printf("edges between layers %d,%d:"
               " min=%d max=%d mean=%f variance=%f\n",
               j, j+1, st->min, st->max, st->sx/st->n,
               (st->sxx - st->sx*st->sx/st->n) / st->n);
    }
}

int main(int argc, char **argv)
{
    static const char stdin_identifier[] = "<standard input>";
    const char *infile = NULL;
    bool doing_opts = true;
    enum { USER_INPUT, AUTOTEST } mode = USER_INPUT;

    while (--argc > 0) {
        const char *arg = *++argv;

        if (doing_opts && arg[0] == '-' && arg[1]) {
            if (!strcmp(arg, "--")) {
                doing_opts = false;
            } else if (!strcmp(arg, "--random")) {
                char buf[64];
                int len = sprintf(buf, "%lu", (unsigned long)time(NULL));
                rs = random_new(buf, len);
            } else if (!strcmp(arg, "--autotest")) {
                mode = AUTOTEST;
            } else {
                fprintf(stderr, "matching: unrecognised option '%s'\n", arg);
                return 1;
            }
        } else {
            if (!infile) {
                infile = (!strcmp(arg, "-") ? stdin_identifier : arg);
            } else {
                fprintf(stderr, "matching: too many arguments\n");
                return 1;
            }
        }
    }

    if (mode == USER_INPUT) {
        FILE *fp;

        if (!infile)
            infile = stdin_identifier;

        if (infile != stdin_identifier) {
            fp = fopen(infile, "r");
            if (!fp) {
                fprintf(stderr, "matching: could not open input file '%s'\n",
                        infile);
                return 1;
            }
        } else {
            fp = stdin;
        }

        matching_from_user_input(fp, infile);

        if (infile != stdin_identifier)
            fclose(fp);
    }

    if (mode == AUTOTEST) {
        if (infile) {
            fprintf(stderr, "matching: expected no filename argument "
                    "with --autotest\n");
            return 1;
        }

        test_subsets();
    }

    return 0;
}

#endif /* STANDALONE_MATCHING_TEST */


<|start_filename|>matching.h<|end_filename|>
/*
 * Hopcroft-Karp algorithm for finding a maximal matching in a
 * bipartite graph.
 */

#ifndef MATCHING_MATCHING_H
#define MATCHING_MATCHING_H

/*
 * The actual algorithm.
 * 
 * Inputs:
 * 
 *  - 'scratch' is previously allocated scratch space of a size
 *    previously determined by calling 'matching_scratch_size'.
 * 
 *  - 'nl' is the number of vertices on the left side of the graph.
 *    Left vertices are numbered from 0 to nl-1.
 * 
 *  - 'nr' is the number of vertices on the left side of the graph.
 *    Right vertices are numbered from 0 to nr-1.
 * 
 *  - 'adjlists' and 'adjsizes' represents the graph in adjacency-list
 *    form. For each left vertex L, adjlists[L] points to an array of
 *    adjsizes[L] integers giving the list of right vertices adjacent
 *    to L.
 *
 *  - 'rs', if not NULL, is a random_state used to perturb the
 *    progress of the algorithm so as to choose randomly from the
 *    possible matchings if there's more than one. (The exact
 *    probability distribution can't be guaranteed, but at the very
 *    least, any matching that exists should be a _possible_ output.)
 *
 * If 'rs' is not NULL, then each list in adjlists[] will be permuted
 * during the course of the algorithm as a side effect. (That's why
 * it's not an array of _const_ int pointers.)
 * 
 * Output:
 * 
 *  - 'outl' may be NULL. If non-NULL, it is an array of 'nl'
 *    integers, and outl[L] will be assigned the index of the right
 *    vertex that the output matching paired with the left vertex L,
 *    or -1 if L is unpaired.
 * 
 *  - 'outr' may be NULL. If non-NULL, it is an array of 'nr'
 *    integers, and outr[R] will be assigned the index of the left
 *    vertex that the output matching paired with the right vertex R,
 *    or -1 if R is unpaired.
 * 
 *  - the returned value from the function is the total number of
 *    edges in the matching.
 */
int matching_with_scratch(void *scratch,
                          int nl, int nr, int **adjlists, int *adjsizes,
                          random_state *rs, int *outl, int *outr);

/*
 * The above function expects its 'scratch' parameter to have already
 * been set up. This function tells you how much space is needed for a
 * given size of graph, so that you can allocate a single instance of
 * scratch space and run the algorithm multiple times without the
 * overhead of an alloc and free every time.
 */
size_t matching_scratch_size(int nl, int nr);

/*
 * Simplified version of the above function. All parameters are the
 * same, except that 'scratch' is constructed internally and freed on
 * exit. This is the simplest way to call the algorithm as a one-off;
 * however, if you need to call it multiple times on the same size of
 * graph, it is probably better to call the above version directly so
 * that you only construct 'scratch' once.
 *
 * Additional return value is now -1, meaning that scratch space
 * could not be allocated.
 */
int matching(int nl, int nr, int **adjlists, int *adjsizes,
             random_state *rs, int *outl, int *outr);

#endif /* MATCHING_MATCHING_H */


<|start_filename|>html/blackbox.html<|end_filename|>
Black Box
<p>
Determine where the hidden balls are in the box, by observing the
behaviour of light beams fired into the box from the sides.
<p>
Click in a square around the edge of the box to send a beam into the
box. Possible results are 'H' (the beam hit a ball dead-on and
stopped), 'R' (the beam was either reflected back the way it came or
there was a ball just to one side of its entry point) or a number
appearing in two squares (indicating that the beam entered one of
those squares and emerged from the other).
<p>
Click in the middle of the box to place your guessed ball positions.
When you have placed enough, a green button will appear in the top
left; click that to indicate that you think you have the answer.
You can also right-click to mark squares as definitely known.


<|start_filename|>html/cube.html<|end_filename|>
Cube
<p>
Roll the cube around the grid, picking up the blue squares on its
faces. Try to get all the blue squares on to the object at the same
time, in as few moves as possible.
<p>
Use the arrow keys to roll the cube, or click the mouse where you
want it to roll towards. After every roll, the grid square and cube
face that you brought into contact swap their colours, so that a
non-blue cube face can pick up a blue square, but a blue face rolled
on to a non-blue square puts it down again.
<p>
When you have mastered the cube, use the Type menu to select other
regular solids!


<|start_filename|>html/lightup.html<|end_filename|>
Light Up
<p>
Place light bulbs in the grid so as to light up all the blank
squares. A light illuminates its own square and all the squares in
the same row or column unless blocked by walls (black squares).
Lights may not illuminate each other. Each numbered square must be
orthogonally adjacent to exactly the given number of lights.
<p>
Click on a square to place or remove a light. Right-click to place a
dot indicating that you think there is no light in that square.


<|start_filename|>PSTCollectionView/Examples/DecorationViews/DecorationViewLayoutAttributes.h<|end_filename|>
//
//  DecorationViewLayoutAttributes.h
//  PSCollectionViewExample
//
//  Created by <NAME> on 7/03/13.
//

#import "PSTCollectionView.h"

@interface DecorationViewLayoutAttributes : PSUICollectionViewLayoutAttributes

@property (nonatomic,strong) UIColor *backgroundColor;

@end


<|start_filename|>PSTCollectionView/Examples/FlowLayoutNoNIB/FlowLayoutNoNIB/AppDelegate.h<|end_filename|>
//
//  AppDelegate.h
//  FlowLayoutNoNIB
//
//  Created by <NAME> on 2012.10.29.
//
//

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end


<|start_filename|>html/solo.html<|end_filename|>
Solo
<p>
Fill in a number in every square so that every number appears
exactly once in each row, each column and each block marked by thick
lines.
<p>
To place a number, click in a square to select it, then type the
number on the keyboard. To erase a number, click to select a square
and then press Backspace.
<p>
Right-click in a square and then type a number to add or remove the
number as a pencil mark, indicating numbers that you think
<em>might</em> go in that square.
<p>
When you master the basic game, try Jigsaw mode (irregularly shaped
blocks), X mode (the two main diagonals of the grid must also
contain every number once), Killer mode (instead of single-cell
clues you are given regions of the grid each of which must add up to
a given total, again without reusing any digits), or all of those at
once!


<|start_filename|>html/inertia.html<|end_filename|>
Inertia
<p>
Slide the ball around the grid picking up the gems. Every time the
ball moves, it will keep sliding until it either hits a wall, or
stops on a stop square (the broken circles). Try to collect every
gem without running into any of the mines.
<p>
Use the numeric keypad to slide the ball horizontally, vertically or
diagonally. Alternatively, click on the grid to make the ball move
towards where you clicked.
<p>
If you hit a mine and explode, you can select Undo from the Game
menu and continue playing; the game will track how many times you
died.


<|start_filename|>PSTCollectionView/Examples/SelectionDelegateExample/SelectionDelegateExample/UILabel+Highlight.h<|end_filename|>
//
//  UILabel+Highlight.h
//  SelectionDelegateExample
//
//  Created by <NAME> on 1/21/13.
//  Copyright (c) 2013 orta therox. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface UILabel (Highlight)

@end


<|start_filename|>html/mines.html<|end_filename|>
Mines
<p>
Try to expose every square in the grid that is not one of the hidden
mines, without opening any square that is a mine.
<p>
Click in a square to open it. Every opened square are marked with
the number of mines in the surrounding 8 squares, if there are any;
if not, all the surrounding squares are automatically opened.
<p>
Right-click in a square to mark it with a flag if you think it is a
mine. If a numbered square has exactly the right number of flags
around it, you can click in it to open all the squares around it
that are not flagged.
<p>
The first square you open is guaranteed to be safe, and (by default)
you are guaranteed to be able to solve the whole grid by deduction
rather than guesswork. (Deductions may require you to think about
the total number of mines.)


<|start_filename|>penrose.h<|end_filename|>
/* penrose.h
 *
 * Penrose tiling functions.
 *
 * Provides an interface with which to generate Penrose tilings
 * by recursive subdivision of an initial tile of choice (one of the
 * four sets of two pairs kite/dart, or thin/thick rhombus).
 *
 * You supply a callback function and a context pointer, which is
 * called with each tile in turn: you choose how many times to recurse.
 */

#ifndef _PENROSE_H
#define _PENROSE_H

#ifndef PHI
#define PHI 1.6180339887
#endif

typedef struct vector vector;

double v_x(vector *vs, int i);
double v_y(vector *vs, int i);

typedef struct penrose_state penrose_state;

/* Return non-zero to clip the tree here (i.e. not recurse
 * below this tile).
 *
 * Parameters are state, vector array, npoints, depth.
 * ctx is inside state.
 */
typedef int (*tile_callback)(penrose_state *, vector *, int, int);

struct penrose_state {
    int start_size;  /* initial side length */
    int max_depth;      /* Recursion depth */

    tile_callback new_tile;
    void *ctx;          /* for callback */
};

enum { PENROSE_P2, PENROSE_P3 };

extern int penrose(penrose_state *state, int which, int angle);

/* Returns the side-length of a penrose tile at recursion level
 * gen, given a starting side length. */
extern double penrose_side_length(double start_size, int depth);

/* Returns the count of each type of tile at a given recursion depth. */
extern void penrose_count_tiles(int gen, int *nlarge, int *nsmall);

/* Calculate start size and recursion depth required to produce a
 * width-by-height sized patch of penrose tiles with the given tilesize */
extern void penrose_calculate_size(int which, int tilesize, int w, int h,
                                   double *required_radius, int *start_size, int *depth);

#endif


<|start_filename|>loopgen.c<|end_filename|>
/*
 * loopgen.c: loop generation functions for grid.[ch].
 */

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <math.h>

#include "puzzles.h"
#include "tree234.h"
#include "grid.h"
#include "loopgen.h"


/* We're going to store lists of current candidate faces for colouring black
 * or white.
 * Each face gets a 'score', which tells us how adding that face right
 * now would affect the curliness of the solution loop.  We're trying to
 * maximise that quantity so will bias our random selection of faces to
 * colour those with high scores */
struct face_score {
    int white_score;
    int black_score;
    unsigned long random;
    /* No need to store a grid_face* here.  The 'face_scores' array will
     * be a list of 'face_score' objects, one for each face of the grid, so
     * the position (index) within the 'face_scores' array will determine
     * which face corresponds to a particular face_score.
     * Having a single 'face_scores' array for all faces simplifies memory
     * management, and probably improves performance, because we don't have to 
     * malloc/free each individual face_score, and we don't have to maintain
     * a mapping from grid_face* pointers to face_score* pointers.
     */
};

static int generic_sort_cmpfn(void *v1, void *v2, size_t offset)
{
    struct face_score *f1 = v1;
    struct face_score *f2 = v2;
    int r;

    r = *(int *)((char *)f2 + offset) - *(int *)((char *)f1 + offset);
    if (r) {
        return r;
    }

    if (f1->random < f2->random)
        return -1;
    else if (f1->random > f2->random)
        return 1;

    /*
     * It's _just_ possible that two faces might have been given
     * the same random value. In that situation, fall back to
     * comparing based on the positions within the face_scores list.
     * This introduces a tiny directional bias, but not a significant one.
     */
    return f1 - f2;
}

static int white_sort_cmpfn(void *v1, void *v2)
{
    return generic_sort_cmpfn(v1, v2, offsetof(struct face_score,white_score));
}

static int black_sort_cmpfn(void *v1, void *v2)
{
    return generic_sort_cmpfn(v1, v2, offsetof(struct face_score,black_score));
}

/* 'board' is an array of enum face_colour, indicating which faces are
 * currently black/white/grey.  'colour' is FACE_WHITE or FACE_BLACK.
 * Returns whether it's legal to colour the given face with this colour. */
static bool can_colour_face(grid *g, char* board, int face_index,
                            enum face_colour colour)
{
    int i, j;
    grid_face *test_face = g->faces + face_index;
    grid_face *starting_face, *current_face;
    grid_dot *starting_dot;
    int transitions;
    bool current_state, s; /* equal or not-equal to 'colour' */
    bool found_same_coloured_neighbour = false;
    assert(board[face_index] != colour);

    /* Can only consider a face for colouring if it's adjacent to a face
     * with the same colour. */
    for (i = 0; i < test_face->order; i++) {
        grid_edge *e = test_face->edges[i];
        grid_face *f = (e->face1 == test_face) ? e->face2 : e->face1;
        if (FACE_COLOUR(f) == colour) {
            found_same_coloured_neighbour = true;
            break;
        }
    }
    if (!found_same_coloured_neighbour)
        return false;

    /* Need to avoid creating a loop of faces of this colour around some
     * differently-coloured faces.
     * Also need to avoid meeting a same-coloured face at a corner, with
     * other-coloured faces in between.  Here's a simple test that (I believe)
     * takes care of both these conditions:
     *
     * Take the circular path formed by this face's edges, and inflate it
     * slightly outwards.  Imagine walking around this path and consider
     * the faces that you visit in sequence.  This will include all faces
     * touching the given face, either along an edge or just at a corner.
     * Count the number of 'colour'/not-'colour' transitions you encounter, as
     * you walk along the complete loop.  This will obviously turn out to be
     * an even number.
     * If 0, we're either in the middle of an "island" of this colour (should
     * be impossible as we're not supposed to create black or white loops),
     * or we're about to start a new island - also not allowed.
     * If 4 or greater, there are too many separate coloured regions touching
     * this face, and colouring it would create a loop or a corner-violation.
     * The only allowed case is when the count is exactly 2. */

    /* i points to a dot around the test face.
     * j points to a face around the i^th dot.
     * The current face will always be:
     *     test_face->dots[i]->faces[j]
     * We assume dots go clockwise around the test face,
     * and faces go clockwise around dots. */

    /*
     * The end condition is slightly fiddly. In sufficiently strange
     * degenerate grids, our test face may be adjacent to the same
     * other face multiple times (typically if it's the exterior
     * face). Consider this, in particular:
     * 
     *   +--+
     *   |  |
     *   +--+--+
     *   |  |  |
     *   +--+--+
     * 
     * The bottom left face there is adjacent to the exterior face
     * twice, so we can't just terminate our iteration when we reach
     * the same _face_ we started at. Furthermore, we can't
     * condition on having the same (i,j) pair either, because
     * several (i,j) pairs identify the bottom left contiguity with
     * the exterior face! We canonicalise the (i,j) pair by taking
     * one step around before we set the termination tracking.
     */

    i = j = 0;
    current_face = test_face->dots[0]->faces[0];
    if (current_face == test_face) {
        j = 1;
        current_face = test_face->dots[0]->faces[1];
    }
    transitions = 0;
    current_state = (FACE_COLOUR(current_face) == colour);
    starting_dot = NULL;
    starting_face = NULL;
    while (true) {
        /* Advance to next face.
         * Need to loop here because it might take several goes to
         * find it. */
        while (true) {
            j++;
            if (j == test_face->dots[i]->order)
                j = 0;

            if (test_face->dots[i]->faces[j] == test_face) {
                /* Advance to next dot round test_face, then
                 * find current_face around new dot
                 * and advance to the next face clockwise */
                i++;
                if (i == test_face->order)
                    i = 0;
                for (j = 0; j < test_face->dots[i]->order; j++) {
                    if (test_face->dots[i]->faces[j] == current_face)
                        break;
                }
                /* Must actually find current_face around new dot,
                 * or else something's wrong with the grid. */
                assert(j != test_face->dots[i]->order);
                /* Found, so advance to next face and try again */
            } else {
                break;
            }
        }
        /* (i,j) are now advanced to next face */
        current_face = test_face->dots[i]->faces[j];
        s = (FACE_COLOUR(current_face) == colour);
	if (!starting_dot) {
	    starting_dot = test_face->dots[i];
	    starting_face = current_face;
	    current_state = s;
	} else {
	    if (s != current_state) {
		++transitions;
		current_state = s;
		if (transitions > 2)
		    break;
	    }
	    if (test_face->dots[i] == starting_dot &&
		current_face == starting_face)
		break;
        }
    }

    return (transitions == 2) ? true : false;
}

/* Count the number of neighbours of 'face', having colour 'colour' */
static int face_num_neighbours(grid *g, char *board, grid_face *face,
                               enum face_colour colour)
{
    int colour_count = 0;
    int i;
    grid_face *f;
    grid_edge *e;
    for (i = 0; i < face->order; i++) {
        e = face->edges[i];
        f = (e->face1 == face) ? e->face2 : e->face1;
        if (FACE_COLOUR(f) == colour)
            ++colour_count;
    }
    return colour_count;
}

/* The 'score' of a face reflects its current desirability for selection
 * as the next face to colour white or black.  We want to encourage moving
 * into grey areas and increasing loopiness, so we give scores according to
 * how many of the face's neighbours are currently coloured the same as the
 * proposed colour. */
static int face_score(grid *g, char *board, grid_face *face,
                      enum face_colour colour)
{
    /* Simple formula: score = 0 - num. same-coloured neighbours,
     * so a higher score means fewer same-coloured neighbours. */
    return -face_num_neighbours(g, board, face, colour);
}

/*
 * Generate a new complete random closed loop for the given grid.
 *
 * The method is to generate a WHITE/BLACK colouring of all the faces,
 * such that the WHITE faces will define the inside of the path, and the
 * BLACK faces define the outside.
 * To do this, we initially colour all faces GREY.  The infinite space outside
 * the grid is coloured BLACK, and we choose a random face to colour WHITE.
 * Then we gradually grow the BLACK and the WHITE regions, eliminating GREY
 * faces, until the grid is filled with BLACK/WHITE.  As we grow the regions,
 * we avoid creating loops of a single colour, to preserve the topological
 * shape of the WHITE and BLACK regions.
 * We also try to make the boundary as loopy and twisty as possible, to avoid
 * generating paths that are uninteresting.
 * The algorithm works by choosing a BLACK/WHITE colour, then choosing a GREY
 * face that can be coloured with that colour (without violating the
 * topological shape of that region).  It's not obvious, but I think this
 * algorithm is guaranteed to terminate without leaving any GREY faces behind.
 * Indeed, if there are any GREY faces at all, both the WHITE and BLACK
 * regions can be grown.
 * This is checked using assert()ions, and I haven't seen any failures yet.
 *
 * Hand-wavy proof: imagine what can go wrong...
 *
 * Could the white faces get completely cut off by the black faces, and still
 * leave some grey faces remaining?
 * No, because then the black faces would form a loop around both the white
 * faces and the grey faces, which is disallowed because we continually
 * maintain the correct topological shape of the black region.
 * Similarly, the black faces can never get cut off by the white faces.  That
 * means both the WHITE and BLACK regions always have some room to grow into
 * the GREY regions.
 * Could it be that we can't colour some GREY face, because there are too many
 * WHITE/BLACK transitions as we walk round the face? (see the
 * can_colour_face() function for details)
 * No.  Imagine otherwise, and we see WHITE/BLACK/WHITE/BLACK as we walk
 * around the face.  The two WHITE faces would be connected by a WHITE path,
 * and the BLACK faces would be connected by a BLACK path.  These paths would
 * have to cross, which is impossible.
 * Another thing that could go wrong: perhaps we can't find any GREY face to
 * colour WHITE, because it would create a loop-violation or a corner-violation
 * with the other WHITE faces?
 * This is a little bit tricky to prove impossible.  Imagine you have such a
 * GREY face (that is, if you coloured it WHITE, you would create a WHITE loop
 * or corner violation).
 * That would cut all the non-white area into two blobs.  One of those blobs
 * must be free of BLACK faces (because the BLACK stuff is a connected blob).
 * So we have a connected GREY area, completely surrounded by WHITE
 * (including the GREY face we've tentatively coloured WHITE).
 * A well-known result in graph theory says that you can always find a GREY
 * face whose removal leaves the remaining GREY area connected.  And it says
 * there are at least two such faces, so we can always choose the one that
 * isn't the "tentative" GREY face.  Colouring that face WHITE leaves
 * everything nice and connected, including that "tentative" GREY face which
 * acts as a gateway to the rest of the non-WHITE grid.
 */
void generate_loop(grid *g, char *board, random_state *rs,
                   loopgen_bias_fn_t bias, void *biasctx)
{
    int i, j;
    int num_faces = g->num_faces;
    struct face_score *face_scores; /* Array of face_score objects */
    struct face_score *fs; /* Points somewhere in the above list */
    struct grid_face *cur_face;
    tree234 *lightable_faces_sorted;
    tree234 *darkable_faces_sorted;
    int *face_list;
    bool do_random_pass;

    /* Make a board */
    memset(board, FACE_GREY, num_faces);
    
    /* Create and initialise the list of face_scores */
    face_scores = snewn(num_faces, struct face_score);
    for (i = 0; i < num_faces; i++) {
        face_scores[i].random = random_bits(rs, 31);
        face_scores[i].black_score = face_scores[i].white_score = 0;
    }
    
    /* Colour a random, finite face white.  The infinite face is implicitly
     * coloured black.  Together, they will seed the random growth process
     * for the black and white areas. */
    i = random_upto(rs, num_faces);
    board[i] = FACE_WHITE;

    /* We need a way of favouring faces that will increase our loopiness.
     * We do this by maintaining a list of all candidate faces sorted by
     * their score and choose randomly from that with appropriate skew.
     * In order to avoid consistently biasing towards particular faces, we
     * need the sort order _within_ each group of scores to be completely
     * random.  But it would be abusing the hospitality of the tree234 data
     * structure if our comparison function were nondeterministic :-).  So with
     * each face we associate a random number that does not change during a
     * particular run of the generator, and use that as a secondary sort key.
     * Yes, this means we will be biased towards particular random faces in
     * any one run but that doesn't actually matter. */

    lightable_faces_sorted = newtree234(white_sort_cmpfn);
    darkable_faces_sorted = newtree234(black_sort_cmpfn);

    /* Initialise the lists of lightable and darkable faces.  This is
     * slightly different from the code inside the while-loop, because we need
     * to check every face of the board (the grid structure does not keep a
     * list of the infinite face's neighbours). */
    for (i = 0; i < num_faces; i++) {
        grid_face *f = g->faces + i;
        struct face_score *fs = face_scores + i;
        if (board[i] != FACE_GREY) continue;
        /* We need the full colourability check here, it's not enough simply
         * to check neighbourhood.  On some grids, a neighbour of the infinite
         * face is not necessarily darkable. */
        if (can_colour_face(g, board, i, FACE_BLACK)) {
            fs->black_score = face_score(g, board, f, FACE_BLACK);
            add234(darkable_faces_sorted, fs);
        }
        if (can_colour_face(g, board, i, FACE_WHITE)) {
            fs->white_score = face_score(g, board, f, FACE_WHITE);
            add234(lightable_faces_sorted, fs);
        }
    }

    /* Colour faces one at a time until no more faces are colourable. */
    while (true)
    {
        enum face_colour colour;
        tree234 *faces_to_pick;
        int c_lightable = count234(lightable_faces_sorted);
        int c_darkable = count234(darkable_faces_sorted);
        if (c_lightable == 0 && c_darkable == 0) {
            /* No more faces we can use at all. */
            break;
        }
	assert(c_lightable != 0 && c_darkable != 0);

        /* Choose a colour, and colour the best available face
         * with that colour. */
        colour = random_upto(rs, 2) ? FACE_WHITE : FACE_BLACK;

        if (colour == FACE_WHITE)
            faces_to_pick = lightable_faces_sorted;
        else
            faces_to_pick = darkable_faces_sorted;
        if (bias) {
            /*
             * Go through all the candidate faces and pick the one the
             * bias function likes best, breaking ties using the
             * ordering in our tree234 (which is why we replace only
             * if score > bestscore, not >=).
             */
            int j, k;
            struct face_score *best = NULL;
            int score, bestscore = 0;

            for (j = 0;
                 (fs = (struct face_score *)index234(faces_to_pick, j))!=NULL;
                 j++) {

                assert(fs);
                k = fs - face_scores;
                assert(board[k] == FACE_GREY);
                board[k] = colour;
                score = bias(biasctx, board, k);
                board[k] = FACE_GREY;
                bias(biasctx, board, k); /* let bias know we put it back */

                if (!best || score > bestscore) {
                    bestscore = score;
                    best = fs;
                }
            }
            fs = best;
        } else {
            fs = (struct face_score *)index234(faces_to_pick, 0);
        }
        assert(fs);
        i = fs - face_scores;
        assert(board[i] == FACE_GREY);
        board[i] = colour;
        if (bias)
            bias(biasctx, board, i); /* notify bias function of the change */

        /* Remove this newly-coloured face from the lists.  These lists should
         * only contain grey faces. */
        del234(lightable_faces_sorted, fs);
        del234(darkable_faces_sorted, fs);

        /* Remember which face we've just coloured */
        cur_face = g->faces + i;

        /* The face we've just coloured potentially affects the colourability
         * and the scores of any neighbouring faces (touching at a corner or
         * edge).  So the search needs to be conducted around all faces
         * touching the one we've just lit.  Iterate over its corners, then
         * over each corner's faces.  For each such face, we remove it from
         * the lists, recalculate any scores, then add it back to the lists
         * (depending on whether it is lightable, darkable or both). */
        for (i = 0; i < cur_face->order; i++) {
            grid_dot *d = cur_face->dots[i];
            for (j = 0; j < d->order; j++) {
                grid_face *f = d->faces[j];
                int fi; /* face index of f */

                if (f == NULL)
                    continue;
                if (f == cur_face)
                    continue;
                
                /* If the face is already coloured, it won't be on our
                 * lightable/darkable lists anyway, so we can skip it without 
                 * bothering with the removal step. */
                if (FACE_COLOUR(f) != FACE_GREY) continue; 

                /* Find the face index and face_score* corresponding to f */
                fi = f - g->faces;                
                fs = face_scores + fi;

                /* Remove from lightable list if it's in there.  We do this,
                 * even if it is still lightable, because the score might
                 * be different, and we need to remove-then-add to maintain
                 * correct sort order. */
                del234(lightable_faces_sorted, fs);
                if (can_colour_face(g, board, fi, FACE_WHITE)) {
                    fs->white_score = face_score(g, board, f, FACE_WHITE);
                    add234(lightable_faces_sorted, fs);
                }
                /* Do the same for darkable list. */
                del234(darkable_faces_sorted, fs);
                if (can_colour_face(g, board, fi, FACE_BLACK)) {
                    fs->black_score = face_score(g, board, f, FACE_BLACK);
                    add234(darkable_faces_sorted, fs);
                }
            }
        }
    }

    /* Clean up */
    freetree234(lightable_faces_sorted);
    freetree234(darkable_faces_sorted);
    sfree(face_scores);

    /* The next step requires a shuffled list of all faces */
    face_list = snewn(num_faces, int);
    for (i = 0; i < num_faces; ++i) {
        face_list[i] = i;
    }
    shuffle(face_list, num_faces, sizeof(int), rs);

    /* The above loop-generation algorithm can often leave large clumps
     * of faces of one colour.  In extreme cases, the resulting path can be 
     * degenerate and not very satisfying to solve.
     * This next step alleviates this problem:
     * Go through the shuffled list, and flip the colour of any face we can
     * legally flip, and which is adjacent to only one face of the opposite
     * colour - this tends to grow 'tendrils' into any clumps.
     * Repeat until we can find no more faces to flip.  This will
     * eventually terminate, because each flip increases the loop's
     * perimeter, which cannot increase for ever.
     * The resulting path will have maximal loopiness (in the sense that it
     * cannot be improved "locally".  Unfortunately, this allows a player to
     * make some illicit deductions.  To combat this (and make the path more
     * interesting), we do one final pass making random flips. */

    /* Set to true for final pass */
    do_random_pass = false;

    while (true) {
        /* Remember whether a flip occurred during this pass */
        bool flipped = false;

        for (i = 0; i < num_faces; ++i) {
            int j = face_list[i];
            enum face_colour opp =
                (board[j] == FACE_WHITE) ? FACE_BLACK : FACE_WHITE;
            if (can_colour_face(g, board, j, opp)) {
                grid_face *face = g->faces +j;
                if (do_random_pass) {
                    /* final random pass */
                    if (!random_upto(rs, 10))
                        board[j] = opp;
                } else {
                    /* normal pass - flip when neighbour count is 1 */
                    if (face_num_neighbours(g, board, face, opp) == 1) {
                        board[j] = opp;
                        flipped = true;
                    }
                }
            }
        }

        if (do_random_pass) break;
        if (!flipped) do_random_pass = true;
    }

    sfree(face_list);
}


<|start_filename|>PSTCollectionView/Examples/SelectionDelegateExample/SelectionDelegateExample/ViewController.h<|end_filename|>
//
//  ViewController.h
//  SelectionDelegateExample
//
//  Created by <NAME> on 06/11/2012.
//  Copyright (c) 2012 <NAME>. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <PSTCollectionViewDataSource, PSTCollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate>

@end


<|start_filename|>html/unruly.html<|end_filename|>
Unruly
<p>
Colour every square either black or white, in such a way that:
<ul><li>no three consecutive squares, horizontally or vertically, are
the same colour
<li>each row and column contains the same number of black and white
squares.</ul>
<p>
Left-click in an empty square to turn it black, or right-click to turn
it white. Click again in an already-filled square to cycle it between
black and white and empty; middle-click to reset any square to empty.


<|start_filename|>html/range.html<|end_filename|>
Range
<p>
Colour some squares black, so as to meet the following conditions:
<ul>
<li>
No two black squares are orthogonally adjacent.
<li>
No group of white squares is separated from the rest of the grid by
black squares.
<li>
Each numbered cell can see precisely that many white squares in
total by looking in all four orthogonal directions, counting itself.
(Black squares block the view. So, for example, a 2 clue must be
adjacent to three black squares or grid edges, and in the fourth
direction there must be one white square and then a black one beyond
it.)
</ul>

<p>
Left-click to colour a square black. Right-click to mark a square
with a dot, if you know it should not be black.


<|start_filename|>html/group.html<|end_filename|>
unfinished:Group
<p>
Fill in the grid with the letters shown to the top and left of it, so
that the full grid is a valid
<a href="http://en.wikipedia.org/wiki/Cayley_table">Cayley table</a>
for a
<a href="http://en.wikipedia.org/wiki/Group_(mathematics)">group</a>.
<p>
If you don't already know what a group is, I don't really recommend
trying to play this game. But if you want to try anyway, the above is
equivalent to saying that the following conditions must be satisfied:
<ul>
<li>
<strong>Latin square</strong>. Every row and column must contain
exactly one of each letter.
<li>
<strong>Identity</strong>. There must be some letter <i>e</i> such
that, for all <i>a</i>, the letter in row <i>e</i> column <i>a</i> and
the one in row <i>a</i> column <i>e</i> are both <i>a</i>. In the
default mode, this letter is always <i>e</i> and its row and column
are filled in for you; by reconfiguring the game using the Type menu,
you can select a mode in which you have to work out which letter is
the identity.
<li>
<strong>Inverses</strong>. For every letter <i>a</i>, there must be
some letter <i>b</i> (which may sometimes be the same letter
as <i>a</i>) such that the letters in row <i>a</i> column <i>b</i> and
in row <i>b</i> column <i>a</i> are both the identity letter (as
defined above).
<li>
<strong>Associativity</strong>. For every combination of
letters <i>a</i>, <i>b</i>, and <i>c</i>, denote the letter in
row <i>a</i> column <i>b</i> by <i>d</i>, and the one in row <i>b</i>
column <i>c</i> by <i>e</i>. Then the letters in row <i>d</i>
column <i>c</i> and in row <i>a</i> column <i>e</i> must be the same.
</ul>
<p>
To place a letter, click in a square to select it, then type the
letter on the keyboard. To erase a letter, click to select a square
and then press Backspace.
<p>
Right-click in a square and then type a letter to add or remove the
number as a pencil mark, indicating letters that you think
<em>might</em> go in that square.
<p>
You can rearrange the order of elements in the rows and columns by
dragging the column or row headings back and forth. (The rows and
columns will stay in sync with each other.) Also,
left-clicking <em>between</em> two row or column headings will add or
remove a thick line between those two rows and the corresponding pair
of columns (which is useful if you're considering a subgroup and its
cosets).


<|start_filename|>version.c<|end_filename|>
/*
 * Puzzles version numbering.
 */

#include "version.h"

char ver[] = VER;


<|start_filename|>html/keen.html<|end_filename|>
Keen
<p>
Fill in the grid with digits from 1 to the grid size, so that every
digit appears exactly once in each row and column, and so that all
the arithmetic clues are satisfied (i.e. the clue number in each
thick box should be possible to construct from the digits in the box
using the specified arithmetic operation).
<p>
To place a number, click in a square to select it, then type the
number on the keyboard. To erase a number, click to select a square
and then press Backspace.
<p>
Right-click in a square and then type a number to add or remove the
number as a pencil mark, indicating numbers that you think
<em>might</em> go in that square.


<|start_filename|>html/guess.html<|end_filename|>
Guess
<p>
Try to guess the hidden combination of colours. You will be given
limited information about each guess you make, enabling you to
refine the next guess.
<p>
Drag from the colours on the left into the topmost unfilled row to
make a guess; then click on the small circles to submit that guess.
The small circles give you your feedback: black pegs indicate how
many of the colours you guessed were the right colour in the right
place, and white pegs indicate how many of the rest were the right
colours but in the wrong place.


<|start_filename|>PSTCollectionView/Examples/FlowLayoutNoNIB/FlowLayoutNoNIB/CollectionViewCell.h<|end_filename|>
//
//  CollectionViewCell.h
//  FlowLayoutNoNIB
//
//  Created by <NAME> on 2012.10.29.
//
//

#import "PSTCollectionView.h"

@interface CollectionViewCell : PSUICollectionViewCell

@end


<|start_filename|>html/singles.html<|end_filename|>
Singles
<p>
Black out some of the squares, in such a way that:
<ul><li>no number appears twice in any row or column
<li>no two black squares are adjacent
<li>the white squares form a single connected group (connections
along diagonals do not count).</ul>
<p>
Click in a square to black it out, and again to uncover it.
Right-click in a square to mark it with a circle, indicating that
you're sure it should <em>not</em> be blacked out.


<|start_filename|>sort.c<|end_filename|>
/*
 * Implement arraysort() defined in puzzles.h.
 *
 * Strategy: heapsort.
 */

#include <stddef.h>
#include <string.h>

#include "puzzles.h"

static void memswap(void *av, void *bv, size_t size)
{
    char t[4096];
    char *a = (char *)av, *b = (char *)bv;

    while (size > 0) {
        size_t thissize = size < sizeof(t) ? size : sizeof(t);

        memcpy(t, a, thissize);
        memcpy(a, b, thissize);
        memcpy(b, t, thissize);

        size -= thissize;
        a += thissize;
        b += thissize;
    }
}

#define PTR(i) ((char *)array + size * (i))
#define SWAP(i,j) memswap(PTR(i), PTR(j), size)
#define CMP(i,j) cmp(PTR(i), PTR(j), ctx)

#define LCHILD(i) (2*(i)+1)
#define RCHILD(i) (2*(i)+2)
#define PARENT(i) (((i)-1)/2)

static void downheap(void *array, size_t nmemb, size_t size,
                     arraysort_cmpfn_t cmp, void *ctx, size_t i)
{
    while (LCHILD(i) < nmemb) {
        /* Identify the smallest element out of i and its children. */
        size_t j = i;
        if (CMP(j, LCHILD(i)) < 0)
            j = LCHILD(i);
        if (RCHILD(i) < nmemb &&
            CMP(j, RCHILD(i)) < 0)
            j = RCHILD(i);

        if (j == i)
            return; /* smallest element is already where it should be */

        SWAP(j, i);
        i = j;
    }
}

void arraysort_fn(void *array, size_t nmemb, size_t size,
                  arraysort_cmpfn_t cmp, void *ctx)
{
    size_t i;

    if (nmemb < 2)
        return;                        /* trivial */

    /*
     * Stage 1: build the heap.
     *
     * Linear-time if we do it by downheaping the elements in
     * decreasing order of index, instead of the more obvious approach
     * of upheaping in increasing order. (Also, it means we don't need
     * the upheap function at all.)
     *
     * We don't need to downheap anything in the second half of the
     * array, because it can't have any children to swap with anyway.
     */
    for (i = PARENT(nmemb-1) + 1; i-- > 0 ;)
        downheap(array, nmemb, size, cmp, ctx, i);

    /*
     * Stage 2: dismantle the heap by repeatedly swapping the root
     * element (at index 0) into the last position and then
     * downheaping the new root.
     */
    for (i = nmemb-1; i > 0; i--) {
        SWAP(0, i);
        downheap(array, i, size, cmp, ctx, 0);
    }
}

#ifdef SORT_TEST

#include <stdlib.h>
#include <time.h>

int testcmp(const void *av, const void *bv, void *ctx)
{
    int a = *(const int *)av, b = *(const int *)bv;
    const int *keys = (const int *)ctx;
    return keys[a] < keys[b] ? -1 : keys[a] > keys[b] ? +1 : 0;
}

int resetcmp(const void *av, const void *bv)
{
    int a = *(const int *)av, b = *(const int *)bv;
    return a < b ? -1 : a > b ? +1 : 0;
}

int main(int argc, char **argv)
{
    typedef int Array[3723];
    Array data, keys;
    int iteration;
    unsigned seed;

    seed = (argc > 1 ? strtoul(argv[1], NULL, 0) : time(NULL));
    printf("Random seed = %u\n", seed);
    srand(seed);

    for (iteration = 0; iteration < 10000; iteration++) {
        int j;
        const char *fail = NULL;

        for (j = 0; j < lenof(data); j++) {
            data[j] = j;
            keys[j] = rand();
        }

        arraysort(data, lenof(data), testcmp, keys);

        for (j = 1; j < lenof(data); j++) {
            if (keys[data[j]] < keys[data[j-1]])
                fail = "output misordered";
        }
        if (!fail) {
            Array reset;
            memcpy(reset, data, sizeof(data));
            qsort(reset, lenof(reset), sizeof(*reset), resetcmp);
            for (j = 0; j < lenof(reset); j++)
                if (reset[j] != j)
                    fail = "output not permuted";
        }

        if (fail) {
            printf("Failed at iteration %d: %s\n", iteration, fail);
            printf("Key values:\n");
            for (j = 0; j < lenof(keys); j++)
                printf("  [%2d] %10d\n", j, keys[j]);
            printf("Output sorted order:\n");
            for (j = 0; j < lenof(data); j++)
                printf("  [%2d] %10d\n", data[j], keys[data[j]]);
            return 1;
        }
    }

    printf("OK\n");
    return 0;
}

#endif /* SORT_TEST */


<|start_filename|>html/loopy.html<|end_filename|>
Loopy
<p>
Form a single closed loop out of the grid edges, in such a way that
every numbered square has exactly that many of its edges included in
the loop.
<p>
Click on a grid edge to mark it as part of the loop (black), and
again to return to marking it as undecided (yellow). Right-click on
a grid edge to mark it as definitely not part of the loop (faint
grey), and again to mark it as undecided again.
<p>
When you have mastered the square grid, look in the Type menu for
many other types of tiling!


<|start_filename|>html/sixteen.html<|end_filename|>
Sixteen
<p>
Slide the grid squares around so that the numbers end up in
consecutive order from the top left corner.
<p>
Click on the arrows at the edges of the grid to move a row or column
left, right, up or down. The square that falls off the end of the
row comes back on the other end.


<|start_filename|>version.h<|end_filename|>
/*
 * This header file provides the version #define for a particular
 * build of Puzzles.
 *
 * When my automated build system does a full build, Buildscr
 * completely overwrites this file with information appropriate to
 * that build. The information _here_ is default stuff used for local
 * development runs of 'make'.
 */

#define VER "Unidentified build"


<|start_filename|>PSTCollectionView/Examples/DecorationViews/CollectionViewLayout.h<|end_filename|>
//
//  CollectionViewLayout.h
//  PSCollectionViewExample
//
//  Created by <NAME> on 7/03/13.
//

#import "PSTCollectionView.h"

@interface CollectionViewLayout : PSUICollectionViewFlowLayout

@end


<|start_filename|>html/signpost.html<|end_filename|>
Signpost
<p>
Connect all the squares together into a sequence, so that every
square's arrow points towards the square that follows it (though the
next square can be any distance away in that direction).

<p>
Left-drag from a square to the square that should follow it, or
right-drag from a square to the square that should precede it.

<p>
Left-drag a square off the grid to break all links to it. Right-drag
a square off the grid to break all links to it and everything else
in its connected chain.


<|start_filename|>PSTCollectionView/Examples/DecorationViews/ViewController.h<|end_filename|>
//
//  ViewController.h
//  PSPDFKit
//
//  Copyright (c) 2012 <NAME>. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "PSTCollectionView.h"

@interface ViewController : PSUICollectionViewController

@end


<|start_filename|>html/map.html<|end_filename|>
Map
<p>
Colour the map with four colours, so that no two adjacent regions
have the same colour. (Regions touching at only one corner do not
count as adjacent.) There is a unique colouring consistent with the
coloured regions you are already given.
<p>
Drag from a coloured region to a blank one to colour the latter the
same colour as the former. Drag from outside the grid into a region
to erase its colour. (You cannot change the colours of the regions
you are given at the start of the game.)
<p>
Right-drag from a coloured region to a blank one to add dots marking
the latter region as <em>possibly</em> the same colour as the
former, or to remove those dots again.


<|start_filename|>PSTCollectionView/Examples/DecorationViews/DecorationView.h<|end_filename|>
//
//  DecorationView.h
//  PSCollectionViewExample
//
//  Created by <NAME> on 7/03/13.
//

#import "PSTCollectionView.h"

@interface DecorationView : PSUICollectionReusableView

@end


<|start_filename|>PSTCollectionView/Examples/Basic/Cell.h<|end_filename|>
//
//  Cell.h
//  PSPDFKit
//
//  Copyright (c) 2012 <NAME>. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "PSTCollectionViewCell.h"

@interface Cell : PSUICollectionViewCell

@property (strong, nonatomic) UILabel* label;

@end


<|start_filename|>PSTCollectionView/Examples/SelectionDelegateExample/SelectionDelegateExample/AppDelegate.h<|end_filename|>
//
//  AppDelegate.h
//  SelectionDelegateExample
//
//  Created by <NAME> on 06/11/2012.
//  Copyright (c) 2012 <NAME>. All rights reserved.
//

#import <UIKit/UIKit.h>


@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UIViewController *viewController;

@end


<|start_filename|>html/untangle.html<|end_filename|>
Untangle
<p>
Move the points around so that none of the lines cross.
<p>
Click on a point and drag it to move it.


<|start_filename|>html/flood.html<|end_filename|>
Flood
<p>
Try to get the whole grid to be the same colour within the given
number of moves, by repeatedly flood-filling the top left corner in
different colours.
<p>
Click in a square to flood-fill the top left corner with that square's
colour.


<|start_filename|>html/tracks.html<|end_filename|>
Tracks
<p>
Complete the track from A to B so that the rows and
columns contain the same number of track segments as are indicated in the
clues to the top and right of the grid. There are only straight and
90-degree curved rail sections, and the track may not cross itself.
<p>
Left-click on an edge between two squares to add a track segment between
the two squares. Right-click on an edge to add a cross on the edge,
indicating no track is possible there.
<p>
Left-click in a square to add a colour indicator showing that you know the
square must contain a track, even if you don't know which edges it crosses
yet. Right-click in a square to add a cross indicating it contains no
track segment.
<p>
Left- or right-drag between squares to lay a straight line of is-track or
is-not-track indicators, useful for filling in rows or columns to match the
clue.


<|start_filename|>html/net.html<|end_filename|>
Net
<p>
Rotate the grid squares so that they all join up into a single
connected network with no loops.
<p>
Left-click in a square to rotate it anticlockwise. Right-click to
rotate it clockwise. Middle-click, or shift-left-click if you have
no middle mouse button, to lock a square once you think it is
correct (so you don't accidentally rotate it again); do the same
again to unlock it if you change your mind.
<p>
Squares connected to the middle square are lit up. Aim to light up
every square in the grid (not just the endpoint blobs).
<p>
When this gets too easy, select a 'wrapping' variant from the Type
menu to enable grid lines to run off one edge of the playing area
and come back on the opposite edge!


<|start_filename|>html/twiddle.html<|end_filename|>
Twiddle
<p>
Rotate square sections of the grid to arrange the squares into
numerical order starting from the top left.
<p>
In the basic game, you rotate a 2&times;2 square section. Left-click
in the centre of that section (i.e. on a corner point between four
squares) to rotate the whole section anticlockwise. Right-click to
rotate the section clockwise.
<p>
When you master the basic game, go to the Type menu to try it with
larger rotating groups (for a 3&times;3 group you must click in the
centre of a square to rotate the block around it). Or select the
'orientable' mode in which every square must end up the right way
round as well as in the right place. Or both!


<|start_filename|>html/flip.html<|end_filename|>
Flip
<p>
Try to light up all the squares in the grid by flipping combinations
of them.
<p>
Click in a square to flip it and some of its neighbours. The diagram
in each square indicates which other squares will flip.
<p>
Select one of the 'Random' settings from the Type menu for more
varied puzzles.


<|start_filename|>html/palisade.html<|end_filename|>
Palisade
<p>
Draw lines along the grid edges, in such a way that the grid is
divided into connected regions, all of the size shown in the status
line. Also, each square containing a number should have that many of
its edges drawn in.
<p>
Click on a grid edge to mark it as a division between regions (black),
and again to return to marking it as undecided (yellow). Right-click
on a grid edge to mark it as definitely not part of the loop (faint
grey), and again to mark it as undecided again.


<|start_filename|>PSTCollectionView/Examples/SelectionDelegateExample/SelectionDelegateExample/ImageGridCell.h<|end_filename|>
//
//  ImageGridCell.h
//  SelectionDelegateExample
//
//  Created by <NAME> on 06/11/2012.
//  Copyright (c) 2012 <NAME>. All rights reserved.
//

#include "UILabel+Highlight.h"

@interface ImageGridCell : PSUICollectionViewCell

@property (strong, nonatomic) IBOutlet UIImageView *image;
@property (strong, nonatomic) IBOutlet UILabel *label;

@end


<|start_filename|>PSTCollectionView/Examples/FlowLayoutNoNIB/FlowLayoutNoNIB/ViewController.h<|end_filename|>
//
//  ViewController.h
//  FlowLayoutNoNIB
//
//  Created by <NAME> on 2012.10.29.
//
//

#import <UIKit/UIKit.h>
#import "PSTCollectionView.h"

@interface ViewController : UIViewController <PSUICollectionViewDataSource, PSUICollectionViewDelegate>

@end


<|start_filename|>PSTCollectionView/Examples/FlowLayoutNoNIB/FlowLayoutNoNIB/FooterView.h<|end_filename|>
//
//  FooterView.h
//  FlowLayoutNoNIB
//
//  Created by <NAME> on 2012.10.29.
//
//

#import "PSTCollectionView.h"

@interface FooterView : PSUICollectionReusableView

@end


<|start_filename|>html/undead.html<|end_filename|>
Undead
<p>
Fill in every grid square which doesn't contain a mirror with either a
ghost, a vampire, or a zombie. The numbers round the grid edges show
how many monsters must be visible along your line of sight if you look
directly into the grid from that position, along a row or column.
Zombies are always visible; ghosts are only visible when reflected in
at least one mirror; vampires are only visible when not reflected in
any mirror.

<p>
To place a monster, click in a square to select it, then type the
monster's letter on the keyboard: G for a ghost, V for a vampire or Z
for a zombie. To erase a monster, click to select a square and then
press Backspace.
<p>
Right-click in a square and then type a letter to add or remove the
monster as a pencil mark, indicating monsters that you think
<em>might</em> go in that square.
<p>
Left-click on a clue to mark it as done (grey it out). To unmark a
clue as done, left-click on it again.


<|start_filename|>style.css<|end_filename|>
body {
    font-family: sans-serif;
}

h1 {
    font-size: 150%;
}

h2 {
    font-size: 120%;
}


<|start_filename|>html/pegs.html<|end_filename|>
Pegs
<p>
Jump one peg over another to remove the one you jumped over. Try to
remove all but one peg.
<p>
Drag a peg into an empty space to make a move. The target space must
be exactly two holes away from the starting peg, in an orthogonal
direction, and there must be a peg in the hole in between.


<|start_filename|>html/slant.html<|end_filename|>
Slant
<p>
Fill in a diagonal line in every grid square so that there are no
loops in the grid, and so that every numbered point has that many
lines meeting at it.
<p>
Left-click in a square to mark it with a <code>\</code>; right-click
to mark it with a <code>/</code>. Keep clicking in a square to
cycle it between <code>\</code>, <code>/</code> and empty.
