September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -2,7 +2,7 @@ There are 100 doors in a row that are all initially closed.
You make 100 [[task feature::Rosetta Code:multiple passes|passes]] by the doors.
The first time through, visit every door and   ''toggle''   the door   (if the door is closed,   open it;   if it is open,   close it).
The first time through, visit every door and  ''toggle''  the door  (if the door is closed,  open it;   if it is open,  close it).
The second time, only visit every 2<sup>nd</sup> door &nbsp; (door #2, #4, #6, ...), &nbsp; and toggle it.

View file

@ -1,14 +1,9 @@
form open_doors_opt.
data: lv_square type i value 1,
lv_inc type i value 3.
data: lt_doors type standard table of c initial size 100.
field-symbols: <wa_door> type c.
do 100 times.
append initial line to lt_doors assigning <wa_door>.
if sy-index = lv_square.
<wa_door> = 'X'.
add: lv_inc to lv_square, 2 to lv_inc.
write : / 'Door', (4) sy-index right-justified, 'is open' no-gap.
endif.
enddo.
endform.
cl_demo_output=>display( REDUCE stringtab( INIT list TYPE stringtab
aux TYPE i
FOR door = 1 WHILE door <= 100
FOR pass = 1 WHILE pass <= 100
NEXT aux = COND #( WHEN pass = 1 THEN 1
WHEN door MOD pass = 0 THEN aux + 1 ELSE aux )
list = COND #( WHEN pass = 100
THEN COND #( WHEN aux MOD 2 <> 0 THEN VALUE #( BASE list ( CONV #( door ) ) )
ELSE list ) ELSE list ) ) ).

View file

@ -0,0 +1,14 @@
form open_doors_opt.
data: lv_square type i value 1,
lv_inc type i value 3.
data: lt_doors type standard table of c initial size 100.
field-symbols: <wa_door> type c.
do 100 times.
append initial line to lt_doors assigning <wa_door>.
if sy-index = lv_square.
<wa_door> = 'X'.
add: lv_inc to lv_square, 2 to lv_inc.
write : / 'Door', (4) sy-index right-justified, 'is open' no-gap.
endif.
enddo.
endform.

View file

@ -0,0 +1,4 @@
DO 10 TIMES.
DATA(val) = sy-index * sy-index.
WRITE: / val.
ENDDO.

View file

