home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MAGAZINE / MISC / QBNWS301.ZIP / BALLS.ZIP / BALLS.BAS next >
Encoding:
BASIC Source File  |  1991-11-17  |  20.1 KB  |  339 lines

  1. '12BALL.BAS ... solves The 12 Ball Problem in QuickBASIC
  2. 'Copyright 1991 by Charles Graham, POB 58634, St. Louis, MO 63158
  3. 'All rights reserved
  4. '
  5. '-----------------------The 12 Ball Problem--------------------------
  6. 'You have a balance scale and 12 balls that look and feel identical.
  7. 'Eleven of the balls are the same weight. One of the balls is
  8. 'slightly heavier or lighter -- you don't know which -- than the
  9. 'other 11. Using only the balance scale and only for 3 weighings, you
  10. 'must determine which is the odd ball, and whether it is lighter or
  11. 'heavier.
  12. '--------------------------------------------------------------------
  13. '
  14. '-----------------------The logical solution-------------------------
  15. 'The 1st weighing is always 1 2 3 4 against 5 6 7 8.  If they
  16. 'balance, you know that balls 1-8 are equal and the odd ball must be
  17. 'in 9-12.  If they don't balance, you know that balls 9-12 are
  18. 'equal, and you know that either the light ball must be on the side
  19. 'that goes up, or the heavy ball must be on the side that goes down.
  20. '
  21. 'The 2nd weighing depends upon the results of the 1st weighing.
  22. 'If the 1st weighing was equal, you'd now weigh 3 of the suspect
  23. 'balls (9-12) against 3 of the known equal balls (1-8); for example,
  24. 'weigh 9 10 11 on the left against 1 2 3 on the right.  If the left
  25. 'side went down, we'd know that the odd ball was in 9 10 11 and that
  26. 'it was heavier.  If the left side went up, we'd know that the odd
  27. 'ball was in 9 10 11 and that it was lighter.  If both sides
  28. 'balanced, we'd know that the odd ball was ball 12, but we wouldn't
  29. 'know if it was lighter or heavier.
  30. '
  31. 'If the 1st weighing wasn't equal, you'd now weigh (on the left) 3
  32. 'of the balls originally on the left side in the 1st weighing, plus
  33. '1 of the balls originally on the right side in the 1st weighing,
  34. 'against (on the right) 3 of the known equal balls, plus the lone
  35. 'ball that was originally on the left in the 1st weighing but wasn't
  36. 'included on the left in the 2nd weighing.  For example, weigh 1 2 3
  37. '8 against 9 10 11 4.
  38. '
  39. 'If they balanced, you'd know that the odd ball was one of 5 6 7,
  40. 'and you'd know if it was lighter or heavier based on the outcome of
  41. 'the 1st weighing.
  42. '
  43. 'If they didn't balance, there would be several possibilities.  If
  44. 'the left side went in the same direction that it did on the 1st
  45. 'weighing, you'd know that the odd ball was in 1 2 3, and you'd know
  46. 'that it was lighter or heavier based on the results of the 1st
  47. 'weighing.  If the left side went in the opposite direction from
  48. 'that which it went on the 1st weighing, you'd know that the odd
  49. 'ball was 8 or 4, and was lighter or heavier based on which
  50. 'direction it went in both the 1st and 2nd weighings.
  51. '
  52. 'The 3rd weighing depends upon the results of the 1st 2 weighings.
  53. 'By the time you get here, one of three possible conditions will
  54. 'exist:  (1) you will know which is the odd ball but will not know
  55. 'if it's lighter or heavier, (2) you will know that the odd ball is
  56. 'one of two balls and know that if it's one of them, it's lighter,
  57. 'but if it's the other one, it's heavier, or (3) you will know that
  58. 'the odd ball is one of three balls and also know whether it's
  59. 'lighter or heavier.
  60. '
  61. 'In either of the 1st two cases, weigh the odd ball or (one of the
  62. 'two suspects) against a ball known to be equal.  In the 3rd case,
  63. 'weigh two of the three suspect balls against each other.
  64. '--------------------------------------------------------------------
  65. '
  66. '---------------------The QuickBASIC solution------------------------
  67. DIM ball(12), attribute$(12)                'Set up 12 balls and attributes
  68. RANDOMIZE TIMER                             'Seed the RND function
  69.                                             '
  70. begin:                                      '
  71. FOR x = 1 TO 12                             'Give each ball an initial
  72.     ball(x) = 1                             ' weight of 1 and an initial
  73.     attribute$(x) = " equal"                ' attribute of "equal"
  74. NEXT x                                      '
  75. oddball = INT(RND * 12) + 1                 'Pick the odd ball randomly
  76. IF RND < .5 THEN                            'Pick the odd ball's weight:
  77.     oddweight = .9                          ' a little less
  78. ELSE                                        ' or
  79.     oddweight = 1.1                         ' a little more
  80. END IF                                      ' than the others
  81. ball(oddball) = oddweight                   'Give the odd ball its odd weight
  82. COLOR 7, 0                                  'White on black
  83. CLS                                         'Clear the screen
  84. COLOR 15, 1                                 'Bright white on blue
  85. PRINT "QuickBASIC solves the 12 ball problem"'Whadda we doin' here?
  86. PRINT                                       'Skip a line
  87. COLOR 15, 1                                 'Bright white on blue
  88. PRINT "Procedure:                           "'Title for displaying weighings
  89. COLOR 14, 0                                 'Bright yellow on black
  90. GOSUB firstweigh                            'Weigh 'em once
  91. GOSUB secondweigh                           'Weigh 'em twice
  92. GOSUB thirdweigh                            'Weigh 'em thrice
  93. PRINT                                       'Skip a line
  94. COLOR 15, 1                                 'Bright white on blue
  95. PRINT "Results:                             "'Title for displaying weights
  96.                                             ' and attributes
  97. COLOR 14, 0                                 'Bright green on black
  98. PRINT "Ball", "Weight", "Attribute"         'Print column headings
  99. FOR x = 1 TO 12                             'Print the ball numbers,
  100.     IF ball(x) = 1 THEN                     ' their weights and attributes.
  101.         COLOR 11, 0                         ' Use light cyan for all but
  102.     ELSE                                    ' the odd ball.
  103.         COLOR 12, 0                         ' Use light red for it.
  104.     END IF                                  '
  105.     PRINT USING "###"; x;                   '
  106.     PRINT ,                                 '
  107.     PRINT USING " #.#"; ball(x);            '
  108.     LOCATE , 30                             '
  109.     IF attribute$(x) = " equal" THEN        '
  110.         COLOR 11, 0                         '
  111.     ELSE                                    '
  112.         COLOR 12, 0                         '
  113.     END IF                                  '
  114.     PRINT attribute$(x)                     '
  115. NEXT x                                      '
  116. COLOR 15, 1                                 'Bright red on blue
  117. PRINT                                       'Skip a line
  118. PRINT "ESCape ends -- any other key repeats."; 'Whadda we do now?
  119. a$ = ""                                     'Initialize a$ to null
  120. WHILE a$ = ""                               'While a$ is null
  121.     a$ = INKEY$                             ' Try to capture a key press
  122. WEND                                        '  as long as a$ is null
  123. IF a$ = CHR$(27) THEN                       'ESCape pressed?
  124.     COLOR 7, 0                              ' White on black
  125.     CLS                                     ' Clear the screen
  126.     END                                     ' T-T-That's all folks!
  127. ELSE                                        'Some other key?
  128.     GOTO begin                              ' Crank 'er up again
  129. END IF                                      '
  130.                                             '
  131. firstweigh:                                 '
  132. lside$ = "1 2 3 4"                          'Set display for left side
  133. rside$ = "5 6 7 8"                          'Set display for right side
  134.                                             'Next line:  do sides balance?
  135. IF ball(1) + ball(2) + ball(3) + ball(4) = ball(5) + ball(6) + ball(7) + ball(8) THEN
  136.     FOR x = 9 TO 12                         'Set attribute for balls
  137.         attribute$(x) = "unequal"           ' 9 through 12 to unequal
  138.     NEXT x                                  '
  139.     firstresult = 1                         'Capture result
  140.     operator$ = " = "                       'Set display for operator
  141. ELSE                                        'Next line:  left side heavier?
  142.     IF ball(1) + ball(2) + ball(3) + ball(4) > ball(5) + ball(6) + ball(7) + ball(8) THEN
  143.         FOR x = 1 TO 4                      'Set attribute for balls
  144.             attribute$(x) = "heavier"       ' 1 through 4 to heavier
  145.         NEXT x                              '
  146.         FOR x = 5 TO 8                      'Set attribute for balls
  147.             attribute$(x) = "lighter"       ' 5 through 8 to lighter
  148.         NEXT x                              '
  149.         operator$ = " > "                   'Set display for operator
  150.     ELSE                                    'OK.  Right side is heavier.
  151.         FOR x = 1 TO 4                      'Set attribute for balls
  152.             attribute$(x) = "lighter"       ' 1 through 4 to lighter
  153.         NEXT x                              '
  154.         FOR x = 5 TO 8                      'Set attribute for balls
  155.             attribute$(x) = "heavier"       ' 5 through 8 to heavier
  156.         NEXT x                              '
  157.         operator$ = " < "                   'Set display for operator
  158.     END IF                                  '
  159.     firstresult = 2                         'Capture result
  160. END IF                                      '
  161.                                             'Next line:  display 1st weighing
  162. PRINT "1st weighing is   " + lside$ + operator$ + rside$
  163. RETURN                                      '
  164.                                             '
  165. secondweigh:                                '
  166. IF firstresult = 1 THEN                     'If odd ball is 9, 10, 11 or 12
  167.     lside$ = "9 10 11"                      ' Set display for left side
  168.     rside$ = "1 2 3"                        ' Set display for right side
  169.                                             ' Next line:  are they equal?
  170.     IF ball(9) + ball(10) + ball(11) = ball(1) + ball(2) + ball(3) THEN
  171.         FOR x = 9 TO 11                     '  Set attribute for balls 9 - 11
  172.             attribute$(x) = " equal"        '
  173.         NEXT x                              '
  174.         secondresult = 1                    '  Capture result
  175.         operator$ = " = "                   '  Set display for operator
  176.     ELSE                                    ' If 9 - 11 <> 1 - 3
  177.                                             '  Next line:  left side heavier?
  178.         IF ball(9) + ball(10) + ball(11) > ball(1) + ball(2) + ball(3) THEN
  179.             FOR x = 9 TO 11                 '   Set attribute for balls 9 - 11
  180.                 attribute$(x) = "heavier"   '
  181.             NEXT x                          '
  182.             operator$ = " > "               '   Set display for operator
  183.         ELSE                                '  Right side heavier
  184.             FOR x = 9 TO 11                 '   Set attribute for balls 9 - 11
  185.                 attribute$(x) = "lighter"   '
  186.             NEXT x                          '
  187.             operator$ = " < "               '   Set display for operator
  188.         END IF                              '
  189.         secondresult = 3                    '   Capture result
  190.         attribute$(12) = " equal"           '   Set attribute for ball 12
  191.     END IF                                  '
  192. ELSE                                        'If odd ball is in 1 - 8
  193.     lside$ = "1 2 3 8"                      ' Set display for left side
  194.     rside$ = "9 10 11 4"                    ' Set display for right side
  195.                                             ' Next line: 1 2 3 8 = 9 10 11 4?
  196.     IF ball(1) + ball(2) + ball(3) + ball(8) = ball(9) + ball(10) + ball(11) + ball(4) THEN
  197.         FOR x = 1 TO 4                      '  Set attribute for balls 1 - 4
  198.             attribute$(x) = " equal"        '
  199.         NEXT x                              '
  200.         attribute$(8) = " equal"            '  Set attribute for ball 8
  201.         secondresult = 3                    '  Capture result
  202.         operator$ = " = "                   '  Set display for operator
  203.     ELSE                                    ' 1 2 3 8 <> 9 10 11 4
  204.         FOR x = 5 TO 7                      '  Set attribute for balls 5 - 7
  205.             attribute$(x) = " equal"        '
  206.         NEXT x                              '
  207.                                             '  Next line: 1 2 3 8 > 9 10 11 4?
  208.         IF ball(1) + ball(2) + ball(3) + ball(8) > ball(9) + ball(10) + ball(11) + ball(4) THEN
  209.             IF attribute$(8) = "heavier" THEN ' Do we know ball 8 is heavier?
  210.                 FOR x = 1 TO 3              '    Set attribute for balls 1 - 3
  211.                     attribute$(x) = " equal"'
  212.                 NEXT x                      '
  213.                 secondresult = 2            '    Capture result
  214.             ELSE                            '   Ball 8 is not heavier
  215.                 attribute$(4) = " equal"    '    Set attribute for ball 4
  216.                 attribute$(8) = " equal"    '    Set attribute for ball 8
  217.                 secondresult = 3            '    Capture result
  218.             END IF                          '
  219.             operator$ = " > "               '   Set display for operator
  220.         ELSE                                '  1 2 3 8 < 9 10 11 4
  221.             IF attribute$(8) = "heavier" THEN ' Do we know ball 8 is heavier?
  222.                 attribute$(4) = " equal"    '    Set attribute for ball 4
  223.                 attribute$(8) = " equal"    '    Set attribute for ball 8
  224.                 secondresult = 3            '    Capture result
  225.             ELSE                            '   Ball 8 is not heavier
  226.                 FOR x = 1 TO 3              '    Set attribute for balls 1 - 3
  227.                     attribute$(x) = " equal"'
  228.                 NEXT x                      '
  229.                 secondresult = 2            '    Capture result
  230.             END IF                          '
  231.             operator$ = " < "               '   Set display for operator
  232.         END IF                              '
  233.     END IF                                  '
  234. END IF                                      '
  235.                                             'Next line:  display 2nd weighing
  236. PRINT "2nd weighing is   " + lside$ + operator$ + rside$
  237. RETURN                                      '
  238.                                             '
  239. thirdweigh:                                 '
  240. IF secondresult = 1 THEN                    '9 10 11 = 1 2 3?
  241.     FOR x = 1 TO 12                         ' Find the odd ball and one
  242.         IF attribute$(x) = "unequal" THEN   '  that's not odd
  243.             odd = x                         '
  244.         ELSE                                '
  245.             notodd = x                      '
  246.         END IF                              '
  247.     NEXT x                                  '
  248.     lside$ = RIGHT$(STR$(odd), LEN(STR$(odd)) - 1)'Set display for left side
  249.     rside$ = RIGHT$(STR$(notodd), LEN(STR$(notodd)) - 1)'Set display right "
  250.     IF ball(odd) > ball(notodd) THEN        ' Odd ball heavier?
  251.         attribute$(odd) = "heavier"         '  Set attribute for odd ball
  252.         operator$ = " > "                   '  Set display for operator
  253.     ELSE                                    ' Odd ball lighter?
  254.         attribute$(odd) = "lighter"         '  Set attribute for odd ball
  255.         operator$ = " < "                   '  Set display for operator
  256.     END IF                                  '
  257. ELSE                                        '
  258.     IF secondresult = 2 THEN                ' 1 2 3 8 <> 9 10 11 4?
  259.         odd1 = 0                            '  Initialize 2 possibilities
  260.         odd2 = 0                            '
  261.         FOR x = 1 TO 12                     '  Find the 2 possible odd balls,
  262.             IF attribute$(x) <> " equal" THEN '
  263.                 IF odd1 = 0 THEN            '
  264.                     odd1 = x                '
  265.                 ELSE                        '
  266.                     odd2 = x                '
  267.                 END IF                      '
  268.             ELSE                            '
  269.                 notodd = x                  '   and one that isn't
  270.             END IF                          '
  271.         NEXT x                              '
  272.         rside$ = RIGHT$(STR$(notodd), LEN(STR$(notodd)) - 1)'Set Rside display
  273.         IF ball(odd1) = ball(notodd) THEN   '  If the 1st possible odd ball
  274.             attribute$(odd1) = " equal"     '   isn't odd, note it
  275.             lside$ = RIGHT$(STR$(odd1), LEN(STR$(odd1)) - 1)'Set Lside display
  276.         ELSE                                '  If the 2nd possible odd ball
  277.             attribute$(odd2) = " equal"     '   isn't odd, note it
  278.             lside$ = RIGHT$(STR$(odd2), LEN(STR$(odd2)) - 1)'Set Lside display
  279.         END IF                              '
  280.         operator$ = " = "                   '  Set display for operator
  281.     ELSE                                    ' You've narrowed it down to 3
  282.                                             '  possibilities and you know
  283.                                             '  whether the odd ball is heavier
  284.                                             '  or lighter
  285.         odd1 = 0                            '   Initialize 3 possibilities
  286.         odd2 = 0                            '
  287.         odd3 = 0                            '
  288.         FOR x = 1 TO 12                     '   Find the 3 possible odd balls,
  289.             IF attribute$(x) <> " equal" THEN '
  290.                 IF odd1 = 0 THEN            '
  291.                     odd1 = x                '
  292.                 ELSE                        '
  293.                     IF odd2 = 0 THEN        '
  294.                         odd2 = x            '
  295.                     ELSE                    '
  296.                         odd3 = x            '
  297.                     END IF                  '
  298.                 END IF                      '
  299.             ELSE                            '
  300.                 notodd = x                  '    and one that isn't
  301.             END IF                          '
  302.         NEXT x                              '
  303.         lside$ = RIGHT$(STR$(odd1), LEN(STR$(odd1)) - 1)'Set display for Lside
  304.         rside$ = RIGHT$(STR$(odd2), LEN(STR$(odd2)) - 1)'Set display for Rside
  305.         IF ball(odd1) = ball(odd2) THEN     '   If the 1st and 2nd possibili-
  306.             attribute$(odd1) = " equal"     '    ties aren't odd, note it
  307.             attribute$(odd2) = " equal"     '
  308.             operator$ = " = "               '   Set display for operator
  309.         ELSE                                '
  310.             IF ball(odd1) > ball(odd2) THEN '   If odd1 is heavier than odd2
  311.                 IF attribute$(odd1) = "heavier" THEN 'and it's supposed to be,
  312.                     attribute$(odd2) = " equal"'  mark odd2 as equal
  313.                 ELSE                        '    else
  314.                     attribute$(odd1) = " equal"'  mark odd1 as equal
  315.                 END IF                      '
  316.                 operator$ = " > "           '    Set display for operator
  317.             ELSE                            '
  318.                 IF attribute$(odd1) = "lighter" THEN 'If odd 1 is lighter than
  319.                     attribute$(odd2) = " equal"' odd2 and it's supposed to be,
  320.                 ELSE                        '    mark odd2 as equal, else
  321.                     attribute$(odd1) = " equal"' mark odd1 as equal
  322.                 END IF                      '
  323.                 operator$ = " < "           '    Set display for operator
  324.             END IF                          '
  325.             attribute$(odd3) = " equal"     '    Set attribute of remaining
  326.                                             '     not-odd possibility
  327.         END IF                              '
  328.     END IF                                  '
  329. END IF                                      '
  330. IF lside$ = "12" THEN                       'Adjust spacing for display
  331.     spacer$ = ""                            '
  332. ELSE                                        '
  333.     spacer$ = " "                           '
  334. END IF                                      '
  335.                                             'Next line:  display 3rd weighing
  336. PRINT "3rd weighing is        " + spacer$ + lside$ + operator$ + rside$
  337. RETURN                                      'T-T-That's all folks
  338.  
  339.