Newsgroups: comp.lang.prolog
Path: cantaloupe.srv.cs.cmu.edu!europa.chnt.gtegsc.com!news.sprintlink.net!qns3.qns.com!news.ecn.uoknor.edu!munnari.oz.au!cs.mu.OZ.AU!munta.cs.mu.OZ.AU!fjh
From: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Subject: Re: speed of prolog
Message-ID: <9516822.5774@mulga.cs.mu.OZ.AU>
Sender: news@cs.mu.OZ.AU (CS-Usenet)
Organization: Computer Science, University of Melbourne, Australia
References: <3pam2e$9jh@chuangtsu.acns.carleton.edu> <3pptgj$6do@percy.cs.bham.ac.uk> <D90wt4.32n@cee.hw.ac.uk> <9514714.11493@mulga.cs.mu.OZ.AU> <D9rCu0.Ips@dcc.uchile.cl>
Date: Sat, 17 Jun 1995 12:18:56 GMT
Lines: 119

cc41a@dcc.uchile.cl (Lenguajes de Programacion) writes:

>  Ok, Fergus, Let us say we will make a program, you in C++ and I in Prolog,
>that puts 8 queens in a chess board in a way that no one threatens each other.
>  As you could make a static choice (having an array with the solution and
>displaying it), let us make a program that receives the number of queens (and
>obviously the number of squares in the board would be n*n).
>
>  Do you think you can post it tomorrow, so anyone can test it?

I'll post it today (although with the usual net time-warp, I suspect
that my "today" may be quite a while after your "tomorrow" - I've been
away on a holiday ;-)

>  We will time the program from the moment you enter the number until the moment
>it displays a solution to the problem.
>  If you want, we can display the answer in the same way. I'm going to display
>in which row will be the queen at row i.
>  For example, for a board of 4*4 => 4 queens:
>  Solution:  [3,1,4,2]
>
>  I hope you accept the deal.

Sounds very fair.  Here's my program.
It can find a solution to the 21 queen problem in less than a tenth
of a second on our super-sparc.  I think that should give you a run
for your money ;-)

-- cut here -----------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/* Depending on the architecture, this might be more efficient
   if `a' and `n' were global variables */

enum { FALSE = 0, TRUE = 1 };

static long start_time;

static int safe(int a[], int n, int i)
{
	int j;
	int val = a[i];
	for (j = 0; j < i; j++) {
		int diff = a[j] - val;
		if (diff == j - i || diff == i - j) {
			return FALSE;
		}
	}
	return TRUE;
}

static void search(int a[], int n, int m)
{
        int i;

        if (m == n) {
		printf("[%d", a[0] + 1);
		for (i = 1; i < n; ++i) {
			printf(", %d", a[i] + 1);
		}
		printf("]\n");
		printf("Time for %d queens: %.3f seconds\n", n,
			(clock() - start_time) * 1.0 / CLOCKS_PER_SEC);
		exit(0);
        } else {
		for (i = m; i < n; i++) {
			int tmp;
			tmp = a[i], a[i] = a[m], a[m] = tmp;
			if (safe(a, n, m)) {
				search(a, n, m+1);
			}
			tmp = a[i], a[i] = a[m], a[m] = tmp;
		}
	}
}

static int *init(int n)
{
	int *a;
	int i;

	a = (int *) malloc(n * sizeof(int));
	if (a == NULL) {
		fprintf(stderr, "Memory allocation failed\n");
		exit(1);
	}
	for (i = 0; i < n; i++) {
		a[i] = i;
	}
	return a;
}

int main(void) {
	int *a;
	int n;

	printf("How many queens? ");
	fflush(stdout);
	if (scanf("%d", &n) != 1 || n <= 0) {
		fprintf(stderr, "Invalid input\n");
		exit(1);
	}
	start_time = clock();
	a = init(n);
    	search(a, n, 0);
	printf("No solution\n");
	printf("Time for %d queens: %.3f seconds\n", n,
		(clock() - start_time) * 1.0 / CLOCKS_PER_SEC);
	free(a);
	return 0;
}
-- cut here -----------------------------------------------------------------

-- 
Fergus Henderson
fjh@cs.mu.oz.au
http://www.cs.mu.oz.au/~fjh