@ -0,0 +1,3 @@
cl_demo_output=>display( REDUCE stringtab( INIT list TYPE stringtab
FOR i = 1 WHILE i <= 10
NEXT list = VALUE #( BASE list ( i * i ) ) ) ).

View file

@ -1,11 +0,0 @@
out?doors num
? Simulates the 100 doors problem for any number of doors
? Returns a boolean vector with 1 being open
out??num ? num steps
out??¨out ? Count out the spacing for each step
out?1=out ? Make that into a boolean vector
out??¨out ? Flip each vector around
out?(num°?)¨out ? Copy each out to the right size
out??/out ? XOR each vector, toggling each marked door
out??out ? Disclose the results to get a vector

View file

@ -1,7 +0,0 @@
out?doorsOptimized num;marks
? Returns a boolean vector of the doors that would be left open
marks??num*0.5 ? Take the square root of the size, floored
marks?(?marks)*2 ? Get each door to be opened
out?num?0 ? Make a vector of 0s
out[marks]?1 ? Set the marked doors to 1

View file

@ -1,45 +1,47 @@
-- FINAL DOOR STATES ---------------------------------------------------------
-- finalDoors :: Int -> [(Int, Bool)]
on finalDoors(n)
-- toggledCorridor :: [(Int, Bool)] -> (Int, Bool) -> Int -> [(Int, Bool)]
script toggledCorridor
on lambda(a, _, k)
on |λ|(a, _, k)
-- perhapsToggled :: Bool -> Int -> Bool
script perhapsToggled
on lambda(x, i)
on |λ|(x, i)
if i mod k = 0 then
{i, not item 2 of x}
else
{i, item 2 of x}
end if
end lambda
end |λ|
end script
map(perhapsToggled, a)
end lambda
end |λ|
end script
set lstRange to range(1, n)
set xs to enumFromTo(1, n)
foldl(toggledCorridor, ¬
zip(lstRange, replicate(n, {false})), lstRange)
zip(xs, replicate(n, {false})), xs)
end finalDoors
-- TEST
-- TEST ----------------------------------------------------------------------
on run
-- isOpenAtEnd :: (Int, Bool) -> Bool
script isOpenAtEnd
on lambda(door)
on |λ|(door)
(item 2 of door)
end lambda
end |λ|
end script
-- doorNumber :: (Int, Bool) -> Int
script doorNumber
on lambda(door)
on |λ|(door)
(item 1 of door)
end lambda
end |λ|
end script
map(doorNumber, filter(isOpenAtEnd, finalDoors(100)))
@ -48,8 +50,21 @@ on run
end run
-- GENERIC FUNCTIONS ---------------------------------------------------------
-- GENERIC FUNCTIONS
-- enumFromTo :: Int -> Int -> [Int]
on enumFromTo(m, n)
if n < m then
set d to -1
else
set d to 1
end if
set lst to {}
repeat with i from m to n by d
set end of lst to i
end repeat
return lst
end enumFromTo
-- filter :: (a -> Bool) -> [a] -> [a]
on filter(f, xs)
@ -58,7 +73,7 @@ on filter(f, xs)
set lng to length of xs
repeat with i from 1 to lng
set v to item i of xs
if lambda(v, i, xs) then set end of lst to v
if |λ|(v, i, xs) then set end of lst to v
end repeat
return lst
end tell
@ -70,7 +85,7 @@ on foldl(f, startValue, xs)
set v to startValue
set lng to length of xs
repeat with i from 1 to lng
set v to lambda(v, item i of xs, i, xs)
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
@ -82,40 +97,38 @@ on map(f, xs)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to lambda(item i of xs, i, xs)
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
-- zip :: [a] -> [b] -> [(a, b)]
on zip(xs, ys)
script pair
on lambda(x, i)
[x, item i of ys]
end lambda
end script
if length of xs = length of ys then
map(pair, xs)
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
missing value
x
end if
end zip
end min
-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary
-- assembly of a target length
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- replicate :: Int -> a -> [a]
on replicate(n, a)
if class of a is list then
set out to {}
else
set out to ""
end if
set out to {}
if n < 1 then return out
set dbl to a
set dbl to {a}
repeat while (n > 1)
if (n mod 2) > 0 then set out to out & dbl
@ -125,25 +138,12 @@ on replicate(n, a)
return out & dbl
end replicate
-- range :: Int -> Int -> [Int]
on range(m, n)
set d to 1
if n < m then set d to -1
-- zip :: [a] -> [b] -> [(a, b)]
on zip(xs, ys)
set lng to min(length of xs, length of ys)
set lst to {}
repeat with i from m to n by d
set end of lst to i
repeat with i from 1 to lng
set end of lst to {item i of xs, item i of ys}
end repeat
return lst
end range
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property lambda : f
end script
end if
end mReturn
end zip

View file

@ -1,4 +1,4 @@
map(factorCountMod2, range(1, 100))
map(factorCountMod2, enumFromTo(1, 100))
on factorCountMod2(n)
{n, (length of integerFactors(n)) mod 2 = 1}

View file

@ -2,16 +2,16 @@
on perfectSquaresUpTo(n)
script squared
-- (Int -> Int)
on lambda(x)
on |λ|(x)
x * x
end lambda
end |λ|
end script
set realRoot to n ^ (1 / 2)
set intRoot to realRoot as integer
set blnNotPerfectSquare to not (intRoot = realRoot)
map(squared, range(1, intRoot - (blnNotPerfectSquare as integer)))
map(squared, enumFromTo(1, intRoot - (blnNotPerfectSquare as integer)))
end perfectSquaresUpTo
on run

View file

@ -0,0 +1,4 @@
var doors = falses 100
for a in [:101]:
for b in [a:a:101]: doors[b] = !doors[b]
print "Door $a is $('open.' if doors[a] else 'closed.')"

View file

@ -0,0 +1,9 @@
10 DIM D(100)
20 FOR I=1 TO 100
30 FOR J=I TO 100 STEP I
40 LET D(J)=NOT D(J)
50 NEXT J
60 NEXT I
70 FOR I=1 TO 100
80 IF D(I) THEN PRINT I,
90 NEXT I

View file

@ -0,0 +1,9 @@
10 DIM D(100)
20 FOR I=1 TO 100
30 FOR J=I TO 100 STEP I
40 D(J) = NOT D(J)
50 NEXT J
60 NEXT I
70 FOR I=1 TO 100
80 IF D(I) THEN PRINT I,
90 NEXT I

View file

@ -0,0 +1,13 @@
OPTION BASE 1
DECLARE doors[100]
FOR size = 1 TO 100
FOR pass = 0 TO 100 STEP size
doors[pass] = NOT(doors[pass])
NEXT
NEXT
FOR which = 1 TO 100
IF doors[which] THEN PRINT which
NEXT

View file

@ -0,0 +1,12 @@
/* 0 means door is closed, 1 means door is open */
for (i = 0; i < 100; i++) {
for (j = i; j < 100; j += (i + 1)) {
d[j] = 1 - d[j] /* Toggle door */
}
}
"Open doors:
"
for (i = 0; i < 100; i++) {
if (d[i] == 1) (i + 1)
}

View file

@ -1,11 +1,11 @@
// Display all doors
<cfloop from="1" to="100" index="x">
Door #x# Open: #YesNoFormat(ListGetAt(doorList,x))#<br />
</cfloop>
// Display all doors
<cfloop from="1" to="100" index="x">
Door #x# Open: #YesNoFormat(ListGetAt(doorList,x))#<br />
</cfloop>
// Output only open doors
<cfloop from="1" to="100" index="x">
<cfif ListGetAt(doorList,x) EQ 1>
#x#<br />
</cfif>
</cfloop>
// Output only open doors
<cfloop from="1" to="100" index="x">
<cfif ListGetAt(doorList,x) EQ 1>
#x#<br />
</cfif>
</cfloop>

View file

@ -1,14 +1,14 @@
<Cfparam name="doorlist" default="">
<cfloop from="1" to="100" index="i">
<Cfset doorlist = doorlist & 'c,'>
<Cfset doorlist = doorlist & 'c,'>
</cfloop>
<cfloop from="1" to="100" index="i">
<Cfloop from="1" to="100" index="door" step="#i#">
<Cfif listgetat(doorlist, door) eq 'c'>
<Cfset doorlist = listsetat(doorlist, door, 'O')>
<Cfloop from="1" to="100" index="door" step="#i#">
<Cfif listgetat(doorlist, door) eq 'c'>
<Cfset doorlist = listsetat(doorlist, door, 'O')>
<Cfelse>
<Cfset doorlist = listsetat(doorlist, door, 'c')>
<Cfset doorlist = listsetat(doorlist, door, 'c')>
</Cfif>
</Cfloop>
</Cfloop>
</cfloop>
<Cfoutput>#doorlist#</Cfoutput>

View file

@ -7,7 +7,7 @@ Doors flipUnoptimized(Doors doors) pure nothrow {
doors[] = DoorState.closed;
foreach (immutable i; 0 .. doors.length)
for (int j = i; j < doors.length; j += i + 1)
for (ulong j = i; j < doors.length; j += i + 1)
if (doors[j] == DoorState.open)
doors[j] = DoorState.closed;
else

View file

@ -0,0 +1,5 @@
100[$][0^:1-]# {initialize doors}
%
[s;[$101<][$$;~\:s;+]#%]d: {function d, switch door state function}
1s:[s;101<][d;!s;1+s:]# {increment step width from 1 to 100, execute function d each time}
1[$101<][$$.' ,;['o,'p,'e,'n,10,]['c,'l,'o,'s,'e,'d,10,]?1+]# {loop through doors, print door number and state}

View file

@ -0,0 +1,20 @@
1 open
2 closed
3 closed
4 open
5 closed
6 closed
7 closed
8 closed
9 open
10 closed
11 closed
12 closed
...
94 closed
95 closed
96 closed
97 closed
98 closed
99 closed
100 open

View file

@ -0,0 +1,48 @@
datatype Door = Closed | Open
method InitializeDoors(n:int) returns (doors:array<Door>)
// Precondition: n must be a valid array size.
requires n >= 0
// Postcondition: doors is an array, which is not an alias for any other
// object, with a length of n, all of whose elements are Closed. The "fresh"
// (non-alias) condition is needed to allow doors to be modified by the
// remaining code.
ensures doors != null && fresh(doors) && doors.Length == n
ensures forall j :: 0 <= j < doors.Length ==> doors[j] == Closed;
{
doors := new Door[n];
var i := 0;
// Invariant: i is always a valid index inside the loop, and all doors less
// than i are Closed. These invariants are needed to ensure the second
// postcondition.
while i < doors.Length
invariant i <= doors.Length
invariant forall j :: 0 <= j < i ==> doors[j] == Closed;
{
doors[i] := Closed;
i := i + 1;
}
}
method Main ()
{
var doors := InitializeDoors(100);
var pass := 1;
while pass <= doors.Length
{
var door := pass;
while door < doors.Length
{
doors[door] := if doors[door] == Closed then Open else Closed;
door := door + pass;
}
pass := pass + 1;
}
var i := 0;
while i < doors.Length
{
print i, " is ", if doors[i] == Closed then "closed\n" else "open\n";
i := i + 1;
}
}

View file

@ -1,21 +1,22 @@
#import system.
#import system'routines.
#import extensions.
import system'routines.
import extensions.
#symbol program=
program =
[
#var Doors := Array new:100 set &every: (&index:n) [ false ].
var Doors := Array new:100; populate(:n)( false ).
0 till:100 &doEach: i
0 till:100 do(:i)
[
i till:100 &by:(i + 1) &doEach: j
i till:100 by(i + 1) do(:j)
[
Doors@j := Doors@j not.
].
Doors[j] := Doors[j] not
]
].
0 till:100 &doEach: i
0 till:100 do(:i)
[
console writeLine:"Door #":(i + 1):" :":(Doors@i iif:"Open":"Closed").
console printLine("Door #",i + 1," :",Doors[i] iif("Open","Closed"))
].
console readChar.
].

View file

@ -0,0 +1,17 @@
-- Unoptimized
import List exposing (indexedMap, foldl, repeat, range)
import Html exposing (text)
type Door = Open | Closed
toggle d = if d == Open then Closed else Open
toggleEvery : Int -> List Door -> List Door
toggleEvery k doors = indexedMap
(\i door -> if i % k == 0 then toggle door else door)
doors
n = 100
main =
text (toString (foldl toggleEvery (repeat n Closed) (range 1 n)))

View file

@ -0,0 +1,7 @@
100[$][0 1ø:1-]# {initialize doors}
%
[s;[$101\>][$$;~\:s;+]#%]d: {function d, switch door state function}
1s:[s;101\>][d;!s;1+s:]# {increment step width from 1 to 100, execute function d each time}
1[$101\>][$$." ";$["open
"]?~["closed
"]?1+]# {loop through doors, print door number and state}

View file

@ -0,0 +1,14 @@
1 open
2 closed
3 closed
4 open
5 closed
6 closed
7 closed
8 closed
9 open
10 closed
...
98 closed
99 closed
100 open

View file

@ -0,0 +1,26 @@
# Set doors to empty list
set doors
# Initialize doors arrays
for i in (seq 100)
set doors[$i] 0
end
for i in (seq 100)
set j $i
while test $j -le 100
# Logical not on doors
set doors[$j] (math !$doors[$j])
set j (math $j + $i)
end
end
# Print every door
for i in (seq (count $doors))
echo -n "$i "
if test $doors[$i] -eq 0
echo closed
else
echo open
end
end

View file

@ -0,0 +1,12 @@
# Set doors to empty list
set doors
for i in (seq 100)
set doors[(math "$i * $i")] 1
echo -n "$i "
if test $doors[$i] -eq 1
echo open
else
echo closed
end
end

View file

@ -0,0 +1,16 @@
Public Sub Main()
Dim bDoor As New Boolean[101]
Dim siCount1, siCount2, siStart As Short
For siCount1 = 1 To 100
Inc siStart
For siCount2 = siStart To 100 Step siCount1
bDoor[siCount2] = Not bDoor[siCount2]
Next
Next
For siCount1 = 1 To 100
If bDoor[siCount1] Then Print siCount1;;
Next
End

View file

@ -0,0 +1,4 @@
100` *=0=>d $$ create vector 1..100, create bit pattern d, marking all equal to 0
:for (1..100[.s]){ $$ loop s from 1 to 100
d^(100` %s *=0 )=>d;} $$ d = d xor (bit pattern of vector 1..100 % s)
d $$ output d

View file

@ -0,0 +1,2 @@
Result:
10010000 10000001 00000000 10000000 00010000 00000000 10000000 00000001 00000000 00000000 10000000 00000000 0001

View file

@ -1,10 +1,21 @@
data Door = Open | Closed deriving Show
data Door
= Open
| Closed
deriving (Eq, Show)
toggle Open = Closed
toggle :: Door -> Door
toggle Open = Closed
toggle Closed = Open
toggleEvery :: [Door] -> Int -> [Door]
toggleEvery xs k = zipWith ($) fs xs
where fs = cycle $ (replicate (k-1) id) ++ [toggle]
toggleEvery :: Int -> [Door] -> [Door]
toggleEvery k = zipWith toggleK [1 ..]
where
toggleK n door
| n `mod` k == 0 = toggle door
| otherwise = door
run n = foldl toggleEvery (replicate n Closed) [1..n]
run :: Int -> [Door]
run n = foldr toggleEvery (replicate n Closed) [1 .. n]
main :: IO ()
main = print $ filter ((== Open) . snd) $ zip [1 ..] (run 100)

View file

@ -1,12 +1,6 @@
data Door = Open | Closed deriving Show
gate :: Eq a => [a] -> [a] -> [Door]
gate (x:xs) (y:ys) | x == y = Open : gate xs ys
gate (x:xs) ys = Closed : gate xs ys
gate [] _ = []
toggle Open = Closed
toggle Closed = Open
toggleEvery :: Int -> [Door] -> [Door]
toggleEvery k = zipWith toggleK [1..]
where
toggleK n door | n `mod` k == 0 = toggle door
| otherwise = door
run n = foldr toggleEvery (replicate n Closed) [1..n]
run n = gate [1..n] [k*k | k <- [1..]]

View file

@ -1,6 +1 @@
gate :: Eq a => [a] -> [a] -> [Door]
gate (x:xs) (y:ys) | x == y = Open : gate xs ys
gate (x:xs) ys = Closed : gate xs ys
gate [] _ = []
run n = gate [1..n] [k*k | k <- [1..]]
run n = takeWhile (< n) [k*k | k <- [1..]]

View file

@ -1 +0,0 @@
run n = takeWhile (< n) [k*k | k <- [1..]]

View file

@ -1 +1,17 @@
N.println(IntStream.rangeClosed(1, 100).filter(i -> Math.pow((int) Math.sqrt(i), 2) == i).boxed().join(", ", "Open Doors: ", ""));
class HundredDoors {
public static void main(String[] args) {
boolean[] doors = new boolean[101];
for (int i = 1; i < doors.length; i++) {
for (int j = i; j < doors.length; j += i) {
doors[j] = !doors[j];
}
}
for (int i = 1; i < doors.length; i++) {
if (doors[i]) {
System.out.printf("Door %d is open.%n", i);
}
}
}
}

View file

@ -1,13 +1,6 @@
public class HundredDoors {
class HundredDoors {
public static void main(String[] args) {
boolean[] doors = new boolean[101];
for (int i = 1; i <= 100; i++) {
for (int j = i; j <= 100; j++) {
if(j % i == 0) doors[j] = !doors[j];
}
}
for (int i = 1; i <= 100; i++) {
System.out.printf("Door %d: %s%n", i, doors[i] ? "open" : "closed");
}
for (int i = 1; i <= 10; i++)
System.out.printf("Door %d is open.%n", i * i);
}
}

View file

@ -1,11 +1,12 @@
public class Doors
{
public static void main(String[] args)
{
boolean[] doors=new boolean[100];
for(int i=0;i<10;i++)
doors[i*(i+2)]=true;
for(int i=0;i<100;i++)
System.out.println("Door #"+(i+1)+" is"+(doors[i]?"open.":" closed."));
}
import java.util.stream.Collectors;
import java.util.stream.IntStream;
class HundredDoors {
public static void main(String args[]) {
String openDoors = IntStream.rangeClosed(1, 100)
.filter(i -> Math.pow((int) Math.sqrt(i), 2) == i)
.mapToObj(Integer::toString)
.collect(Collectors.joining(", "));
System.out.printf("Open doors: %s%n", openDoors);
}
}

View file

@ -1,8 +0,0 @@
public class Doors
{
public static void main(String[] args)
{
for(int i=0;i<10;i++)
System.out.println("Door #"+(i*(i+2)+1)+" is open.");
}
}

View file

@ -1,13 +0,0 @@
public class Doors
{
public static void main(final String[] args)
{
boolean[] doors = new boolean[100];
for (int pass = 0; pass < 10; pass++)
doors[(pass + 1) * (pass + 1) - 1] = true;
for(int i = 0; i < 100; i++)
System.out.println("Door #" + (i + 1) + " is " + (doors[i] ? "open." : "closed."));
}
}

View file

@ -1,12 +0,0 @@
public class Doors
{
public static void main(final String[] args)
{
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 10; i++)
sb.append("Door #").append(i*i).append(" is open\n");
System.out.println(sb.toString());
}
}

View file

@ -1,13 +0,0 @@
public class Doors{
public static void main(String[] args){
int i;
for(i = 1; i < 101; i++){
double sqrt = Math.sqrt(i);
if(sqrt != (int)sqrt){
System.out.println("Door " + i + " is closed");
}else{
System.out.println("Door " + i + " is open");
}
}
}
}

View file

@ -1,9 +0,0 @@
// Array comprehension style
[ for (i of Array.apply(null, { length: 100 })) i ].forEach((_, i) => {
var door = i + 1
var sqrt = Math.sqrt(door);
if (sqrt === (sqrt | 0)) {
console.log("Door %d is open", door);
}
});

View file

@ -6,7 +6,7 @@ def doors(n):
| range(1; length+1)
| if $doors[.] then "Door \(.) is open" else empty end;
([][n+1] = null) as $doors
[range(n+1)|null] as $doors
| reduce range(1; n+1) as $run
( $doors; reduce range($run; n+1; $run ) as $door
( .; .[$door] = (.[$door] | not) ) )

View file

@ -1,10 +1,12 @@
fun oneHundredDoors(): List<Int> {
val doors = BooleanArray(100, { false })
for (i in 0..99)
for (j in i..99 step (i + 1))
for (i in 0..99) {
for (j in i..99 step (i + 1)) {
doors[j] = !doors[j]
return doors.asSequence().mapIndexed { i, b -> i to b }.filter { it.second }
.map { it.first + 1 }.toList()
}
}
return doors
.mapIndexed { i, b -> i to b }
.filter { it.second }
.map { it.first + 1 }
}

View file

@ -1,11 +1,7 @@
a=zeros(1,100);
for b=1:100;
for i=b:b:100;
if a(i)==1
a(i)=0;
else
a(i)=1;
end
end
a = false(1,100);
for b=1:100
for i = b:b:100
a(i) = ~a(i);
end
end
a

View file

@ -0,0 +1,16 @@
var %d = $str(0 $+ $chr(32),100), %m = 1
while (%m <= 100) {
var %n = 1
while ($calc(%n * %m) <= 100) {
var %d = $puttok(%d,$iif($gettok(%d,$calc(%n * %m),32),0,1),$calc(%n * %m),32)
inc %n
}
inc %m
}
echo -ag All Doors (Boolean): %d
var %n = 1
while (%n <= $findtok(%d,1,0,32)) {
var %t = %t $findtok(%d,1,%n,32)
inc %n
}
echo -ag Open Door Numbers: %t

View file

@ -0,0 +1,8 @@
is_open = [false for door = 1,100]
for pass = 1,100
for door = pass,100,pass
is_open[door] = not is_open[door]
for i,v in ipairs is_open
print "Door #{i}: " .. if v then 'open' else 'closed'

View file

@ -0,0 +1,37 @@
DROP PROCEDURE IF EXISTS one_hundred_doors;
DELIMITER |
CREATE PROCEDURE one_hundred_doors (n INT)
BEGIN
DROP TEMPORARY TABLE IF EXISTS doors;
CREATE TEMPORARY TABLE doors (
id INTEGER NOT NULL,
open BOOLEAN DEFAULT FALSE,
PRIMARY KEY (id)
);
SET @i = 1;
create_doors: LOOP
INSERT INTO doors (id, open) values (@i, FALSE);
SET @i = @i + 1;
IF @i > n THEN
LEAVE create_doors;
END IF;
END LOOP create_doors;
SET @i = 1;
toggle_doors: LOOP
UPDATE doors SET open = NOT open WHERE MOD(id, @i) = 0;
SET @i = @i + 1;
IF @i > n THEN
LEAVE toggle_doors;
END IF;
END LOOP toggle_doors;
SELECT id FROM doors WHERE open;
END|
DELIMITER ;
CALL one_hundred_doors(100);

View file

@ -1,16 +0,0 @@
from strutils import format
proc check_doors() =
const n = 100
var is_open : array[1..n, bool] # auto-initialized to false
# pass over the doors n times
for pass in 1..n:
var i = pass
while i <= n:
is_open[i] = not is_open[i]
i += pass
# print the result
for door in 1..n:
echo format("door $1 is $2.", door, (if is_open[door]: "open" else: "closed"))
check_doors()

View file

@ -0,0 +1,38 @@
doors = .array~new(100) -- array containing all of the doors
do i = 1 to doors~size -- initialize with a collection of closed doors
doors[i] = .door~new(i)
end
do inc = 1 to doors~size
do d = inc to doors~size by inc
doors[d]~toggle
end
end
say "The open doors after 100 passes:"
do door over doors
if door~isopen then say door
end
::class door -- simple class to represent a door
::method init -- initialize an instance of a door
expose id state -- instance variables of a door
use strict arg id -- set the id
state = .false -- initial state is closed
::method toggle -- toggle the state of the door
expose state
state = \state
::method isopen -- test if the door is open
expose state
return state
::method string -- return a string value for a door
expose state id
if state then return "Door" id "is open"
else return "Door" id "is closed"
::method state -- return door state as a descriptive string
expose state
if state then return "open"
else return "closed"

View file

@ -1,13 +1,12 @@
<?php
$toggleState = array('open' => 'closed', 'closed' => 'open');
$doors = array_fill(1, 100, 'closed');
$doors = array_fill(1, 100, false);
for ($pass = 1; $pass <= 100; ++$pass) {
for ($nr = 1; $nr <= 100; ++$nr) {
if ($nr % $pass == 0) {
$doors[$nr] = $toggleState[$doors[$nr]];
$doors[$nr] = !$doors[$nr];
}
}
}
for ($nr = 1; $nr <= 100; ++$nr)
printf("Door %d is %s\n", $nr, $doors[$nr]);
printf("Door %d: %s\n", $nr, ($doors[$nr])?'open':'closed');
?>

View file

@ -1,34 +1,21 @@
doors_unoptimized(N) :-
length(L, N),
maplist(init, L),
doors(N, N, L, L1),
affiche(N, L1).
main :-
forall(between(1,100,Door), ignore(display(Door))).
init(close).
% show output if door is open after the 100th pass
display(Door) :-
status(Door, 100, open),
format("Door ~d is open~n", [Door]).
doors(Max, 1, L, L1) :-
!,
inverse(1, 1, Max, L, L1).
% true if Door has Status after Pass is done
status(Door, Pass, Status) :-
Pass > 0,
Remainder is Door mod Pass,
toggle(Remainder, OldStatus, Status),
OldPass is Pass - 1,
status(Door, OldPass, OldStatus).
status(_Door, 0, closed).
doors(Max, N, L, L1) :-
N1 is N - 1,
doors(Max, N1, L, L2),
inverse(N, 1, Max, L2, L1).
inverse(N, Max, Max, [V], [V1]) :-
!,
0 =:= Max mod N -> inverse(V, V1); V1 = V.
inverse(N, M, Max, [V|T], [V1|T1]) :-
M1 is M+1,
inverse(N, M1, Max, T, T1),
( 0 =:= M mod N -> inverse(V, V1); V1 = V).
inverse(open, close).
inverse(close, open).
affiche(N, L) :-
forall(between(1, N, I),
( nth1(I, L, open) -> format('Door ~w is open.~n', [I]); true)).
toggle(Remainder, Status, Status) :-
Remainder > 0.
toggle(0, open, closed).
toggle(0, closed, open).

View file

@ -1,31 +1,34 @@
doors(Num, Passes) :-
forall(( everyNth(1,Passes,1,Pass)
, forall((everyNth(Pass,Num,Pass,Door), toggle(Door)))
))
, show(Num)
.
doors_unoptimized(N) :-
length(L, N),
maplist(init, L),
doors(N, N, L, L1),
affiche(N, L1).
init(close).
doors(Max, 1, L, L1) :-
!,
inverse(1, 1, Max, L, L1).
doors(Max, N, L, L1) :-
N1 is N - 1,
doors(Max, N1, L, L2),
inverse(N, 1, Max, L2, L1).
toggle(Door) :-
Opened = opened(Door)
, ( clause(Opened,_) -> retract(Opened)
; asserta(Opened)
).
inverse(N, Max, Max, [V], [V1]) :-
!,
0 =:= Max mod N -> inverse(V, V1); V1 = V.
inverse(N, M, Max, [V|T], [V1|T1]) :-
M1 is M+1,
inverse(N, M1, Max, T, T1),
( 0 =:= M mod N -> inverse(V, V1); V1 = V).
show(Num) :-
forall(( between(1,Num,Door)
, (opened(Door) -> State = opened ; State = closed)
, write(Door), write(' '), write(State), nl
)).
inverse(open, close).
inverse(close, open).
% utils
forall(X) :- findall(_, X, _).
everyNth(From,To,Step,X) :-
From =< To
, ( X = From ; From1 is From + Step, everyNth(From1,To,Step,X) )
.
main :- doors(100,100), halt.
affiche(N, L) :-
forall(between(1, N, I),
( nth1(I, L, open) -> format('Door ~w is open.~n', [I]); true)).

View file

@ -1,4 +1,31 @@
doors_optimized(N) :-
Max is floor(sqrt(N)),
forall(between(1, Max, I),
( J is I*I,format('Door ~w is open.~n',[J]))).
doors(Num, Passes) :-
forall(( everyNth(1,Passes,1,Pass)
, forall((everyNth(Pass,Num,Pass,Door), toggle(Door)))
))
, show(Num)
.
toggle(Door) :-
Opened = opened(Door)
, ( clause(Opened,_) -> retract(Opened)
; asserta(Opened)
).
show(Num) :-
forall(( between(1,Num,Door)
, (opened(Door) -> State = opened ; State = closed)
, write(Door), write(' '), write(State), nl
)).
% utils
forall(X) :- findall(_, X, _).
everyNth(From,To,Step,X) :-
From =< To
, ( X = From ; From1 is From + Step, everyNth(From1,To,Step,X) )
.
main :- doors(100,100), halt.

View file

@ -0,0 +1,4 @@
doors_optimized(N) :-
Max is floor(sqrt(N)),
forall(between(1, Max, I),
( J is I*I,format('Door ~w is open.~n',[J]))).

View file

@ -0,0 +1,23 @@
using system;
// initialize doors as pairs: number, status where 0 means open
let doors = zip (1..100) (repeat 1);
toogle (x,y) = x,~y;
toogleEvery n d = map (tooglep n) d with
tooglep n d@((x,_)) = toogle d if ~(x mod n);
= d otherwise; end;
// show description of given doors
status (n,x) = (str n) + (case x of
1 = " close";
0 = " open"; end);
let result = foldl (\a n -> toogleEvery n a) doors (1..100);
// pretty print the result (only open doors)
showResult = do (puts.status) final when
final = filter open result with
open (_,x) = ~x;
end; end;

View file

@ -1,14 +0,0 @@
/*REXX program to solve the 100 door puzzle, the easy-way version. */
parse arg doors . /*get the first argument (# of doors.) */
if doors=='' then doors=100 /*not specified? Then assume 100 doors*/
/* 0 = closed. */
/* 1 = open. */
door.=0 /*assume all that all doors are closed.*/
say
say 'For the' doors "doors problem, the following doors are open:"
say
do j=1 for doors /*process an easy pass-through. */
p=j**2 /*square the door number. */
if p>doors then leave /*if too large, we're done. */
say right(p,20)
end /*j*/

View file

@ -1,12 +0,0 @@
/*REXX program to solve the 100 door puzzle, the easy-way version 2.*/
parse arg doors . /*get the first argument (# of doors.) */
if doors=='' then doors=1000 /*not specified? Then assume 1000 doors*/
/* 0 = closed. */
/* 1 = open. */
door.=0 /*assume all that all doors are closed.*/
say
say 'For the' doors "doors problem, the open doors are:"
say
do j=1 for doors while j**2<=doors /*limit pass-throughs.*/
say right(j**2,20)
end /*j*/

View file

@ -1,6 +1,8 @@
#![feature(inclusive_range_syntax)]
fn main() {
let mut door_open = [false; 100];
for pass in (1..101) {
for pass in 1...100 {
let mut door = pass;
while door <= 100 {
door_open[door - 1] = !door_open[door - 1];

View file

@ -1,9 +1,11 @@
fn main() {
let squares: Vec<_> = (1..10+1).map(|n| n*n).collect();
let is_square = |num| squares.binary_search(&num).is_ok();
#![feature(inclusive_range_syntax)]
for i in 1..100+1 {
let state = if is_square(i) {"open"} else {"closed"};
println!("Door {} is {}", i, state);
}
fn main() {
let doors = vec![false; 100].iter_mut().enumerate()
.map(|(door, door_state)| (1...100).into_iter()
.filter(|pass| door % pass == 0)
.map(|_| { *door_state = !*door_state; *door_state })
.last().unwrap()).collect::<Vec<_>>();
println!("{:?}", doors);
}

View file

@ -1,5 +1,11 @@
#![feature(inclusive_range_syntax)]
fn main() {
for i in 1u32..11u32{
println!("Door {} is open", i.pow(2));
let squares: Vec<_> = (1...10).map(|n| n*n).collect();
let is_square = |num| squares.binary_search(&num).is_ok();
for i in 1...100 {
let state = if is_square(i) {"open"} else {"closed"};
println!("Door {} is {}", i, state);
}
}

View file

@ -0,0 +1,7 @@
#![feature(inclusive_range_syntax)]
fn main() {
for i in 1u32...10u32{
println!("Door {} is open", i.pow(2));
}
}

View file

@ -0,0 +1,14 @@
doors=zeros(1,100);
for i = 1:100
for j = i:i:100
doors(j) = ~doors(j);
end
end
for i = 1:100
if ( doors(i) )
s = "open";
else
s = "closed";
end
printf("%d %s\n", i, s);
end

View file

@ -1,13 +1,13 @@
var doors = []
100.times { |pass|
100.times { |i|
if (i % pass == 0) {
{ |pass|
{ |i|
if (pass `divides` i) {
doors[i] := false -> not!
}
}
}
} << 1..100
} << 1..100
100.times { |i|
"Door %3d is %s\n".printf(i, doors[i] ? 'open' : 'closed')
}
{ |i|
say ("Door %3d is %s" % (i, doors[i] ? 'open' : 'closed'))
} << 1..100

View file

@ -1,3 +1,3 @@
{ |i|
"Door %3d is %s\n".printf(i, ["closed", "open"][i.is_sqr])
} * 100
"Door %3d is %s\n".printf(i, <closed open>[i.is_sqr])
} << 1..100

View file

@ -0,0 +1,16 @@
BEGIN
INTEGER I, PASS;
BOOLEAN ARRAY DOORS(1:100);
FOR I := 1 STEP 1 UNTIL 100 DO
DOORS(I) := FALSE;
FOR PASS := 1 STEP 1 UNTIL 100 DO
FOR I := PASS STEP PASS UNTIL 100 DO
DOORS(I) := NOT DOORS(I);
FOR I := 1 STEP 1 UNTIL 100 DO
IF DOORS(I)
THEN BEGIN OUTTEXT("DOOR "); OUTINT(I,0); OUTTEXT(" IS OPEN"); OUTIMAGE END
END.

View file

@ -0,0 +1,9 @@
x=1!y=3!z=0
PRINT "Open doors: ";x;" ";
DO
z=x+y
PRINT z;" ";
x=z
y=y+2
UNTIL z>=100
END

View file

@ -0,0 +1,19 @@
datatype Door = Closed | Opened
fun toggle Closed = Opened
| toggle Opened = Closed
fun pass (steps, doors) = List.mapi (fn (k, door) => if (k+1) mod steps = 0 then toggle door else door) doors
(* [1..n] *)
fun runs n = List.tabulate (n, fn k => k+1)
fun run n =
let
val initialdoors = List.tabulate (n, fn _ => Closed)
val runs = runs n
in
foldl pass initialdoors runs
end
fun opened_doors n = List.mapPartiali (fn (k, Closed) => NONE | (k, Opened) => SOME (k+1)) (run n)

View file

@ -0,0 +1,24 @@
clear all
set obs 100
gen doors=0
gen index=_n
forvalues i=1/100 {
quietly replace doors=1-doors if mod(_n,`i')==0
}
list index if doors
+-------+
| index |
|-------|
1. | 1 |
4. | 4 |
9. | 9 |
16. | 16 |
25. | 25 |
|-------|
36. | 36 |
49. | 49 |
64. | 64 |
81. | 81 |
100. | 100 |
+-------+

View file

@ -1,16 +0,0 @@
PROGRAM:DOORS100
:ClrHome
:Disp "SETTING UP LIST"
:Disp "PLEASE WAIT..."
:For(I,1,100,1)
:0?L1(I)
:End
:ClrHome
:Disp "Pass"
:For(I,1,100,1)
:For(J,I,100,I)
:Output(2,1,I)
:not(L1(J))?L1(J)
:End
:End
:ClrHome

View file

@ -1,4 +0,0 @@
PROGRAM:DOORSOPT
:For(I,1,100,1)
:not(fPart(v(I)))?L1(I)
:End

View file

@ -0,0 +1,15 @@
! Optimized solution with True BASIC
OPTION NOLET
x = 1
y = 3
z = 0
PRINT STR$(x) & " Open"
DO UNTIL z >= 100
z = x + y
PRINT STR$(z) & " Open"
x = z
y = y + 2
LOOP
END

View file

@ -0,0 +1,66 @@
; linux x86_64
section .data
open: db "open", 10
closed: db "closed", 10
section .bss
doors resb 101
section .text
global _start
_start:
mov rax, 1
mov bl, 0
zeroset_door:
mov [doors + rax], bl
inc rax
cmp rax, 101
jl zeroset_door
mov rax, 0
set_doors:
inc rax
cmp rax, 101
je display_result
mov rbx, 0
make_pass:
add rbx, rax
cmp rbx, 101
jge set_doors
not byte [doors + rbx]
jmp make_pass
display_result:
mov rbx, 0
display_door:
inc rbx
cmp rbx, 101
je exit
cmp byte [doors + rbx], 0
je print_closed
jmp print_open
print_open:
mov rax, 1
mov rdi, 1
mov rsi, open
mov rdx, 5
syscall
jmp display_door
print_closed:
mov rax, 1
mov rdi, 1
mov rsi, closed
mov rdx, 7
syscall
jmp display_door
exit:
mov rax, 60
mov rdi, 0
syscall

View file

@ -1,47 +0,0 @@
(100doors)
comment: returns the first 100 doors after making 100 passes
(always)
(pr) (first) 100 (passes) 1 (doors)
(doors)
comment: start with an infinite list of closed doors
(always)
(c) "'closed" (doors)
(passes) count doors
comment: count is greater than 100 -> make 100 passes
(>) count 100
doors
(passes) count doors
comment: count is not greater than 100 -> make 100 passes
(always)
(passes) (add1) count
(pass) count doors
(pass) count doors
comment: takes a count and a list of doors -> makes a pass over the doors
(always)
(ZEDpass) count count doors
(ZEDpass) count1 count2 doors
comment: count2 is one -> completes a pass over the doors
(=) count2 1
(c) (toggle) (1) doors
(pass) count1 (!) doors
(ZEDpass) count1 count2 doors
comment: count2 is greater than one -> completes a pass over the doors
(>) count2 1
(c) (1) doors
(ZEDpass) count1 (sub1) count2 (!) doors
(toggle) door
comment: door is closed -> toggles it
(=) door "'closed"
"'open"
(toggle) door
comment: door is open -> toggles it
(=) door "'open"
"'closed"

View file

@ -0,0 +1,3 @@
doors:=List.createLong(100,False); // list of 100 Falses
foreach n,m in (100,[n..99,n+1]){ doors[m]=(not doors[m]); } //foreach{ foreach{} }
doors.filterNs().apply('+(1)).println();

View file

@ -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'}"

View file

@ -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)

View 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")
}
}

View file

@ -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

View file

@ -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

View 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]]]
}

View file

@ -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
}
}
}

View file

@ -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...))
}
}
}

View 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.

View 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) }]];
}

View file

@ -0,0 +1,3 @@
solutions:=u(game24Solver(ask(0,"digits: ")));
println(solutions.len()," solutions:");
solutions.apply2(Console.println);

View file

@ -0,0 +1,8 @@
tfgame{⎕IO1
d?9
i
u[u{¨(0)}(i'1234567890')i]d[d]:'nope'
~/((~bi'1234567890')/i)'+-×÷()':'nope'
24i:'nope'
'Yeah!'
}

View file

@ -1,150 +0,0 @@
@set @dummy=0 /*
::24.bat
::
::Batch file implemetnation of the 24 Game where a player is given four random
::digits n, where 1 <= n <= 9, and needs to provide a simple arithmetic
::operation that does evaluate to 24.
::
::Please open the Batch File Directly to play...
@echo off
setlocal enabledelayedexpansion
title The 24 Game Batch File
cls
echo.
echo The 24 Game
echo.
echo Given four digits, provide a simple arithmetic expression
echo that evaluates to 24 using +,-,*,/.
echo.
echo Reminders (Please read):
echo.
echo 1. Type 'new' (NO quotes) - Fresh digits
echo 2. Type 'show' (NO quotes) - Show digits
echo 3. Type 'exit' (NO quotes) - Quit game
echo 4. Combining two digits as one number is NOT allowed.
echo 5. Use each digit only ONCE in expressions.
echo 6. Use ONLY the Parentheses as the groupting symbols.
echo 7. Do not make any digit Negative.
echo.
echo Why do someone wants to not follow the reminders? To trick me, right? ;)
echo.
pause
:NEW
set TRY=0
::Get four random digits
set /a "DIGIT_1=%RANDOM%%%9+1"
set /a "DIGIT_2=%RANDOM%%%9+1"
set /a "DIGIT_3=%RANDOM%%%9+1"
set /a "DIGIT_4=%RANDOM%%%9+1"
cls
echo.
echo The 24 Game
echo.
goto SHOW
::Main Program Loop
:MAIN
set /a TRY+=1
set ANSWER=
set "TMP_DIGIT_1=%DIGIT_1%"
set "TMP_DIGIT_2=%DIGIT_2%"
set "TMP_DIGIT_3=%DIGIT_3%"
set "TMP_DIGIT_4=%DIGIT_4%"
::Prompt for an answer
echo.
set /p ANSWER="Try %TRY%: "
::Determine if the player inputs a "good" try (input validation...)
if /i "!ANSWER!"=="NEW" goto NEW
if /i "!ANSWER!"=="SHOW" goto SHOW
if /i "!ANSWER!"=="EXIT" goto ABORT
set ANSWER=!ANSWER: =!
set DIGITS_USED=0&set COUNTER=0
:LOOP
set CURR_DIGIT=!ANSWER:~%COUNTER%,1!
if "!CURR_DIGIT!"=="%TMP_DIGIT_1%" (set "TMP_DIGIT_1=X"&goto NEXTCHARSCAN1)
if "!CURR_DIGIT!"=="%TMP_DIGIT_2%" (set "TMP_DIGIT_2=X"&goto NEXTCHARSCAN1)
if "!CURR_DIGIT!"=="%TMP_DIGIT_3%" (set "TMP_DIGIT_3=X"&goto NEXTCHARSCAN1)
if "!CURR_DIGIT!"=="%TMP_DIGIT_4%" (set "TMP_DIGIT_4=X"&goto NEXTCHARSCAN1)
if "!CURR_DIGIT!"=="" goto ALMOST
if "!CURR_DIGIT!"==")" goto SCANMORE
if "!CURR_DIGIT!"=="(" goto SCANMORE
if "!CURR_DIGIT!"=="+" goto NEXTCHARSCAN2
if "!CURR_DIGIT!"=="-" goto DONTALLOWNEGATIVES
if "!CURR_DIGIT!"=="*" goto NEXTCHARSCAN2
if "!CURR_DIGIT!"=="/" goto NEXTCHARSCAN2
goto ERROR_ICHAR_FOUND
:NEXTCHARSCAN1
set /a NEXT=%COUNTER%+1
set NEXT_CHAR=!ANSWER:~%NEXT%,1!
for /l %%w in (1,1,9) do (
if "!NEXT_CHAR!"=="%%w" goto ERROR_POSITION
)
goto :SCANMORE
:DONTALLOWNEGATIVES
set /a NEXT=%COUNTER%-1
if "%NEXT%"=="-1" goto ERROR_NEGA
set NEXT_CHAR=!ANSWER:~%NEXT%,1!
for /l %%z in (1,1,9) do (
if "!NEXT_CHAR!"=="%%z" goto NEXTCHARSCAN2
)
if "!NEXT_CHAR!"=="(" goto ERROR_NEGA
if "!NEXT_CHAR!"==")" goto NEXTCHARSCAN2
goto ERROR_NEGA
:NEXTCHARSCAN2
set /a NEXT=%COUNTER%+1
set NEXT_CHAR=!ANSWER:~%NEXT%,1!
for %%y in (+,-,/) do (
if "!NEXT_CHAR!"=="%%y" goto ERROR_TRICK
)
:SCANMORE
set /a "COUNTER+=1"&goto LOOP
:ALMOST
if not "%TMP_DIGIT_1%%TMP_DIGIT_2%%TMP_DIGIT_3%%TMP_DIGIT_4%"=="XXXX" goto ERROR_CHARS
::(SIGH) Input passed... Now, calculate and evaluate result
set "RESULT="
for /f "usebackq delims=" %%x in (`cscript //nologo //e:jscript "%~f0" "%ANSWER%" 2^>nul`) do set RESULT=%%x
::Wait... Input is STILL erroneous???
if "%RESULT%"=="" goto ERROR_SYNTAX
::YES!!! Correct Expression???
if "%RESULT%"=="24" goto END
::The Outputs
echo Wrong Answer [%RESULT% is not equal to 24.]&goto MAIN
:ERROR_CHARS
echo Invalid input [Please use all the digits above ONCE.]&goto MAIN
:ERROR_ICHAR_FOUND
echo Invalid input [An invalid character is found... C'mon...]&goto MAIN
:ERROR_SYNTAX
echo Invalid input [Syntax Error... Please answer seriously... I'm begging you...]&goto MAIN
:ERROR_POSITION
echo Invalid input [Sorry, digit concatenation is not allowed.]&goto MAIN
:ERROR_TRICK
echo Invalid input [Are you Playing the Game Seriously?]&goto MAIN
:ERROR_NEGA
echo Invalid input [Do not Make any Digit Negative.]&goto MAIN
:SHOW
echo Given digits: %DIGIT_1% %DIGIT_2% %DIGIT_3% %DIGIT_4%&goto MAIN
:END
echo Correct Input [Congratulations^^!]
echo.
echo Press any char key for a new game, or close this window to exit...
pause>nul
goto NEW
:ABORT
echo.
exit
::*/
WScript.echo(eval(WScript.arguments(0)));

View file

@ -1,96 +1,95 @@
#define system.
#define system'routines.
#define system'collections.
#define system'dynamic.
#define extensions.
import system'routines.
import system'collections.
import system'dynamic.
import extensions.
#class ExpressionTree
class ExpressionTree
{
#field theTree.
object theTree.
#constructor new : aLiteral
constructor new : aLiteral
[
#var aLevel := Integer new:0.
var aLevel := Integer new:0.
aLiteral run &each: ch
aLiteral forEach(:ch)
[
#var node := Dynamic new.
var node := DynamicStruct new.
ch =>
#43 ? [ node set &level:(aLevel + 1) set &operation:%add. ] // +
#45 ? [ node set &level:(aLevel + 1) set &operation:%subtract. ] // -
#42 ? [ node set &level:(aLevel + 2) set &operation:%multiply. ] // *
#47 ? [ node set &level:(aLevel + 2) set &operation:%divide. ] // /
#40 ? [ aLevel += 10. ^ $self. ] // (
#41 ? [ aLevel -= 10. ^ $self. ] // )
$43 [ node set level(aLevel + 1); set operation:%add ]; // +
$45 [ node set level(aLevel + 1); set operation:%subtract ]; // -
$42 [ node set level(aLevel + 2); set operation:%multiply ]; // *
$47 [ node set level(aLevel + 2); set operation:%divide ]; // /
$40 [ aLevel append int:10. ^ $self ]; // (
$41 [ aLevel reduce int:10. ^ $self ]; // )
! [
node set &leaf:(ch literal toReal) set &level:((aLevel + 3)).
node set leaf(ch literal; toReal); set level(aLevel + 3).
].
($nil == theTree)
? [ theTree := node. ]
! [
(theTree level >= node level)
? [
node set &left:theTree set &right:$nil.
if ($nil == theTree)
[ theTree := node ];
[
if (theTree level >= node level)
[
node set left:theTree; set right:$nil.
theTree := node.
theTree := node
];
[
var aTop := theTree.
while (($nil != aTop right)and:$(aTop right; level < node level))
[ aTop := aTop right ].
node set left(aTop right); set right:$nil.
aTop set right:node
]
! [
#var aTop := theTree.
#loop (($nil != aTop right)and:[aTop right level < node level] )
? [ aTop := aTop right. ].
node set &left:(aTop right) set &right:$nil.
aTop set &right:node.
].
].
].
]
]
]
#method eval : aNode
eval : aNode
[
(aNode if &leaf)
? [ ^ aNode leaf. ]
! [
#var aLeft := $self eval:(aNode left).
#var aRight := $self eval:(aNode right).
if (aNode containsProperty:%leaf)
[ ^ aNode leaf ];
[
var aLeft := $self eval:(aNode left).
var aRight := $self eval:(aNode right).
^ aLeft::(aNode operation) eval:aRight.
^ aLeft~(aNode operation) eval:aRight
]
]
#method value
value
<= eval:theTree.
#method readLeaves : aList &at:aNode
readLeaves : aList at:aNode
[
($nil == aNode)
? [ #throw InvalidArgumentException new. ].
if ($nil == aNode)
[ InvalidArgumentException new; raise ].
(aNode if &leaf)
? [ aList += aNode leaf. ]
! [
$self readLeaves:aList &at:(aNode left).
$self readLeaves:aList &at:(aNode right).
if (aNode containsProperty:%leaf)
[ aList append(aNode leaf) ];
[
$self readLeaves:aList at(aNode left).
$self readLeaves:aList at(aNode right).
].
]
#method readLeaves : aList
<= readLeaves:aList &at:theTree.
readLeaves : aList
<= readLeaves:aList at:theTree.
}
#class TwentyFourGame
class TwentyFourGame
{
#field theNumbers.
object theNumbers.
#constructor new
constructor new
[
$self newPuzzle.
]
#method newPuzzle
newPuzzle
[
theNumbers := (
1 + randomGenerator eval:9,
@ -99,75 +98,76 @@
1 + randomGenerator eval:9).
]
#method help
help
[
console
writeLine:"------------------------------- Instructions ------------------------------"
writeLine:"Four digits will be displayed."
writeLine:"Enter an equation using all of those four digits that evaluates to 24"
writeLine:"Only * / + - operators and () are allowed"
writeLine:"Digits can only be used once, but in any order you need."
writeLine:"Digits cannot be combined - i.e.: 12 + 12 when given 1,2,2,1 is not allowed"
writeLine:"Submit a blank line to skip the current puzzle."
writeLine:"Type 'q' to quit"
writeLine
writeLine:"Example: given 2 3 8 2, answer should resemble 8*3-(2-2)"
writeLine:"------------------------------- --------------------------------------------".
printLine:"------------------------------- Instructions ------------------------------";
printLine:"Four digits will be displayed.";
printLine:"Enter an equation using all of those four digits that evaluates to 24";
printLine:"Only * / + - operators and () are allowed";
printLine:"Digits can only be used once, but in any order you need.";
printLine:"Digits cannot be combined - i.e.: 12 + 12 when given 1,2,2,1 is not allowed";
printLine:"Submit a blank line to skip the current puzzle.";
printLine:"Type 'q' to quit";
writeLine;
printLine:"Example: given 2 3 8 2, answer should resemble 8*3-(2-2)";
printLine:"------------------------------- --------------------------------------------".
]
#method prompt
prompt
[
theNumbers run &each: n [ console writeLiteral:n:" ". ].
theNumbers forEach(:n) [ console print(n," ") ].
console write:": ".
console print:": "
]
#method resolve : aLine
resolve : aLine
[
#var exp := ExpressionTree new:aLine.
var exp := ExpressionTree new:aLine.
#var Leaves := ArrayList new.
var Leaves := ArrayList new.
exp readLeaves:Leaves.
(Leaves ascendant equal &indexable:(theNumbers ascendant))
! [ console writeLine:"Invalid input. Enter an equation using all of those four digits. Try again.". ^ $self. ].
ifnot (Leaves ascendant; sequenceEqual(theNumbers ascendant))
[ console printLine:"Invalid input. Enter an equation using all of those four digits. Try again.". ^ $self ].
#var aResult := exp value.
(aResult == 24)
? [
console writeLine:"Good work. ":aLine:"=":aResult.
var aResult := exp value.
if (aResult == 24)
[
console printLine("Good work. ",aLine,"=",aResult).
$self newPuzzle.
]
! [ console writeLine:"Incorrect. ":aLine:"=":aResult. ].
];
[ console printLine("Incorrect. ",aLine,"=",aResult) ]
]
}
#class(extension) gameOp
extension gameOp
{
#method playRound : aLine
playRound : aLine
[
(aLine == "q")
? [ ^ false. ]
! [
(aLine == "")
? [ console writeLine:"Skipping this puzzle". self newPuzzle. ]
! [
self resolve:aLine
| if &Error: e
[
console writeLine:"An error occurred. Check your input and try again.".
].
if (aLine == "q")
[ ^ false ];
[
if (aLine == "")
[ console printLine:"Skipping this puzzle". self newPuzzle. ];
[
try(self resolve:aLine)
{
on(Exception e) [
console writeLine:"An error occurred. Check your input and try again."
]
}
].
^ true.
^ true
].
]
}
#symbol program =
program =
[
#var aGame := TwentyFourGame new help.
var aGame := TwentyFourGame new; help.
#loop (aGame prompt playRound:(console readLine)) ? [].
while (aGame prompt; playRound(console readLine)) [].
].

View file

@ -1,43 +1,53 @@
import Char
import Control.Monad.Error
import Data.List
import IO
import Maybe
import Random
import Data.List (sort)
import Data.Char (isDigit)
import Data.Maybe (fromJust)
import Control.Monad (foldM)
import System.Random (randomRs, getStdGen)
import System.IO (hSetBuffering, stdout, BufferMode(NoBuffering))
main = do
hSetBuffering stdout NoBuffering
mapM_ putStrLn
[ "THE 24 GAME\n"
, "Given four digits in the range 1 to 9"
, "Use the +, -, *, and / operators in reverse polish notation"
, "To show how to make an answer of 24.\n"
]
digits <- liftM (sort . take 4 . randomRs (1,9)) getStdGen :: IO [Int]
putStrLn ("Your digits: " ++ intercalate " " (map show digits))
guessLoop digits
where guessLoop digits =
putStr "Your expression: " >>
liftM (processGuess digits . words) getLine >>=
either (\m -> putStrLn m >> guessLoop digits) putStrLn
hSetBuffering stdout NoBuffering
mapM_
putStrLn
[ "THE 24 GAME\n"
, "Given four digits in the range 1 to 9"
, "Use the +, -, *, and / operators in reverse polish notation"
, "To show how to make an answer of 24.\n"
]
digits <- fmap (sort . take 4 . randomRs (1, 9)) getStdGen :: IO [Int]
putStrLn ("Your digits: " ++ unwords (fmap show digits))
guessLoop digits
where
guessLoop digits =
putStr "Your expression: " >> fmap (processGuess digits . words) getLine >>=
either (\m -> putStrLn m >> guessLoop digits) putStrLn
processGuess _ [] = Right ""
processGuess digits xs | not $ matches = Left "Wrong digits used"
where matches = digits == (sort . map read $ filter (all isDigit) xs)
processGuess _ [] = Right ""
processGuess digits xs
| not matches = Left "Wrong digits used"
where
matches = digits == (sort . fmap read $ filter (all isDigit) xs)
processGuess digits xs = calc xs >>= check
where check 24 = Right "Correct"
check x = Left (show (fromRational (x :: Rational)) ++ " is wrong")
where
check 24 = Right "Correct"
check x = Left (show (fromRational (x :: Rational)) ++ " is wrong")
-- A Reverse Polish Notation calculator with full error handling
calc xs = foldM simplify [] xs >>= \ns -> (case ns of
[n] -> Right n
_ -> Left "Too few operators")
calc xs =
foldM simplify [] xs >>=
\ns ->
(case ns of
[n] -> Right n
_ -> Left "Too few operators")
simplify (a:b:ns) s | isOp s = Right ((fromJust $ lookup s ops) b a : ns)
simplify _ s | isOp s = Left ("Too few values before " ++ s)
simplify ns s | all isDigit s = Right (fromIntegral (read s) : ns)
simplify _ s = Left ("Unrecognized symbol: " ++ s)
simplify (a:b:ns) s
| isOp s = Right ((fromJust $ lookup s ops) b a : ns)
simplify _ s
| isOp s = Left ("Too few values before " ++ s)
simplify ns s
| all isDigit s = Right (fromIntegral (read s) : ns)
simplify _ s = Left ("Unrecognized symbol: " ++ s)
isOp v = elem v $ map fst ops
isOp v = elem v $ fmap fst ops
ops = [("+",(+)), ("-",(-)), ("*",(*)), ("/",(/))]
ops = [("+", (+)), ("-", (-)), ("*", (*)), ("/", (/))]

View file

@ -1,6 +1,6 @@
package game24
import java.util.*
import java.util.Random
import java.util.Scanner
import java.util.Stack
internal object Game24 {
fun run() {
@ -10,9 +10,9 @@ internal object Game24 {
print("> ")
val s = Stack<Float>()
var total: Long = 0
var total = 0L
val cin = Scanner(System.`in`)
for (c in cin.nextLine())
for (c in cin.nextLine()) {
when (c) {
in '0'..'9' -> {
val d = c - '0'
@ -20,9 +20,11 @@ internal object Game24 {
s += d.toFloat()
}
else ->
if ("+/-*".indexOf(c) != -1)
if ("+/-*".indexOf(c) != -1) {
s += c.applyOperator(s.pop(), s.pop())
}
}
}
when {
tally(digits) != total ->
@ -34,7 +36,7 @@ internal object Game24 {
}
}
fun Char.applyOperator(a: Float, b: Float) = when (this) {
private fun Char.applyOperator(a: Float, b: Float) = when (this) {
'+' -> a + b
'-' -> b - a
'*' -> a * b
@ -42,7 +44,7 @@ internal object Game24 {
else -> Float.NaN
}
fun tally(a: List<Int>): Long = a.reduce({ t, i -> t + (1 shl (i * 5)) }).toLong()
private fun tally(a: List<Int>): Long = a.reduce({ t, i -> t + (1 shl (i * 5)) }).toLong()
private val target = 24
}

View file

@ -0,0 +1,33 @@
alias 24 {
dialog -m 24-Game 24-Game
}
dialog 24-Game {
title "24-Game"
size -1 -1 100 70
option dbu
text "", 1, 29 7 42 8
text "Equation", 2, 20 21 21 8
edit "", 3, 45 20 40 10
text "Status", 4, 10 34 80 8, center
button "Calculate", 5, 5 45 40 20
button "New", 6, 57 47 35 15
}
on *:DIALOG:24-Game:init:*: {
did -o 24-Game 1 1 Numbers: $rand(1,9) $rand(1,9) $rand(1,9) $rand(1,9)
}
on *:DIALOG:24-Game:sclick:*: {
if ($did == 5) {
if ($regex($did(3),/^[ (]*\d *[-+*/][ (]*\d[ ()]*[-+*/][ ()]*\d[ )]*[-+*/] *\d[ )]*$/)) && ($sorttok($regsubex($did(3),/[^\d]+/g,$chr(32)),32) == $sorttok($remove($did(1),Numbers:),32)) {
did -o 24-Game 4 1 $iif($calc($did(3)) == 24,Correct,Wrong)
}
else {
did -o 24-Game 4 1 Wrong Numbers or Syntax
}
}
elseif ($did == 6) {
did -o 24-Game 1 1 Numbers: $rand(1,9) $rand(1,9) $rand(1,9) $rand(1,9)
}
}

View file

@ -0,0 +1,80 @@
24Game
k number, operator, bracket
; generate 4 random numbers each between 1 & 9
; duplicates allowed!
s n1=$r(9)+1, n2=$r(9)+1, n3=$r(9)+1, n4=$r(9)+1
; save a copy of them so that we can keep restarting
; if the user gets it wrong
s s1=n1,s2=n2,s3=n3,s4=n4
Question
s (numcount,opcount,lbrackcount,rbrackcount)=0
; restart with the random numbers already found
s n1=s1,n2=s2,n3=s3,n4=s4
w !,"Enter an arithmetic expression that evaluates to 24 using (",
n1," ",n2," ",n3," ",n4,"): "
r !,expr
q:expr=""
; validate numbers and operators
s error=""
f n=1:1:$l(expr) {
s char=$e(expr,n)
if char?1n {
s number($i(numcount))=char
w !
zw char
}
elseif char?1(1"*",1"/",1"+",1"-") {
s operator($i(opcount))=char
}
elseif char?1"(" {
s bracket($i(lbrackcount))=char
}
elseif char?1")" {
s bracket($i(rbrackcount))=char
}
else {
s error="That ain't no character I wanted to see"
q
}
}
if error'="" w error g Question
if numcount'=4 {
w "Does not have 4 numbers, do it again."
g Question
}
s error=""
f n=1:1:4 {
if number(n)=n1 {
s n1="dont use again" continue
}
if number(n)=n2 {
s n2="dont use again" continue
}
if number(n)=n3 {
s n3="dont use again" continue
}
if number(n)=n4 {
s n4="dont use again" continue
}
s error="Numbers entered do not match all of the randomly generated numbers."
q
}
if error'="" {
w error
g Question
}
if opcount'=3 {
w "Does not have 3 operators."
g Question
}
if lbrackcount'=rbrackcount {
w "brackets must be in pairs."
g Question
}
x "s x="_expr
if x'=24 {
w !,"Answer does not = 24"
g Question
}
w x
q

View file

@ -1,8 +1,11 @@
import math, strutils, algorithm, sequtils
from random import randomize, random
from strutils import Whitespace
from algorithm import sort
from sequtils import deduplicate
randomize()
template newSeqWith(len: int, init: expr): expr =
var result {.gensym.} = newSeq[type(init)](len)
template newSeqWith(len: int, init: untyped): untyped =
var result = newSeq[type(init)](len)
for i in 0 .. <len:
result[i] = init
result
@ -14,7 +17,7 @@ var
echo "Make 24 with the digits: ", problem
template op(c): stmt =
template op(c) =
let a = stack.pop
stack.add c(stack.pop, a)

Some files were not shown because too many files have changed in this diff Show more