Add tasks for all the new languages
This commit is contained in:
parent
9dc3c2bb62
commit
bba7bfd280
13208 changed files with 134745 additions and 0 deletions
311
Task/24-game-Solve/ERRE/24-game-solve.erre
Normal file
311
Task/24-game-Solve/ERRE/24-game-solve.erre
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
PROGRAM 24SOLVE
|
||||
|
||||
LABEL 98,99,2540,2550,2560
|
||||
|
||||
! possible brackets
|
||||
CONST NBRACKETS=11,ST_CONST$="+-*/^("
|
||||
|
||||
DIM D[4],PERM[24,4]
|
||||
DIM BRAKETS$[NBRACKETS]
|
||||
DIM OP$[3]
|
||||
DIM STACK$[50]
|
||||
|
||||
PROCEDURE COMPATTA_STACK
|
||||
IF NS>1 THEN
|
||||
R=1
|
||||
WHILE R<NS DO
|
||||
IF INSTR(ST_CONST$,STACK$[R])=0 AND INSTR(ST_CONST$,STACK$[R+1])=0 THEN
|
||||
FOR R1=R TO NS-1 DO
|
||||
STACK$[R1]=STACK$[R1+1]
|
||||
END FOR
|
||||
NS=NS-1
|
||||
END IF
|
||||
R=R+1
|
||||
END WHILE
|
||||
END IF
|
||||
END PROCEDURE
|
||||
|
||||
PROCEDURE CALC_ARITM
|
||||
L=NS1
|
||||
WHILE L<=NS2 DO
|
||||
IF STACK$[L]="^" THEN
|
||||
IF L>=NS2 THEN GOTO 99 END IF
|
||||
N1#=VAL(STACK$[L-1]) N2#=VAL(STACK$[L+1]) NOP=NOP-1
|
||||
IF STACK$[L]="^" THEN
|
||||
RI#=N1#^N2#
|
||||
END IF
|
||||
STACK$[L-1]=STR$(RI#)
|
||||
N=L
|
||||
WHILE N<=NS2-2 DO
|
||||
STACK$[N]=STACK$[N+2]
|
||||
N=N+1
|
||||
END WHILE
|
||||
NS2=NS2-2
|
||||
L=NS1-1
|
||||
END IF
|
||||
L=L+1
|
||||
END WHILE
|
||||
|
||||
L=NS1
|
||||
WHILE L<=NS2 DO
|
||||
IF STACK$[L]="*" OR STACK$[L]="/" THEN
|
||||
IF L>=NS2 THEN GOTO 99 END IF
|
||||
N1#=VAL(STACK$[L-1]) N2#=VAL(STACK$[L+1]) NOP=NOP-1
|
||||
IF STACK$[L]="*" THEN
|
||||
RI#=N1#*N2#
|
||||
ELSE
|
||||
IF N2#<>0 THEN RI#=N1#/N2# ELSE NERR=6 RI#=0 END IF
|
||||
END IF
|
||||
STACK$[L-1]=STR$(RI#)
|
||||
N=L
|
||||
WHILE N<=NS2-2 DO
|
||||
STACK$[N]=STACK$[N+2]
|
||||
N=N+1
|
||||
END WHILE
|
||||
NS2=NS2-2
|
||||
L=NS1-1
|
||||
END IF
|
||||
L=L+1
|
||||
END WHILE
|
||||
|
||||
L=NS1
|
||||
WHILE L<=NS2 DO
|
||||
IF STACK$[L]="+" OR STACK$[L]="-" THEN
|
||||
EXIT IF L>=NS2
|
||||
N1#=VAL(STACK$[L-1]) N2#=VAL(STACK$[L+1]) NOP=NOP-1
|
||||
IF STACK$[L]="+" THEN RI#=N1#+N2# ELSE RI#=N1#-N2# END IF
|
||||
STACK$[L-1]=STR$(RI#)
|
||||
N=L
|
||||
WHILE N<=NS2-2 DO
|
||||
STACK$[N]=STACK$[N+2]
|
||||
N=N+1
|
||||
END WHILE
|
||||
NS2=NS2-2
|
||||
L=NS1-1
|
||||
END IF
|
||||
L=L+1
|
||||
END WHILE
|
||||
99:
|
||||
IF NOP<2 THEN ! precedenza tra gli operatori
|
||||
DB#=VAL(STACK$[NS1])
|
||||
ELSE
|
||||
IF NOP<3 THEN
|
||||
DB#=VAL(STACK$[NS1+2])
|
||||
ELSE
|
||||
DB#=VAL(STACK$[NS1+4])
|
||||
END IF
|
||||
END IF
|
||||
END PROCEDURE
|
||||
|
||||
PROCEDURE SVOLGI_PAR
|
||||
NPA=NPA-1
|
||||
FOR J=NS TO 1 STEP -1 DO
|
||||
EXIT IF STACK$[J]="("
|
||||
END FOR
|
||||
IF J=0 THEN
|
||||
NS1=1 NS2=NS CALC_ARITM NERR=7
|
||||
ELSE
|
||||
FOR R=J TO NS-1 DO
|
||||
STACK$[R]=STACK$[R+1]
|
||||
END FOR
|
||||
NS1=J NS2=NS-1 CALC_ARITM
|
||||
IF NS1=2 THEN
|
||||
NS1=1 STACK$[1]=STACK$[2]
|
||||
END IF
|
||||
NS=NS1
|
||||
COMPATTA_STACK
|
||||
END IF
|
||||
END PROCEDURE
|
||||
|
||||
PROCEDURE MYEVAL(EXPRESSION$,DB#,NERR->DB#,NERR)
|
||||
|
||||
NOP=0 NPA=0 NS=1 K$="" NERR=0
|
||||
STACK$[1]="@" ! init stack
|
||||
|
||||
FOR W=1 TO LEN(EXPRESSION$) DO
|
||||
LOOP
|
||||
CODE=ASC(MID$(EXPRESSION$,W,1))
|
||||
IF (CODE>=48 AND CODE<=57) OR CODE=46 THEN
|
||||
K$=K$+CHR$(CODE)
|
||||
W=W+1 IF W>LEN(EXPRESSION$) THEN GOTO 98 END IF
|
||||
ELSE
|
||||
EXIT IF K$=""
|
||||
IF NS>1 OR (NS=1 AND STACK$[1]<>"@") THEN NS=NS+1 END IF
|
||||
IF FLAG=0 THEN
|
||||
STACK$[NS]=K$
|
||||
ELSE
|
||||
STACK$[NS]=STR$(VAL(K$)*FLAG)
|
||||
END IF
|
||||
K$="" FLAG=0
|
||||
EXIT
|
||||
END IF
|
||||
END LOOP
|
||||
IF CODE=43 THEN K$="+" END IF
|
||||
IF CODE=45 THEN K$="-" END IF
|
||||
IF CODE=42 THEN K$="*" END IF
|
||||
IF CODE=47 THEN K$="/" END IF
|
||||
IF CODE=94 THEN K$="^" END IF
|
||||
|
||||
CASE CODE OF
|
||||
43,45,42,47,94-> ! +-*/^
|
||||
IF MID$(EXPRESSION$,W+1,1)="-" THEN FLAG=-1 W=W+1 END IF
|
||||
IF INSTR(ST_CONST$,STACK$[NS])<>0 THEN
|
||||
NERR=5
|
||||
ELSE
|
||||
NS=NS+1 STACK$[NS]=K$ NOP=NOP+1
|
||||
IF NOP>=2 THEN
|
||||
FOR J=NS TO 1 STEP -1 DO
|
||||
IF STACK$[J]<>"(" THEN GOTO 2540 END IF
|
||||
IF J<NS-2 THEN GOTO 2550 ELSE GOTO 2560 END IF
|
||||
2540: END FOR
|
||||
2550: NS1=J+1 NS2=NS CALC_ARITM
|
||||
NS=NS2 STACK$[NS]=K$
|
||||
REGISTRO_X#=VAL(STACK$[NS-1])
|
||||
END IF
|
||||
END IF
|
||||
2560: END ->
|
||||
|
||||
40-> ! (
|
||||
IF NS>1 OR (NS=1 AND STACK$[1]<>"@") THEN NS=NS+1 END IF
|
||||
STACK$[NS]="(" NPA=NPA+1
|
||||
IF MID$(EXPRESSION$,W+1,1)="-" THEN FLAG=-1 W=W+1 END IF
|
||||
END ->
|
||||
|
||||
41-> ! )
|
||||
SVOLGI_PAR
|
||||
IF NERR=7 THEN
|
||||
NERR=0 NOP=0 NPA=0 NS=1
|
||||
ELSE
|
||||
IF NERR=0 OR NERR=1 THEN
|
||||
DB#=VAL(STACK$[NS])
|
||||
REGISTRO_X#=DB#
|
||||
ELSE
|
||||
NOP=0 NPA=0 NS=1
|
||||
END IF
|
||||
END IF
|
||||
END ->
|
||||
|
||||
OTHERWISE
|
||||
NERR=8
|
||||
END CASE
|
||||
K$=""
|
||||
END FOR
|
||||
98:
|
||||
IF K$<>"" THEN
|
||||
IF NS>1 OR (NS=1 AND STACK$[1]<>"@") THEN NS=NS+1 END IF
|
||||
IF FLAG=0 THEN STACK$[NS]=K$ ELSE STACK$[NS]=STR$(VAL(K$)*FLAG) END IF
|
||||
END IF
|
||||
|
||||
IF INSTR(ST_CONST$,STACK$[NS])<>0 THEN
|
||||
NERR=6
|
||||
ELSE
|
||||
WHILE NPA<>0 DO
|
||||
SVOLGI_PAR
|
||||
END WHILE
|
||||
IF NERR<>7 THEN NS1=1 NS2=NS CALCARITM END IF
|
||||
END IF
|
||||
|
||||
NS=1 NOP=0 NPA=0
|
||||
|
||||
END PROCEDURE
|
||||
|
||||
BEGIN
|
||||
PRINT(CHR$(12);) ! CLS
|
||||
|
||||
! possible brackets
|
||||
DATA("4#4#4#4")
|
||||
DATA("(4#4)#4#4")
|
||||
DATA("4#(4#4)#4")
|
||||
DATA("4#4#(4#4)")
|
||||
DATA("(4#4)#(4#4)")
|
||||
DATA("(4#4#4)#4")
|
||||
DATA("4#(4#4#4)")
|
||||
DATA("((4#4)#4)#4")
|
||||
DATA("(4#(4#4))#4")
|
||||
DATA("4#((4#4)#4)")
|
||||
DATA("4#(4#(4#4))")
|
||||
FOR I=1 TO NBRACKETS DO
|
||||
READ(BRAKETS$[I])
|
||||
END FOR
|
||||
|
||||
INPUT("ENTER 4 DIGITS: ",A$)
|
||||
ND=0
|
||||
FOR I=1 TO LEN(A$) DO
|
||||
C$=MID$(A$,I,1)
|
||||
IF INSTR("123456789",C$)>0 THEN
|
||||
ND=ND+1
|
||||
D[ND]=VAL(C$)
|
||||
END IF
|
||||
END FOR
|
||||
! precompute permutations. dumb way.
|
||||
NPERM=1*2*3*4
|
||||
N=0
|
||||
FOR I=1 TO 4 DO
|
||||
FOR J=1 TO 4 DO
|
||||
FOR K=1 TO 4 DO
|
||||
FOR L=1 TO 4 DO
|
||||
! valid permutation (no dupes)
|
||||
IF I<>J AND I<>K AND I<>L AND J<>K AND J<>L AND K<>L THEN
|
||||
N=N+1
|
||||
! actually,we can as well permute given digits
|
||||
PERM[N,1]=D[I]
|
||||
PERM[N,2]=D[J]
|
||||
PERM[N,3]=D[K]
|
||||
PERM[N,4]=D[L]
|
||||
END IF
|
||||
END FOR
|
||||
END FOR
|
||||
END FOR
|
||||
END FOR
|
||||
|
||||
! operations: full search
|
||||
COUNT=0
|
||||
OPS$="+-*/"
|
||||
FOR OP1=1 TO 4 DO
|
||||
OP$[1]=MID$(OPS$,OP1,1)
|
||||
FOR OP2=1 TO 4 DO
|
||||
OP$[2]=MID$(OPS$,OP2,1)
|
||||
FOR OP3=1 TO 4 DO
|
||||
OP$[3]=MID$(OPS$,OP3,1)
|
||||
! substitute all brackets
|
||||
FOR T=1 TO NBRACKETS DO
|
||||
TMPL$=BRAKETS$[T]
|
||||
! now,substitute all digits: permutations.
|
||||
FOR P=1 TO NPERM DO
|
||||
RES$=""
|
||||
NOP=0
|
||||
ND=0
|
||||
FOR I=1 TO LEN(TMPL$) DO
|
||||
C$=MID$(TMPL$,I,1)
|
||||
CASE C$ OF
|
||||
"#"-> ! operations
|
||||
NOP=NOP+1
|
||||
RES$=RES$+OP$[NOP]
|
||||
END ->
|
||||
"4"-> ! digits
|
||||
ND=NOP+1
|
||||
RES$=RES$+MID$(STR$(PERM[P,ND]),2)
|
||||
END ->
|
||||
OTHERWISE ! brackets goes here
|
||||
RES$=RES$+C$
|
||||
END CASE
|
||||
END FOR
|
||||
! eval here
|
||||
MY_EVAL(RES$,DB#,NERR->DB#,NERR)
|
||||
IF DB#=24 AND NERR=0 THEN
|
||||
PRINT("24=";RES$)
|
||||
COUNT=COUNT+1
|
||||
END IF
|
||||
END FOR
|
||||
END FOR
|
||||
END FOR
|
||||
END FOR
|
||||
END FOR
|
||||
|
||||
IF COUNT=0 THEN
|
||||
PRINT("If you see this, probably task cannot be solved with these digits")
|
||||
ELSE
|
||||
PRINT("Total=";COUNT)
|
||||
END IF
|
||||
|
||||
END PROGRAM
|
||||
111
Task/24-game-Solve/EchoLisp/24-game-solve.echolisp
Normal file
111
Task/24-game-Solve/EchoLisp/24-game-solve.echolisp
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
;; use task [[RPN_to_infix_conversion#EchoLisp]] to print results
|
||||
(define (rpn->string rpn)
|
||||
(if (vector? rpn)
|
||||
(infix->string (rpn->infix rpn))
|
||||
"😥 Not found"))
|
||||
|
||||
|
||||
(string-delimiter "")
|
||||
(define OPS #(* + - // )) ;; use float division
|
||||
(define-syntax-rule (commutative? op) (or (= op *) (= op +)))
|
||||
|
||||
;; ---------------------------------
|
||||
;; calc rpn -> num value or #f if bad rpn
|
||||
;; rpn is a vector of ops or numbers
|
||||
;; ----------------------------------
|
||||
(define (calc rpn)
|
||||
(define S (stack 'S))
|
||||
(for ((token rpn))
|
||||
(if (procedure? token)
|
||||
(let [(op2 (pop S)) (op1 (pop S))]
|
||||
(if (and op1 op2)
|
||||
(push S (apply token (list op1 op2)))
|
||||
(push S #f))) ;; not-well formed
|
||||
(push S token ))
|
||||
#:break (not (stack-top S)))
|
||||
(if (= 1 (stack-length S)) (pop S) #f))
|
||||
|
||||
;; check for legal rpn -> #f if not legal
|
||||
(define (rpn? rpn)
|
||||
(define S (stack 'S))
|
||||
(for ((token rpn))
|
||||
(if (procedure? token)
|
||||
(push S (and (pop S) (pop S)))
|
||||
(push S token ))
|
||||
#:break (not (stack-top S)))
|
||||
(stack-top S))
|
||||
|
||||
;; --------------------------------------
|
||||
;; build-rpn : push next rpn op or number
|
||||
;; dleft is number of not used digits
|
||||
;; ---------------------------------------
|
||||
(define count 0)
|
||||
|
||||
(define (build-rpn into: rpn depth maxdepth digits ops dleft target &hit )
|
||||
(define cmpop #f)
|
||||
(cond
|
||||
;; tooo long
|
||||
[(> (++ count) 200_000) (set-box! &hit 'not-found)]
|
||||
;; stop on first hit
|
||||
[(unbox &hit) &hit]
|
||||
;; partial rpn must be legal
|
||||
[(not (rpn? rpn)) #f]
|
||||
;; eval rpn if complete
|
||||
[(> depth maxdepth)
|
||||
(when (= target (calc rpn)) (set-box! &hit rpn))]
|
||||
;; else, add a digit to rpn
|
||||
[else
|
||||
[when (< depth maxdepth) ;; digits anywhere except last
|
||||
(for [(d digits) (i 10)]
|
||||
#:continue (zero? d)
|
||||
(vector-set! digits i 0) ;; mark used
|
||||
(vector-set! rpn depth d)
|
||||
(build-rpn rpn (1+ depth) maxdepth digits ops (1- dleft) target &hit)
|
||||
(vector-set! digits i d)) ;; mark unused
|
||||
] ;; add digit
|
||||
;; or, add an op
|
||||
;; ops anywhere except positions 0,1
|
||||
[when (and (> depth 1) (<= (+ depth dleft) maxdepth));; cutter : must use all digits
|
||||
(set! cmpop
|
||||
(and (number? [rpn (1- depth)])
|
||||
(number? [rpn (- depth 2)])
|
||||
(> [rpn (1- depth)] [rpn (- depth 2)])))
|
||||
|
||||
(for [(op ops)]
|
||||
#:continue (and cmpop (commutative? op)) ;; cutter : 3 4 + === 4 3 +
|
||||
(vector-set! rpn depth op)
|
||||
(build-rpn rpn (1+ depth) maxdepth digits ops dleft target &hit)
|
||||
(vector-set! rpn depth 0))] ;; add op
|
||||
] ; add something to rpn vector
|
||||
)) ; build-rpn
|
||||
|
||||
;;------------------------
|
||||
;;gen24 : num random numbers
|
||||
;;------------------------
|
||||
(define (gen24 num maxrange)
|
||||
(->> (append (range 1 maxrange)(range 1 maxrange)) shuffle (take num)))
|
||||
|
||||
;;-------------------------------------------
|
||||
;; try-rpn : sets starter values for build-rpn
|
||||
;;-------------------------------------------
|
||||
(define (try-rpn digits target)
|
||||
(set! digits (list-sort > digits)) ;; seems to accelerate things
|
||||
(define rpn (make-vector (1- (* 2 (length digits)))))
|
||||
(define &hit (box #f))
|
||||
(set! count 0)
|
||||
|
||||
(build-rpn rpn starter-depth: 0
|
||||
max-depth: (1- (vector-length rpn))
|
||||
(list->vector digits)
|
||||
OPS
|
||||
remaining-digits: (length digits)
|
||||
target &hit )
|
||||
(writeln target '= (rpn->string (unbox &hit)) 'tries= count))
|
||||
|
||||
;; -------------------------------
|
||||
;; (task numdigits target maxrange)
|
||||
;; --------------------------------
|
||||
(define (task (numdigits 4) (target 24) (maxrange 10))
|
||||
(define digits (gen24 numdigits maxrange))
|
||||
(writeln digits '→ target)
|
||||
(try-rpn digits target))
|
||||
121
Task/24-game-Solve/Phix/24-game-solve.phix
Normal file
121
Task/24-game-Solve/Phix/24-game-solve.phix
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
--
|
||||
-- 24_game_solve.exw
|
||||
-- =================
|
||||
--
|
||||
-- Write a function that given four digits subject to the rules of the 24 game, computes an expression to solve the game if possible.
|
||||
-- Show examples of solutions generated by the function
|
||||
--
|
||||
-- The following 5 parse expressions are possible.
|
||||
-- Obviously numbers 1234 represent 24 permutations from
|
||||
-- {1,2,3,4} to {4,3,2,1} of indexes to the real numbers.
|
||||
-- Likewise "+-*" is like "123" representing 64 combinations
|
||||
-- from {1,1,1} to {4,4,4} of indexes to "+-*/".
|
||||
-- Both will be replaced if/when the strings get printed.
|
||||
--
|
||||
constant OPS = "+-*/"
|
||||
constant expressions = {"1+(2-(3*4))",
|
||||
"1+((2-3)*4)",
|
||||
"(1+2)-(3*4)",
|
||||
"(1+(2-3))*4",
|
||||
"((1+2)-3)*4"} -- (equivalent to "1+2-3*4")
|
||||
--TODO: I'm sure there is a simple (recursive) way to programatically
|
||||
-- generate the above (for n=2..9) but I'm not seeing it yet...
|
||||
|
||||
-- The above represented as three sequential operations (the result gets
|
||||
-- left in <(map)1>, ie vars[perms[operations[i][3][1]]] aka vars[lhs]):
|
||||
constant operations = {{{3,'*',4},{2,'-',3},{1,'+',2}}, --3*=4; 2-=3; 1+=2
|
||||
{{2,'-',3},{2,'*',4},{1,'+',2}}, --2-=3; 2*=4; 1+=2
|
||||
{{1,'+',2},{3,'*',4},{1,'-',3}}, --1+=2; 3*=4; 1-=3
|
||||
{{2,'-',3},{1,'+',2},{1,'*',4}}, --2-=3; 1+=2; 1*=4
|
||||
{{1,'+',2},{1,'-',3},{1,'*',4}}} --1+=2; 1-=3; 1*=4
|
||||
--TODO: ... and likewise for parsing "expressions" to yield "operations".
|
||||
|
||||
function evalopset(sequence opset, sequence perms, sequence ops, sequence vars)
|
||||
-- invoked 5*24*64 = 7680 times, to try all possible expressions/vars/operators
|
||||
-- (btw, vars is copy-on-write, like all parameters not explicitly returned, so
|
||||
-- we can safely re-use it without clobbering the callee version.)
|
||||
integer lhs,op,rhs
|
||||
atom inf
|
||||
for i=1 to length(opset) do
|
||||
{lhs,op,rhs} = opset[i]
|
||||
lhs = perms[lhs]
|
||||
op = ops[find(op,OPS)]
|
||||
rhs = perms[rhs]
|
||||
if op='+' then
|
||||
vars[lhs] += vars[rhs]
|
||||
elsif op='-' then
|
||||
vars[lhs] -= vars[rhs]
|
||||
elsif op='*' then
|
||||
vars[lhs] *= vars[rhs]
|
||||
elsif op='/' then
|
||||
if vars[rhs]=0 then inf = 1e300*1e300 return inf end if
|
||||
vars[lhs] /= vars[rhs]
|
||||
end if
|
||||
end for
|
||||
return vars[lhs]
|
||||
end function
|
||||
|
||||
integer nSolutions
|
||||
sequence xSolutions
|
||||
|
||||
procedure success(string expr, sequence perms, sequence ops, sequence vars, atom r)
|
||||
integer ch
|
||||
for i=1 to length(expr) do
|
||||
ch = expr[i]
|
||||
if ch>='1' and ch<='9' then
|
||||
expr[i] = vars[perms[ch-'0']]+'0'
|
||||
else
|
||||
ch = find(ch,OPS)
|
||||
if ch then
|
||||
expr[i] = ops[ch]
|
||||
end if
|
||||
end if
|
||||
end for
|
||||
if not find(expr,xSolutions) then
|
||||
-- avoid duplicates for eg {1,1,2,7} because this has found
|
||||
-- the "same" solution but with the 1st and 2nd 1s swapped,
|
||||
-- and likewise whenever an operator is used more than once.
|
||||
printf(1,"success: %s = %s\n",{expr,sprint(r)})
|
||||
nSolutions += 1
|
||||
xSolutions = append(xSolutions,expr)
|
||||
end if
|
||||
end procedure
|
||||
|
||||
procedure tryperms(sequence perms, sequence ops, sequence vars)
|
||||
atom r
|
||||
for i=1 to length(operations) do
|
||||
-- 5 parse expressions
|
||||
r = evalopset(operations[i], perms, ops, vars)
|
||||
if r=24 then
|
||||
success(expressions[i], perms, ops, vars, r)
|
||||
end if
|
||||
end for
|
||||
end procedure
|
||||
|
||||
include builtins/factorial.e
|
||||
include builtins/permute.e
|
||||
|
||||
procedure tryops(sequence ops, sequence vars)
|
||||
for p=1 to factorial(4) do
|
||||
-- 24 var permutations
|
||||
tryperms(permute(p,{1,2,3,4}),ops, vars)
|
||||
end for
|
||||
end procedure
|
||||
|
||||
global procedure solve24(sequence vars)
|
||||
nSolutions = 0
|
||||
xSolutions = {}
|
||||
for op1=1 to 4 do
|
||||
for op2=1 to 4 do
|
||||
for op3=1 to 4 do
|
||||
-- 64 operator combinations
|
||||
tryops({OPS[op1],OPS[op2],OPS[op3]},vars)
|
||||
end for
|
||||
end for
|
||||
end for
|
||||
|
||||
printf(1,"\n%d solutions\n",{nSolutions})
|
||||
end procedure
|
||||
|
||||
solve24({1,1,2,7})
|
||||
if getc(0) then end if
|
||||
32
Task/24-game-Solve/Sidef/24-game-solve-1.sidef
Normal file
32
Task/24-game-Solve/Sidef/24-game-solve-1.sidef
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
var formats = [
|
||||
'((%d %s %d) %s %d) %s %d',
|
||||
'(%d %s (%d %s %d)) %s %d',
|
||||
'(%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;
|
||||
|
||||
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;
|
||||
);
|
||||
|
||||
var n = input.split.map{.to_i};
|
||||
var numbers = n.permute;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
Task/24-game-Solve/Sidef/24-game-solve-2.sidef
Normal file
57
Task/24-game-Solve/Sidef/24-game-solve-2.sidef
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
var formats = [
|
||||
{|a,b,c|
|
||||
Hash.new(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
func => {|d,e,f,g| d.$a(e.$b(f.$c(g))) },
|
||||
format => "%d #{a} (%d #{b} (%d #{c} %d))",
|
||||
)
|
||||
},
|
||||
];
|
||||
|
||||
var op = %w( + - * / );
|
||||
var blocks = op.map { |a| op.map { |b| op.map { |c| formats.map { |format|
|
||||
format(a,b,c)
|
||||
}}}}.flatten;
|
||||
|
||||
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;
|
||||
);
|
||||
|
||||
var n = input.split.map{.to_num};
|
||||
var numbers = n.permute;
|
||||
|
||||
blocks.each { |block|
|
||||
numbers.each { |n|
|
||||
if (block{:func}.call(n...) == 24) {
|
||||
say (block{:format} % (n...));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
172
Task/24-game-Solve/Swift/24-game-solve.swift
Normal file
172
Task/24-game-Solve/Swift/24-game-solve.swift
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
import Darwin
|
||||
import Foundation
|
||||
|
||||
var solution = ""
|
||||
|
||||
println("24 Game")
|
||||
println("Generating 4 digits...")
|
||||
|
||||
func randomDigits() -> [Int] {
|
||||
var result = [Int]()
|
||||
for i in 0 ..< 4 {
|
||||
result.append(Int(arc4random_uniform(9)+1))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Choose 4 digits
|
||||
let digits = randomDigits()
|
||||
|
||||
print("Make 24 using these digits : ")
|
||||
|
||||
for digit in digits {
|
||||
print("\(digit) ")
|
||||
}
|
||||
println()
|
||||
|
||||
// get input from operator
|
||||
var input = NSString(data:NSFileHandle.fileHandleWithStandardInput().availableData, encoding:NSUTF8StringEncoding)!
|
||||
|
||||
var enteredDigits = [Double]()
|
||||
|
||||
var enteredOperations = [Character]()
|
||||
|
||||
let inputString = input as String
|
||||
|
||||
// store input in the appropriate table
|
||||
for character in inputString {
|
||||
switch character {
|
||||
case "1", "2", "3", "4", "5", "6", "7", "8", "9":
|
||||
let digit = String(character)
|
||||
enteredDigits.append(Double(digit.toInt()!))
|
||||
case "+", "-", "*", "/":
|
||||
enteredOperations.append(character)
|
||||
case "\n":
|
||||
println()
|
||||
default:
|
||||
println("Invalid expression")
|
||||
}
|
||||
}
|
||||
|
||||
// check value of expression provided by the operator
|
||||
var value = 0.0
|
||||
|
||||
if enteredDigits.count == 4 && enteredOperations.count == 3 {
|
||||
value = enteredDigits[0]
|
||||
for (i, operation) in enumerate(enteredOperations) {
|
||||
switch operation {
|
||||
case "+":
|
||||
value = value + enteredDigits[i+1]
|
||||
case "-":
|
||||
value = value - enteredDigits[i+1]
|
||||
case "*":
|
||||
value = value * enteredDigits[i+1]
|
||||
case "/":
|
||||
value = value / enteredDigits[i+1]
|
||||
default:
|
||||
println("This message should never happen!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func evaluate(dPerm: [Double], oPerm: [String]) -> Bool {
|
||||
var value = 0.0
|
||||
|
||||
if dPerm.count == 4 && oPerm.count == 3 {
|
||||
value = dPerm[0]
|
||||
for (i, operation) in enumerate(oPerm) {
|
||||
switch operation {
|
||||
case "+":
|
||||
value = value + dPerm[i+1]
|
||||
case "-":
|
||||
value = value - dPerm[i+1]
|
||||
case "*":
|
||||
value = value * dPerm[i+1]
|
||||
case "/":
|
||||
value = value / dPerm[i+1]
|
||||
default:
|
||||
println("This message should never happen!")
|
||||
}
|
||||
}
|
||||
}
|
||||
return (abs(24 - value) < 0.001)
|
||||
}
|
||||
|
||||
func isSolvable(inout digits: [Double]) -> Bool {
|
||||
|
||||
var result = false
|
||||
var dPerms = [[Double]]()
|
||||
permute(&digits, &dPerms, 0)
|
||||
|
||||
let total = 4 * 4 * 4
|
||||
var oPerms = [[String]]()
|
||||
permuteOperators(&oPerms, 4, total)
|
||||
|
||||
|
||||
for dig in dPerms {
|
||||
for opr in oPerms {
|
||||
var expression = ""
|
||||
|
||||
if evaluate(dig, opr) {
|
||||
for digit in dig {
|
||||
expression += "\(digit)"
|
||||
}
|
||||
|
||||
for oper in opr {
|
||||
expression += oper
|
||||
}
|
||||
|
||||
solution = beautify(expression)
|
||||
result = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func permute(inout lst: [Double], inout res: [[Double]], k: Int) -> Void {
|
||||
for i in k ..< lst.count {
|
||||
swap(&lst[i], &lst[k])
|
||||
permute(&lst, &res, k + 1)
|
||||
swap(&lst[k], &lst[i])
|
||||
}
|
||||
if k == lst.count {
|
||||
res.append(lst)
|
||||
}
|
||||
}
|
||||
|
||||
// n=4, total=64, npow=16
|
||||
func permuteOperators(inout res: [[String]], n: Int, total: Int) -> Void {
|
||||
let posOperations = ["+", "-", "*", "/"]
|
||||
let npow = n * n
|
||||
for i in 0 ..< total {
|
||||
res.append([posOperations[(i / npow)], posOperations[((i % npow) / n)], posOperations[(i % n)]])
|
||||
}
|
||||
}
|
||||
|
||||
func beautify(infix: String) -> String {
|
||||
let newString = infix as NSString
|
||||
|
||||
var solution = ""
|
||||
|
||||
solution += newString.substringWithRange(NSMakeRange(0, 1))
|
||||
solution += newString.substringWithRange(NSMakeRange(12, 1))
|
||||
solution += newString.substringWithRange(NSMakeRange(3, 1))
|
||||
solution += newString.substringWithRange(NSMakeRange(13, 1))
|
||||
solution += newString.substringWithRange(NSMakeRange(6, 1))
|
||||
solution += newString.substringWithRange(NSMakeRange(14, 1))
|
||||
solution += newString.substringWithRange(NSMakeRange(9, 1))
|
||||
|
||||
return solution
|
||||
}
|
||||
|
||||
if value != 24 {
|
||||
println("The value of the provided expression is \(value) instead of 24!")
|
||||
if isSolvable(&enteredDigits) {
|
||||
println("A possible solution could have been " + solution)
|
||||
} else {
|
||||
println("Anyway, there was no known solution to this one.")
|
||||
}
|
||||
} else {
|
||||
println("Congratulations, you found a solution!")
|
||||
}
|
||||
40
Task/24-game-Solve/jq/24-game-solve-1.jq
Normal file
40
Task/24-game-Solve/jq/24-game-solve-1.jq
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# Generate a stream of the permutations of the input array.
|
||||
def permutations:
|
||||
if length == 0 then []
|
||||
else
|
||||
. as $in | range(0;length) | . as $i
|
||||
| ($in|del(.[$i])|permutations)
|
||||
| [$in[$i]] + .
|
||||
end ;
|
||||
|
||||
# Generate a stream of arrays of length n,
|
||||
# with members drawn from the input array.
|
||||
def take(n):
|
||||
length as $l |
|
||||
if n == 1 then range(0;$l) as $i | [ .[$i] ]
|
||||
else take(n-1) + take(1)
|
||||
end;
|
||||
|
||||
# Emit an array with elements that alternate between those in the input array and those in short,
|
||||
# starting with the former, and using nothing if "short" is too too short.
|
||||
def intersperse(short):
|
||||
. as $in
|
||||
| reduce range(0;length) as $i
|
||||
([]; . + [ $in[$i], (short[$i] // empty) ]);
|
||||
|
||||
# Emit a stream of all the nested triplet groupings of the input array elements,
|
||||
# e.g. [1,2,3,4,5] =>
|
||||
# [1,2,[3,4,5]]
|
||||
# [[1,2,3],4,5]
|
||||
#
|
||||
def triples:
|
||||
. as $in
|
||||
| if length == 3 then .
|
||||
elif length == 1 then $in[0]
|
||||
elif length < 3 then empty
|
||||
else
|
||||
(range(0; (length-1) / 2) * 2 + 1) as $i
|
||||
| ($in[0:$i] | triples) as $head
|
||||
| ($in[$i+1:] | triples) as $tail
|
||||
| [$head, $in[$i], $tail]
|
||||
end;
|
||||
23
Task/24-game-Solve/jq/24-game-solve-2.jq
Normal file
23
Task/24-game-Solve/jq/24-game-solve-2.jq
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# Evaluate the input, which must be a number or a triple: [x, op, y]
|
||||
def eval:
|
||||
if type == "array" then
|
||||
.[1] as $op
|
||||
| if .[0] == null or .[2] == null then null
|
||||
else
|
||||
(.[0] | eval) as $left | (.[2] | eval) as $right
|
||||
| if $left == null or $right == null then null
|
||||
elif $op == "+" then $left + $right
|
||||
elif $op == "-" then $left - $right
|
||||
elif $op == "*" then $left * $right
|
||||
elif $op == "/" then
|
||||
if $right == 0 then null
|
||||
else $left / $right
|
||||
end
|
||||
else "invalid arithmetic operator: \($op)" | error
|
||||
end
|
||||
end
|
||||
else .
|
||||
end;
|
||||
|
||||
def pp:
|
||||
"\(.)" | explode | map([.] | implode | if . == "," then " " elif . == "\"" then "" else . end) | join("");
|
||||
21
Task/24-game-Solve/jq/24-game-solve-3.jq
Normal file
21
Task/24-game-Solve/jq/24-game-solve-3.jq
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
def OPERATORS: ["+", "-", "*", "/"];
|
||||
|
||||
# Input: an array of 4 digits
|
||||
# o: an array of 3 operators
|
||||
# Output: a stream
|
||||
def EXPRESSIONS(o):
|
||||
intersperse( o ) | triples;
|
||||
|
||||
def solve(objective):
|
||||
length as $length
|
||||
| [ (OPERATORS | take($length-1)) as $poperators
|
||||
| permutations | EXPRESSIONS($poperators)
|
||||
| select( eval == objective)
|
||||
] as $answers
|
||||
| if $answers|length > 3 then "That was too easy. I found \($answers|length) answers, e.g. \($answers[0] | pp)"
|
||||
elif $answers|length > 1 then $answers[] | pp
|
||||
else "You lose! There are no solutions."
|
||||
end
|
||||
;
|
||||
|
||||
solve(24), "Please try again."
|
||||
16
Task/24-game-Solve/jq/24-game-solve-4.jq
Normal file
16
Task/24-game-Solve/jq/24-game-solve-4.jq
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
$ jq -r -f Solve.jq
|
||||
[1,2,3,4]
|
||||
That was too easy. I found 242 answers, e.g. [4 * [1 + [2 + 3]]]
|
||||
Please try again.
|
||||
[1,2,3,40,1]
|
||||
That was too easy. I found 636 answers, e.g. [[[1 / 2] * 40] + [3 + 1]]
|
||||
Please try again.
|
||||
[3,8,9]
|
||||
That was too easy. I found 8 answers, e.g. [[8 / 3] * 9]
|
||||
Please try again.
|
||||
[4,5,6]
|
||||
You lose! There are no solutions.
|
||||
Please try again.
|
||||
[1,2,3,4,5,6]
|
||||
That was too easy. I found 197926 answers, e.g. [[2 * [1 + 4]] + [3 + [5 + 6]]]
|
||||
Please try again.
|
||||
Loading…
Add table
Add a link
Reference in a new issue