ListNode *reverseKGroup(ListNode *head, int k)
	{
		if (head == NULL || head->next == NULL || k <= 1)
			return head;

		ListNode *currStart, *currEnd;
		ListNode *nextStart, *prevEnd;

		ListNode emptyNode(0);
		prevEnd = &emptyNode;
		currStart = head;

		while (currStart)
		{
			currEnd = currStart->next;
			for (int i = 2; currEnd && i < k; i++)
				currEnd = currEnd->next;

			if (currEnd == NULL) break;
			nextStart = currEnd->next;

			reverseGroup(currStart, k);

			prevEnd->next = currEnd;
			prevEnd = currStart;

			currStart->next = nextStart;
			currStart = nextStart;
		}

		return emptyNode.next ? emptyNode.next : head;
	}
Example #2
0
Node *HashLife::emptyNode(size_t depth)
{
	if (depth >= static_cast<size_t>(m_emptyNode.size()))
	{
		Node *sub = emptyNode(depth - 1);
		Node *node = m_nodeHash->get(sub, sub, sub, sub);
		m_emptyNode.push_back(node);
		return node;
	}
	else
		return m_emptyNode[depth];
}
Example #3
0
void HashLife::expand()
{
	Node *e = emptyNode(m_depth - 1);
	Node *nul = m_nodeHash->get(e, e, e, m_root->ul);
	Node *nur = m_nodeHash->get(e, e, m_root->ur, e);
	Node *ndl = m_nodeHash->get(e, m_root->dl, e, e);
	Node *ndr = m_nodeHash->get(m_root->dr, e, e, e);
	m_root = m_nodeHash->get(nul, nur, ndl, ndr);
	BigInteger offset = BigInteger::exp2(m_depth - 1);
	m_x -= offset;
	m_y -= offset;
	m_depth++;
}
Example #4
0
void HashLife::run()
{
	QTime timer;
	timer.start();
	m_running = true;
	m_writeLock->lock();
	m_readLock->lock();
	while (m_increment + 2 > m_depth)
		expand();
	Node *e = emptyNode(m_depth - 2);
	// Test boundary to be empty, or we have to expand() to guarantee the result fits in the boundary
	// This requires m_depth to be at least Block::DEPTH + 2
	if ((m_root->ul->ul != e || m_root->ul->ur != e || m_root->ul->dl != e)
		|| (m_root->ur->ul != e || m_root->ur->ur != e || m_root->ur->dr != e)
		|| (m_root->dl->ul != e || m_root->dl->dl != e || m_root->dl->dr != e)
		|| (m_root->dr->ur != e || m_root->dr->dl != e || m_root->dr->dr != e))
		expand();
	// To make the depth of RESULT equal to m_depth, we first expand the universe
	// This is nearly identical to code in expand() except we don't need to touch m_x and m_y
	e = emptyNode(m_depth - 1);
	Node *nul = m_nodeHash->get(e, e, e, m_root->ul);
	Node *nur = m_nodeHash->get(e, e, m_root->ur, e);
	Node *ndl = m_nodeHash->get(e, m_root->dl, e, e);
	Node *ndr = m_nodeHash->get(m_root->dr, e, e, e);
	Node *nroot = m_nodeHash->get(nul, nur, ndl, ndr);
	m_readLock->unlock();
	Node *new_root = runNode(nroot, m_depth + 1);
	m_readLock->lock();
	m_root = new_root;
	m_readLock->unlock();
	m_writeLock->unlock();
	m_generation += BigInteger::exp2(m_increment);
	m_running = false;
	emit gridChanged();
	qDebug() << timer.elapsed();
}
Example #5
0
HashLife::HashLife()
	: m_readLock(new QMutex()), m_writeLock(new QMutex()), m_running(false),
      m_blockHash(new HashTable<Block, uchar>()), m_nodeHash(new HashTable<Node, Node *>()),
	  m_x(0), m_y(0), m_generation(0)
{
	m_increment = 0; // TODO
	Node *e = reinterpret_cast<Node *>(m_blockHash->get(0, 0, 0, 0));
	m_emptyNode.resize(Block::DEPTH + 1);
	for (size_t i = 0; i < Block::DEPTH; i++)
		m_emptyNode[i] = NULL;
	m_emptyNode[Block::DEPTH] = e;
	m_root = emptyNode(Block::DEPTH + 1);
	m_depth = Block::DEPTH + 1;
	expand(); // run() requires m_depth >= Block::DEPTH + 2
}
Example #6
0
void HashLife::paint(CanvasPainter *painter, const BigInteger &x, const BigInteger &y, int w, int h, size_t scale)
{
	m_readLock->lock();
	treePaint<HashLife, Block, Node>(this, painter, x, y, w, h, scale, m_x, m_y, m_depth, m_root, emptyNode(m_depth));
	m_readLock->unlock();
}