September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -1,87 +0,0 @@
|
|||
# This program tries to find some way to turn four digits into an arithmetic
|
||||
# expression that adds up to 24.
|
||||
#
|
||||
# Example solution for 5, 7, 8, 8:
|
||||
# (((8 + 7) * 8) / 5)
|
||||
|
||||
|
||||
solve_24_game = (digits...) ->
|
||||
# Create an array of objects for our helper functions
|
||||
arr = for digit in digits
|
||||
{
|
||||
val: digit
|
||||
expr: digit
|
||||
}
|
||||
combo4 arr...
|
||||
|
||||
combo4 = (a, b, c, d) ->
|
||||
arr = [a, b, c, d]
|
||||
# Reduce this to a three-node problem by combining two
|
||||
# nodes from the array.
|
||||
permutations = [
|
||||
[0, 1, 2, 3]
|
||||
[0, 2, 1, 3]
|
||||
[0, 3, 1, 2]
|
||||
[1, 2, 0, 3]
|
||||
[1, 3, 0, 2]
|
||||
[2, 3, 0, 1]
|
||||
]
|
||||
for permutation in permutations
|
||||
[i, j, k, m] = permutation
|
||||
for combo in combos arr[i], arr[j]
|
||||
answer = combo3 combo, arr[k], arr[m]
|
||||
return answer if answer
|
||||
null
|
||||
|
||||
combo3 = (a, b, c) ->
|
||||
arr = [a, b, c]
|
||||
permutations = [
|
||||
[0, 1, 2]
|
||||
[0, 2, 1]
|
||||
[1, 2, 0]
|
||||
]
|
||||
for permutation in permutations
|
||||
[i, j, k] = permutation
|
||||
for combo in combos arr[i], arr[j]
|
||||
answer = combo2 combo, arr[k]
|
||||
return answer if answer
|
||||
null
|
||||
|
||||
combo2 = (a, b) ->
|
||||
for combo in combos a, b
|
||||
return combo.expr if combo.val == 24
|
||||
null
|
||||
|
||||
combos = (a, b) ->
|
||||
[
|
||||
val: a.val + b.val
|
||||
expr: "(#{a.expr} + #{b.expr})"
|
||||
,
|
||||
val: a.val * b.val
|
||||
expr: "(#{a.expr} * #{b.expr})"
|
||||
,
|
||||
val: a.val - b.val
|
||||
expr: "(#{a.expr} - #{b.expr})"
|
||||
,
|
||||
val: b.val - a.val
|
||||
expr: "(#{b.expr} - #{a.expr})"
|
||||
,
|
||||
val: a.val / b.val
|
||||
expr: "(#{a.expr} / #{b.expr})"
|
||||
,
|
||||
val: b.val / a.val
|
||||
expr: "(#{b.expr} / #{a.expr})"
|
||||
,
|
||||
]
|
||||
|
||||
# test
|
||||
do ->
|
||||
rand_digit = -> 1 + Math.floor (9 * Math.random())
|
||||
|
||||
for i in [1..15]
|
||||
a = rand_digit()
|
||||
b = rand_digit()
|
||||
c = rand_digit()
|
||||
d = rand_digit()
|
||||
solution = solve_24_game a, b, c, d
|
||||
console.log "Solution for #{[a,b,c,d]}: #{solution ? 'no solution'}"
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
> coffee 24_game.coffee
|
||||
Solution for 8,3,1,8: ((1 + 8) * (8 / 3))
|
||||
Solution for 6,9,5,7: (6 - ((5 - 7) * 9))
|
||||
Solution for 4,2,1,1: no solution
|
||||
Solution for 3,5,1,3: (((3 + 5) * 1) * 3)
|
||||
Solution for 6,4,1,7: ((7 - (4 - 1)) * 6)
|
||||
Solution for 8,1,3,1: (((8 + 1) - 1) * 3)
|
||||
Solution for 6,1,3,3: (((6 + 1) * 3) + 3)
|
||||
Solution for 7,1,5,6: (((7 - 1) * 5) - 6)
|
||||
Solution for 4,2,3,1: ((3 + 1) * (4 + 2))
|
||||
Solution for 8,8,5,8: ((5 * 8) - (8 + 8))
|
||||
Solution for 3,8,4,1: ((1 - (3 - 8)) * 4)
|
||||
Solution for 6,4,3,8: ((8 - (6 / 3)) * 4)
|
||||
Solution for 2,1,8,7: (((2 * 8) + 1) + 7)
|
||||
Solution for 5,2,7,5: ((2 * 7) + (5 + 5))
|
||||
Solution for 2,4,8,9: ((9 - (2 + 4)) * 8)
|
||||
99
Task/24-game-Solve/Kotlin/24-game-solve.kotlin
Normal file
99
Task/24-game-Solve/Kotlin/24-game-solve.kotlin
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
// version 1.1.3
|
||||
|
||||
import java.util.Random
|
||||
|
||||
const val N_CARDS = 4
|
||||
const val SOLVE_GOAL = 24
|
||||
const val MAX_DIGIT = 9
|
||||
|
||||
class Frac(val num: Int, val den: Int)
|
||||
|
||||
enum class OpType { NUM, ADD, SUB, MUL, DIV }
|
||||
|
||||
class Expr(
|
||||
var op: OpType = OpType.NUM,
|
||||
var left: Expr? = null,
|
||||
var right: Expr? = null,
|
||||
var value: Int = 0
|
||||
)
|
||||
|
||||
fun showExpr(e: Expr?, prec: OpType, isRight: Boolean) {
|
||||
if (e == null) return
|
||||
val op = when (e.op) {
|
||||
OpType.NUM -> { print(e.value); return }
|
||||
OpType.ADD -> " + "
|
||||
OpType.SUB -> " - "
|
||||
OpType.MUL -> " x "
|
||||
OpType.DIV -> " / "
|
||||
}
|
||||
|
||||
if ((e.op == prec && isRight) || e.op < prec) print("(")
|
||||
showExpr(e.left, e.op, false)
|
||||
print(op)
|
||||
showExpr(e.right, e.op, true)
|
||||
if ((e.op == prec && isRight) || e.op < prec) print(")")
|
||||
}
|
||||
|
||||
fun evalExpr(e: Expr?): Frac {
|
||||
if (e == null) return Frac(0, 1)
|
||||
if (e.op == OpType.NUM) return Frac(e.value, 1)
|
||||
val l = evalExpr(e.left)
|
||||
val r = evalExpr(e.right)
|
||||
return when (e.op) {
|
||||
OpType.ADD -> Frac(l.num * r.den + l.den * r.num, l.den * r.den)
|
||||
OpType.SUB -> Frac(l.num * r.den - l.den * r.num, l.den * r.den)
|
||||
OpType.MUL -> Frac(l.num * r.num, l.den * r.den)
|
||||
OpType.DIV -> Frac(l.num * r.den, l.den * r.num)
|
||||
else -> throw IllegalArgumentException("Unknown op: ${e.op}")
|
||||
}
|
||||
}
|
||||
|
||||
fun solve(ea: Array<Expr?>, len: Int): Boolean {
|
||||
if (len == 1) {
|
||||
val final = evalExpr(ea[0])
|
||||
if (final.num == final.den * SOLVE_GOAL && final.den != 0) {
|
||||
showExpr(ea[0], OpType.NUM, false)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
val ex = arrayOfNulls<Expr>(N_CARDS)
|
||||
for (i in 0 until len - 1) {
|
||||
for (j in i + 1 until len) ex[j - 1] = ea[j]
|
||||
val node = Expr()
|
||||
ex[i] = node
|
||||
for (j in i + 1 until len) {
|
||||
node.left = ea[i]
|
||||
node.right = ea[j]
|
||||
for (k in OpType.values().drop(1)) {
|
||||
node.op = k
|
||||
if (solve(ex, len - 1)) return true
|
||||
}
|
||||
node.left = ea[j]
|
||||
node.right = ea[i]
|
||||
node.op = OpType.SUB
|
||||
if (solve(ex, len - 1)) return true
|
||||
node.op = OpType.DIV
|
||||
if (solve(ex, len - 1)) return true
|
||||
ex[j] = ea[j]
|
||||
}
|
||||
ex[i] = ea[i]
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun solve24(n: IntArray) =
|
||||
solve (Array(N_CARDS) { Expr(value = n[it]) }, N_CARDS)
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val r = Random()
|
||||
val n = IntArray(N_CARDS)
|
||||
for (j in 0..9) {
|
||||
for (i in 0 until N_CARDS) {
|
||||
n[i] = 1 + r.nextInt(MAX_DIGIT)
|
||||
print(" ${n[i]}")
|
||||
}
|
||||
print(": ")
|
||||
println(if (solve24(n)) "" else "No solution")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
editvar /modify -random- = <10
|
||||
:a
|
||||
editvar /newvar /withothervar /value=-random- /title=1
|
||||
editvar /newvar /withothervar /value=-random- /title=2
|
||||
editvar /newvar /withothervar /value=-random- /title=3
|
||||
editvar /newvar /withothervar /value=-random- /title=4
|
||||
printline These are your four digits: -1- -2- -3- -4-
|
||||
printline Use an algorithm to make the number 24.
|
||||
editvar /newvar /value=a /userinput=1 /title=Algorithm:
|
||||
do -a-
|
||||
if -a- /hasvalue 24 printline Your algorithm worked! & goto :b (
|
||||
) else printline Your algorithm did not work.
|
||||
editvar /newvar /value=b /userinput=1 /title=Do you want to see how you could have done it?
|
||||
if -b- /hasvalue y goto :c else goto :b
|
||||
:b
|
||||
editvar /newvar /value=c /userinput=1 /title=Do you want to play again?
|
||||
if -c- /hasvalue y goto :a else exitcurrentprogram
|
||||
:c
|
||||
editvar /newvar /value=do -1- + -2- + -3- + -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
editvar /newvar /value=do -1- - -2- + -3- + -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
editvar /newvar /value=do -1- / -2- + -3- + -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
editvar /newvar /value=do -1- * -2- + -3- + -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
editvar /newvar /value=do -1- + -2- - -3- + -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
editvar /newvar /value=do -1- + -2- / -3- + -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
editvar /newvar /value=do -1- + -2- * -3- + -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
editvar /newvar /value=do -1- + -2- + -3- - -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
editvar /newvar /value=do -1- + -2- + -3- / -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
editvar /newvar /value=do -1- + -2- + -3- * -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
editvar /newvar /value=do -1- - -2- - -3- - -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
editvar /newvar /value=do -1- / -2- / -3- / -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
editvar /newvar /value=do -1- * -2- * -3- * -4- /title=c & do -c- >d & if -d- /hasvalue 24 goto :solve
|
||||
:solve
|
||||
printline you could have done it by doing -c-
|
||||
stoptask
|
||||
goto :b
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
These are your four digits: 1 4 5 2
|
||||
Use an algorithm to make the number 24.
|
||||
Algorithm: 4 + 2 - 5 + 1
|
||||
Your algorithm did not work.
|
||||
Do you want to play again? y
|
||||
|
||||
These are your four digits: 1 8 9 6
|
||||
Use an algorithm to make the number 24.
|
||||
Algorithm: 1 + 8 + 9 + 6
|
||||
Your algorithm worked!
|
||||
Do you want to play again? n
|
||||
165
Task/24-game-Solve/Rust/24-game-solve.rust
Normal file
165
Task/24-game-Solve/Rust/24-game-solve.rust
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
#[derive(Clone, Copy, Debug)]
|
||||
enum Operator {
|
||||
Sub,
|
||||
Plus,
|
||||
Mul,
|
||||
Div,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Factor {
|
||||
content: String,
|
||||
value: i32,
|
||||
}
|
||||
|
||||
fn apply(op: Operator, left: &[Factor], right: &[Factor]) -> Vec<Factor> {
|
||||
let mut ret = Vec::new();
|
||||
for l in left.iter() {
|
||||
for r in right.iter() {
|
||||
use Operator::*;
|
||||
ret.push(match op {
|
||||
Sub if l.value > r.value => Factor {
|
||||
content: format!("({} - {})", l.content, r.content),
|
||||
value: l.value - r.value,
|
||||
},
|
||||
Plus => Factor {
|
||||
content: format!("({} + {})", l.content, r.content),
|
||||
value: l.value + r.value,
|
||||
},
|
||||
Mul => Factor {
|
||||
content: format!("({} x {})", l.content, r.content),
|
||||
value: l.value * r.value,
|
||||
},
|
||||
Div if l.value >= r.value && r.value > 0 && l.value % r.value == 0 => Factor {
|
||||
content: format!("({} / {})", l.content, r.content),
|
||||
value: l.value / r.value,
|
||||
},
|
||||
_ => continue,
|
||||
})
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn calc(op: [Operator; 3], numbers: [i32; 4]) -> Vec<Factor> {
|
||||
fn calc(op: &[Operator], numbers: &[i32], acc: &[Factor]) -> Vec<Factor> {
|
||||
use Operator::*;
|
||||
if op.is_empty() {
|
||||
return Vec::from(acc)
|
||||
}
|
||||
let mut ret = Vec::new();
|
||||
let mono_factor = [Factor {
|
||||
content: numbers[0].to_string(),
|
||||
value: numbers[0],
|
||||
}];
|
||||
match op[0] {
|
||||
Mul => ret.extend_from_slice(&apply(op[0], acc, &mono_factor)),
|
||||
Div => {
|
||||
ret.extend_from_slice(&apply(op[0], acc, &mono_factor));
|
||||
ret.extend_from_slice(&apply(op[0], &mono_factor, acc));
|
||||
},
|
||||
Sub => {
|
||||
ret.extend_from_slice(&apply(op[0], acc, &mono_factor));
|
||||
ret.extend_from_slice(&apply(op[0], &mono_factor, acc));
|
||||
},
|
||||
Plus => ret.extend_from_slice(&apply(op[0], acc, &mono_factor)),
|
||||
}
|
||||
calc(&op[1..], &numbers[1..], &ret)
|
||||
}
|
||||
calc(&op, &numbers[1..], &[Factor { content: numbers[0].to_string(), value: numbers[0] }])
|
||||
}
|
||||
|
||||
fn solutions(numbers: [i32; 4]) -> Vec<Factor> {
|
||||
use std::collections::hash_set::HashSet;
|
||||
let mut ret = Vec::new();
|
||||
let mut hash_set = HashSet::new();
|
||||
|
||||
for ops in OpIter(0) {
|
||||
for o in orders().iter() {
|
||||
let numbers = apply_order(numbers, o);
|
||||
let r = calc(ops, numbers);
|
||||
ret.extend(r.into_iter().filter(|&Factor { value, ref content }| value == 24 && hash_set.insert(content.to_owned())))
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut numbers = Vec::new();
|
||||
if let Some(input) = std::env::args().skip(1).next() {
|
||||
for c in input.chars() {
|
||||
if let Ok(n) = c.to_string().parse() {
|
||||
numbers.push(n)
|
||||
}
|
||||
if numbers.len() == 4 {
|
||||
let numbers = [numbers[0], numbers[1], numbers[2], numbers[3]];
|
||||
let solutions = solutions(numbers);
|
||||
let len = solutions.len();
|
||||
if len == 0 {
|
||||
println!("no solution for {}, {}, {}, {}", numbers[0], numbers[1], numbers[2], numbers[3]);
|
||||
return
|
||||
}
|
||||
println!("solutions for {}, {}, {}, {}", numbers[0], numbers[1], numbers[2], numbers[3]);
|
||||
for s in solutions {
|
||||
println!("{}", s.content)
|
||||
}
|
||||
println!("{} solutions found", len);
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("empty input")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct OpIter (usize);
|
||||
|
||||
impl Iterator for OpIter {
|
||||
type Item = [Operator; 3];
|
||||
fn next(&mut self) -> Option<[Operator; 3]> {
|
||||
use Operator::*;
|
||||
const OPTIONS: [Operator; 4] = [Mul, Sub, Plus, Div];
|
||||
if self.0 >= 1 << 6 {
|
||||
return None
|
||||
}
|
||||
let f1 = OPTIONS[(self.0 & (3 << 4)) >> 4];
|
||||
let f2 = OPTIONS[(self.0 & (3 << 2)) >> 2];
|
||||
let f3 = OPTIONS[(self.0 & (3 << 0)) >> 0];
|
||||
self.0 += 1;
|
||||
Some([f1, f2, f3])
|
||||
}
|
||||
}
|
||||
|
||||
fn orders() -> [[usize; 4]; 24] {
|
||||
[
|
||||
[0, 1, 2, 3],
|
||||
[0, 1, 3, 2],
|
||||
[0, 2, 1, 3],
|
||||
[0, 2, 3, 1],
|
||||
[0, 3, 1, 2],
|
||||
[0, 3, 2, 1],
|
||||
[1, 0, 2, 3],
|
||||
[1, 0, 3, 2],
|
||||
[1, 2, 0, 3],
|
||||
[1, 2, 3, 0],
|
||||
[1, 3, 0, 2],
|
||||
[1, 3, 2, 0],
|
||||
[2, 0, 1, 3],
|
||||
[2, 0, 3, 1],
|
||||
[2, 1, 0, 3],
|
||||
[2, 1, 3, 0],
|
||||
[2, 3, 0, 1],
|
||||
[2, 3, 1, 0],
|
||||
[3, 0, 1, 2],
|
||||
[3, 0, 2, 1],
|
||||
[3, 1, 0, 2],
|
||||
[3, 1, 2, 0],
|
||||
[3, 2, 0, 1],
|
||||
[3, 2, 1, 0]
|
||||
]
|
||||
}
|
||||
|
||||
fn apply_order(numbers: [i32; 4], order: &[usize; 4]) -> [i32; 4] {
|
||||
[numbers[order[0]], numbers[order[1]], numbers[order[2]], numbers[order[3]]]
|
||||
}
|
||||
|
|
@ -4,28 +4,29 @@ var formats = [
|
|||
'(%d %s %d) %s (%d %s %d)',
|
||||
'%d %s ((%d %s %d) %s %d)',
|
||||
'%d %s (%d %s (%d %s %d))',
|
||||
];
|
||||
]
|
||||
|
||||
var op = %w( + - * / );
|
||||
var operators = op.map { |a| op.map {|b| op.map {|c| "#{a} #{b} #{c}" } } }.flatten;
|
||||
var op = %w( + - * / )
|
||||
var operators = op.map { |a| op.map {|b| op.map {|c| "#{a} #{b} #{c}" } } }.flat
|
||||
|
||||
loop {
|
||||
var input = Sys.scanln("Enter four integers or 'q' to exit: ");
|
||||
input == 'q' && break;
|
||||
var input = read("Enter four integers or 'q' to exit: ", String)
|
||||
input == 'q' && break
|
||||
|
||||
input ~~ /^\h*[1-9]\h+[1-9]\h+[1-9]\h+[1-9]\h*$/ || (
|
||||
say "Invalid input!"; next;
|
||||
);
|
||||
if (input !~ /^\h*[1-9]\h+[1-9]\h+[1-9]\h+[1-9]\h*$/) {
|
||||
say "Invalid input!"
|
||||
next
|
||||
}
|
||||
|
||||
var n = input.split.map{.to_i};
|
||||
var numbers = n.permute;
|
||||
var n = input.split.map{.to_n}
|
||||
var numbers = n.permutations
|
||||
|
||||
formats.each { |format|
|
||||
numbers.each { |n|
|
||||
operators.each { |operator|
|
||||
var o = operator.split;
|
||||
var str = (format % (n[0],o[0],n[1],o[1],n[2],o[2],n[3]));
|
||||
eval(str) == 24 && say str;
|
||||
var str = (format % (n[0],o[0],n[1],o[1],n[2],o[2],n[3]))
|
||||
eval(str) == 24 && say str
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,56 +1,57 @@
|
|||
var formats = [
|
||||
{|a,b,c|
|
||||
Hash.new(
|
||||
Hash(
|
||||
func => {|d,e,f,g| ((d.$a(e)).$b(f)).$c(g) },
|
||||
format => "((%d #{a} %d) #{b} %d) #{c} %d"
|
||||
)
|
||||
},
|
||||
{|a,b,c|
|
||||
Hash.new(
|
||||
Hash(
|
||||
func => {|d,e,f,g| (d.$a((e.$b(f)))).$c(g) },
|
||||
format => "(%d #{a} (%d #{b} %d)) #{c} %d",
|
||||
)
|
||||
},
|
||||
{|a,b,c|
|
||||
Hash.new(
|
||||
Hash(
|
||||
func => {|d,e,f,g| (d.$a(e)).$b(f.$c(g)) },
|
||||
format => "(%d #{a} %d) #{b} (%d #{c} %d)",
|
||||
)
|
||||
},
|
||||
{|a,b,c|
|
||||
Hash.new(
|
||||
Hash(
|
||||
func => {|d,e,f,g| (d.$a(e)).$b(f.$c(g)) },
|
||||
format => "(%d #{a} %d) #{b} (%d #{c} %d)",
|
||||
)
|
||||
},
|
||||
{|a,b,c|
|
||||
Hash.new(
|
||||
Hash(
|
||||
func => {|d,e,f,g| d.$a(e.$b(f.$c(g))) },
|
||||
format => "%d #{a} (%d #{b} (%d #{c} %d))",
|
||||
)
|
||||
},
|
||||
];
|
||||
|
||||
var op = %w( + - * / );
|
||||
var op = %w( + - * / )
|
||||
var blocks = op.map { |a| op.map { |b| op.map { |c| formats.map { |format|
|
||||
format(a,b,c)
|
||||
}}}}.flatten;
|
||||
}}}}.flat
|
||||
|
||||
loop {
|
||||
var input = Sys.scanln("Enter four integers or 'q' to exit: ");
|
||||
input == 'q' && break;
|
||||
|
||||
input ~~ /^\h*[1-9]\h+[1-9]\h+[1-9]\h+[1-9]\h*$/ || (
|
||||
say "Invalid input!"; next;
|
||||
);
|
||||
if (input !~ /^\h*[1-9]\h+[1-9]\h+[1-9]\h+[1-9]\h*$/) {
|
||||
say "Invalid input!"
|
||||
next
|
||||
}
|
||||
|
||||
var n = input.split.map{.to_num};
|
||||
var numbers = n.permute;
|
||||
var n = input.split.map{.to_n}
|
||||
var numbers = n.permutations
|
||||
|
||||
blocks.each { |block|
|
||||
numbers.each { |n|
|
||||
if (block{:func}.call(n...) == 24) {
|
||||
say (block{:format} % (n...));
|
||||
say (block{:format} % (n...))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
297
Task/24-game-Solve/Simula/24-game-solve.simula
Normal file
297
Task/24-game-Solve/Simula/24-game-solve.simula
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
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);
|
||||
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;
|
||||
|
||||
INTEGER SOLUTION;
|
||||
INTEGER D1,D2,D3,D4;
|
||||
INTEGER O1,O2,O3;
|
||||
TEXT OPS;
|
||||
|
||||
OPS :- "+-*/";
|
||||
|
||||
E :- NEW EXPR;
|
||||
OUTTEXT("ENTER FOUR INTEGERS: ");
|
||||
OUTIMAGE;
|
||||
FOR I := 1 STEP 1 UNTIL 4 DO DIGITS(I) := ININT; !RANDINT(0, 9, SEED);
|
||||
|
||||
! DIGITS ;
|
||||
FOR D1 := 1 STEP 1 UNTIL 4 DO
|
||||
FOR D2 := 1 STEP 1 UNTIL 4 DO IF D2 <> D1 THEN
|
||||
FOR D3 := 1 STEP 1 UNTIL 4 DO IF D3 <> D2 AND
|
||||
D3 <> D1 THEN
|
||||
FOR D4 := 1 STEP 1 UNTIL 4 DO IF D4 <> D3 AND
|
||||
D4 <> D2 AND
|
||||
D4 <> D1 THEN
|
||||
! OPERATORS ;
|
||||
FOR O1 := 1 STEP 1 UNTIL 4 DO
|
||||
FOR O2 := 1 STEP 1 UNTIL 4 DO
|
||||
FOR O3 := 1 STEP 1 UNTIL 4 DO
|
||||
BEGIN
|
||||
PROCEDURE P(FMT); TEXT FMT;
|
||||
BEGIN
|
||||
INTEGER PLUS;
|
||||
TRY.SETPOS(1);
|
||||
WHILE FMT.MORE DO
|
||||
BEGIN
|
||||
CHARACTER C;
|
||||
C := FMT.GETCHAR;
|
||||
IF (C >= '1') AND (C <= '4') THEN
|
||||
BEGIN
|
||||
INTEGER DIG; CHARACTER NCH;
|
||||
DIG := IF C = '1' THEN DIGITS(D1)
|
||||
ELSE IF C = '2' THEN DIGITS(D2)
|
||||
ELSE IF C = '3' THEN DIGITS(D3)
|
||||
ELSE DIGITS(D4);
|
||||
NCH := CHAR( DIG + RANK('0') );
|
||||
TRY.PUTCHAR(NCH);
|
||||
END
|
||||
ELSE IF C = '+' THEN
|
||||
BEGIN
|
||||
PLUS := PLUS + 1;
|
||||
OPS.SETPOS(IF PLUS = 1 THEN O1 ELSE
|
||||
IF PLUS = 2 THEN O2
|
||||
ELSE O3);
|
||||
TRY.PUTCHAR(OPS.GETCHAR);
|
||||
END
|
||||
ELSE IF (C = '(') OR (C = ')') OR (C = ' ') THEN
|
||||
TRY.PUTCHAR(C)
|
||||
ELSE
|
||||
ERROR("ILLEGAL EXPRESSION");
|
||||
END;
|
||||
IF E.EVAL(TRY) THEN
|
||||
BEGIN
|
||||
IF ABS(E.RESULT - 24) < 0.001 THEN
|
||||
BEGIN
|
||||
SOLUTION := SOLUTION + 1;
|
||||
OUTTEXT(TRY); OUTTEXT(" = ");
|
||||
OUTFIX(E.RESULT, 4, 10);
|
||||
OUTIMAGE;
|
||||
END;
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
IF E.ERR <> "DIV BY ZERO" THEN
|
||||
BEGIN
|
||||
OUTTEXT(TRY); OUTIMAGE;
|
||||
OUTTEXT(E.ERR); OUTIMAGE;
|
||||
END;
|
||||
END;
|
||||
END P;
|
||||
TEXT TRY;
|
||||
TRY :- BLANKS(17);
|
||||
P("(1 + 2) + (3 + 4)");
|
||||
P("(1 + (2 + 3)) + 4");
|
||||
P("((1 + 2) + 3) + 4");
|
||||
P("1 + ((2 + 3) + 4)");
|
||||
P("1 + (2 + (3 + 4))");
|
||||
END;
|
||||
OUTINT(SOLUTION, 0);
|
||||
OUTTEXT(" SOLUTIONS FOUND");
|
||||
OUTIMAGE;
|
||||
END.
|
||||
26
Task/24-game-Solve/Zkl/24-game-solve-1.zkl
Normal file
26
Task/24-game-Solve/Zkl/24-game-solve-1.zkl
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
var [const] H=Utils.Helpers;
|
||||
fcn u(xs){ xs.reduce(fcn(us,s){us.holds(s) and us or us.append(s) },L()) }
|
||||
var ops=u(H.combosK(3,"+-*/".split("")).apply(H.permute).flatten());
|
||||
var fs=T(
|
||||
fcn f0(a,b,c,d,x,y,z){ Op(z)(Op(y)(Op(x)(a,b),c),d) }, // ((AxB)yC)zD
|
||||
fcn f1(a,b,c,d,x,y,z){ Op(y)(Op(x)(a,b),Op(z)(c,d)) }, // (AxB)y(CzD)
|
||||
fcn f2(a,b,c,d,x,y,z){ Op(z)(Op(x)(a,Op(y)(b,c)),d) }, // (Ax(ByC))zD
|
||||
fcn f3(a,b,c,d,x,y,z){ Op(x)(a,Op(z)(Op(y)(b,c),d)) }, // Ax((ByC)zD)
|
||||
fcn f4(a,b,c,d,x,y,z){ Op(x)(a,Op(y)(b,Op(z)(c,d))) }, // Ax(By(CzD))
|
||||
);
|
||||
|
||||
var fts= // format strings for human readable formulas
|
||||
T("((d.d).d).d", "(d.d).(d.d)", "(d.(d.d)).d", "d.((d.d).d)", "d.(d.(d.d))")
|
||||
.pump(List,T("replace","d","%d"),T("replace",".","%s"));
|
||||
|
||||
fcn f2s(digits,ops,f){
|
||||
fts[f.name[1].toInt()].fmt(digits.zip(ops).flatten().xplode(),digits[3]);
|
||||
}
|
||||
|
||||
fcn game24Solver(digitsString){
|
||||
digits:=digitsString.split("").apply("toFloat");
|
||||
[[(digits4,ops3,f); H.permute(digits); ops; // list comprehension
|
||||
fs,{ try{f(digits4.xplode(),ops3.xplode()).closeTo(24,0.001) }
|
||||
catch(MathError){ False } };
|
||||
{ f2s(digits4,ops3,f) }]];
|
||||
}
|
||||
3
Task/24-game-Solve/Zkl/24-game-solve-2.zkl
Normal file
3
Task/24-game-Solve/Zkl/24-game-solve-2.zkl
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
solutions:=u(game24Solver(ask(0,"digits: ")));
|
||||
println(solutions.len()," solutions:");
|
||||
solutions.apply2(Console.println);
|
||||
Loading…
Add table
Add a link
Reference in a new issue