Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,6 +1,7 @@
|
|||
The [[wp:24 Game|24 Game]] tests one's mental arithmetic.
|
||||
|
||||
Write a program that [[task feature::Rosetta Code:randomness|randomly]] chooses and [[task feature::Rosetta Code:user output|displays]] four digits, each from one to nine, with repetitions allowed. The program should prompt for the player to enter an arithmetic expression using ''just'' those, and ''all'' of those four digits. The program should ''check'' then [[task feature::Rosetta Code:parsing|evaluate the expression]]. The goal is for the player to [[task feature::Rosetta Code:user input|enter]] an expression that evaluates to '''24'''.
|
||||
Write a program that [[task feature::Rosetta Code:randomness|randomly]] chooses and [[task feature::Rosetta Code:user output|displays]] four digits, each from one to nine, with repetitions allowed. The program should prompt for the player to enter an arithmetic expression using ''just'' those, and ''all'' of those four digits, used exactly ''once'' each. The program should ''check'' then [[task feature::Rosetta Code:parsing|evaluate the expression]].
|
||||
The goal is for the player to [[task feature::Rosetta Code:user input|enter]] an expression that evaluates to '''24'''.
|
||||
* Only multiplication, division, addition, and subtraction operators/functions are allowed.
|
||||
* Division should use floating point or rational arithmetic, etc, to preserve remainders.
|
||||
* Brackets are allowed, if using an infix expression evaluator.
|
||||
|
|
|
|||
83
Task/24-game/Batch-File/24-game.bat
Normal file
83
Task/24-game/Batch-File/24-game.bat
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
@echo off
|
||||
::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.
|
||||
::
|
||||
::Note: [1]This implementation does not evaluate brackets
|
||||
:: [2]This implementation does not keep remainders since batch language
|
||||
:: has no support for floating point calculations
|
||||
cls
|
||||
echo The 24 Game
|
||||
echo.
|
||||
echo Given four digits, provide a simple arithmetic expression
|
||||
echo that evaluates to 24 using +,-,*,/.
|
||||
echo.
|
||||
echo Enter 'SHOW' to show the digits or 'EXIT' to end the game.
|
||||
echo.
|
||||
|
||||
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"
|
||||
|
||||
goto SHOW
|
||||
|
||||
::Main Program Loop
|
||||
:MAIN
|
||||
set /a TRY+=1
|
||||
set "TMP_DIGIT_1=%DIGIT_1%"
|
||||
set "TMP_DIGIT_2=%DIGIT_2%"
|
||||
set "TMP_DIGIT_3=%DIGIT_3%"
|
||||
set "TMP_DIGIT_4=%DIGIT_4%"
|
||||
|
||||
::Promt for an answer and trim answer string
|
||||
set /p ANSWER="Try %TRY%: "
|
||||
set "ANSWER=%ANSWER: =%"
|
||||
|
||||
|
||||
if /i "%ANSWER%"=="SHOW" goto SHOW
|
||||
if /i "%ANSWER%"=="EXIT" goto ABORT
|
||||
if "%ANSWER:~6,1%"=="" goto ERROR_MISSING_CHARS:
|
||||
|
||||
::Determine if each digits has ben used once in the input equation
|
||||
set DIGITS_USED=0
|
||||
set COUNTER=0
|
||||
:LOOP
|
||||
call set CURR_DIGIT=%%ANSWER:~%COUNTER%,1%%
|
||||
if %CURR_DIGIT%==%TMP_DIGIT_1% (set "TMP_DIGIT_1=" & set /a "DIGITS_USED+=1")
|
||||
if %CURR_DIGIT%==%TMP_DIGIT_2% (set "TMP_DIGIT_2=" & set /a "DIGITS_USED+=2")
|
||||
if %CURR_DIGIT%==%TMP_DIGIT_3% (set "TMP_DIGIT_3=" & set /a "DIGITS_USED+=4")
|
||||
if %CURR_DIGIT%==%TMP_DIGIT_4% (set "TMP_DIGIT_4=" & set /a "DIGITS_USED+=8")
|
||||
set /a "COUNTER+=2"
|
||||
if not "%COUNTER%"=="8" goto LOOP
|
||||
if not "%DIGITS_USED%"=="15" goto ERROR_INCORRECT_INPUT
|
||||
|
||||
::Calculate and evaluate result
|
||||
set /a "RESULT=%ANSWER%"
|
||||
if "%RESULT%"=="24" goto END
|
||||
|
||||
echo Invalid input [Bad result: Expected 24, Received %RESULT%]
|
||||
goto MAIN
|
||||
|
||||
:ERROR_MISSING_CHARS
|
||||
echo Invalid input [insufficient number of characters]
|
||||
goto MAIN
|
||||
|
||||
:ERROR_INCORRECT_INPUT
|
||||
echo Invalid input [incorrect digits]
|
||||
goto MAIN
|
||||
|
||||
:SHOW
|
||||
echo Given digits: %DIGIT_1% %DIGIT_2% %DIGIT_3% %DIGIT_4%
|
||||
goto MAIN
|
||||
|
||||
:END
|
||||
echo Correct input [Congratulations!]
|
||||
|
||||
:ABORT
|
||||
echo.
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
chosen-digits)
|
||||
(read))
|
||||
(lose () (error 'bad-equation))
|
||||
(choose () (setf chosen-digits (loop repeat 4 collecting (random 10))))
|
||||
(choose () (setf chosen-digits (loop repeat 4 collecting (1+ (random 9)))))
|
||||
(check (e)
|
||||
(typecase e
|
||||
((eql bye) (return-from 24-game))
|
||||
|
|
|
|||
62
Task/24-game/Java/24-game.java
Normal file
62
Task/24-game/Java/24-game.java
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import java.util.*;
|
||||
|
||||
public class Game24 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
int[] digits = randomDigits();
|
||||
Scanner in = new Scanner(System.in);
|
||||
|
||||
System.out.print("Make 24 using these digits: ");
|
||||
System.out.println(Arrays.toString(digits));
|
||||
System.out.print("> ");
|
||||
|
||||
Stack<Float> s = new Stack<>();
|
||||
long total = 0;
|
||||
for (char c : in.nextLine().toCharArray()) {
|
||||
if ('0' <= c && c <= '9') {
|
||||
int d = c - '0';
|
||||
total += (1 << (d * 5));
|
||||
s.push((float) d);
|
||||
} else if ("+/-*".indexOf(c) != -1) {
|
||||
s.push(applyOperator(s.pop(), s.pop(), c));
|
||||
}
|
||||
}
|
||||
if (tallyDigits(digits) != total)
|
||||
System.out.print("Not the same digits. ");
|
||||
else if (Math.abs(24 - s.peek()) < 0.001F)
|
||||
System.out.println("Correct!");
|
||||
else
|
||||
System.out.print("Not correct.");
|
||||
}
|
||||
|
||||
static float applyOperator(float a, float b, char c) {
|
||||
switch (c) {
|
||||
case '+':
|
||||
return a + b;
|
||||
case '-':
|
||||
return b - a;
|
||||
case '*':
|
||||
return a * b;
|
||||
case '/':
|
||||
return b / a;
|
||||
default:
|
||||
return Float.NaN;
|
||||
}
|
||||
}
|
||||
|
||||
static long tallyDigits(int[] a) {
|
||||
long total = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
total += (1 << (a[i] * 5));
|
||||
return total;
|
||||
}
|
||||
|
||||
static int[] randomDigits() {
|
||||
Random r = new Random();
|
||||
int[] result = new int[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
result[i] = r.nextInt(9) + 1;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +1,51 @@
|
|||
String.prototype.replaceAll = function(patt,repl) { var that = this;
|
||||
that = that.replace(patt,repl);
|
||||
if (that.search(patt) != -1) {
|
||||
that = that.replaceAll(patt,repl);
|
||||
}
|
||||
return that;
|
||||
};
|
||||
function twentyfour(numbers, input) {
|
||||
var invalidChars = /[^\d\+\*\/\s-\(\)]/;
|
||||
|
||||
function validChars(input) { var regInvalidChar = /[^\d\+\*\/\s-\(\)]/;
|
||||
return input.search(regInvalidChar) == -1;
|
||||
}
|
||||
var validNums = function(str) {
|
||||
// Create a duplicate of our input numbers, so that
|
||||
// both lists will be sorted.
|
||||
var mnums = numbers.slice();
|
||||
mnums.sort();
|
||||
|
||||
function validNums(str, nums) {
|
||||
var arr, l;
|
||||
arr = str.replaceAll(/[^\d\s]/," ").replaceAll(" "," ").trim().split(" ").sort();
|
||||
l = arr.length;
|
||||
// Sort after mapping to numbers, to make comparisons valid.
|
||||
return str.replace(/[^\d\s]/g, " ")
|
||||
.trim()
|
||||
.split(/\s+/)
|
||||
.map(function(n) { return parseInt(n, 10); })
|
||||
.sort()
|
||||
.every(function(v, i) { return v === mnums[i]; });
|
||||
};
|
||||
|
||||
while(l--) { arr[l] = Number(arr[l]); }
|
||||
var validEval = function(input) {
|
||||
try {
|
||||
return eval(input);
|
||||
} catch (e) {
|
||||
return {error: e.toString()};
|
||||
}
|
||||
};
|
||||
|
||||
return _.isEqual(arr,nums.sort());
|
||||
if (input.trim() === "") return "You must enter a value.";
|
||||
if (input.match(invalidChars)) return "Invalid chars used, try again. Use only:\n + - * / ( )";
|
||||
if (!validNums(input)) return "Wrong numbers used, try again.";
|
||||
var calc = validEval(input);
|
||||
if (typeof calc !== 'number') return "That is not a valid input; please try again.";
|
||||
if (calc !== 24) return "Wrong answer: " + String(calc) + "; please try again.";
|
||||
return input + " == 24. Congratulations!";
|
||||
};
|
||||
|
||||
// I/O below.
|
||||
|
||||
while (true) {
|
||||
var numbers = [1, 2, 3, 4].map(function() {
|
||||
return Math.floor(Math.random() * 8 + 1);
|
||||
});
|
||||
|
||||
var input = prompt(
|
||||
"Your numbers are:\n" + numbers.join(" ") +
|
||||
"\nEnter expression. (use only + - * / and parens).\n", +"'x' to exit.", "");
|
||||
|
||||
if (input === 'x') {
|
||||
break;
|
||||
}
|
||||
alert(twentyfour(numbers, input));
|
||||
}
|
||||
|
||||
function validEval(input) { try { eval(input); } catch (e) { return false; };
|
||||
return true;
|
||||
}
|
||||
|
||||
var input;
|
||||
|
||||
while(true){ var numbers = [];
|
||||
var i = 4;
|
||||
while(i--) { numbers.push(Math.floor(Math.random()*8+1));
|
||||
}
|
||||
|
||||
input = prompt("Your numbers are:\n"
|
||||
+ numbers.join(" ")
|
||||
+ "\nEnter expression. (use only + - * / and parens).\n"
|
||||
+ "'x' to exit."
|
||||
);
|
||||
|
||||
if (input === 'x') break;
|
||||
|
||||
!validChars(input) ? alert("Invalid chars used, try again. Use only:\n + - * / ( )")
|
||||
: !validNums(input,numbers) ? alert("Wrong numbers used, try again.")
|
||||
: !validEval(input) ? alert("Could not evaluate input, try again.")
|
||||
: eval(input) != 24 ? alert("Wrong answer:" + eval(input) + "\nTry again.")
|
||||
: alert(input + "== 24. Congrats!!")
|
||||
;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,63 +1,28 @@
|
|||
validexpr(ex::Expr) = ex.head == :call && ex.args[1] in [:*,:/,:+,:-] && all(validexpr, ex.args[2:end])
|
||||
validexpr(ex::Int) = true
|
||||
validexpr(ex::Any) = false
|
||||
findnumbers(ex::Number) = Int[ex]
|
||||
findnumbers(ex::Expr) = vcat(map(findnumbers, ex.args)...)
|
||||
findnumbers(ex::Any) = Int[]
|
||||
function twentyfour()
|
||||
function check(input)
|
||||
d = ref(Int)
|
||||
for i in input.args
|
||||
if typeof(i) == Expr
|
||||
c = check(i)
|
||||
typeof(c) == String || append!(d,c)
|
||||
elseif contains([:*,:/,:-,:+],i)
|
||||
continue
|
||||
elseif contains([1:9],i)
|
||||
push!(d,i)
|
||||
continue
|
||||
elseif i > 9 || i < 1
|
||||
d = "Sorry, $i is not allowed, please use only numbers between 1 and 9"
|
||||
else
|
||||
d = "Sorry, $i isn't allowed"
|
||||
end
|
||||
end
|
||||
return d
|
||||
end
|
||||
new_digits() = [rand(1:9),rand(1:9),rand(1:9),rand(1:9)]
|
||||
answer = new_digits()
|
||||
print("The 24 Game\nYou will be given any four digits in the range 1 to 9, which may have repetitions.\n
|
||||
Using just the +, -, *, and / operators show how to make an answer of 24.\n
|
||||
Use parentheses, (), to ensure proper order of evaulation.\n
|
||||
Enter 'n' fDouble>()
|
||||
|
||||
while( scanner.hasNext() ) {
|
||||
if( scanner.hasNextInt() ) {
|
||||
var n = scanner.nextInt()
|
||||
|
||||
// Make sure they're allowed to use n
|
||||
if( n or a new set of digits, and 'q' to quit. Good luck!\n
|
||||
Here's your first 4 digits\n$(answer[1]) $(answer[2]) $(answer[3]) $(answer[4])\n
|
||||
>")
|
||||
while true
|
||||
input = chomp(readline(STDIN))
|
||||
input == "q" && break
|
||||
if input == "n"
|
||||
answer = new_digits()
|
||||
print("\nLet's try again, go ahead and guess\n Here's your 4 digits\n$(answer[1]) $(answer[2]) $(answer[3]) $(answer[4])\n>")
|
||||
continue
|
||||
end
|
||||
input = try
|
||||
parse(input)
|
||||
catch
|
||||
print("I couldn't calculate your answer, please try again\n>");
|
||||
continue
|
||||
end
|
||||
c = check(input)
|
||||
cc = all([sum(i .== answer) == sum(i .== c) for i in answer])
|
||||
!cc && (print("Sorry, valid digits are \n$(answer[1]) $(answer[2]) $(answer[3]) $(answer[4])\n are allowed and all four must be used. Please try again\n>"); continue)
|
||||
if eval(input) == 24
|
||||
answer = new_digits()
|
||||
print("\nYou did it!\nLet's do another round, or enter 'q' to quit\n
|
||||
Here's your 4 digits\n$(answer[1]) $(answer[2]) $(answer[3]) $(answer[4])\n
|
||||
>")
|
||||
continue
|
||||
else
|
||||
print("\nSorry your answer calculates to $(eval(input))\nTry again\n>")
|
||||
end
|
||||
end
|
||||
digits = sort!(rand(1:9, 4))
|
||||
while true
|
||||
print("enter expression using $digits => ")
|
||||
ex = parse(readline())
|
||||
try
|
||||
validexpr(ex) || error("only *, /, +, - of integers is allowed")
|
||||
nums = sort!(findnumbers(ex))
|
||||
nums == digits || error("expression $ex used numbers $nums != $digits")
|
||||
val = eval(ex)
|
||||
val == 24 || error("expression $ex evaluated to $val, not 24")
|
||||
println("you won!")
|
||||
return
|
||||
catch e
|
||||
if isa(e, ErrorException)
|
||||
println("incorrect: ", e.msg)
|
||||
else
|
||||
rethrow()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,38 +1,23 @@
|
|||
say "Here are your digits: ",
|
||||
constant @digits = (1..9).roll(4)».Str;
|
||||
|
||||
grammar Exp24 {
|
||||
token TOP { ^ <exp> $ }
|
||||
token exp { <term> [ <op> <term> ]* }
|
||||
token term { '(' <exp> ')' | \d }
|
||||
token op { '+' | '-' | '*' | '/' }
|
||||
token TOP { ^ <exp> $ { fail unless EVAL($/) == 24 } }
|
||||
rule exp { <term>+ % <op> }
|
||||
rule term { '(' <exp> ')' | <@digits> }
|
||||
token op { < + - * / > }
|
||||
}
|
||||
|
||||
my @digits = roll 4, 1..9; # to a gamer, that's a "4d9" roll
|
||||
say "Here's your digits: {@digits}";
|
||||
|
||||
while my $exp = prompt "\n24-Exp? " {
|
||||
unless is-valid($exp, @digits) {
|
||||
say "Sorry, your expression is not valid!";
|
||||
next;
|
||||
while my $exp = prompt "\n24? " {
|
||||
if Exp24.parse: $exp {
|
||||
say "You win :)";
|
||||
last;
|
||||
} else {
|
||||
say pick 1,
|
||||
'Sorry. Try again.' xx 20,
|
||||
'Try harder.' xx 5,
|
||||
'Nope. Not even close.' xx 2,
|
||||
'Are you five or something?',
|
||||
'Come on, you can do better than that.';
|
||||
}
|
||||
|
||||
my $value = eval $exp;
|
||||
say "$exp = $value";
|
||||
if $value == 24 {
|
||||
say "You win!";
|
||||
last;
|
||||
}
|
||||
say "Sorry, your expression doesn't evaluate to 24!";
|
||||
}
|
||||
|
||||
sub is-valid($exp, @digits) {
|
||||
unless ?Exp24.parse($exp) {
|
||||
say "Expression doesn't match rules!";
|
||||
return False;
|
||||
}
|
||||
|
||||
unless $exp.comb(/\d/).sort.join == @digits.sort.join {
|
||||
say "Expression must contain digits {@digits} only!";
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,122 +1,46 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
#!/usr/bin/env perl
|
||||
use warnings;
|
||||
use strict;
|
||||
use feature 'say';
|
||||
|
||||
print <<'EOF';
|
||||
The 24 Game
|
||||
|
||||
Given any four digits in the range 1 to 9, which may have repetitions,
|
||||
Using just the +, -, *, and / operators; and the possible use of
|
||||
brackets, (), show how to make an answer of 24.
|
||||
parentheses, (), show how to make an answer of 24.
|
||||
|
||||
An answer of "q" will quit the game.
|
||||
An answer of "!" will generate a new set of four digits.
|
||||
Otherwise you are repeatedly asked for an expression until it evaluates to 24
|
||||
An answer of "q" or EOF will quit the game.
|
||||
A blank answer will generate a new set of four digits.
|
||||
Otherwise you are repeatedly asked for an expression until it evaluates to 24.
|
||||
|
||||
Note: you cannot form multiple digit numbers from the supplied digits,
|
||||
so an answer of 12+12 when given 1, 2, 2, and 1 would not be allowed.
|
||||
EOF
|
||||
|
||||
while(1)
|
||||
{
|
||||
my $iteration_num = 0;
|
||||
my $try = 1;
|
||||
while (1) {
|
||||
my @digits = map { 1+int(rand(9)) } 1..4;
|
||||
say "\nYour four digits: ", join(" ", @digits);
|
||||
print "Expression (try ", $try++, "): ";
|
||||
|
||||
my $numbers = make_numbers();
|
||||
my $entry = <>;
|
||||
if (!defined $entry || $entry eq 'q')
|
||||
{ say "Goodbye. Sorry you couldn't win."; last; }
|
||||
$entry =~ s/\s+//g; # remove all white space
|
||||
next if $entry eq '';
|
||||
|
||||
TRY_SOLVING:
|
||||
while(1)
|
||||
{
|
||||
$iteration_num++;
|
||||
print "Expression ${iteration_num}: ";
|
||||
my $given_digits = join "", sort @digits;
|
||||
my $entry_digits = join "", sort grep { /\d/ } split(//, $entry);
|
||||
if ($given_digits ne $entry_digits || # not correct digits
|
||||
$entry =~ /\d\d/ || # combined digits
|
||||
$entry =~ m|[-+*/]{2}| || # combined operators
|
||||
$entry =~ tr|-0-9()+*/||c) # Invalid characters
|
||||
{ say "That's not valid"; next; }
|
||||
|
||||
my $entry = <>;
|
||||
chomp($entry);
|
||||
my $n = eval $entry;
|
||||
|
||||
last TRY_SOLVING if $entry eq '!';
|
||||
|
||||
exit if $entry eq 'q';
|
||||
|
||||
my $result = play($numbers, $entry);
|
||||
|
||||
if (!defined $result)
|
||||
{
|
||||
print "That's not valid\n";
|
||||
next TRY_SOLVING;
|
||||
}
|
||||
elsif ($result != 24)
|
||||
{
|
||||
print "Sorry, that's $result\n";
|
||||
next TRY_SOLVING;
|
||||
}
|
||||
else
|
||||
{
|
||||
print "That's right! 24!!\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub make_numbers
|
||||
{
|
||||
my %numbers = ();
|
||||
|
||||
print "Your four digits:";
|
||||
|
||||
for(1..4)
|
||||
{
|
||||
my $i = 1 + int(rand(9));
|
||||
$numbers{$i}++;
|
||||
print "$i ";
|
||||
}
|
||||
|
||||
print "\n";
|
||||
|
||||
return \%numbers;
|
||||
}
|
||||
|
||||
sub play
|
||||
{
|
||||
my ($numbers, $expression) = @_;
|
||||
|
||||
my %running_numbers = %$numbers;
|
||||
|
||||
my @chars = split //, $expression;
|
||||
|
||||
my $operator = 1;
|
||||
|
||||
CHARS:
|
||||
foreach (@chars)
|
||||
{
|
||||
next CHARS if $_ =~ /[()]/;
|
||||
|
||||
$operator = !$operator;
|
||||
|
||||
if (! $operator)
|
||||
{
|
||||
if (defined $running_numbers{$_} && $running_numbers{$_} > 0)
|
||||
{
|
||||
$running_numbers{$_}--;
|
||||
next CHARS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return if $_ !~ m{[-+*/]};
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $remaining (values(%running_numbers))
|
||||
{
|
||||
if ($remaining > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return eval($expression);
|
||||
if (!defined $n) { say "Invalid expression"; }
|
||||
elsif ($n == 24) { say "You win!"; last; }
|
||||
else { say "Sorry, your expression is $n, not 24"; }
|
||||
}
|
||||
|
|
|
|||
30
Task/24-game/Prolog/24-game.pro
Normal file
30
Task/24-game/Prolog/24-game.pro
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
:- initialization(main).
|
||||
|
||||
|
||||
answer(24).
|
||||
play :- round, play ; true.
|
||||
|
||||
round :-
|
||||
prompt(Ns), get_line(Input), Input \= "stop"
|
||||
, ( phrase(parse(Ns,[]), Input) -> Result = 'correct'
|
||||
; Result = 'wrong'
|
||||
), write(Result), nl, nl
|
||||
. % where
|
||||
prompt(Ns) :- length(Ns,4), maplist(random(1,10), Ns)
|
||||
, write('Digits: '), write(Ns), nl
|
||||
.
|
||||
|
||||
parse([],[X]) --> { answer(X) }.
|
||||
parse(Ns,[Y,X|S]) --> "+", { Z is X + Y }, parse(Ns,[Z|S]).
|
||||
parse(Ns,[Y,X|S]) --> "-", { Z is X - Y }, parse(Ns,[Z|S]).
|
||||
parse(Ns,[Y,X|S]) --> "*", { Z is X * Y }, parse(Ns,[Z|S]).
|
||||
parse(Ns,[Y,X|S]) --> "/", { Z is X div Y }, parse(Ns,[Z|S]).
|
||||
parse(Ns,Stack) --> " ", parse(Ns,Stack).
|
||||
parse(Ns,Stack) --> { select(N,Ns,Ns1), number_codes(N,[Code]) }
|
||||
, [Code], parse(Ns1,[N|Stack])
|
||||
.
|
||||
|
||||
get_line(Xs) :- get_code(X)
|
||||
, ( X == 10 -> Xs = [] ; Xs = [X|Ys], get_line(Ys) )
|
||||
.
|
||||
main :- randomize, play, halt.
|
||||
|
|
@ -1,204 +1,22 @@
|
|||
/*REXX program which allows a user to play the game of 24 (twenty-four).*/
|
||||
/*
|
||||
╔══════════════════════════════════════════════════════════════════╗
|
||||
║ Argument is either of three forms: (blank) ║
|
||||
║ ssss ║
|
||||
║ ssss-ffff ║
|
||||
║ ║
|
||||
║ where one or both strings must be exactly four numerals (digits) ║
|
||||
║ comprised soley of the numerals (digits) 1 ──> 9 (no zeroes). ║
|
||||
║ ║
|
||||
║ SSSS is the start, ║
|
||||
║ FFFF is the start. ║
|
||||
║ ║
|
||||
║ If no argument is specified, this program finds a four digit ║
|
||||
║ number (no zeroes) which has at least one solution, and shows ║
|
||||
║ the number to the user, requesting that they enter a solution ║
|
||||
║ in the form of: w operator x operator y operator z ║
|
||||
║ where w x y and z are single digit numbers (no zeroes), ║
|
||||
║ and operator can be any one of: + - * / ║
|
||||
║ Parentheses () may be used in the normal manner for grouping, ║
|
||||
║ as well as brackets [] or braces {}. ║
|
||||
╚══════════════════════════════════════════════════════════════════╝ */
|
||||
parse arg orig /*get the guess from the argument. */
|
||||
orig=space(orig,0) /*remove extraneous blanks from ORIG. */
|
||||
parse var orig start '-' finish /*get the start and finish (maybe). */
|
||||
finish=word(finish start,1) /*if no FINISH specified, use START.*/
|
||||
opers='+-*/' /*define the legal arithmetic operators*/
|
||||
ops=length(opers) /* ... and the count of them (length). */
|
||||
groupsymbols='()[]{}' /*legal grouping symbols. */
|
||||
indent=left('',30) /*used to indent display of solutions. */
|
||||
Lpar='(' /*a string to make REXX code prettier. */
|
||||
Rpar=')' /*ditto. */
|
||||
show=1 /*flag used show solutions (0 = not). */
|
||||
digs=123456789 /*numerals (digits) that can be used. */
|
||||
|
||||
do j=1 for ops /*define a version for fast execution. */
|
||||
o.j=substr(opers,j,1)
|
||||
end /*j*/
|
||||
|
||||
if orig\=='' then do
|
||||
sols=solve(start,finish)
|
||||
if sols<0 then exit 13
|
||||
if sols==0 then sols='No' /*un-geek the SOLS var.*/
|
||||
say; say sols 'unique solution's(finds) "found for" orig
|
||||
exit /* [↑] "S" pluralizes.*/
|
||||
end
|
||||
show=0 /*stop SOLVE from blabbing solutions. */
|
||||
do forever
|
||||
rrrr=random(1111,9999)
|
||||
if pos(0,rrrr)\==0 then iterate
|
||||
if solve(rrrr)\==0 then leave
|
||||
end /*forever*/
|
||||
show=1 /*enable SOLVE to show solutions. */
|
||||
rrrr=sort(rrrr) /*sort four elements. */
|
||||
rd.=0
|
||||
do j=1 for 9 /*digit count # for each digit in RRRR.*/
|
||||
_=substr(rrrr,j,1)
|
||||
rd._=countdigs(rrrr,_)
|
||||
end /*j*/
|
||||
|
||||
do guesses=1; say
|
||||
say 'Using the digits' rrrr", enter an expression that equals 24 (or QUIT):"
|
||||
pull y; y=space(y,0) /*get Y from CL, then remove all blanks*/
|
||||
if y=='QUIT' then exit /*Does user want to quit? If so, exit.*/
|
||||
_v=verify(y, digs || opers || groupsymbols); __=substr(y, _v, 1)
|
||||
if _v\==0 then do; call ger 'invalid character:' __; iterate; end
|
||||
if pos('**',y) then do; call ger 'invalid ** operator'; iterate; end
|
||||
if pos('//',y) then do; call ger 'invalid // operator'; iterate; end
|
||||
yL=length(y)
|
||||
if y=='' then do; call validate y; iterate; end
|
||||
|
||||
do j=1 for yL-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 guesses
|
||||
end /*j*/
|
||||
|
||||
yd=countdigs(y,digs) /*count of digits 123456789.*/
|
||||
if yd<4 then do
|
||||
call ger 'not enough digits entered.'
|
||||
iterate guesses
|
||||
end
|
||||
if yd>4 then do
|
||||
call ger 'too many digits entered.'
|
||||
iterate guesses
|
||||
end
|
||||
|
||||
do j=1 for 9; if rd.j==0 then iterate
|
||||
_d=countdigs(y,j)
|
||||
if _d==rd.j then iterate
|
||||
if _d<rd.j then call ger 'not enough' j "digits, must be" rd.j
|
||||
else call ger 'too many' j "digits, must be" rd.j
|
||||
iterate guesses
|
||||
end /*j*/
|
||||
|
||||
y=translate(y,'()()',"[]{}")
|
||||
signal on syntax
|
||||
interpret 'ans='y; ans=ans/1
|
||||
if ans==24 then leave guesses
|
||||
say 'incorrect,' y'='ans
|
||||
end /*guesses*/
|
||||
|
||||
say
|
||||
say center('┌─────────────────────┐', 79)
|
||||
say center('│ │', 79)
|
||||
say center('│ congratulations ! │', 79)
|
||||
say center('│ │', 79)
|
||||
say center('└─────────────────────┘', 79)
|
||||
exit
|
||||
/*───────────────────────────SOLVE subroutine───────────────────────────*/
|
||||
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
|
||||
if \validate(ffff) then return -1
|
||||
finds=0 /*number of found solutions (so far). */
|
||||
x.=0 /*a method to hold unique expressions. */
|
||||
/*alternative: indent=copies(' ',30) */
|
||||
|
||||
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 /*define a version for fast execution. */
|
||||
g.j=substr(g,j,1)
|
||||
end /*j*/
|
||||
|
||||
do i =1 for ops /*insert an operator after 1st number. */
|
||||
do j =1 for ops /*insert an operator after 2nd number. */
|
||||
do k =1 for ops /*insert an operator after 2nd number. */
|
||||
do m=0 to 4-1; L.="" /*assume no left parenthesis so far. */
|
||||
do n=m+1 to 4 /*match left paren with a right paren. */
|
||||
L.m=Lpar /*define a left paren, m=0 means ignore*/
|
||||
R.="" /*un-define all right parenthesis. */
|
||||
if m==1 & n==2 then L.="" /*special case: (n)+ ... */
|
||||
else if m\==0 then R.n=Rpar /*no (, no )*/
|
||||
e = L.1 g.1 o.i L.2 g.2 o.j L.3 g.3 R.3 o.k g.4 R.4
|
||||
e=space(e,0) /*remove all blanks from the expression*/
|
||||
|
||||
/*(below) change expression: */
|
||||
/* /(yyy) ===> /div(yyy) */
|
||||
/*Enables to check for division by zero*/
|
||||
origE=e /*keep old version for the display. */
|
||||
if pos('/(',e)\==0 then e=changestr('/(',e,"/div(")
|
||||
/*The above could be replaced by: */
|
||||
/* e=changestr('/(',e,"/div(") */
|
||||
|
||||
/*INTERPRET stresses REXX's groin, */
|
||||
/*so try to avoid repeated lifting. */
|
||||
if x.e then iterate /*was the expression already used? */
|
||||
x.e=1 /*mark this expression as unique. */
|
||||
/*have REXX do the heavy lifting. */
|
||||
interpret 'x=' e
|
||||
x=x/1 /*remove trailing decimal points. */
|
||||
if x\==24 then iterate /*Not correct? Try again.*/
|
||||
finds=finds+1 /*bump number of found solutions. */
|
||||
_=translate(origE, '][', ")(") /*show [], not ().*/
|
||||
if show then say indent 'a solution:' _ /*show solution.*/
|
||||
end /*n*/
|
||||
end /*m*/
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
end /*i*/
|
||||
end /*g*/
|
||||
|
||||
return finds
|
||||
/*───────────────────────────CHANGESTR subroutine───────────────────────*/
|
||||
changestr: procedure; parse arg o,h,n,,r; w=length(o); if w==0 then return n||h
|
||||
do forever; parse var h y (o) _ +(w) h; if _=='' then return r||y; r=r||y||n; end
|
||||
/*───────────────────────────COUNTDIGS subroutine───────────────────────*/
|
||||
countdigs: arg field,numerals /*count of digits NUMERALS.*/
|
||||
return length(field)-length(space(translate(field,,numerals),0))
|
||||
/*───────────────────────────DIV subroutine─────────────────────────────*/
|
||||
div: procedure; parse arg q /*tests if dividing by 0 (zero). */
|
||||
if q=0 then q=1e9 /*if dividing by zero, change divisor. */
|
||||
return q /*changing Q invalidates the expression*/
|
||||
/*───────────────────────────GER subroutine─────────────────────────────*/
|
||||
ger: say; say '*** error! *** for argument:' y; say arg(1); say; errCode=1; return 0
|
||||
/*───────────────────────────S subroutine───────────────────────────────*/
|
||||
s: if arg(1)==1 then return ''; return 's' /*simple pluralizer.*/
|
||||
/*───────────────────────────SORT subroutine────────────────────────────*/
|
||||
sort: procedure; arg nnnn; L=length(nnnn)
|
||||
|
||||
do i=1 for L /*build an array of digits from NNNN.*/
|
||||
a.i=substr(nnnn,i,1) /*this enables SORT to sort an array. */
|
||||
end /*i*/
|
||||
|
||||
do j=1 for L; _=a.j
|
||||
do k=j+1 to L
|
||||
if a.k<_ then parse value a.j a.k with a.k a.j
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
return a.1 || a.2 || a.3 || a.4
|
||||
/*───────────────────────────SYNTAX subroutin───────────────────────────*/
|
||||
syntax: call ger 'illegal syntax in' y; exit
|
||||
/*───────────────────────────validate subroutine────────────────────────*/
|
||||
validate: parse arg y; errCode=0; _v=verify(y,digs)
|
||||
select
|
||||
when y=='' then call ger 'no digits entered.'
|
||||
when length(y)<4 then call ger 'not enough digits entered, must be 4'
|
||||
when length(y)>4 then call ger 'too many digits entered, must be 4'
|
||||
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 \errCode
|
||||
╔══════════════════════════════════════════════════════════════════════════╗
|
||||
║ Argument for the "24" program is either of three forms: (blank) ║
|
||||
║ ssss ║
|
||||
║ ssss-ffff ║
|
||||
║ ║
|
||||
║ where one or both strings must be exactly four numerals (digits) ║
|
||||
║ comprised soley of the numerals (digits) 1 ──► 9 (with no zeroes). ║
|
||||
║ ║
|
||||
║ SSSS is the start, ║
|
||||
║ FFFF is the finish. ║
|
||||
║ ║
|
||||
║ If no argument is specified, this program finds a four digit number with ║
|
||||
║ no zeroes) which has at least one solution, and shows the number to ║
|
||||
║ the user, requesting that they enter a solution in the form of: ║
|
||||
║ ║
|
||||
║ w operator x operator y operator z ║
|
||||
║ ║
|
||||
║ where w x y and z are single digit numbers (no zeroes). ║
|
||||
║ and operator can be any one of: + - * / ║
|
||||
║ Parentheses ( ), brackets [ ], and/or braces { } may be used in the║
|
||||
║ normal manner for grouping expressions. Leading signs are permitted. ║
|
||||
╚══════════════════════════════════════════════════════════════════════════╝
|
||||
|
|
|
|||
|
|
@ -1,25 +1,158 @@
|
|||
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
|
||||
/*REXX program which allows a user to play the game of 24 (twenty-four). */
|
||||
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 var yyy start '-' fin /*get the START and FINish (maybe). */
|
||||
fin = word(fin start,1) /*if no FINish specified, use START.*/
|
||||
opers = '+-*/' /*define the legal arithmetic operators*/
|
||||
ops = length(opers) /* ··· and the count of them (length). */
|
||||
groupSymbols = '()[]{}' /*legal grouping symbols for this game.*/
|
||||
indent = left('',30) /*used to indent display of solutions. */
|
||||
Lpar = '(' /*a string to make the output prettier.*/
|
||||
Rpar = ')' /*Ditto. [You can say that again.] */
|
||||
digs = 123456789 /*numerals (digits) that can be used. */
|
||||
show = 1 /*flag used show solutions (0 = not). */
|
||||
do j=1 for ops /*define a version for fast execution. */
|
||||
@.j=substr(opers,j,1) /*assign each operation to an array. */
|
||||
end /*j*/
|
||||
signal on syntax /*enable program to trap syntax errors.*/
|
||||
if yyy\=='' then do /*if START (or FINish), then solve 'em.*/
|
||||
sols=solve(start,fin) /*solve START ───► FINish. */
|
||||
if sols <0 then exit 13 /*Was there a problem with input? */
|
||||
if sols==0 then sols='No' /*Englishize the SOLS variable.*/
|
||||
say; say sols 'unique solution's(sols) "found for" yyy
|
||||
exit /*S [↑] does pluralizations. */
|
||||
end
|
||||
show=0 /*stop SOLVE from blabbing solutions.*/
|
||||
do forever; rrrr=random(1111, 9999)
|
||||
if pos(0, rrrr)\==0 then iterate /*if contains a zero, ignore it*/
|
||||
if solve(rrrr)\==0 then leave /*if solved, then stop looking.*/
|
||||
end /*forever*/
|
||||
show=1 /*enable SOLVE to display solutions. */
|
||||
rrrr=sort(rrrr) /*sort four digits (for consistancy). */
|
||||
$.=0
|
||||
do j=1 for length(rrrr) /*digit count for each digit in RRRR. */
|
||||
_=substr(rrrr, j, 1) /*pick off one of the digits in RRRR. */
|
||||
$._=countDigs(rrrr, _) /*define the count for this digit. */
|
||||
end /*j*/ /* [↑] counts duplicates twice, no harm*/
|
||||
|
||||
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)*/
|
||||
pull y; y=space(y,0) /*get Y from CL, then remove all blanks*/
|
||||
if abbrev('QUIT',y,1) then exit /*Does the user want to quit this game?*/
|
||||
_v=verify(y, digs || opers || groupSymbols); a=substr(y, max(1,_v), 1)
|
||||
if _v\==0 then do; call ger 'invalid character:' a; iterate; end
|
||||
if pos('**',y) then do; call ger 'invalid ** operator'; iterate; end
|
||||
if pos('//',y) then do; call ger 'invalid // operator'; iterate; end
|
||||
yL=length(y)
|
||||
if y=='' then do; call validate y; iterate; end
|
||||
|
||||
do j=1 for yL-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*/
|
||||
|
||||
y=translate(y, '()()', "[]{}")
|
||||
interpret 'ans=' 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)
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────one─liner subroutines─────────────────────*/
|
||||
countDigs: arg ?; return length(?) - length(space(translate(?, , arg(2)), 0))
|
||||
div: if arg(1)=0 then return 7e9; return arg(1) /*if ÷ by 0, fudge result*/
|
||||
ger: say; say '***error!*** for argument:' y; say arg(1); say;errCode=1;return 0
|
||||
s: if arg(1)==1 then return ''; return 's' /*simple pluralizer.*/
|
||||
syntax: call ger 'illegal syntax in' y; exit
|
||||
/*──────────────────────────────────SOLVE subroutine──────────────────────────*/
|
||||
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) */
|
||||
|
||||
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 /*define a version for fast execution. */
|
||||
g.j=substr(g, j, 1) /*extract each digit of G into array.*/
|
||||
end /*j*/
|
||||
|
||||
do i =1 for ops /*insert an operator after 1st number. */
|
||||
do j =1 for ops /*insert an operator after 2nd number. */
|
||||
do k =1 for ops /*insert an operator after 2nd number. */
|
||||
do m=0 to 3; L.= /*assume no left parenthesis so far. */
|
||||
do n=m+1 to 4 /*match left paren with a right paren. */
|
||||
L.m=Lpar /*define a left paren, m=0 means ignore*/
|
||||
R.= /*un-define all right parenthesis. */
|
||||
if m==1 & n==2 then L.= /*special case of : (n) + ··· */
|
||||
else if m\==0 then R.n=Rpar /*no (, no )*/
|
||||
e = L.1 g.1 @.i L.2 g.2 @.j L.3 g.3 R.3 @.k g.4 R.4
|
||||
e=space(e, 0) /*remove all blanks from the expression*/
|
||||
/* [↓] change expression: */
|
||||
/* /(yyy) ═══► /div(yyy) */
|
||||
/*Enables to check for division by zero*/
|
||||
yyyE=e /*keep old the version for the display.*/
|
||||
if pos('/(', e)\==0 then e=changestr( '/(', e, "/div(" )
|
||||
/* [↓] INTERPRET stresses REXX's groin,*/
|
||||
/* so try to avoid repeated lifting.*/
|
||||
if !.e then iterate /*was this expression already used? */
|
||||
!.e=1 /*mark this expression as being used. */
|
||||
interpret 'x=' e /*have REXX do all the heavy lifting */
|
||||
x=x/1 /*remove any trailing decimal point. */
|
||||
if x\==24 then iterate /*Is the result incorrect? Try again. */
|
||||
#=#+1 /*bump number of found solutions. */
|
||||
_=translate(yyyE, '][', ")(") /*display [], not (). */
|
||||
if show then say indent 'a solution:' _
|
||||
end /*n*/ /* [↑] show a solution.*/
|
||||
end /*m*/
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
end /*i*/
|
||||
end /*g*/
|
||||
|
||||
return #
|
||||
/*──────────────────────────────────SORT subroutine───────────────────────────*/
|
||||
sort: procedure; arg nnnn; L=length(nnnn)
|
||||
|
||||
do i=1 for L /*build an array of digits from NNNN. */
|
||||
s.i=substr(nnnn, i, 1) /*this enables SORT to sort an array. */
|
||||
end /*i*/
|
||||
|
||||
do j=1 for L; _=s.j
|
||||
do k=j+1 to L
|
||||
if s.k<_ then parse value s.j s.k with s.k s.j
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
return s.1 || s.2 || s.3 || s.4
|
||||
/*──────────────────────────────────VALIDATE subroutine───────────────────────*/
|
||||
validate: parse arg y; errCode=0; _v=verify(y,digs)
|
||||
select
|
||||
when y=='' then call ger 'no digits entered.'
|
||||
when length(y)<4 then call ger 'not enough digits entered, must be four.'
|
||||
when length(y)>4 then call ger 'too many digits entered, must be four.'
|
||||
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 \errCode
|
||||
|
|
|
|||
25
Task/24-game/REXX/24-game-3.rexx
Normal file
25
Task/24-game/REXX/24-game-3.rexx
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
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,4 +1,4 @@
|
|||
require "rational"
|
||||
require "rational" # for Ruby versions before 2.0
|
||||
|
||||
def play
|
||||
digits = Array.new(4){rand(1..9)}
|
||||
|
|
|
|||
30
Task/24-game/UNIX-Shell/24-game.sh
Normal file
30
Task/24-game/UNIX-Shell/24-game.sh
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
gen_digits() {
|
||||
awk 'BEGIN { srand()
|
||||
for(i = 1; i <= 4; i++) print 1 + int(9 * rand())
|
||||
}' | sort
|
||||
}
|
||||
|
||||
same_digits() {
|
||||
[ "$(tr -dc 0-9 | sed 's/./&\n/g' | grep . | sort)" = "$*" ]
|
||||
}
|
||||
|
||||
guessed() {
|
||||
[ "$(echo "$1" | tr -dc '\n0-9()*/+-' | bc 2>/dev/null)" = 24 ]
|
||||
}
|
||||
|
||||
|
||||
while :
|
||||
do
|
||||
digits=$(gen_digits)
|
||||
echo
|
||||
echo Digits: $digits
|
||||
read -r expr
|
||||
|
||||
echo " $expr" | same_digits "$digits" || \
|
||||
{ echo digits should be: $digits; continue; }
|
||||
|
||||
guessed "$expr" && message=correct \
|
||||
|| message=wrong
|
||||
|
||||
echo $message
|
||||
done
|
||||
Loading…
Add table
Add a link
Reference in a new issue