Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

 
 
Thread Tools Display Modes
Prev Previous Post in Thread   Next Post in Thread Next
Old Dec 8th, 2007, 3:23 PM   #1
Sane
Banned
 
Sane's Avatar
 
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 2,101
Rep Power: 6 Sane will become famous soon enough
Send a message via MSN to Sane
Mastermind Algorithm

I stumbled across a very difficult programming challenge.

The challenge is... given a set of clues and results from the game "Mastermind", determine the answer, and whether or not there's many or no possible answers.

For example:

9793 0/1
2384 0/2
6264 0/1
3383 1/0
2795 0/0
0218 1/0

The number 3411 is the only one that satisfies the rules.

An explanation of the challenge, and the rules of Mastermind are here:
http://cemc.math.uwaterloo.ca/ccc/1996/21b-prob.html

Now, it's not a difficult challenge at all if you brute force it. Go through every number from 0000 to 9999 and see which ones satisfy all of the clues.

But... that's a terribly ugly algorithm. Very bad complexity. There must be a way to deduce an answer more logically? Thinking about it sends my brain in wild directions though. Seems very difficult.

Have any ideas?

This is my brute force method:

safe.in
4
6
9793 0/1
2384 0/2
6264 0/1
3383 1/0
2795 0/0
0218 1/0
1
1234 4/0
1
1234 2/2
2
6428 3/0
1357 3/0

1996_2.1b.c
c Syntax (Toggle Plain Text)
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. void isMatch(char *with, char *against, int *r_1, int *r_2) {
  5. int i, j;
  6. *r_1 = 0;
  7. *r_2 = 0;
  8. int used[4];
  9. int matched[4];
  10.  
  11. for (i=0; i<4; i++)
  12. if (with[i] == against[i]) {
  13. (*r_1)++;
  14. used[i] = 1; matched[i] = 1;
  15. }
  16. else {
  17. used[i] = 0; matched[i] = 0;
  18. }
  19.  
  20. for (i=0; i<4; i++)
  21. for (j=0; j<4; j++)
  22. if (i!=j && !matched[j] && !used[i] && with[i] == against[j]) {
  23. // used[i] = 1; // Redundant once we break;
  24. matched[j] = 1;
  25. (*r_2)++;
  26. break;
  27. }
  28. }
  29.  
  30. int main() {
  31. int cases, n, i, r_1, r_2, end;
  32. char against[10][5];
  33. char with[5], hasMatch[5];
  34. int exact[10], moved[10];
  35. with[4] = 0;
  36.  
  37. freopen("safe.in", "rt", stdin);
  38. freopen("safe.out", "wt", stdout);
  39.  
  40. scanf("%d\n", &cases);
  41. while (cases--) {
  42. scanf("%d\n", &n);
  43. for (i=0; i<n; i++) scanf("%s %d/%d", against[i], &exact[i], &moved[i]);
  44.  
  45. hasMatch[0] = 0;
  46. end = 0;
  47.  
  48. for (with[0]='0'; with[0]<='9' && !end; with[0]++) {
  49. for (with[1]='0'; with[1]<='9' && !end; with[1]++) {
  50. for (with[2]='0'; with[2]<='9' && !end; with[2]++) {
  51. for (with[3]='0'; with[3]<='9' && !end; with[3]++) {
  52.  
  53. for (i=0; i<n; i++) {
  54. isMatch(with, against[i], &r_1, &r_2);
  55. if (exact[i] != r_1 || moved[i] != r_2) {
  56. i--; break;
  57. }
  58. }
  59.  
  60. if (i==n) {
  61. if (hasMatch[0])
  62. end = 1; // already a match
  63. else
  64. strcpy(hasMatch, with); // new match
  65. }
  66.  
  67. }
  68. }
  69. }
  70. }
  71.  
  72. if (end)
  73. printf("indeterminate\n");
  74. else if (hasMatch[0])
  75. printf("%s\n", hasMatch);
  76. else
  77. printf("impossible\n");
  78. }
  79.  
  80. return 0;
  81. }

safe.out
3411
1234
indeterminate
impossible

Last edited by Sane; Dec 8th, 2007 at 3:46 PM.
Sane is offline   Reply With Quote
 

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes