September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
8
Task/24-game/APL/24-game.apl
Normal file
8
Task/24-game/APL/24-game.apl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
tfgame←{⎕IO←1
|
||||
⎕←d←?⍵⍴9
|
||||
i←⍞
|
||||
u[⍋u←{⍎¨⍣(0≠≢⍵)⊢⍵}(i∊'1234567890')⊆i]≢d[⍋d]:'nope'
|
||||
~∧/((~b←i∊'1234567890')/i)∊'+-×÷()':'nope'
|
||||
24≠⍎i:'nope'
|
||||
'Yeah!'
|
||||
}
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
@set @dummy=0 /*
|
||||
|
||||
::24.bat
|
||||
::
|
||||
::Batch file implemetnation of the 24 Game where a player is given four random
|
||||
::digits n, where 1 <= n <= 9, and needs to provide a simple arithmetic
|
||||
::operation that does evaluate to 24.
|
||||
::
|
||||
::Please open the Batch File Directly to play...
|
||||
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
title The 24 Game Batch File
|
||||
cls
|
||||
echo.
|
||||
echo The 24 Game
|
||||
echo.
|
||||
echo Given four digits, provide a simple arithmetic expression
|
||||
echo that evaluates to 24 using +,-,*,/.
|
||||
echo.
|
||||
echo Reminders (Please read):
|
||||
echo.
|
||||
echo 1. Type 'new' (NO quotes) - Fresh digits
|
||||
echo 2. Type 'show' (NO quotes) - Show digits
|
||||
echo 3. Type 'exit' (NO quotes) - Quit game
|
||||
echo 4. Combining two digits as one number is NOT allowed.
|
||||
echo 5. Use each digit only ONCE in expressions.
|
||||
echo 6. Use ONLY the Parentheses as the groupting symbols.
|
||||
echo 7. Do not make any digit Negative.
|
||||
echo.
|
||||
echo Why do someone wants to not follow the reminders? To trick me, right? ;)
|
||||
echo.
|
||||
pause
|
||||
|
||||
:NEW
|
||||
set TRY=0
|
||||
|
||||
::Get four random digits
|
||||
set /a "DIGIT_1=%RANDOM%%%9+1"
|
||||
set /a "DIGIT_2=%RANDOM%%%9+1"
|
||||
set /a "DIGIT_3=%RANDOM%%%9+1"
|
||||
set /a "DIGIT_4=%RANDOM%%%9+1"
|
||||
|
||||
cls
|
||||
echo.
|
||||
echo The 24 Game
|
||||
echo.
|
||||
goto SHOW
|
||||
|
||||
::Main Program Loop
|
||||
:MAIN
|
||||
set /a TRY+=1
|
||||
set ANSWER=
|
||||
set "TMP_DIGIT_1=%DIGIT_1%"
|
||||
set "TMP_DIGIT_2=%DIGIT_2%"
|
||||
set "TMP_DIGIT_3=%DIGIT_3%"
|
||||
set "TMP_DIGIT_4=%DIGIT_4%"
|
||||
|
||||
::Prompt for an answer
|
||||
echo.
|
||||
set /p ANSWER="Try %TRY%: "
|
||||
|
||||
::Determine if the player inputs a "good" try (input validation...)
|
||||
if /i "!ANSWER!"=="NEW" goto NEW
|
||||
if /i "!ANSWER!"=="SHOW" goto SHOW
|
||||
if /i "!ANSWER!"=="EXIT" goto ABORT
|
||||
|
||||
set ANSWER=!ANSWER: =!
|
||||
set DIGITS_USED=0&set COUNTER=0
|
||||
|
||||
:LOOP
|
||||
set CURR_DIGIT=!ANSWER:~%COUNTER%,1!
|
||||
if "!CURR_DIGIT!"=="%TMP_DIGIT_1%" (set "TMP_DIGIT_1=X"&goto NEXTCHARSCAN1)
|
||||
if "!CURR_DIGIT!"=="%TMP_DIGIT_2%" (set "TMP_DIGIT_2=X"&goto NEXTCHARSCAN1)
|
||||
if "!CURR_DIGIT!"=="%TMP_DIGIT_3%" (set "TMP_DIGIT_3=X"&goto NEXTCHARSCAN1)
|
||||
if "!CURR_DIGIT!"=="%TMP_DIGIT_4%" (set "TMP_DIGIT_4=X"&goto NEXTCHARSCAN1)
|
||||
if "!CURR_DIGIT!"=="" goto ALMOST
|
||||
if "!CURR_DIGIT!"==")" goto SCANMORE
|
||||
if "!CURR_DIGIT!"=="(" goto SCANMORE
|
||||
if "!CURR_DIGIT!"=="+" goto NEXTCHARSCAN2
|
||||
if "!CURR_DIGIT!"=="-" goto DONTALLOWNEGATIVES
|
||||
if "!CURR_DIGIT!"=="*" goto NEXTCHARSCAN2
|
||||
if "!CURR_DIGIT!"=="/" goto NEXTCHARSCAN2
|
||||
goto ERROR_ICHAR_FOUND
|
||||
|
||||
:NEXTCHARSCAN1
|
||||
set /a NEXT=%COUNTER%+1
|
||||
set NEXT_CHAR=!ANSWER:~%NEXT%,1!
|
||||
for /l %%w in (1,1,9) do (
|
||||
if "!NEXT_CHAR!"=="%%w" goto ERROR_POSITION
|
||||
)
|
||||
goto :SCANMORE
|
||||
:DONTALLOWNEGATIVES
|
||||
set /a NEXT=%COUNTER%-1
|
||||
if "%NEXT%"=="-1" goto ERROR_NEGA
|
||||
set NEXT_CHAR=!ANSWER:~%NEXT%,1!
|
||||
for /l %%z in (1,1,9) do (
|
||||
if "!NEXT_CHAR!"=="%%z" goto NEXTCHARSCAN2
|
||||
)
|
||||
if "!NEXT_CHAR!"=="(" goto ERROR_NEGA
|
||||
if "!NEXT_CHAR!"==")" goto NEXTCHARSCAN2
|
||||
goto ERROR_NEGA
|
||||
:NEXTCHARSCAN2
|
||||
set /a NEXT=%COUNTER%+1
|
||||
set NEXT_CHAR=!ANSWER:~%NEXT%,1!
|
||||
for %%y in (+,-,/) do (
|
||||
if "!NEXT_CHAR!"=="%%y" goto ERROR_TRICK
|
||||
)
|
||||
:SCANMORE
|
||||
set /a "COUNTER+=1"&goto LOOP
|
||||
|
||||
:ALMOST
|
||||
if not "%TMP_DIGIT_1%%TMP_DIGIT_2%%TMP_DIGIT_3%%TMP_DIGIT_4%"=="XXXX" goto ERROR_CHARS
|
||||
::(SIGH) Input passed... Now, calculate and evaluate result
|
||||
set "RESULT="
|
||||
for /f "usebackq delims=" %%x in (`cscript //nologo //e:jscript "%~f0" "%ANSWER%" 2^>nul`) do set RESULT=%%x
|
||||
::Wait... Input is STILL erroneous???
|
||||
if "%RESULT%"=="" goto ERROR_SYNTAX
|
||||
::YES!!! Correct Expression???
|
||||
if "%RESULT%"=="24" goto END
|
||||
|
||||
::The Outputs
|
||||
|
||||
echo Wrong Answer [%RESULT% is not equal to 24.]&goto MAIN
|
||||
:ERROR_CHARS
|
||||
echo Invalid input [Please use all the digits above ONCE.]&goto MAIN
|
||||
:ERROR_ICHAR_FOUND
|
||||
echo Invalid input [An invalid character is found... C'mon...]&goto MAIN
|
||||
:ERROR_SYNTAX
|
||||
echo Invalid input [Syntax Error... Please answer seriously... I'm begging you...]&goto MAIN
|
||||
:ERROR_POSITION
|
||||
echo Invalid input [Sorry, digit concatenation is not allowed.]&goto MAIN
|
||||
:ERROR_TRICK
|
||||
echo Invalid input [Are you Playing the Game Seriously?]&goto MAIN
|
||||
:ERROR_NEGA
|
||||
echo Invalid input [Do not Make any Digit Negative.]&goto MAIN
|
||||
:SHOW
|
||||
echo Given digits: %DIGIT_1% %DIGIT_2% %DIGIT_3% %DIGIT_4%&goto MAIN
|
||||
:END
|
||||
echo Correct Input [Congratulations^^!]
|
||||
echo.
|
||||
echo Press any char key for a new game, or close this window to exit...
|
||||
pause>nul
|
||||
goto NEW
|
||||
:ABORT
|
||||
echo.
|
||||
exit
|
||||
::*/
|
||||
|
||||
WScript.echo(eval(WScript.arguments(0)));
|
||||
|
|
@ -1,96 +1,95 @@
|
|||
#define system.
|
||||
#define system'routines.
|
||||
#define system'collections.
|
||||
#define system'dynamic.
|
||||
#define extensions.
|
||||
import system'routines.
|
||||
import system'collections.
|
||||
import system'dynamic.
|
||||
import extensions.
|
||||
|
||||
#class ExpressionTree
|
||||
class ExpressionTree
|
||||
{
|
||||
#field theTree.
|
||||
object theTree.
|
||||
|
||||
#constructor new : aLiteral
|
||||
constructor new : aLiteral
|
||||
[
|
||||
#var aLevel := Integer new:0.
|
||||
var aLevel := Integer new:0.
|
||||
|
||||
aLiteral run &each: ch
|
||||
aLiteral forEach(:ch)
|
||||
[
|
||||
#var node := Dynamic new.
|
||||
var node := DynamicStruct new.
|
||||
|
||||
ch =>
|
||||
#43 ? [ node set &level:(aLevel + 1) set &operation:%add. ] // +
|
||||
#45 ? [ node set &level:(aLevel + 1) set &operation:%subtract. ] // -
|
||||
#42 ? [ node set &level:(aLevel + 2) set &operation:%multiply. ] // *
|
||||
#47 ? [ node set &level:(aLevel + 2) set &operation:%divide. ] // /
|
||||
#40 ? [ aLevel += 10. ^ $self. ] // (
|
||||
#41 ? [ aLevel -= 10. ^ $self. ] // )
|
||||
$43 [ node set level(aLevel + 1); set operation:%add ]; // +
|
||||
$45 [ node set level(aLevel + 1); set operation:%subtract ]; // -
|
||||
$42 [ node set level(aLevel + 2); set operation:%multiply ]; // *
|
||||
$47 [ node set level(aLevel + 2); set operation:%divide ]; // /
|
||||
$40 [ aLevel append int:10. ^ $self ]; // (
|
||||
$41 [ aLevel reduce int:10. ^ $self ]; // )
|
||||
! [
|
||||
node set &leaf:(ch literal toReal) set &level:((aLevel + 3)).
|
||||
node set leaf(ch literal; toReal); set level(aLevel + 3).
|
||||
].
|
||||
|
||||
($nil == theTree)
|
||||
? [ theTree := node. ]
|
||||
! [
|
||||
(theTree level >= node level)
|
||||
? [
|
||||
node set &left:theTree set &right:$nil.
|
||||
if ($nil == theTree)
|
||||
[ theTree := node ];
|
||||
[
|
||||
if (theTree level >= node level)
|
||||
[
|
||||
node set left:theTree; set right:$nil.
|
||||
|
||||
theTree := node.
|
||||
theTree := node
|
||||
];
|
||||
[
|
||||
var aTop := theTree.
|
||||
while (($nil != aTop right)and:$(aTop right; level < node level))
|
||||
[ aTop := aTop right ].
|
||||
|
||||
node set left(aTop right); set right:$nil.
|
||||
|
||||
aTop set right:node
|
||||
]
|
||||
! [
|
||||
#var aTop := theTree.
|
||||
#loop (($nil != aTop right)and:[aTop right level < node level] )
|
||||
? [ aTop := aTop right. ].
|
||||
|
||||
node set &left:(aTop right) set &right:$nil.
|
||||
|
||||
aTop set &right:node.
|
||||
].
|
||||
].
|
||||
].
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
#method eval : aNode
|
||||
eval : aNode
|
||||
[
|
||||
(aNode if &leaf)
|
||||
? [ ^ aNode leaf. ]
|
||||
! [
|
||||
#var aLeft := $self eval:(aNode left).
|
||||
#var aRight := $self eval:(aNode right).
|
||||
if (aNode containsProperty:%leaf)
|
||||
[ ^ aNode leaf ];
|
||||
[
|
||||
var aLeft := $self eval:(aNode left).
|
||||
var aRight := $self eval:(aNode right).
|
||||
|
||||
^ aLeft::(aNode operation) eval:aRight.
|
||||
^ aLeft~(aNode operation) eval:aRight
|
||||
]
|
||||
]
|
||||
|
||||
#method value
|
||||
value
|
||||
<= eval:theTree.
|
||||
|
||||
#method readLeaves : aList &at:aNode
|
||||
readLeaves : aList at:aNode
|
||||
[
|
||||
($nil == aNode)
|
||||
? [ #throw InvalidArgumentException new. ].
|
||||
if ($nil == aNode)
|
||||
[ InvalidArgumentException new; raise ].
|
||||
|
||||
(aNode if &leaf)
|
||||
? [ aList += aNode leaf. ]
|
||||
! [
|
||||
$self readLeaves:aList &at:(aNode left).
|
||||
$self readLeaves:aList &at:(aNode right).
|
||||
if (aNode containsProperty:%leaf)
|
||||
[ aList append(aNode leaf) ];
|
||||
[
|
||||
$self readLeaves:aList at(aNode left).
|
||||
$self readLeaves:aList at(aNode right).
|
||||
].
|
||||
]
|
||||
|
||||
#method readLeaves : aList
|
||||
<= readLeaves:aList &at:theTree.
|
||||
readLeaves : aList
|
||||
<= readLeaves:aList at:theTree.
|
||||
}
|
||||
|
||||
#class TwentyFourGame
|
||||
class TwentyFourGame
|
||||
{
|
||||
#field theNumbers.
|
||||
object theNumbers.
|
||||
|
||||
#constructor new
|
||||
constructor new
|
||||
[
|
||||
$self newPuzzle.
|
||||
]
|
||||
|
||||
#method newPuzzle
|
||||
newPuzzle
|
||||
[
|
||||
theNumbers := (
|
||||
1 + randomGenerator eval:9,
|
||||
|
|
@ -99,75 +98,76 @@
|
|||
1 + randomGenerator eval:9).
|
||||
]
|
||||
|
||||
#method help
|
||||
help
|
||||
[
|
||||
console
|
||||
writeLine:"------------------------------- Instructions ------------------------------"
|
||||
writeLine:"Four digits will be displayed."
|
||||
writeLine:"Enter an equation using all of those four digits that evaluates to 24"
|
||||
writeLine:"Only * / + - operators and () are allowed"
|
||||
writeLine:"Digits can only be used once, but in any order you need."
|
||||
writeLine:"Digits cannot be combined - i.e.: 12 + 12 when given 1,2,2,1 is not allowed"
|
||||
writeLine:"Submit a blank line to skip the current puzzle."
|
||||
writeLine:"Type 'q' to quit"
|
||||
writeLine
|
||||
writeLine:"Example: given 2 3 8 2, answer should resemble 8*3-(2-2)"
|
||||
writeLine:"------------------------------- --------------------------------------------".
|
||||
printLine:"------------------------------- Instructions ------------------------------";
|
||||
printLine:"Four digits will be displayed.";
|
||||
printLine:"Enter an equation using all of those four digits that evaluates to 24";
|
||||
printLine:"Only * / + - operators and () are allowed";
|
||||
printLine:"Digits can only be used once, but in any order you need.";
|
||||
printLine:"Digits cannot be combined - i.e.: 12 + 12 when given 1,2,2,1 is not allowed";
|
||||
printLine:"Submit a blank line to skip the current puzzle.";
|
||||
printLine:"Type 'q' to quit";
|
||||
writeLine;
|
||||
printLine:"Example: given 2 3 8 2, answer should resemble 8*3-(2-2)";
|
||||
printLine:"------------------------------- --------------------------------------------".
|
||||
]
|
||||
|
||||
#method prompt
|
||||
prompt
|
||||
[
|
||||
theNumbers run &each: n [ console writeLiteral:n:" ". ].
|
||||
theNumbers forEach(:n) [ console print(n," ") ].
|
||||
|
||||
console write:": ".
|
||||
console print:": "
|
||||
]
|
||||
|
||||
#method resolve : aLine
|
||||
resolve : aLine
|
||||
[
|
||||
#var exp := ExpressionTree new:aLine.
|
||||
var exp := ExpressionTree new:aLine.
|
||||
|
||||
#var Leaves := ArrayList new.
|
||||
var Leaves := ArrayList new.
|
||||
exp readLeaves:Leaves.
|
||||
|
||||
(Leaves ascendant equal &indexable:(theNumbers ascendant))
|
||||
! [ console writeLine:"Invalid input. Enter an equation using all of those four digits. Try again.". ^ $self. ].
|
||||
ifnot (Leaves ascendant; sequenceEqual(theNumbers ascendant))
|
||||
[ console printLine:"Invalid input. Enter an equation using all of those four digits. Try again.". ^ $self ].
|
||||
|
||||
#var aResult := exp value.
|
||||
(aResult == 24)
|
||||
? [
|
||||
console writeLine:"Good work. ":aLine:"=":aResult.
|
||||
var aResult := exp value.
|
||||
if (aResult == 24)
|
||||
[
|
||||
console printLine("Good work. ",aLine,"=",aResult).
|
||||
|
||||
$self newPuzzle.
|
||||
]
|
||||
! [ console writeLine:"Incorrect. ":aLine:"=":aResult. ].
|
||||
];
|
||||
[ console printLine("Incorrect. ",aLine,"=",aResult) ]
|
||||
]
|
||||
}
|
||||
|
||||
#class(extension) gameOp
|
||||
extension gameOp
|
||||
{
|
||||
#method playRound : aLine
|
||||
playRound : aLine
|
||||
[
|
||||
(aLine == "q")
|
||||
? [ ^ false. ]
|
||||
! [
|
||||
(aLine == "")
|
||||
? [ console writeLine:"Skipping this puzzle". self newPuzzle. ]
|
||||
! [
|
||||
self resolve:aLine
|
||||
| if &Error: e
|
||||
[
|
||||
console writeLine:"An error occurred. Check your input and try again.".
|
||||
].
|
||||
if (aLine == "q")
|
||||
[ ^ false ];
|
||||
[
|
||||
if (aLine == "")
|
||||
[ console printLine:"Skipping this puzzle". self newPuzzle. ];
|
||||
[
|
||||
try(self resolve:aLine)
|
||||
{
|
||||
on(Exception e) [
|
||||
console writeLine:"An error occurred. Check your input and try again."
|
||||
]
|
||||
}
|
||||
].
|
||||
|
||||
^ true.
|
||||
^ true
|
||||
].
|
||||
]
|
||||
}
|
||||
|
||||
#symbol program =
|
||||
program =
|
||||
[
|
||||
#var aGame := TwentyFourGame new help.
|
||||
var aGame := TwentyFourGame new; help.
|
||||
|
||||
#loop (aGame prompt playRound:(console readLine)) ? [].
|
||||
while (aGame prompt; playRound(console readLine)) [].
|
||||
].
|
||||
|
|
|
|||
|
|
@ -1,43 +1,53 @@
|
|||
import Char
|
||||
import Control.Monad.Error
|
||||
import Data.List
|
||||
import IO
|
||||
import Maybe
|
||||
import Random
|
||||
import Data.List (sort)
|
||||
import Data.Char (isDigit)
|
||||
import Data.Maybe (fromJust)
|
||||
import Control.Monad (foldM)
|
||||
import System.Random (randomRs, getStdGen)
|
||||
import System.IO (hSetBuffering, stdout, BufferMode(NoBuffering))
|
||||
|
||||
main = do
|
||||
hSetBuffering stdout NoBuffering
|
||||
mapM_ putStrLn
|
||||
[ "THE 24 GAME\n"
|
||||
, "Given four digits in the range 1 to 9"
|
||||
, "Use the +, -, *, and / operators in reverse polish notation"
|
||||
, "To show how to make an answer of 24.\n"
|
||||
]
|
||||
digits <- liftM (sort . take 4 . randomRs (1,9)) getStdGen :: IO [Int]
|
||||
putStrLn ("Your digits: " ++ intercalate " " (map show digits))
|
||||
guessLoop digits
|
||||
where guessLoop digits =
|
||||
putStr "Your expression: " >>
|
||||
liftM (processGuess digits . words) getLine >>=
|
||||
either (\m -> putStrLn m >> guessLoop digits) putStrLn
|
||||
hSetBuffering stdout NoBuffering
|
||||
mapM_
|
||||
putStrLn
|
||||
[ "THE 24 GAME\n"
|
||||
, "Given four digits in the range 1 to 9"
|
||||
, "Use the +, -, *, and / operators in reverse polish notation"
|
||||
, "To show how to make an answer of 24.\n"
|
||||
]
|
||||
digits <- fmap (sort . take 4 . randomRs (1, 9)) getStdGen :: IO [Int]
|
||||
putStrLn ("Your digits: " ++ unwords (fmap show digits))
|
||||
guessLoop digits
|
||||
where
|
||||
guessLoop digits =
|
||||
putStr "Your expression: " >> fmap (processGuess digits . words) getLine >>=
|
||||
either (\m -> putStrLn m >> guessLoop digits) putStrLn
|
||||
|
||||
processGuess _ [] = Right ""
|
||||
processGuess digits xs | not $ matches = Left "Wrong digits used"
|
||||
where matches = digits == (sort . map read $ filter (all isDigit) xs)
|
||||
processGuess _ [] = Right ""
|
||||
processGuess digits xs
|
||||
| not matches = Left "Wrong digits used"
|
||||
where
|
||||
matches = digits == (sort . fmap read $ filter (all isDigit) xs)
|
||||
processGuess digits xs = calc xs >>= check
|
||||
where check 24 = Right "Correct"
|
||||
check x = Left (show (fromRational (x :: Rational)) ++ " is wrong")
|
||||
where
|
||||
check 24 = Right "Correct"
|
||||
check x = Left (show (fromRational (x :: Rational)) ++ " is wrong")
|
||||
|
||||
-- A Reverse Polish Notation calculator with full error handling
|
||||
calc xs = foldM simplify [] xs >>= \ns -> (case ns of
|
||||
[n] -> Right n
|
||||
_ -> Left "Too few operators")
|
||||
calc xs =
|
||||
foldM simplify [] xs >>=
|
||||
\ns ->
|
||||
(case ns of
|
||||
[n] -> Right n
|
||||
_ -> Left "Too few operators")
|
||||
|
||||
simplify (a:b:ns) s | isOp s = Right ((fromJust $ lookup s ops) b a : ns)
|
||||
simplify _ s | isOp s = Left ("Too few values before " ++ s)
|
||||
simplify ns s | all isDigit s = Right (fromIntegral (read s) : ns)
|
||||
simplify _ s = Left ("Unrecognized symbol: " ++ s)
|
||||
simplify (a:b:ns) s
|
||||
| isOp s = Right ((fromJust $ lookup s ops) b a : ns)
|
||||
simplify _ s
|
||||
| isOp s = Left ("Too few values before " ++ s)
|
||||
simplify ns s
|
||||
| all isDigit s = Right (fromIntegral (read s) : ns)
|
||||
simplify _ s = Left ("Unrecognized symbol: " ++ s)
|
||||
|
||||
isOp v = elem v $ map fst ops
|
||||
isOp v = elem v $ fmap fst ops
|
||||
|
||||
ops = [("+",(+)), ("-",(-)), ("*",(*)), ("/",(/))]
|
||||
ops = [("+", (+)), ("-", (-)), ("*", (*)), ("/", (/))]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package game24
|
||||
|
||||
import java.util.*
|
||||
import java.util.Random
|
||||
import java.util.Scanner
|
||||
import java.util.Stack
|
||||
|
||||
internal object Game24 {
|
||||
fun run() {
|
||||
|
|
@ -10,9 +10,9 @@ internal object Game24 {
|
|||
print("> ")
|
||||
|
||||
val s = Stack<Float>()
|
||||
var total: Long = 0
|
||||
var total = 0L
|
||||
val cin = Scanner(System.`in`)
|
||||
for (c in cin.nextLine())
|
||||
for (c in cin.nextLine()) {
|
||||
when (c) {
|
||||
in '0'..'9' -> {
|
||||
val d = c - '0'
|
||||
|
|
@ -20,9 +20,11 @@ internal object Game24 {
|
|||
s += d.toFloat()
|
||||
}
|
||||
else ->
|
||||
if ("+/-*".indexOf(c) != -1)
|
||||
if ("+/-*".indexOf(c) != -1) {
|
||||
s += c.applyOperator(s.pop(), s.pop())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
when {
|
||||
tally(digits) != total ->
|
||||
|
|
@ -34,7 +36,7 @@ internal object Game24 {
|
|||
}
|
||||
}
|
||||
|
||||
fun Char.applyOperator(a: Float, b: Float) = when (this) {
|
||||
private fun Char.applyOperator(a: Float, b: Float) = when (this) {
|
||||
'+' -> a + b
|
||||
'-' -> b - a
|
||||
'*' -> a * b
|
||||
|
|
@ -42,7 +44,7 @@ internal object Game24 {
|
|||
else -> Float.NaN
|
||||
}
|
||||
|
||||
fun tally(a: List<Int>): Long = a.reduce({ t, i -> t + (1 shl (i * 5)) }).toLong()
|
||||
private fun tally(a: List<Int>): Long = a.reduce({ t, i -> t + (1 shl (i * 5)) }).toLong()
|
||||
|
||||
private val target = 24
|
||||
}
|
||||
|
|
|
|||
33
Task/24-game/MIRC-Scripting-Language/24-game.mirc
Normal file
33
Task/24-game/MIRC-Scripting-Language/24-game.mirc
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
alias 24 {
|
||||
dialog -m 24-Game 24-Game
|
||||
}
|
||||
|
||||
dialog 24-Game {
|
||||
title "24-Game"
|
||||
size -1 -1 100 70
|
||||
option dbu
|
||||
text "", 1, 29 7 42 8
|
||||
text "Equation", 2, 20 21 21 8
|
||||
edit "", 3, 45 20 40 10
|
||||
text "Status", 4, 10 34 80 8, center
|
||||
button "Calculate", 5, 5 45 40 20
|
||||
button "New", 6, 57 47 35 15
|
||||
}
|
||||
|
||||
on *:DIALOG:24-Game:init:*: {
|
||||
did -o 24-Game 1 1 Numbers: $rand(1,9) $rand(1,9) $rand(1,9) $rand(1,9)
|
||||
}
|
||||
|
||||
on *:DIALOG:24-Game:sclick:*: {
|
||||
if ($did == 5) {
|
||||
if ($regex($did(3),/^[ (]*\d *[-+*/][ (]*\d[ ()]*[-+*/][ ()]*\d[ )]*[-+*/] *\d[ )]*$/)) && ($sorttok($regsubex($did(3),/[^\d]+/g,$chr(32)),32) == $sorttok($remove($did(1),Numbers:),32)) {
|
||||
did -o 24-Game 4 1 $iif($calc($did(3)) == 24,Correct,Wrong)
|
||||
}
|
||||
else {
|
||||
did -o 24-Game 4 1 Wrong Numbers or Syntax
|
||||
}
|
||||
}
|
||||
elseif ($did == 6) {
|
||||
did -o 24-Game 1 1 Numbers: $rand(1,9) $rand(1,9) $rand(1,9) $rand(1,9)
|
||||
}
|
||||
}
|
||||
80
Task/24-game/MUMPS/24-game.mumps
Normal file
80
Task/24-game/MUMPS/24-game.mumps
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
24Game
|
||||
k number, operator, bracket
|
||||
; generate 4 random numbers each between 1 & 9
|
||||
; duplicates allowed!
|
||||
s n1=$r(9)+1, n2=$r(9)+1, n3=$r(9)+1, n4=$r(9)+1
|
||||
; save a copy of them so that we can keep restarting
|
||||
; if the user gets it wrong
|
||||
s s1=n1,s2=n2,s3=n3,s4=n4
|
||||
Question
|
||||
s (numcount,opcount,lbrackcount,rbrackcount)=0
|
||||
; restart with the random numbers already found
|
||||
s n1=s1,n2=s2,n3=s3,n4=s4
|
||||
w !,"Enter an arithmetic expression that evaluates to 24 using (",
|
||||
n1," ",n2," ",n3," ",n4,"): "
|
||||
r !,expr
|
||||
q:expr=""
|
||||
; validate numbers and operators
|
||||
s error=""
|
||||
f n=1:1:$l(expr) {
|
||||
s char=$e(expr,n)
|
||||
if char?1n {
|
||||
s number($i(numcount))=char
|
||||
w !
|
||||
zw char
|
||||
}
|
||||
elseif char?1(1"*",1"/",1"+",1"-") {
|
||||
s operator($i(opcount))=char
|
||||
}
|
||||
elseif char?1"(" {
|
||||
s bracket($i(lbrackcount))=char
|
||||
}
|
||||
elseif char?1")" {
|
||||
s bracket($i(rbrackcount))=char
|
||||
}
|
||||
else {
|
||||
s error="That ain't no character I wanted to see"
|
||||
q
|
||||
}
|
||||
}
|
||||
if error'="" w error g Question
|
||||
if numcount'=4 {
|
||||
w "Does not have 4 numbers, do it again."
|
||||
g Question
|
||||
}
|
||||
s error=""
|
||||
f n=1:1:4 {
|
||||
if number(n)=n1 {
|
||||
s n1="dont use again" continue
|
||||
}
|
||||
if number(n)=n2 {
|
||||
s n2="dont use again" continue
|
||||
}
|
||||
if number(n)=n3 {
|
||||
s n3="dont use again" continue
|
||||
}
|
||||
if number(n)=n4 {
|
||||
s n4="dont use again" continue
|
||||
}
|
||||
s error="Numbers entered do not match all of the randomly generated numbers."
|
||||
q
|
||||
}
|
||||
if error'="" {
|
||||
w error
|
||||
g Question
|
||||
}
|
||||
if opcount'=3 {
|
||||
w "Does not have 3 operators."
|
||||
g Question
|
||||
}
|
||||
if lbrackcount'=rbrackcount {
|
||||
w "brackets must be in pairs."
|
||||
g Question
|
||||
}
|
||||
x "s x="_expr
|
||||
if x'=24 {
|
||||
w !,"Answer does not = 24"
|
||||
g Question
|
||||
}
|
||||
w x
|
||||
q
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
import math, strutils, algorithm, sequtils
|
||||
from random import randomize, random
|
||||
from strutils import Whitespace
|
||||
from algorithm import sort
|
||||
from sequtils import deduplicate
|
||||
randomize()
|
||||
|
||||
template newSeqWith(len: int, init: expr): expr =
|
||||
var result {.gensym.} = newSeq[type(init)](len)
|
||||
template newSeqWith(len: int, init: untyped): untyped =
|
||||
var result = newSeq[type(init)](len)
|
||||
for i in 0 .. <len:
|
||||
result[i] = init
|
||||
result
|
||||
|
|
@ -14,7 +17,7 @@ var
|
|||
|
||||
echo "Make 24 with the digits: ", problem
|
||||
|
||||
template op(c): stmt =
|
||||
template op(c) =
|
||||
let a = stack.pop
|
||||
stack.add c(stack.pop, a)
|
||||
|
||||
|
|
|
|||
149
Task/24-game/Nit/24-game.nit
Normal file
149
Task/24-game/Nit/24-game.nit
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
redef class Char
|
||||
fun is_op: Bool do return "-+/*".has(self)
|
||||
end
|
||||
|
||||
# Get `numbers` and `operands` from string `operation` collect with `gets` in `main` function
|
||||
# Fill `numbers` and `operands` array with previous extraction
|
||||
fun exportation(operation: String, numbers: Array[Int], operands: Array[Char]) do
|
||||
var previous_char: nullable Char = null
|
||||
var number: nullable Int = null
|
||||
var negative = false
|
||||
|
||||
for i in operation.length.times do
|
||||
var current_char = operation[i]
|
||||
var current_int = current_char.to_i
|
||||
|
||||
if (previous_char == null or previous_char.is_op) and current_char == '-' then
|
||||
negative = true
|
||||
continue
|
||||
end
|
||||
|
||||
if current_char.is_digit then
|
||||
if number == null then
|
||||
number = current_int
|
||||
else
|
||||
number = number * 10 + current_int
|
||||
end
|
||||
end
|
||||
|
||||
if negative and (current_char.is_op or i == operation.length - 1) then
|
||||
number = number - number * 2
|
||||
negative = false
|
||||
end
|
||||
|
||||
if (current_char.is_op or i == operation.length - 1) and number != null then
|
||||
numbers.add(number)
|
||||
number = null
|
||||
end
|
||||
|
||||
if not negative and current_char.is_op then
|
||||
operands.add(current_char)
|
||||
end
|
||||
previous_char = current_char
|
||||
end
|
||||
# Update `numbers` and `operands` array in main function with pointer
|
||||
end
|
||||
|
||||
# Create random numbers between 1 to 9
|
||||
fun random: Array[Int] do
|
||||
return [for i in 4.times do 1 + 9.rand]
|
||||
end
|
||||
|
||||
# Make mathematical operation with `numbers` and `operands` and add the operation result into `random_numbers`
|
||||
fun calculation(random_numbers, numbers: Array[Int], operands: Array[Char]) do
|
||||
var number = 0
|
||||
var temp_numbers = numbers.clone
|
||||
|
||||
while temp_numbers.length > 1 do
|
||||
var operand = operands.shift
|
||||
var a = temp_numbers.shift
|
||||
var b = temp_numbers.shift
|
||||
|
||||
if operand == '+' then number = a + b
|
||||
if operand == '-' then number = a - b
|
||||
if operand == '*' then number = a * b
|
||||
if operand == '/' then number = a / b
|
||||
|
||||
temp_numbers.unshift(number)
|
||||
end
|
||||
if number != 0 then random_numbers.add(number)
|
||||
end
|
||||
|
||||
# Check if used `numbers` exist in the `random_numbers` created
|
||||
fun numbers_exists(random_numbers, numbers: Array[Int]): Bool do
|
||||
for number in numbers do
|
||||
if not random_numbers.count(number) >= numbers.count(number) then return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
# Remove `numbers` when they are used
|
||||
fun remove_numbers(random_numbers, numbers: Array[Int]) do
|
||||
for number in numbers do random_numbers.remove(number)
|
||||
end
|
||||
|
||||
# Check if the mathematical `operation` is valid
|
||||
fun check(operation: String): Bool do
|
||||
var previous_char: nullable Char = null
|
||||
var next_char: nullable Char = null
|
||||
var next_1_char: nullable Char = null
|
||||
|
||||
for i in operation.length.times do
|
||||
var current_char = operation[i]
|
||||
|
||||
if i + 1 < operation.length then
|
||||
next_char = operation[i + 1]
|
||||
if i + 2 < operation.length then
|
||||
next_1_char = operation[i + 2]
|
||||
else
|
||||
next_1_char = null
|
||||
end
|
||||
else
|
||||
next_char = null
|
||||
end
|
||||
|
||||
if not current_char.is_op and not current_char.is_digit then return false
|
||||
if next_char == null and current_char.is_op then return false
|
||||
|
||||
if previous_char == null then
|
||||
if next_char == null or next_1_char == null then return false
|
||||
if current_char == '-' and not next_char.is_digit then return false
|
||||
if current_char != '-' and not current_char.is_digit then return false
|
||||
else
|
||||
if next_char != null then
|
||||
if previous_char.is_digit and current_char.is_op and
|
||||
not (next_char == '-' and next_1_char != null and
|
||||
next_1_char.is_digit or next_char.is_digit) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
previous_char = current_char
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
var random_numbers = new Array[Int]
|
||||
var operation = ""
|
||||
|
||||
random_numbers = random
|
||||
while not random_numbers.has(24) and random_numbers.length > 1 do
|
||||
var numbers = new Array[Int]
|
||||
var operands = new Array[Char]
|
||||
|
||||
print "numbers: " + random_numbers.join(", ")
|
||||
operation = gets
|
||||
if check(operation) then
|
||||
exportation(operation, numbers, operands)
|
||||
if numbers_exists(random_numbers, numbers) then
|
||||
calculation(random_numbers, numbers, operands)
|
||||
remove_numbers(random_numbers, numbers)
|
||||
else
|
||||
print "NUMBERS ERROR!"
|
||||
end
|
||||
else
|
||||
print "STRING ERROR!"
|
||||
end
|
||||
end
|
||||
|
||||
if random_numbers.has(24) then print "CONGRATULATIONS" else print "YOU LOSE"
|
||||
33
Task/24-game/Python/24-game-2.py
Normal file
33
Task/24-game/Python/24-game-2.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import random, re
|
||||
chars = ["(",")","/","+","-","*"]
|
||||
while True:
|
||||
charsandints, ints = [], []
|
||||
for x in range(4):
|
||||
ints.append(str(random.randrange(1,10)))
|
||||
charsandints = chars + ints
|
||||
print "Numbers are:", ints
|
||||
guess = raw_input("Enter your guess:")
|
||||
if guess.lower() == "q":
|
||||
break
|
||||
elif guess.lower() == "|":
|
||||
pass
|
||||
else:
|
||||
flag = True
|
||||
for a in guess:
|
||||
if a not in charsandints or guess.count(a) > charsandints.count(a):
|
||||
flag = False
|
||||
if re.search("\d\d", guess):
|
||||
print "You cannot combine digits."
|
||||
break
|
||||
if flag:
|
||||
print "Your result is: ", eval(guess)
|
||||
if eval(guess) == 24:
|
||||
print "You won"
|
||||
break
|
||||
else:
|
||||
print "You lost"
|
||||
break
|
||||
else:
|
||||
print "You cannot use anthing other than", charsandints
|
||||
break
|
||||
print "Thanks for playing"
|
||||
|
|
@ -1,17 +1,14 @@
|
|||
/*REXX program supports a human to play the game of 24 (twenty-four) with error checking*/
|
||||
numeric digits 15 /*allow more leeway when computing #s. */
|
||||
parse arg yyy /*get the optional arguments from C.L. */
|
||||
yyy = space(yyy, 0) /*remove extraneous blanks from YYY. */
|
||||
parse arg yyy; yyy=space(yyy, 0) /*get optional CL args; elide blanks. */
|
||||
parse var yyy start '-' fin /*get the START and FINish (maybe). */
|
||||
fin = word(fin start, 1) /*if no FINish specified, use START.*/
|
||||
ops = '+-*/' ; Lops = length(0ps) /*define the legal arithmetic operators*/
|
||||
groupSym = '()[]{}' /*legal grouping symbols for this game.*/
|
||||
indent = left('', 30) /*used to indent display of solutions. */
|
||||
Lpar = '(' ; Rpar = ')' /*strings to make the output prettier.*/
|
||||
digs = 123456789 /*numerals (digits) that can be used. */
|
||||
show = 1 /*flag used show solutions (0 = not). */
|
||||
do j=1 for Lops; @.j=substr(ops,j,1) /*define a version for fast execution. */
|
||||
end /*j*/
|
||||
fin= word(fin start, 1) /*if no FINish specified, use START.*/
|
||||
ops= '+-*/' ; Lops= length(0ps) /*define the legal arithmetic operators*/
|
||||
groupSym= '()[]{}' /*legal grouping symbols for this game.*/
|
||||
pad= left('', 30) /*used to indent display of solutions. */
|
||||
Lpar= '(' ; Rpar= ')' /*strings to make the output prettier.*/
|
||||
digs= 123456789 /*numerals (digits) that can be used. */
|
||||
show= 1 /*flag used show solutions (0 = not). */
|
||||
do j=1 for Lops; @.j=substr(ops,j,1); end /*for fast execution. */
|
||||
signal on syntax /*enable program to trap syntax errors.*/
|
||||
if yyy\=='' then do; sols=solve(start, fin) /*solve from START ───► FINish. */
|
||||
if sols <0 then exit 13 /*Was there a problem with the input? */
|
||||
|
|
@ -30,11 +27,10 @@ $.=0
|
|||
do j=1 for Lrrrr; _=substr(rrrr,j,1) /*digit count for each digit in RRRR. */
|
||||
$._= countDigs(rrrr, _) /*define the count for this digit. */
|
||||
end /*j*/ /* [↑] counts duplicates twice, no harm*/
|
||||
|
||||
__ = copies('─', 9) /*used for output highlighting. */
|
||||
__ = copies('─', 9) /*used for output highlighting. */
|
||||
prompt= 'Using the digits ' rrrr", enter an expression that equals 24 (or QUIT):"
|
||||
/* [↓] ITERATE needs a variable name.*/
|
||||
do prompter=0; say; say __ prompt /*display blank line and the prompt (P)*/
|
||||
do prompter=0 by 0; say; say __ prompt /*display blank line and the prompt (P)*/
|
||||
pull y; y=space(y, 0) /*get Y from CL, then remove all blanks*/
|
||||
if abbrev('QUIT', y, 1) then exit 0 /*Does the user want to quit this game?*/
|
||||
_v=verify(y, digs || ops || groupSym); a=substr(y, max(1,_v), 1)
|
||||
|
|
@ -43,33 +39,29 @@ prompt= 'Using the digits ' rrrr", enter an expression that equals 24 (or
|
|||
if pos('//', y) then do; call ger "invalid // operator"; iterate; end
|
||||
Ly=length(y)
|
||||
if y=='' then do; call validate y; iterate; end
|
||||
|
||||
do j=1 for Ly-1; if \datatype(substr(y, j , 1), 'W') then iterate
|
||||
if \datatype(substr(y, j+1, 1), 'W') then iterate
|
||||
call ger 'invalid use of "digit abuttal".'
|
||||
iterate prompter
|
||||
end /*j*/
|
||||
|
||||
yd=countDigs(y, digs) /*count of the digits 1──►9 (123456789)*/
|
||||
do j=1 for Ly-1; if \datatype(substr(y,j ,1), 'W') then iterate
|
||||
if \datatype(substr(y,j+1,1), 'W') then iterate
|
||||
call ger 'invalid use of "digit abuttal".'
|
||||
iterate prompter
|
||||
end /*j*/
|
||||
yd=countDigs(y,digs) /*count of the digits 1──►9 (123456789)*/
|
||||
if yd<4 then do; call ger 'not enough digits entered.'; iterate /*prompter*/; end
|
||||
if yd>4 then do; call ger 'too many digits entered.' ; iterate /*prompter*/; end
|
||||
|
||||
do j=1 for 9; if $.j==0 then iterate
|
||||
_d=countDigs(y, j); if $.j==_d then iterate
|
||||
if _d<$.j then call ger 'not enough' j "digits, must be" $.j
|
||||
else call ger 'too many' j "digits, must be" $.j
|
||||
iterate prompter
|
||||
end /*j*/
|
||||
|
||||
do j=1 for 9; if $.j==0 then iterate
|
||||
_d=countDigs(y, j); if $.j==_d then iterate
|
||||
if _d<$.j then call ger 'not enough' j "digits, must be" $.j
|
||||
else call ger 'too many' j "digits, must be" $.j
|
||||
iterate prompter
|
||||
end /*j*/
|
||||
interpret 'ans=' translate(y, '()()', "[]{}"); ans=ans/1
|
||||
if ans==24 then leave prompter; say 'incorrect, ' y"="ans
|
||||
end /*prompter*/
|
||||
|
||||
say; say center('┌─────────────────────┐', 79)
|
||||
say center('│ │', 79)
|
||||
say center('│ congratulations ! │', 79)
|
||||
say center('│ │', 79)
|
||||
say center('└─────────────────────┘', 79)
|
||||
say; say center('┌─────────────────────┐', 79)
|
||||
say center('│ │', 79)
|
||||
say center('│ congratulations ! │', 79)
|
||||
say center('│ │', 79)
|
||||
say center('└─────────────────────┘', 79)
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
countDigs: arg ?; return length(?) - length(space(translate(?, , arg(2)), 0))
|
||||
|
|
@ -79,18 +71,12 @@ s: if arg(1)==1 then return ''; return "s" /*a simple plu
|
|||
syntax: call ger 'illegal syntax in' y; exit
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
solve: parse arg ssss, ffff /*parse the argument passed to SOLVE. */
|
||||
if ffff=='' then ffff=ssss /*create a FFFF if necessary. */
|
||||
if \validate(ssss) then return -1 /*validate the SSSS field. */
|
||||
if \validate(ffff) then return -1 /* " " FFFF " */
|
||||
#=0 /*number of found solutions (so far). */
|
||||
!.=0 /*a method to hold unique expressions. */
|
||||
/*alternative: indent=copies(' ',30) */
|
||||
if ffff=='' then ffff=ssss /*create a FFFF if necessary. */
|
||||
if \validate(ssss) | \validate(ffff) then return -1 /*validate SSSS & FFFF*/
|
||||
!.=0; #=0 /*holds unique expressions; # solutions*/
|
||||
do g=ssss to ffff /*process a (possible) range of values.*/
|
||||
if pos(0, g)\==0 then iterate /*ignore values with zero in them. */
|
||||
|
||||
do j=1 for 4; g.j=substr(g, j, 1) /*define a version for fast execution. */
|
||||
end /*j*/
|
||||
|
||||
do j=1 for 4; g.j=substr(g,j,1); end /*for fast execution.*/
|
||||
do i =1 for Lops /*insert an operator after 1st number. */
|
||||
do j =1 for Lops /* " " " " 2nd " */
|
||||
do k =1 for Lops /* " " " " 3rd " */
|
||||
|
|
@ -108,14 +94,13 @@ solve: parse arg ssss, ffff /*parse the argument passed to
|
|||
interpret 'x=' e /*have REXX do all the heavy lifting */
|
||||
if x\=24 then iterate /*Is the result incorrect? Try again. */
|
||||
#=#+1 /*bump number of found solutions. */
|
||||
if show then say indent 'a solution:' translate(yyyE, '][', ")(")
|
||||
if show then say pad 'a solution for' g": " translate(yyyE,'][',")(")
|
||||
end /*n*/ /* [↑] display a (single) solution. */
|
||||
end /*m*/
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
end /*i*/
|
||||
end /*g*/
|
||||
|
||||
return #
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
sort: procedure; parse arg #; L=length(#); !.= /*this is a modified bin sort.*/
|
||||
|
|
@ -130,5 +115,4 @@ validate: parse arg y; OK=1; _v=verify(y,digs); DE='digits entered, there must
|
|||
when pos(0,y)\==0 then call ger "can't use the digit 0 (zero)."
|
||||
when _v\==0 then call ger "illegal character: " substr(y, _v, 1)
|
||||
otherwise nop
|
||||
end /*select*/
|
||||
return OK
|
||||
end /*select*/; return OK
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
changestr: Procedure
|
||||
/* change needle to newneedle in haystack (as often as specified */
|
||||
/* or all of them if count is omitted */
|
||||
Parse Arg needle,haystack,newneedle,count
|
||||
If count>'' Then Do
|
||||
If count=0 Then Do
|
||||
Say 'chstr count must be > 0'
|
||||
Signal Syntax
|
||||
End
|
||||
End
|
||||
res=""
|
||||
changes=0
|
||||
px=1
|
||||
do Until py=0
|
||||
py=pos(needle,haystack,px)
|
||||
if py>0 then Do
|
||||
res=res||substr(haystack,px,py-px)||newneedle
|
||||
px=py+length(needle)
|
||||
changes=changes+1
|
||||
If count>'' Then
|
||||
If changes=count Then Leave
|
||||
End
|
||||
end
|
||||
res=res||substr(haystack,px)
|
||||
Return res
|
||||
|
|
@ -1,34 +1,34 @@
|
|||
const digits = (1..9 -> pick(4));
|
||||
const grammar = Regex.new(
|
||||
const digits = (1..9 -> pick(4))
|
||||
const grammar = Regex(
|
||||
'^ (?&exp) \z
|
||||
(?(DEFINE)
|
||||
(?<exp> ( (?&term) (?&op) (?&term) )+ )
|
||||
(?<term> \( (?&exp) \) | [' + digits.join + '])
|
||||
(?<op> [-+*/] )
|
||||
(?<op> [\-+*/] )
|
||||
)', 'x'
|
||||
);
|
||||
|
||||
say "Here are your digits: #{digits.join(' ')}";
|
||||
|
||||
)
|
||||
|
||||
say "Here are your digits: #{digits.join(' ')}"
|
||||
|
||||
loop {
|
||||
var input = Sys.scanln("Expression: ");
|
||||
|
||||
var expr = input;
|
||||
expr -= /\s+/g; # remove all whitespace
|
||||
|
||||
input == 'q' && (
|
||||
say "Goodbye. Sorry you couldn't win.";
|
||||
break;
|
||||
);
|
||||
|
||||
var given_digits = digits.map{.to_s}.sort.join;
|
||||
var entry_digits = input.scan(/\d/).sort.join;
|
||||
|
||||
if ((given_digits != entry_digits) || (expr !~ grammar)) {
|
||||
say "That's not valid";
|
||||
next;
|
||||
var input = read("Expression: ", String)
|
||||
|
||||
var expr = input
|
||||
expr -= /\s+/g # remove all whitespace
|
||||
|
||||
if (input == 'q') {
|
||||
say "Goodbye. Sorry you couldn't win."
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
var given_digits = digits.map{.to_s}.sort.join
|
||||
var entry_digits = input.scan(/\d/).sort.join
|
||||
|
||||
if ((given_digits != entry_digits) || (expr !~ grammar)) {
|
||||
say "That's not valid"
|
||||
next
|
||||
}
|
||||
|
||||
given(var n = eval(input)) {
|
||||
when (24) { say "You win!"; break }
|
||||
default { say "Sorry, your expression is #{n}, not 24" }
|
||||
|
|
|
|||
296
Task/24-game/Simula/24-game.simula
Normal file
296
Task/24-game/Simula/24-game.simula
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
BEGIN
|
||||
|
||||
CLASS EXPR;
|
||||
BEGIN
|
||||
|
||||
|
||||
REAL PROCEDURE POP;
|
||||
BEGIN
|
||||
IF STACKPOS > 0 THEN
|
||||
BEGIN STACKPOS := STACKPOS - 1; POP := STACK(STACKPOS); END;
|
||||
END POP;
|
||||
|
||||
|
||||
PROCEDURE PUSH(NEWTOP); REAL NEWTOP;
|
||||
BEGIN
|
||||
STACK(STACKPOS) := NEWTOP;
|
||||
STACKPOS := STACKPOS + 1;
|
||||
END PUSH;
|
||||
|
||||
|
||||
REAL PROCEDURE CALC(OPERATOR, ERR); CHARACTER OPERATOR; LABEL ERR;
|
||||
BEGIN
|
||||
REAL X, Y; X := POP; Y := POP;
|
||||
IF OPERATOR = '+' THEN PUSH(Y + X)
|
||||
ELSE IF OPERATOR = '-' THEN PUSH(Y - X)
|
||||
ELSE IF OPERATOR = '*' THEN PUSH(Y * X)
|
||||
ELSE IF OPERATOR = '/' THEN BEGIN
|
||||
IF X = 0 THEN
|
||||
BEGIN
|
||||
EVALUATEDERR :- "DIV BY ZERO";
|
||||
GOTO ERR;
|
||||
END;
|
||||
PUSH(Y / X);
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
EVALUATEDERR :- "UNKNOWN OPERATOR";
|
||||
GOTO ERR;
|
||||
END
|
||||
END CALC;
|
||||
|
||||
|
||||
PROCEDURE READCHAR(CH); NAME CH; CHARACTER CH;
|
||||
BEGIN
|
||||
IF T.MORE THEN CH := T.GETCHAR ELSE CH := EOT;
|
||||
END READCHAR;
|
||||
|
||||
|
||||
PROCEDURE SKIPWHITESPACE(CH); NAME CH; CHARACTER CH;
|
||||
BEGIN
|
||||
WHILE (CH = SPACE) OR (CH = TAB) OR (CH = CR) OR (CH = LF) DO
|
||||
READCHAR(CH);
|
||||
END SKIPWHITESPACE;
|
||||
|
||||
|
||||
PROCEDURE BUSYBOX(OP, ERR); INTEGER OP; LABEL ERR;
|
||||
BEGIN
|
||||
CHARACTER OPERATOR;
|
||||
REAL NUMBR;
|
||||
BOOLEAN NEGATIVE;
|
||||
|
||||
SKIPWHITESPACE(CH);
|
||||
|
||||
IF OP = EXPRESSION THEN
|
||||
BEGIN
|
||||
|
||||
NEGATIVE := FALSE;
|
||||
WHILE (CH = '+') OR (CH = '-') DO
|
||||
BEGIN
|
||||
IF CH = '-' THEN NEGATIVE := NOT NEGATIVE;
|
||||
READCHAR(CH);
|
||||
END;
|
||||
|
||||
BUSYBOX(TERM, ERR);
|
||||
|
||||
IF NEGATIVE THEN
|
||||
BEGIN
|
||||
NUMBR := POP; PUSH(0 - NUMBR);
|
||||
END;
|
||||
|
||||
WHILE (CH = '+') OR (CH = '-') DO
|
||||
BEGIN
|
||||
OPERATOR := CH; READCHAR(CH);
|
||||
BUSYBOX(TERM, ERR); CALC(OPERATOR, ERR);
|
||||
END;
|
||||
|
||||
END
|
||||
ELSE IF OP = TERM THEN
|
||||
BEGIN
|
||||
|
||||
BUSYBOX(FACTOR, ERR);
|
||||
WHILE (CH = '*') OR (CH = '/') DO
|
||||
BEGIN
|
||||
OPERATOR := CH; READCHAR(CH);
|
||||
BUSYBOX(FACTOR, ERR); CALC(OPERATOR, ERR)
|
||||
END
|
||||
|
||||
END
|
||||
ELSE IF OP = FACTOR THEN
|
||||
BEGIN
|
||||
|
||||
IF (CH = '+') OR (CH = '-') THEN
|
||||
BUSYBOX(EXPRESSION, ERR)
|
||||
ELSE IF (CH >= '0') AND (CH <= '9') THEN
|
||||
BUSYBOX(NUMBER, ERR)
|
||||
ELSE IF CH = '(' THEN
|
||||
BEGIN
|
||||
READCHAR(CH);
|
||||
BUSYBOX(EXPRESSION, ERR);
|
||||
IF CH = ')' THEN READCHAR(CH) ELSE GOTO ERR;
|
||||
END
|
||||
ELSE GOTO ERR;
|
||||
|
||||
END
|
||||
ELSE IF OP = NUMBER THEN
|
||||
BEGIN
|
||||
|
||||
NUMBR := 0;
|
||||
WHILE (CH >= '0') AND (CH <= '9') DO
|
||||
BEGIN
|
||||
NUMBR := 10 * NUMBR + RANK(CH) - RANK('0'); READCHAR(CH);
|
||||
END;
|
||||
IF CH = '.' THEN
|
||||
BEGIN
|
||||
REAL FAKTOR;
|
||||
READCHAR(CH);
|
||||
FAKTOR := 10;
|
||||
WHILE (CH >= '0') AND (CH <= '9') DO
|
||||
BEGIN
|
||||
NUMBR := NUMBR + (RANK(CH) - RANK('0')) / FAKTOR;
|
||||
FAKTOR := 10 * FAKTOR;
|
||||
READCHAR(CH);
|
||||
END;
|
||||
END;
|
||||
PUSH(NUMBR);
|
||||
|
||||
END;
|
||||
|
||||
SKIPWHITESPACE(CH);
|
||||
|
||||
END BUSYBOX;
|
||||
|
||||
|
||||
BOOLEAN PROCEDURE EVAL(INP); TEXT INP;
|
||||
BEGIN
|
||||
EVALUATEDERR :- NOTEXT;
|
||||
STACKPOS := 0;
|
||||
T :- COPY(INP.STRIP);
|
||||
READCHAR(CH);
|
||||
BUSYBOX(EXPRESSION, ERRORLABEL);
|
||||
! OUTTEXT("T = '");
|
||||
! OUTTEXT(T);
|
||||
! OUTTEXT("'");
|
||||
! OUTTEXT(", T.POS = ");
|
||||
! OUTINT(T.POS, 0);
|
||||
! OUTTEXT(", STACKPOS = ");
|
||||
! OUTINT(STACKPOS, 0);
|
||||
! OUTTEXT(", T.MORE = ");
|
||||
! OUTCHAR(IF T.MORE THEN 'T' ELSE 'F');
|
||||
! OUTTEXT(", CH = ");
|
||||
! OUTCHAR(CH);
|
||||
! OUTIMAGE;
|
||||
IF NOT T.MORE AND STACKPOS = 1 AND CH = EOT THEN
|
||||
BEGIN
|
||||
EVALUATED := POP;
|
||||
EVAL := TRUE;
|
||||
GOTO NOERRORLABEL;
|
||||
END;
|
||||
ERRORLABEL:
|
||||
EVAL := FALSE;
|
||||
IF EVALUATEDERR = NOTEXT THEN
|
||||
EVALUATEDERR :- "INVALID EXPRESSION: " & INP;
|
||||
NOERRORLABEL:
|
||||
END EVAL;
|
||||
|
||||
|
||||
REAL PROCEDURE RESULT;
|
||||
RESULT := EVALUATED;
|
||||
|
||||
TEXT PROCEDURE ERR;
|
||||
ERR :- EVALUATEDERR;
|
||||
|
||||
TEXT T;
|
||||
|
||||
INTEGER EXPRESSION;
|
||||
INTEGER TERM;
|
||||
INTEGER FACTOR;
|
||||
INTEGER NUMBER;
|
||||
|
||||
CHARACTER TAB;
|
||||
CHARACTER LF;
|
||||
CHARACTER CR;
|
||||
CHARACTER SPACE;
|
||||
CHARACTER EOT;
|
||||
|
||||
CHARACTER CH;
|
||||
REAL ARRAY STACK(0:31);
|
||||
INTEGER STACKPOS;
|
||||
|
||||
REAL EVALUATED;
|
||||
TEXT EVALUATEDERR;
|
||||
|
||||
EXPRESSION := 1;
|
||||
TERM := 2;
|
||||
FACTOR := 3;
|
||||
NUMBER := 4;
|
||||
|
||||
TAB := CHAR(9);
|
||||
LF := CHAR(10);
|
||||
CR := CHAR(13);
|
||||
SPACE := CHAR(32);
|
||||
EOT := CHAR(0);
|
||||
|
||||
END EXPR;
|
||||
|
||||
INTEGER ARRAY DIGITS(1:4);
|
||||
INTEGER SEED, I;
|
||||
REF(EXPR) E;
|
||||
|
||||
E :- NEW EXPR;
|
||||
OUTTEXT("ENTER RANDOM SEED: ");
|
||||
OUTIMAGE;
|
||||
SEED := ININT;
|
||||
FOR I := 1 STEP 1 UNTIL 4 DO DIGITS(I) := RANDINT(0, 9, SEED);
|
||||
|
||||
L: BEGIN
|
||||
INTEGER ARRAY DIGITSUSED(0:9);
|
||||
INTEGER ARRAY DIGITSTAKEN(0:9);
|
||||
CHARACTER C, LASTC;
|
||||
TEXT INP;
|
||||
|
||||
LASTC := CHAR(0);
|
||||
OUTTEXT("MAKE 24 USING THESE DIGITS: ");
|
||||
FOR I := 1 STEP 1 UNTIL 4 DO
|
||||
BEGIN
|
||||
OUTINT(DIGITS(I), 2);
|
||||
DIGITSUSED( DIGITS(I) ) := DIGITSUSED( DIGITS(I) ) + 1;
|
||||
END;
|
||||
OUTIMAGE;
|
||||
INIMAGE;
|
||||
INP :- COPY(SYSIN.IMAGE.STRIP);
|
||||
OUTIMAGE;
|
||||
WHILE INP.MORE DO
|
||||
BEGIN
|
||||
C := INP.GETCHAR;
|
||||
IF (C >= '0') AND (C <= '9') THEN
|
||||
BEGIN
|
||||
INTEGER D;
|
||||
IF (LASTC >= '0') AND (LASTC <= '9') THEN
|
||||
BEGIN
|
||||
OUTTEXT("NUMBER HAS TOO MANY DIGITS: ");
|
||||
OUTCHAR(LASTC);
|
||||
OUTCHAR(C);
|
||||
OUTIMAGE;
|
||||
GOTO L;
|
||||
END;
|
||||
D := RANK(C) - RANK('0');
|
||||
DIGITSTAKEN(D) := DIGITSTAKEN(D) + 1;
|
||||
END
|
||||
ELSE IF NOT ((C = '+') OR (C = '-') OR (C = '/') OR (C = '*') OR
|
||||
(C = ' ') OR (C = '(') OR (C = ')')) THEN
|
||||
BEGIN
|
||||
OUTTEXT("ILLEGAL INPUT CHARACTER: ");
|
||||
OUTCHAR(C);
|
||||
OUTIMAGE;
|
||||
GOTO L;
|
||||
END;
|
||||
LASTC := C;
|
||||
END;
|
||||
FOR I := 0 STEP 1 UNTIL 9 DO
|
||||
BEGIN
|
||||
IF DIGITSUSED(I) <> DIGITSTAKEN(I) THEN
|
||||
BEGIN
|
||||
OUTTEXT("NOT THE SAME DIGITS.");
|
||||
OUTIMAGE;
|
||||
GOTO L;
|
||||
END;
|
||||
END;
|
||||
IF E.EVAL(INP) THEN
|
||||
BEGIN
|
||||
OUTTEXT("RESULT IS ");
|
||||
OUTFIX(E.RESULT, 4, 10);
|
||||
OUTIMAGE;
|
||||
OUTTEXT(IF ABS(E.RESULT - 24) < 0.001
|
||||
THEN "YOU WIN"
|
||||
ELSE "YOU LOOSE");
|
||||
OUTIMAGE;
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
OUTTEXT(E.ERR);
|
||||
OUTIMAGE;
|
||||
END;
|
||||
END;
|
||||
|
||||
END.
|
||||
19
Task/24-game/Zkl/24-game.zkl
Normal file
19
Task/24-game/Zkl/24-game.zkl
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
while(1){
|
||||
digits := [1..4].pump(String,(0).random.fpM("11-",1,9));
|
||||
exp := ask("Enter an expression using the digits ",digits,
|
||||
" that evals to 24: ") - " \n";
|
||||
expf:=exp.apply(fcn(c){if ("1"<=c<="9") "(%s).toFloat()".fmt(c) else c});
|
||||
reg r;
|
||||
try { Compiler.Compiler.compileText(expf).__constructor(); r=vm.regX }
|
||||
catch { println("bad expression"); continue; }
|
||||
else{
|
||||
extra := (exp - "+-/*()" - digits);
|
||||
if (extra) { println("Extra goodies in expression: ",extra); continue; }
|
||||
(digits.split("").sort() != (exp - "+-/*()").split("").sort()) :
|
||||
if(_) { println("You can only use the digits ",digits," once each"); continue; };
|
||||
if (exp.matches("*[1-9][1-9]*"))
|
||||
{ println("no repeated digits"); continue; }
|
||||
if (r.closeTo(24,0.001)) "nice!".println();
|
||||
else println("That evaled to ",r,", not 24");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue