diff --git a/Conf/.task.yaml.swp b/Conf/.task.yaml.swp new file mode 100644 index 0000000000..1c46e5b3ff Binary files /dev/null and b/Conf/.task.yaml.swp differ diff --git a/Conf/task.yaml b/Conf/task.yaml index c15f6be775..6f7b785603 100644 --- a/Conf/task.yaml +++ b/Conf/task.yaml @@ -1,3 +1,5 @@ +100 doors: +24 game: 99 Bottles of Beer: Ackermann function: Anagrams: diff --git a/Lang/4DOS-Batch/100-doors b/Lang/4DOS-Batch/100-doors new file mode 120000 index 0000000000..43f7d07b48 --- /dev/null +++ b/Lang/4DOS-Batch/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/4DOS-Batch \ No newline at end of file diff --git a/Lang/6502-Assembly/100-doors b/Lang/6502-Assembly/100-doors new file mode 120000 index 0000000000..c5c4533a89 --- /dev/null +++ b/Lang/6502-Assembly/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/6502-Assembly \ No newline at end of file diff --git a/Lang/ABAP/100-doors b/Lang/ABAP/100-doors new file mode 120000 index 0000000000..52a02d553f --- /dev/null +++ b/Lang/ABAP/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/ABAP \ No newline at end of file diff --git a/Lang/ACL2/100-doors b/Lang/ACL2/100-doors new file mode 120000 index 0000000000..fe3a7c2026 --- /dev/null +++ b/Lang/ACL2/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/ACL2 \ No newline at end of file diff --git a/Lang/ALGOL-68/100-doors b/Lang/ALGOL-68/100-doors new file mode 120000 index 0000000000..a57790f750 --- /dev/null +++ b/Lang/ALGOL-68/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/ALGOL-68 \ No newline at end of file diff --git a/Lang/APL/100-doors b/Lang/APL/100-doors new file mode 120000 index 0000000000..3824935bc0 --- /dev/null +++ b/Lang/APL/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/APL \ No newline at end of file diff --git a/Lang/AWK/100-doors b/Lang/AWK/100-doors new file mode 120000 index 0000000000..99c9a19f16 --- /dev/null +++ b/Lang/AWK/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/AWK \ No newline at end of file diff --git a/Lang/ActionScript/100-doors b/Lang/ActionScript/100-doors new file mode 120000 index 0000000000..d1ccbbe62e --- /dev/null +++ b/Lang/ActionScript/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/ActionScript \ No newline at end of file diff --git a/Lang/Ada/100-doors b/Lang/Ada/100-doors new file mode 120000 index 0000000000..fd3281cd91 --- /dev/null +++ b/Lang/Ada/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Ada \ No newline at end of file diff --git a/Lang/Ada/24-game b/Lang/Ada/24-game new file mode 120000 index 0000000000..3288e3df81 --- /dev/null +++ b/Lang/Ada/24-game @@ -0,0 +1 @@ +../../Task/24-game/Ada \ No newline at end of file diff --git a/Lang/Aikido/100-doors b/Lang/Aikido/100-doors new file mode 120000 index 0000000000..504fb1bb6d --- /dev/null +++ b/Lang/Aikido/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Aikido \ No newline at end of file diff --git a/Lang/AmigaE/100-doors b/Lang/AmigaE/100-doors new file mode 120000 index 0000000000..09b10c248a --- /dev/null +++ b/Lang/AmigaE/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/AmigaE \ No newline at end of file diff --git a/Lang/AppleScript/100-doors b/Lang/AppleScript/100-doors new file mode 120000 index 0000000000..43afb2e380 --- /dev/null +++ b/Lang/AppleScript/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/AppleScript \ No newline at end of file diff --git a/Lang/Arbre/100-doors b/Lang/Arbre/100-doors new file mode 120000 index 0000000000..1bac55af41 --- /dev/null +++ b/Lang/Arbre/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Arbre \ No newline at end of file diff --git a/Lang/Argile/100-doors b/Lang/Argile/100-doors new file mode 120000 index 0000000000..295eb6690a --- /dev/null +++ b/Lang/Argile/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Argile \ No newline at end of file diff --git a/Lang/Argile/24-game b/Lang/Argile/24-game new file mode 120000 index 0000000000..cae8c5a75c --- /dev/null +++ b/Lang/Argile/24-game @@ -0,0 +1 @@ +../../Task/24-game/Argile \ No newline at end of file diff --git a/Lang/AutoHotkey/100-doors b/Lang/AutoHotkey/100-doors new file mode 120000 index 0000000000..763a04376c --- /dev/null +++ b/Lang/AutoHotkey/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/AutoHotkey \ No newline at end of file diff --git a/Lang/AutoHotkey/24-game b/Lang/AutoHotkey/24-game new file mode 120000 index 0000000000..335ae197b5 --- /dev/null +++ b/Lang/AutoHotkey/24-game @@ -0,0 +1 @@ +../../Task/24-game/AutoHotkey \ No newline at end of file diff --git a/Lang/AutoIt/100-doors b/Lang/AutoIt/100-doors new file mode 120000 index 0000000000..dc33892277 --- /dev/null +++ b/Lang/AutoIt/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/AutoIt \ No newline at end of file diff --git a/Lang/AutoIt/24-game b/Lang/AutoIt/24-game new file mode 120000 index 0000000000..58672d0f10 --- /dev/null +++ b/Lang/AutoIt/24-game @@ -0,0 +1 @@ +../../Task/24-game/AutoIt \ No newline at end of file diff --git a/Lang/Axiom/100-doors b/Lang/Axiom/100-doors new file mode 120000 index 0000000000..e89302311b --- /dev/null +++ b/Lang/Axiom/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Axiom \ No newline at end of file diff --git a/Lang/BASIC/100-doors b/Lang/BASIC/100-doors new file mode 120000 index 0000000000..98c4a0b7b8 --- /dev/null +++ b/Lang/BASIC/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/BASIC \ No newline at end of file diff --git a/Lang/Befunge/100-doors b/Lang/Befunge/100-doors new file mode 120000 index 0000000000..7f4eabe501 --- /dev/null +++ b/Lang/Befunge/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Befunge \ No newline at end of file diff --git a/Lang/C/100-doors b/Lang/C/100-doors new file mode 120000 index 0000000000..aa4a06c4e5 --- /dev/null +++ b/Lang/C/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/C \ No newline at end of file diff --git a/Lang/C/24-game b/Lang/C/24-game new file mode 120000 index 0000000000..57f7300946 --- /dev/null +++ b/Lang/C/24-game @@ -0,0 +1 @@ +../../Task/24-game/C \ No newline at end of file diff --git a/Lang/Clojure/100-doors b/Lang/Clojure/100-doors new file mode 120000 index 0000000000..1d46b9c007 --- /dev/null +++ b/Lang/Clojure/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Clojure \ No newline at end of file diff --git a/Lang/Clojure/24-game b/Lang/Clojure/24-game new file mode 120000 index 0000000000..98e6944f92 --- /dev/null +++ b/Lang/Clojure/24-game @@ -0,0 +1 @@ +../../Task/24-game/Clojure \ No newline at end of file diff --git a/Lang/CoffeeScript/100-doors b/Lang/CoffeeScript/100-doors new file mode 120000 index 0000000000..70390b1ee3 --- /dev/null +++ b/Lang/CoffeeScript/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/CoffeeScript \ No newline at end of file diff --git a/Lang/CoffeeScript/24-game b/Lang/CoffeeScript/24-game new file mode 120000 index 0000000000..963439f728 --- /dev/null +++ b/Lang/CoffeeScript/24-game @@ -0,0 +1 @@ +../../Task/24-game/CoffeeScript \ No newline at end of file diff --git a/Lang/Dylan/100-doors b/Lang/Dylan/100-doors new file mode 120000 index 0000000000..ff98b94b30 --- /dev/null +++ b/Lang/Dylan/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Dylan \ No newline at end of file diff --git a/Lang/Eiffel/100-doors b/Lang/Eiffel/100-doors new file mode 120000 index 0000000000..09c3cb3779 --- /dev/null +++ b/Lang/Eiffel/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Eiffel \ No newline at end of file diff --git a/Lang/Erlang/100-doors b/Lang/Erlang/100-doors new file mode 120000 index 0000000000..3e2d079a44 --- /dev/null +++ b/Lang/Erlang/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Erlang \ No newline at end of file diff --git a/Lang/Erlang/24-game b/Lang/Erlang/24-game new file mode 120000 index 0000000000..0aff6a97eb --- /dev/null +++ b/Lang/Erlang/24-game @@ -0,0 +1 @@ +../../Task/24-game/Erlang \ No newline at end of file diff --git a/Lang/Forth/100-doors b/Lang/Forth/100-doors new file mode 120000 index 0000000000..a464f06648 --- /dev/null +++ b/Lang/Forth/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Forth \ No newline at end of file diff --git a/Lang/Fortran/100-doors b/Lang/Fortran/100-doors new file mode 120000 index 0000000000..8211efec90 --- /dev/null +++ b/Lang/Fortran/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Fortran \ No newline at end of file diff --git a/Lang/Fortran/24-game b/Lang/Fortran/24-game new file mode 120000 index 0000000000..888567e82d --- /dev/null +++ b/Lang/Fortran/24-game @@ -0,0 +1 @@ +../../Task/24-game/Fortran \ No newline at end of file diff --git a/Lang/Go/100-doors b/Lang/Go/100-doors new file mode 120000 index 0000000000..4f29e66c09 --- /dev/null +++ b/Lang/Go/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Go \ No newline at end of file diff --git a/Lang/Go/24-game b/Lang/Go/24-game new file mode 120000 index 0000000000..e0caef6ee0 --- /dev/null +++ b/Lang/Go/24-game @@ -0,0 +1 @@ +../../Task/24-game/Go \ No newline at end of file diff --git a/Lang/Haskell/100-doors b/Lang/Haskell/100-doors new file mode 120000 index 0000000000..530e4001d9 --- /dev/null +++ b/Lang/Haskell/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Haskell \ No newline at end of file diff --git a/Lang/Haskell/24-game b/Lang/Haskell/24-game new file mode 120000 index 0000000000..01f4a675c9 --- /dev/null +++ b/Lang/Haskell/24-game @@ -0,0 +1 @@ +../../Task/24-game/Haskell \ No newline at end of file diff --git a/Lang/Java/100-doors b/Lang/Java/100-doors new file mode 120000 index 0000000000..1365ca941c --- /dev/null +++ b/Lang/Java/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Java \ No newline at end of file diff --git a/Lang/JavaScript/100-doors b/Lang/JavaScript/100-doors new file mode 120000 index 0000000000..750d5abf18 --- /dev/null +++ b/Lang/JavaScript/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/24-game b/Lang/JavaScript/24-game new file mode 120000 index 0000000000..253b4773b9 --- /dev/null +++ b/Lang/JavaScript/24-game @@ -0,0 +1 @@ +../../Task/24-game/JavaScript \ No newline at end of file diff --git a/Lang/Lua/100-doors b/Lang/Lua/100-doors new file mode 120000 index 0000000000..ce373fa8af --- /dev/null +++ b/Lang/Lua/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Lua \ No newline at end of file diff --git a/Lang/Lua/24-game b/Lang/Lua/24-game new file mode 120000 index 0000000000..cd1dbd50e0 --- /dev/null +++ b/Lang/Lua/24-game @@ -0,0 +1 @@ +../../Task/24-game/Lua \ No newline at end of file diff --git a/Lang/PHP/100-doors b/Lang/PHP/100-doors new file mode 120000 index 0000000000..ef467c3e5d --- /dev/null +++ b/Lang/PHP/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/PHP \ No newline at end of file diff --git a/Lang/PHP/24-game b/Lang/PHP/24-game new file mode 120000 index 0000000000..3e61d468bd --- /dev/null +++ b/Lang/PHP/24-game @@ -0,0 +1 @@ +../../Task/24-game/PHP \ No newline at end of file diff --git a/Lang/Perl/100-doors b/Lang/Perl/100-doors new file mode 120000 index 0000000000..1d1df2e2c6 --- /dev/null +++ b/Lang/Perl/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Perl \ No newline at end of file diff --git a/Lang/Perl/24-game b/Lang/Perl/24-game new file mode 120000 index 0000000000..acc0990cfd --- /dev/null +++ b/Lang/Perl/24-game @@ -0,0 +1 @@ +../../Task/24-game/Perl \ No newline at end of file diff --git a/Lang/PicoLisp/100-doors b/Lang/PicoLisp/100-doors new file mode 120000 index 0000000000..95ec1dcd9c --- /dev/null +++ b/Lang/PicoLisp/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/PicoLisp \ No newline at end of file diff --git a/Lang/PicoLisp/24-game b/Lang/PicoLisp/24-game new file mode 120000 index 0000000000..ba1526e50e --- /dev/null +++ b/Lang/PicoLisp/24-game @@ -0,0 +1 @@ +../../Task/24-game/PicoLisp \ No newline at end of file diff --git a/Lang/Prolog/100-doors b/Lang/Prolog/100-doors new file mode 120000 index 0000000000..cad18a8d37 --- /dev/null +++ b/Lang/Prolog/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Prolog \ No newline at end of file diff --git a/Lang/Python/100-doors b/Lang/Python/100-doors new file mode 120000 index 0000000000..46194a281e --- /dev/null +++ b/Lang/Python/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Python \ No newline at end of file diff --git a/Lang/Python/24-game b/Lang/Python/24-game new file mode 120000 index 0000000000..fe33ad50ce --- /dev/null +++ b/Lang/Python/24-game @@ -0,0 +1 @@ +../../Task/24-game/Python \ No newline at end of file diff --git a/Lang/R/100-doors b/Lang/R/100-doors new file mode 120000 index 0000000000..08951e41b2 --- /dev/null +++ b/Lang/R/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/R \ No newline at end of file diff --git a/Lang/R/24-game b/Lang/R/24-game new file mode 120000 index 0000000000..6af8313b01 --- /dev/null +++ b/Lang/R/24-game @@ -0,0 +1 @@ +../../Task/24-game/R \ No newline at end of file diff --git a/Lang/REXX/100-doors b/Lang/REXX/100-doors new file mode 120000 index 0000000000..a7d769e4a1 --- /dev/null +++ b/Lang/REXX/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/REXX \ No newline at end of file diff --git a/Lang/REXX/24-game b/Lang/REXX/24-game new file mode 120000 index 0000000000..480a0c794c --- /dev/null +++ b/Lang/REXX/24-game @@ -0,0 +1 @@ +../../Task/24-game/REXX \ No newline at end of file diff --git a/Lang/Racket/100-doors b/Lang/Racket/100-doors new file mode 120000 index 0000000000..d761a0d6c7 --- /dev/null +++ b/Lang/Racket/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Racket \ No newline at end of file diff --git a/Lang/Racket/24-game b/Lang/Racket/24-game new file mode 120000 index 0000000000..12b48d6cfd --- /dev/null +++ b/Lang/Racket/24-game @@ -0,0 +1 @@ +../../Task/24-game/Racket \ No newline at end of file diff --git a/Lang/Ruby/100-doors b/Lang/Ruby/100-doors new file mode 120000 index 0000000000..ac5e864566 --- /dev/null +++ b/Lang/Ruby/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Ruby \ No newline at end of file diff --git a/Lang/Ruby/24-game b/Lang/Ruby/24-game new file mode 120000 index 0000000000..0955b88d12 --- /dev/null +++ b/Lang/Ruby/24-game @@ -0,0 +1 @@ +../../Task/24-game/Ruby \ No newline at end of file diff --git a/Lang/Sather/100-doors b/Lang/Sather/100-doors new file mode 120000 index 0000000000..ecb9d3a5ad --- /dev/null +++ b/Lang/Sather/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Sather \ No newline at end of file diff --git a/Lang/Scala/100-doors b/Lang/Scala/100-doors new file mode 120000 index 0000000000..314b5a8798 --- /dev/null +++ b/Lang/Scala/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Scala \ No newline at end of file diff --git a/Lang/Scala/24-game b/Lang/Scala/24-game new file mode 120000 index 0000000000..93d89b3e48 --- /dev/null +++ b/Lang/Scala/24-game @@ -0,0 +1 @@ +../../Task/24-game/Scala \ No newline at end of file diff --git a/Lang/Scheme/100-doors b/Lang/Scheme/100-doors new file mode 120000 index 0000000000..e83ca9b118 --- /dev/null +++ b/Lang/Scheme/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Scheme \ No newline at end of file diff --git a/Lang/Scheme/24-game b/Lang/Scheme/24-game new file mode 120000 index 0000000000..711f0719e6 --- /dev/null +++ b/Lang/Scheme/24-game @@ -0,0 +1 @@ +../../Task/24-game/Scheme \ No newline at end of file diff --git a/Lang/Smalltalk/100-doors b/Lang/Smalltalk/100-doors new file mode 120000 index 0000000000..485bd6b41a --- /dev/null +++ b/Lang/Smalltalk/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Smalltalk \ No newline at end of file diff --git a/Lang/Tcl/100-doors b/Lang/Tcl/100-doors new file mode 120000 index 0000000000..5a93bbc0de --- /dev/null +++ b/Lang/Tcl/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/Tcl \ No newline at end of file diff --git a/Lang/Tcl/24-game b/Lang/Tcl/24-game new file mode 120000 index 0000000000..16ffc61b21 --- /dev/null +++ b/Lang/Tcl/24-game @@ -0,0 +1 @@ +../../Task/24-game/Tcl \ No newline at end of file diff --git a/Meta/00Tasks.yaml b/Meta/00Tasks.yaml index 8770be8cab..3cc58f06fc 100644 --- a/Meta/00Tasks.yaml +++ b/Meta/00Tasks.yaml @@ -1,4 +1,12 @@ --- +100 doors: + name: 100 doors + path: 100-doors + url: 100_doors +24 game: + name: 24 game + path: 24-game + url: 24_game 99 Bottles of Beer: name: 99 Bottles of Beer path: 99-Bottles-of-Beer diff --git a/Task/100-doors/0DESCRIPTION b/Task/100-doors/0DESCRIPTION new file mode 100644 index 0000000000..8c619b3cb6 --- /dev/null +++ b/Task/100-doors/0DESCRIPTION @@ -0,0 +1,5 @@ +Problem: You have 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, you visit every door and toggle the door (if the door is closed, you open it; if it is open, you close it). The second time you only visit every 2nd door (door #2, #4, #6, ...). The third time, every 3rd door (door #3, #6, #9, ...), etc, until you only visit the 100th door. + +Question: What state are the doors in after the last pass? Which are open, which are closed? [http://www.techinterview.org/Puzzles/fog0000000079.html] + +'''[[task feature::Rosetta Code:extra credit|Alternate]]:''' As noted in this page's [[Talk:100 doors|discussion page]], the only doors that remain open are whose numbers are perfect squares of integers. Opening only those doors is an [[task feature::Rosetta Code:optimization|optimization]] that may also be expressed. diff --git a/Task/100-doors/4DOS-Batch/100-doors-1.4dos b/Task/100-doors/4DOS-Batch/100-doors-1.4dos new file mode 100644 index 0000000000..d27b273652 --- /dev/null +++ b/Task/100-doors/4DOS-Batch/100-doors-1.4dos @@ -0,0 +1,7 @@ +@echo off +set doors=%@repeat[C,100] +do step = 1 to 100 + do door = %step to 100 by %step + set doors=%@left[%@eval[%door-1],%doors]%@if[%@instr[%@eval[%door-1],1,%doors]==C,O,C]%@right[%@eval[100-%door],%doors] + enddo +enddo diff --git a/Task/100-doors/4DOS-Batch/100-doors-2.4dos b/Task/100-doors/4DOS-Batch/100-doors-2.4dos new file mode 100644 index 0000000000..380e7997e8 --- /dev/null +++ b/Task/100-doors/4DOS-Batch/100-doors-2.4dos @@ -0,0 +1,3 @@ +%@left[n,string] ^: Return n leftmost chars in string +%@right[n,string] ^: Return n rightmost chars in string +%@if[condition,true-val,false-val] ^: Evaluate condition; return true-val if true, false-val if false diff --git a/Task/100-doors/6502-Assembly/100-doors.6502 b/Task/100-doors/6502-Assembly/100-doors.6502 new file mode 100644 index 0000000000..0a02bc7b81 --- /dev/null +++ b/Task/100-doors/6502-Assembly/100-doors.6502 @@ -0,0 +1,10 @@ + ;assume all memory is initially set to 0 + inc $1 ;start out with a delta of 1 +openloop: inc $200,X ;open a door at X + inc $1 ;add 2 to delta + inc $1 + txa ;add delta to X + adc $1 + tax + cpx #$65 ;check to see if we're at the 100th door + bmi openloop ;jump back to openloop if less than 100 diff --git a/Task/100-doors/ABAP/100-doors-1.abap b/Task/100-doors/ABAP/100-doors-1.abap new file mode 100644 index 0000000000..b107651407 --- /dev/null +++ b/Task/100-doors/ABAP/100-doors-1.abap @@ -0,0 +1,30 @@ +form open_doors_unopt. + data: lv_door type i, + lv_count type i value 1. + data: lt_doors type standard table of c initial size 100. + field-symbols: type c. + do 100 times. + append initial line to lt_doors assigning . + = 'X'. + enddo. + + while lv_count < 100. + lv_count = lv_count + 1. + lv_door = lv_count. + while lv_door < 100. + read table lt_doors index lv_door assigning . + if = ' '. + = 'X'. + else. + = ' '. + endif. + add lv_count to lv_door. + endwhile. + endwhile. + + loop at lt_doors assigning . + if = 'X'. + write : / 'Door', (4) sy-tabix right-justified, 'is open' no-gap. + endif. + endloop. +endform. diff --git a/Task/100-doors/ABAP/100-doors-2.abap b/Task/100-doors/ABAP/100-doors-2.abap new file mode 100644 index 0000000000..9a68228308 --- /dev/null +++ b/Task/100-doors/ABAP/100-doors-2.abap @@ -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: type c. + do 100 times. + append initial line to lt_doors assigning . + if sy-index = lv_square. + = '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. diff --git a/Task/100-doors/ACL2/100-doors.acl2 b/Task/100-doors/ACL2/100-doors.acl2 new file mode 100644 index 0000000000..ce32fd5e39 --- /dev/null +++ b/Task/100-doors/ACL2/100-doors.acl2 @@ -0,0 +1,21 @@ +(defun rep (n x) + (if (zp n) + nil + (cons x + (rep (- n 1) x)))) + +(defun toggle-every-r (n i bs) + (if (endp bs) + nil + (cons (if (zp i) + (not (first bs)) + (first bs)) + (toggle-every-r n (mod (1- i) n) (rest bs))))) + +(defun toggle-every (n bs) + (toggle-every-r n (1- n) bs)) + +(defun 100-doors (i doors) + (if (zp i) + doors + (100-doors (1- i) (toggle-every i doors)))) diff --git a/Task/100-doors/ALGOL-68/100-doors-1.alg b/Task/100-doors/ALGOL-68/100-doors-1.alg new file mode 100644 index 0000000000..6c5343b067 --- /dev/null +++ b/Task/100-doors/ALGOL-68/100-doors-1.alg @@ -0,0 +1,25 @@ +# declare some constants # +INT limit = 100; + +PROC doors = VOID: +( + MODE DOORSTATE = BOOL; + BOOL closed = FALSE; + BOOL open = NOT closed; + MODE DOORLIST = [limit]DOORSTATE; + + DOORLIST the doors; + FOR i FROM LWB the doors TO UPB the doors DO the doors[i]:=closed OD; + + FOR i FROM LWB the doors TO UPB the doors DO + FOR j FROM LWB the doors TO UPB the doors DO + IF j MOD i = 0 THEN + the doors[j] := NOT the doors[j] + FI + OD + OD; + FOR i FROM LWB the doors TO UPB the doors DO + printf(($g" is "gl$,i,(the doors[i]|"opened"|"closed"))) + OD +); +doors; diff --git a/Task/100-doors/ALGOL-68/100-doors-2.alg b/Task/100-doors/ALGOL-68/100-doors-2.alg new file mode 100644 index 0000000000..70f031cd84 --- /dev/null +++ b/Task/100-doors/ALGOL-68/100-doors-2.alg @@ -0,0 +1,7 @@ +PROC doors optimised = ( INT limit )VOID: + FOR i TO limit DO + REAL num := sqrt(i); + printf(($g" is "gl$,i,(ENTIER num = num |"opened"|"closed") )) + OD +; +doors optimised(limit) diff --git a/Task/100-doors/APL/100-doors-1.apl b/Task/100-doors/APL/100-doors-1.apl new file mode 100644 index 0000000000..355458c8f8 --- /dev/null +++ b/Task/100-doors/APL/100-doors-1.apl @@ -0,0 +1,11 @@ +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 diff --git a/Task/100-doors/APL/100-doors-2.apl b/Task/100-doors/APL/100-doors-2.apl new file mode 100644 index 0000000000..d131e625c1 --- /dev/null +++ b/Task/100-doors/APL/100-doors-2.apl @@ -0,0 +1,7 @@ +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 diff --git a/Task/100-doors/AWK/100-doors-1.awk b/Task/100-doors/AWK/100-doors-1.awk new file mode 100644 index 0000000000..1c2a279c09 --- /dev/null +++ b/Task/100-doors/AWK/100-doors-1.awk @@ -0,0 +1,17 @@ +BEGIN { + for(i=1; i <= 100; i++) + { + doors[i] = 0 # close the doors + } + for(i=1; i <= 100; i++) + { + for(j=i; j <= 100; j += i) + { + doors[j] = (doors[j]+1) % 2 + } + } + for(i=1; i <= 100; i++) + { + print i, doors[i] ? "open" : "close" + } +} diff --git a/Task/100-doors/AWK/100-doors-2.awk b/Task/100-doors/AWK/100-doors-2.awk new file mode 100644 index 0000000000..9344bbec27 --- /dev/null +++ b/Task/100-doors/AWK/100-doors-2.awk @@ -0,0 +1,14 @@ +BEGIN { + for(i=1; i <= 100; i++) { + doors[i] = 0 # close the doors + } + for(i=1; i <= 100; i++) { + if ( int(sqrt(i)) == sqrt(i) ) { + doors[i] = 1 + } + } + for(i=1; i <= 100; i++) + { + print i, doors[i] ? "open" : "close" + } +} diff --git a/Task/100-doors/ActionScript/100-doors.as b/Task/100-doors/ActionScript/100-doors.as new file mode 100644 index 0000000000..0cdd255b01 --- /dev/null +++ b/Task/100-doors/ActionScript/100-doors.as @@ -0,0 +1,21 @@ +package { + import flash.display.Sprite; + + public class Doors extends Sprite { + public function Doors() { + + // Initialize the array + var doors:Array = new Array(100); + for (var i:Number = 0; i < 100; i++) { + doors[i] = false; + + // Do the work + for (var pass:Number = 0; pass < 100; pass++) { + for (var j:Number = pass; j < 100; j += (pass+1)) { + doors[j] = !doors[j]; + } + } + trace(doors); + } + } +} diff --git a/Task/100-doors/Ada/100-doors-1.ada b/Task/100-doors/Ada/100-doors-1.ada new file mode 100644 index 0000000000..fd746501f2 --- /dev/null +++ b/Task/100-doors/Ada/100-doors-1.ada @@ -0,0 +1,22 @@ +with Ada.Text_Io; use Ada.Text_Io; + + procedure Doors is + type Door_State is (Closed, Open); + type Door_List is array(Positive range 1..100) of Door_State; + The_Doors : Door_List := (others => Closed); + begin + for I in 1..100 loop + for J in The_Doors'range loop + if J mod I = 0 then + if The_Doors(J) = Closed then + The_Doors(J) := Open; + else + The_Doors(J) := Closed; + end if; + end if; + end loop; + end loop; + for I in The_Doors'range loop + Put_Line(Integer'Image(I) & " is " & Door_State'Image(The_Doors(I))); + end loop; + end Doors; diff --git a/Task/100-doors/Ada/100-doors-2.ada b/Task/100-doors/Ada/100-doors-2.ada new file mode 100644 index 0000000000..0af233cef5 --- /dev/null +++ b/Task/100-doors/Ada/100-doors-2.ada @@ -0,0 +1,16 @@ +with Ada.Text_Io; use Ada.Text_Io; + with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions; + + procedure Doors_Optimized is + Num : Float; + begin + for I in 1..100 loop + Num := Sqrt(Float(I)); + Put(Integer'Image(I) & " is "); + if Float'Floor(Num) = Num then + Put_Line("Opened"); + else + Put_Line("Closed"); + end if; + end loop; + end Doors_Optimized; diff --git a/Task/100-doors/Aikido/100-doors.aikido b/Task/100-doors/Aikido/100-doors.aikido new file mode 100644 index 0000000000..576c4a9216 --- /dev/null +++ b/Task/100-doors/Aikido/100-doors.aikido @@ -0,0 +1,13 @@ +var doors = new int [100] + +foreach pass 100 { + for (var door = pass ; door < 100 ; door += pass+1) { + doors[door] = !doors[door] + } +} + +var d = 1 +foreach door doors { + println ("door " + d++ + " is " + (door ? "open" : "closed")) + +} diff --git a/Task/100-doors/AmigaE/100-doors.amiga b/Task/100-doors/AmigaE/100-doors.amiga new file mode 100644 index 0000000000..3b3fd9dfa4 --- /dev/null +++ b/Task/100-doors/AmigaE/100-doors.amiga @@ -0,0 +1,14 @@ +PROC main() + DEF t[100]: ARRAY, + pass, door + FOR door := 0 TO 99 DO t[door] := FALSE + FOR pass := 0 TO 99 + door := pass + WHILE door <= 99 + t[door] := Not(t[door]) + door := door + pass + 1 + ENDWHILE + ENDFOR + FOR door := 0 TO 99 DO WriteF('\d is \s\n', door+1, + IF t[door] THEN 'open' ELSE 'closed') +ENDPROC diff --git a/Task/100-doors/AppleScript/100-doors.applescript b/Task/100-doors/AppleScript/100-doors.applescript new file mode 100644 index 0000000000..9e6bba322c --- /dev/null +++ b/Task/100-doors/AppleScript/100-doors.applescript @@ -0,0 +1,17 @@ +set is_open to {} +repeat 100 times + set end of is_open to false +end +repeat with pass from 1 to 100 + repeat with door from pass to 100 by pass + set item door of is_open to not item door of is_open + end +end +set open_doors to {} +repeat with door from 1 to 100 + if item door of is_open then + set end of open_doors to door + end +end +set text item delimiters to ", " +display dialog "Open doors: " & open_doors diff --git a/Task/100-doors/Arbre/100-doors.arbre b/Task/100-doors/Arbre/100-doors.arbre new file mode 100644 index 0000000000..12ab2fec3e --- /dev/null +++ b/Task/100-doors/Arbre/100-doors.arbre @@ -0,0 +1,12 @@ +openshut(n): + for x in [1..n] + x%n==0 + +pass(n): + if n==100 + openshut(n) + else + openshut(n) xor pass(n+1) + +100doors(): + pass(1) -> io diff --git a/Task/100-doors/Argile/100-doors.argile b/Task/100-doors/Argile/100-doors.argile new file mode 100644 index 0000000000..0d331d4f69 --- /dev/null +++ b/Task/100-doors/Argile/100-doors.argile @@ -0,0 +1,16 @@ +use std, array + +close all doors +for each pass from 1 to 100 + for (door = pass) (door <= 100) (door += pass) + toggle door + +let int pass, door. + +.: close all doors :. {memset doors 0 size of doors} +.:toggle :. { !!(doors[door - 1]) } + +let doors be an array of 100 bool + +for each door from 1 to 100 + printf "#%.3d %s\n" door (doors[door - 1]) ? "[ ]", "[X]" diff --git a/Task/100-doors/AutoHotkey/100-doors-1.ahk b/Task/100-doors/AutoHotkey/100-doors-1.ahk new file mode 100644 index 0000000000..937fb13b68 --- /dev/null +++ b/Task/100-doors/AutoHotkey/100-doors-1.ahk @@ -0,0 +1,27 @@ +Loop, 100 + Door%A_Index% := "closed" + +Loop, 100 { + x := A_Index, y := A_Index + While (x <= 100) + { + CurrentDoor := Door%x% + If CurrentDoor contains closed + { + Door%x% := "open" + x += y + } + else if CurrentDoor contains open + { + Door%x% := "closed" + x += y + } + } +} + +Loop, 100 { + CurrentDoor := Door%A_Index% + If CurrentDoor contains open + Res .= "Door " A_Index " is open`n" +} +MsgBox % Res diff --git a/Task/100-doors/AutoHotkey/100-doors-2.ahk b/Task/100-doors/AutoHotkey/100-doors-2.ahk new file mode 100644 index 0000000000..8860f1e943 --- /dev/null +++ b/Task/100-doors/AutoHotkey/100-doors-2.ahk @@ -0,0 +1,6 @@ +increment := 3, square := 1 +Loop, 100 + If (A_Index = square) + outstring .= "`nDoor " A_Index " is open" + ,square += increment, increment += 2 +MsgBox,, Succesfull, % SubStr(outstring, 2) diff --git a/Task/100-doors/AutoHotkey/100-doors-3.ahk b/Task/100-doors/AutoHotkey/100-doors-3.ahk new file mode 100644 index 0000000000..e0040f8619 --- /dev/null +++ b/Task/100-doors/AutoHotkey/100-doors-3.ahk @@ -0,0 +1,3 @@ +While (Door := A_Index ** 2) <= 100 + Result .= "Door " Door " is open`n" +MsgBox, %Result% diff --git a/Task/100-doors/AutoIt/100-doors.autoit b/Task/100-doors/AutoIt/100-doors.autoit new file mode 100644 index 0000000000..d8988366c6 --- /dev/null +++ b/Task/100-doors/AutoIt/100-doors.autoit @@ -0,0 +1,17 @@ +#include +$doors = 100 + +;door array, 0 = closed, 1 = open +Local $door[$doors +1] + +For $ii = 1 To $doors + For $i = $ii To $doors Step $ii + $door[$i] = Not $door[$i] + next +Next + +;display to screen +For $i = 1 To $doors + ConsoleWrite (Number($door[$i])& " ") + If Mod($i,10) = 0 Then ConsoleWrite(@CRLF) +Next diff --git a/Task/100-doors/Axiom/100-doors-1.axiom b/Task/100-doors/Axiom/100-doors-1.axiom new file mode 100644 index 0000000000..4584f36188 --- /dev/null +++ b/Task/100-doors/Axiom/100-doors-1.axiom @@ -0,0 +1,6 @@ +(open,closed,change,open?) := (true,false,not,test); +doors := bits(100,closed); +for i in 1..#doors repeat + for j in i..#doors by i repeat + doors.j := change doors.j +[i for i in 1..#doors | open? doors.i] diff --git a/Task/100-doors/Axiom/100-doors-2.axiom b/Task/100-doors/Axiom/100-doors-2.axiom new file mode 100644 index 0000000000..1efe20a441 --- /dev/null +++ b/Task/100-doors/Axiom/100-doors-2.axiom @@ -0,0 +1,2 @@ +[i for i in 1..100 | perfectSquare? i] -- or +[i^2 for i in 1..sqrt(100)::Integer] diff --git a/Task/100-doors/BASIC/100-doors-1.bas b/Task/100-doors/BASIC/100-doors-1.bas new file mode 100644 index 0000000000..f2179f24e0 --- /dev/null +++ b/Task/100-doors/BASIC/100-doors-1.bas @@ -0,0 +1,16 @@ +DIM doors(0 TO 99) +FOR pass = 0 TO 99 + FOR door = pass TO 99 STEP pass + 1 + PRINT doors(door) + PRINT NOT doors(door) + doors(door) = NOT doors(door) + NEXT door +NEXT pass +FOR i = 0 TO 99 + PRINT "Door #"; i + 1; " is "; + IF NOT doors(i) THEN + PRINT "closed" + ELSE + PRINT "open" + END IF +NEXT i diff --git a/Task/100-doors/BASIC/100-doors-2.bas b/Task/100-doors/BASIC/100-doors-2.bas new file mode 100644 index 0000000000..ddaffaa2c1 --- /dev/null +++ b/Task/100-doors/BASIC/100-doors-2.bas @@ -0,0 +1,12 @@ +DIM doors(0 TO 99) +FOR door = 0 TO 99 + IF INT(SQR(door)) = SQR(door) THEN doors(door) = -1 +NEXT door +FOR i = 0 TO 99 + PRINT "Door #"; i + 1; " is "; + IF NOT doors(i) THEN + PRINT "closed" + ELSE + PRINT "open" + END IF +NEXT i diff --git a/Task/100-doors/BASIC/100-doors-3.bas b/Task/100-doors/BASIC/100-doors-3.bas new file mode 100644 index 0000000000..14a02c2b80 --- /dev/null +++ b/Task/100-doors/BASIC/100-doors-3.bas @@ -0,0 +1,10 @@ +'lrcvs 04.11.12 +cls +x = 1 : y = 3 : z = 0 +print x + " Open" +do +z = x + y +print z + " Open" +x = z : y = y + 2 +until z >= 100 +end diff --git a/Task/100-doors/Befunge/100-doors.bf b/Task/100-doors/Befunge/100-doors.bf new file mode 100644 index 0000000000..9c1d170708 --- /dev/null +++ b/Task/100-doors/Befunge/100-doors.bf @@ -0,0 +1,4 @@ +108p0>:18p;;>:9g!18g9p08g] +*`!0\|+relet|-1`*aap81::+] +;::+1$08g1+:08paa[ +*`#@_^._aa diff --git a/Task/100-doors/C/100-doors-1.c b/Task/100-doors/C/100-doors-1.c new file mode 100644 index 0000000000..fcee57d070 --- /dev/null +++ b/Task/100-doors/C/100-doors-1.c @@ -0,0 +1,18 @@ +#include + +int main() +{ + char is_open[100] = { 0 }; + int pass, door; + + // do the 100 passes + for (pass = 0; pass < 100; ++pass) + for (door = pass; door < 100; door += pass+1) + is_open[door] = !is_open[door]; + + // output the result + for (door = 0; door < 100; ++door) + printf("door #%d is %s.\n", door+1, (is_open[door]? "open" : "closed")); + + return 0; +} diff --git a/Task/100-doors/C/100-doors-2.c b/Task/100-doors/C/100-doors-2.c new file mode 100644 index 0000000000..fb7f7feb29 --- /dev/null +++ b/Task/100-doors/C/100-doors-2.c @@ -0,0 +1,19 @@ +#include + +int main() +{ + int square = 1, increment = 3, door; + for (door = 1; door <= 100; ++door) + { + printf("door #%d", door); + if (door == square) + { + printf(" is open.\n"); + square += increment; + increment += 2; + } + else + printf(" is closed.\n"); + } + return 0; +} diff --git a/Task/100-doors/C/100-doors-3.c b/Task/100-doors/C/100-doors-3.c new file mode 100644 index 0000000000..a1972a382b --- /dev/null +++ b/Task/100-doors/C/100-doors-3.c @@ -0,0 +1,9 @@ +#include + +int main() +{ + int door, square, increment; + for (door = 1, square = 1, increment = 1; door <= 100; door++ == square && (square += increment += 2)) + printf("door #%d is %s.\n", door, (door == square? "open" : "closed")); + return 0; +} diff --git a/Task/100-doors/C/100-doors-4.c b/Task/100-doors/C/100-doors-4.c new file mode 100644 index 0000000000..4988099e36 --- /dev/null +++ b/Task/100-doors/C/100-doors-4.c @@ -0,0 +1,10 @@ +#include + +int main() +{ + int i; + for (i = 1; i * i <= 100; i++) + printf("door %d open\n", i * i); + + return 0; +} diff --git a/Task/100-doors/Clojure/100-doors-1.clj b/Task/100-doors/Clojure/100-doors-1.clj new file mode 100644 index 0000000000..c8c01944a7 --- /dev/null +++ b/Task/100-doors/Clojure/100-doors-1.clj @@ -0,0 +1,13 @@ +(defn doors [] + (let [doors (into-array (repeat 100 false))] + (doseq [pass (range 1 101) + i (range (dec pass) 100 pass) ] + (aset doors i (not (aget doors i)))) + doors)) + +(defn open-doors [] (for [[d n] (map vector (doors) (iterate inc 1)) :when d] n)) + +(defn print-open-doors [] + (println + "Open doors after 100 passes:" + (apply str (interpose ", " (open-doors))))) diff --git a/Task/100-doors/Clojure/100-doors-2.clj b/Task/100-doors/Clojure/100-doors-2.clj new file mode 100644 index 0000000000..199f8bd2f4 --- /dev/null +++ b/Task/100-doors/Clojure/100-doors-2.clj @@ -0,0 +1,13 @@ +(defn doors [] + (reduce (fn [doors toggle-idx] (update-in doors [toggle-idx] not)) + (into [] (repeat 100 false)) + (for [pass (range 1 101) + i (range (dec pass) 100 pass) ] + i))) + +(defn open-doors [] (for [[d n] (map vector (doors) (iterate inc 1)) :when d] n)) + +(defn print-open-doors [] + (println + "Open doors after 100 passes:" + (apply str (interpose ", " (open-doors))))) diff --git a/Task/100-doors/Clojure/100-doors-3.clj b/Task/100-doors/Clojure/100-doors-3.clj new file mode 100644 index 0000000000..0ef6ba4ae7 --- /dev/null +++ b/Task/100-doors/Clojure/100-doors-3.clj @@ -0,0 +1,11 @@ +(defn doors [] + (reduce (fn [doors idx] (assoc doors idx true)) + (into [] (repeat 100 false)) + (map #(dec (* % %)) (range 1 11)))) + +(defn open-doors [] (for [[d n] (map vector (doors) (iterate inc 1)) :when d] n)) + +(defn print-open-doors [] + (println + "Open doors after 100 passes:" + (apply str (interpose ", " (open-doors))))) diff --git a/Task/100-doors/CoffeeScript/100-doors-1.coffee b/Task/100-doors/CoffeeScript/100-doors-1.coffee new file mode 100644 index 0000000000..28e4ed5dc4 --- /dev/null +++ b/Task/100-doors/CoffeeScript/100-doors-1.coffee @@ -0,0 +1,10 @@ +doors = [] + +for pass in [1..100] + for i in [pass..100] by pass + doors[i] = !doors[i] + +console.log "Doors #{index for index, open of doors when open} are open" + +# matrix output +console.log doors.map (open) -> +open diff --git a/Task/100-doors/CoffeeScript/100-doors-2.coffee b/Task/100-doors/CoffeeScript/100-doors-2.coffee new file mode 100644 index 0000000000..789398a34c --- /dev/null +++ b/Task/100-doors/CoffeeScript/100-doors-2.coffee @@ -0,0 +1,3 @@ +isInteger = (i) -> Math.floor(i) == i + +console.log door for door in [1..100] when isInteger Math.sqrt door diff --git a/Task/100-doors/CoffeeScript/100-doors-3.coffee b/Task/100-doors/CoffeeScript/100-doors-3.coffee new file mode 100644 index 0000000000..2ed4ecb6a4 --- /dev/null +++ b/Task/100-doors/CoffeeScript/100-doors-3.coffee @@ -0,0 +1 @@ +console.log Math.pow(i,2) for i in [1..10] diff --git a/Task/100-doors/Dylan/100-doors.dylan b/Task/100-doors/Dylan/100-doors.dylan new file mode 100644 index 0000000000..5de4af0d8e --- /dev/null +++ b/Task/100-doors/Dylan/100-doors.dylan @@ -0,0 +1,13 @@ +define method doors() + let doors = make(, fill: #f, size: 100); + for (x from 0 below 100) + for (y from x below 100 by x + 1) + doors[y] := ~doors[y] + end + end; + for (x from 1 to 100) + if (doors[x - 1]) + format-out("door %d open\n", x) + end + end +end diff --git a/Task/100-doors/Eiffel/100-doors-1.e b/Task/100-doors/Eiffel/100-doors-1.e new file mode 100644 index 0000000000..d3e090614a --- /dev/null +++ b/Task/100-doors/Eiffel/100-doors-1.e @@ -0,0 +1,64 @@ +note + description: "100 Doors problem" + date: "07-AUG-2011" + revision: "1.0" + +class + APPLICATION + +create + make + +feature {NONE} -- Initialization + + doors: LINKED_LIST [DOOR] + -- A set of doors + once + create Result.make + end + + make + -- Run application. + local + count, i: INTEGER + do + --initialize doors + count := 100 + from + i := 1 + until + i > count + loop + doors.extend (create {DOOR}.make (i, false)) + i := i + 1 + end + + -- toggle doors + from + i := 1 + until + i > count + loop + across + doors as this + loop + if this.item.address \\ i = 0 then + this.item.open := not this.item.open + end + end -- across doors + i := i + 1 + end -- for i + + -- print results + doors.do_all (agent (door: DOOR) + do + if door.open then + io.put_string ("Door " + door.address.out + " is open.") + elseif not door.open then + io.put_string ("Door " + door.address.out + " is closed.") + end + io.put_new_line + end) + end -- make + +end -- APPLICATION diff --git a/Task/100-doors/Eiffel/100-doors-2.e b/Task/100-doors/Eiffel/100-doors-2.e new file mode 100644 index 0000000000..b009c03553 --- /dev/null +++ b/Task/100-doors/Eiffel/100-doors-2.e @@ -0,0 +1,44 @@ +note + description: "A door with an address and an open or closed state." + date: "07-AUG-2011" + revision: "1.0" + +class + DOOR + +create + make + +feature -- initialization + + make (addr: INTEGER; status: BOOLEAN) + -- create door with address and status + require + valid_address: addr /= '%U' + valid_status: status /= '%U' + do + address := addr + open := status + ensure + address_set: address = addr + status_set: open = status + end + +feature -- access + + address: INTEGER + + open: BOOLEAN assign set_open + +feature -- mutators + + set_open (status: BOOLEAN) + require + valid_status: status /= '%U' + do + open := status + ensure + open_updated: open = status + end + +end diff --git a/Task/100-doors/Erlang/100-doors.erl b/Task/100-doors/Erlang/100-doors.erl new file mode 100644 index 0000000000..3815a08743 --- /dev/null +++ b/Task/100-doors/Erlang/100-doors.erl @@ -0,0 +1,5 @@ +doors() -> + F = fun(X) -> Root = math:pow(X,0.5), Root == trunc(Root) end, + Out = fun(X, true) -> io:format("Door ~p: open~n",[X]); + (X, false)-> io:format("Door ~p: close~n",[X]) end, + [Out(X,F(X)) || X <- lists:seq(1,100)]. diff --git a/Task/100-doors/Forth/100-doors-1.fth b/Task/100-doors/Forth/100-doors-1.fth new file mode 100644 index 0000000000..d5fe636dc1 --- /dev/null +++ b/Task/100-doors/Forth/100-doors-1.fth @@ -0,0 +1,18 @@ +: toggle ( c-addr -- ) \ toggle the byte at c-addr + dup c@ 1 xor swap c! ; + +100 1+ ( 1-based indexing ) constant ndoors +create doors ndoors allot + +: init ( -- ) doors ndoors erase ; \ close all doors + +: pass ( n -- ) \ toggle every nth door + ndoors over do + doors i + toggle + dup ( n ) +loop drop ; + +: run ( -- ) ndoors 1 do i pass loop ; +: display ( -- ) \ display open doors + ndoors 1 do doors i + c@ if i . then loop cr ; + +init run display diff --git a/Task/100-doors/Forth/100-doors-2.fth b/Task/100-doors/Forth/100-doors-2.fth new file mode 100644 index 0000000000..891a4c32af --- /dev/null +++ b/Task/100-doors/Forth/100-doors-2.fth @@ -0,0 +1,6 @@ +: squared ( n -- n' ) dup * ; +: doors ( n -- ) + 1 begin 2dup squared >= while + dup squared . + 1+ repeat 2drop ; +100 doors diff --git a/Task/100-doors/Fortran/100-doors-1.f b/Task/100-doors/Fortran/100-doors-1.f new file mode 100644 index 0000000000..e0d194e1ff --- /dev/null +++ b/Task/100-doors/Fortran/100-doors-1.f @@ -0,0 +1,22 @@ +PROGRAM DOORS + + INTEGER, PARAMETER :: n = 100 ! Number of doors + INTEGER :: i, j + LOGICAL :: door(n) = .TRUE. ! Initially closed + + DO i = 1, n + DO j = i, n, i + door(j) = .NOT. door(j) + END DO + END DO + + DO i = 1, n + WRITE(*,"(A,I3,A)", ADVANCE="NO") "Door ", i, " is " + IF (door(i)) THEN + WRITE(*,"(A)") "closed" + ELSE + WRITE(*,"(A)") "open" + END IF + END DO + +END PROGRAM DOORS diff --git a/Task/100-doors/Fortran/100-doors-2.f b/Task/100-doors/Fortran/100-doors-2.f new file mode 100644 index 0000000000..965ff2929e --- /dev/null +++ b/Task/100-doors/Fortran/100-doors-2.f @@ -0,0 +1,20 @@ +PROGRAM DOORS + + INTEGER, PARAMETER :: n = 100 ! Number of doors + INTEGER :: i + LOGICAL :: door(n) = .TRUE. ! Initially closed + + DO i = 1, SQRT(REAL(n)) + door(i*i) = .FALSE. + END DO + + DO i = 1, n + WRITE(*,"(A,I3,A)", ADVANCE="NO") "Door ", i, " is " + IF (door(i)) THEN + WRITE(*,"(A)") "closed" + ELSE + WRITE(*,"(A)") "open" + END IF + END DO + +END PROGRAM DOORS diff --git a/Task/100-doors/Go/100-doors-1.go b/Task/100-doors/Go/100-doors-1.go new file mode 100644 index 0000000000..38b55b0949 --- /dev/null +++ b/Task/100-doors/Go/100-doors-1.go @@ -0,0 +1,30 @@ +package main + +import "fmt" + +func main() { + doors := make([]bool, 100) + + // the 100 passes called for in the task description + for pass := 1; pass <= 100; pass++ { + for door := pass-1; door < 100; door += pass { + doors[door] = !doors[door] + } + } + + // one more pass to answer the question + for i, v := range doors { + if v { + fmt.Print("1") + } else { + fmt.Print("0") + } + + if i%10 == 9 { + fmt.Print("\n") + } else { + fmt.Print(" ") + } + + } +} diff --git a/Task/100-doors/Go/100-doors-2.go b/Task/100-doors/Go/100-doors-2.go new file mode 100644 index 0000000000..0b0503ce54 --- /dev/null +++ b/Task/100-doors/Go/100-doors-2.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + +func main() { + var door int = 1 + var incrementer = 0 + + for current := 1; current <= 100; current++ { + fmt.Printf("Door %d ", current) + + if current == door { + fmt.Printf("Open\n") + incrementer++ + door += 2*incrementer + 1 + } else { + fmt.Printf("Closed\n") + } + } +} diff --git a/Task/100-doors/Haskell/100-doors-1.hs b/Task/100-doors/Haskell/100-doors-1.hs new file mode 100644 index 0000000000..f76307dd9c --- /dev/null +++ b/Task/100-doors/Haskell/100-doors-1.hs @@ -0,0 +1,10 @@ +data Door = Open | Closed deriving Show + +toggle Open = Closed +toggle Closed = Open + +toggleEvery :: [Door] -> Int -> [Door] +toggleEvery xs k = zipWith ($) fs xs + where fs = cycle $ (replicate (k-1) id) ++ [toggle] + +run n = foldl toggleEvery (replicate n Closed) [0..n] diff --git a/Task/100-doors/Haskell/100-doors-2.hs b/Task/100-doors/Haskell/100-doors-2.hs new file mode 100644 index 0000000000..2cea247dfd --- /dev/null +++ b/Task/100-doors/Haskell/100-doors-2.hs @@ -0,0 +1,6 @@ +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..]] diff --git a/Task/100-doors/Haskell/100-doors-3.hs b/Task/100-doors/Haskell/100-doors-3.hs new file mode 100644 index 0000000000..44f44aa391 --- /dev/null +++ b/Task/100-doors/Haskell/100-doors-3.hs @@ -0,0 +1 @@ +run n = takeWhile (< n) [k*k | k <- [1..]] diff --git a/Task/100-doors/Java/100-doors-1.java b/Task/100-doors/Java/100-doors-1.java new file mode 100644 index 0000000000..e215518087 --- /dev/null +++ b/Task/100-doors/Java/100-doors-1.java @@ -0,0 +1,13 @@ +public 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"); + } + } +} diff --git a/Task/100-doors/Java/100-doors-2.java b/Task/100-doors/Java/100-doors-2.java new file mode 100644 index 0000000000..318cd39a24 --- /dev/null +++ b/Task/100-doors/Java/100-doors-2.java @@ -0,0 +1,13 @@ +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.")); + } +} diff --git a/Task/100-doors/Java/100-doors-3.java b/Task/100-doors/Java/100-doors-3.java new file mode 100644 index 0000000000..2d89ca9dc4 --- /dev/null +++ b/Task/100-doors/Java/100-doors-3.java @@ -0,0 +1,12 @@ +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()); + } +} diff --git a/Task/100-doors/Java/100-doors-4.java b/Task/100-doors/Java/100-doors-4.java new file mode 100644 index 0000000000..4d4b8e884c --- /dev/null +++ b/Task/100-doors/Java/100-doors-4.java @@ -0,0 +1,13 @@ +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"); + } + } + } +} diff --git a/Task/100-doors/JavaScript/100-doors-1.js b/Task/100-doors/JavaScript/100-doors-1.js new file mode 100644 index 0000000000..f8a3ff0ce2 --- /dev/null +++ b/Task/100-doors/JavaScript/100-doors-1.js @@ -0,0 +1,11 @@ +var doors = [], n = 100, i, j; + +for (i = 1; i <= n; i++) { + for (j = i; j <= n; j += i) { + doors[j] = !doors[j]; + } +} + +for (i = 1 ; i <= n ; i++) { + if (doors[i]) console.log("Door " + i + " is open"); +} diff --git a/Task/100-doors/JavaScript/100-doors-2.js b/Task/100-doors/JavaScript/100-doors-2.js new file mode 100644 index 0000000000..d4d2a0027c --- /dev/null +++ b/Task/100-doors/JavaScript/100-doors-2.js @@ -0,0 +1,19 @@ +var + n = 100, + doors = [n], + step, + idx; +// now, start opening and closing +for (step = 1; step <= n; step += 1) + for (idx = step; idx <= n; idx += step) + // toggle state of door + doors[idx] = !doors[idx]; + +// find out which doors are open +var open = doors.reduce(function(open, val, idx) { + if (val) { + open.push(idx); + } + return open; +}, []); +document.write("These doors are open: " + open.join(', ')); diff --git a/Task/100-doors/Lua/100-doors.lua b/Task/100-doors/Lua/100-doors.lua new file mode 100644 index 0000000000..c8c0b476a3 --- /dev/null +++ b/Task/100-doors/Lua/100-doors.lua @@ -0,0 +1,17 @@ +is_open = {} + +for door = 1,100 do is_open[door] = false end + +for pass = 1,100 do + for door = pass,100,pass do + is_open[door] = not is_open[door] + end +end + +for i,v in next,is_open do + if v then + print ('Door '..i..':','open') + else + print ('Door '..i..':', 'close') + end +end diff --git a/Task/100-doors/PHP/100-doors-1.php b/Task/100-doors/PHP/100-doors-1.php new file mode 100644 index 0000000000..e7a538570d --- /dev/null +++ b/Task/100-doors/PHP/100-doors-1.php @@ -0,0 +1,7 @@ + diff --git a/Task/100-doors/PHP/100-doors-2.php b/Task/100-doors/PHP/100-doors-2.php new file mode 100644 index 0000000000..8f598ce832 --- /dev/null +++ b/Task/100-doors/PHP/100-doors-2.php @@ -0,0 +1,13 @@ + 'closed', 'closed' => 'open'); +$doors = array_fill(1, 100, 'closed'); +for ($pass = 1; $pass <= 100; ++$pass) { + for ($nr = 1; $nr <= 100; ++$nr) { + if ($nr % $pass == 0) { + $doors[$nr] = $toggleState[$doors[$nr]]; + } + } +} +for ($nr = 1; $nr <= 100; ++$nr) + printf("Door %d is %s\n", $nr, $doors[$nr]); +?> diff --git a/Task/100-doors/Perl/100-doors-1.pl b/Task/100-doors/Perl/100-doors-1.pl new file mode 100644 index 0000000000..861319e8f0 --- /dev/null +++ b/Task/100-doors/Perl/100-doors-1.pl @@ -0,0 +1,10 @@ +my @doors; +for my $pass (1 .. 100) { + for (1 .. 100) { + if (0 == $_ % $pass) { + $doors[$_] = not $doors[$_]; + }; + }; +}; + +print "Door $_ is ", $doors[$_] ? "open" : "closed", "\n" for 1 .. 100; diff --git a/Task/100-doors/Perl/100-doors-2.pl b/Task/100-doors/Perl/100-doors-2.pl new file mode 100644 index 0000000000..27827647b5 --- /dev/null +++ b/Task/100-doors/Perl/100-doors-2.pl @@ -0,0 +1 @@ +print "Door $_ is open\n" for map $_**2, 1 .. 10; diff --git a/Task/100-doors/Perl/100-doors-3.pl b/Task/100-doors/Perl/100-doors-3.pl new file mode 100644 index 0000000000..934096bc3e --- /dev/null +++ b/Task/100-doors/Perl/100-doors-3.pl @@ -0,0 +1 @@ +print "Door $_ is ", qw"closed open"[int sqrt == sqrt], "\n" for 1..100; diff --git a/Task/100-doors/Perl/100-doors-4.pl b/Task/100-doors/Perl/100-doors-4.pl new file mode 100644 index 0000000000..8925cc9e0e --- /dev/null +++ b/Task/100-doors/Perl/100-doors-4.pl @@ -0,0 +1,12 @@ +while( ++$i <= 100 ) +{ + $root = sqrt($i); + if ( int( $root ) == $root ) + { + print "Door $i is open\n"; + } + else + { + print "Door $i is closed\n"; + } +} diff --git a/Task/100-doors/PicoLisp/100-doors-1.l b/Task/100-doors/PicoLisp/100-doors-1.l new file mode 100644 index 0000000000..fefa7a3a88 --- /dev/null +++ b/Task/100-doors/PicoLisp/100-doors-1.l @@ -0,0 +1,5 @@ +(let Doors (need 100) + (for I 100 + (for (D (nth Doors I) D (cdr (nth D I))) + (set D (not (car D))) ) ) + (println Doors) ) diff --git a/Task/100-doors/PicoLisp/100-doors-2.l b/Task/100-doors/PicoLisp/100-doors-2.l new file mode 100644 index 0000000000..080c0f5aed --- /dev/null +++ b/Task/100-doors/PicoLisp/100-doors-2.l @@ -0,0 +1,4 @@ +(let Doors (need 100) + (for I (sqrt 100) + (set (nth Doors (* I I)) T) ) + (println Doors) ) diff --git a/Task/100-doors/PicoLisp/100-doors-3.l b/Task/100-doors/PicoLisp/100-doors-3.l new file mode 100644 index 0000000000..6f69c0f924 --- /dev/null +++ b/Task/100-doors/PicoLisp/100-doors-3.l @@ -0,0 +1,6 @@ +(let Doors (need 100) + (for I (sqrt 100) + (set (nth Doors (* I I)) T) ) + (make + (for (N . D) Doors + (when D (link N)) ) ) ) diff --git a/Task/100-doors/Prolog/100-doors-1.pro b/Task/100-doors/Prolog/100-doors-1.pro new file mode 100644 index 0000000000..eaac239216 --- /dev/null +++ b/Task/100-doors/Prolog/100-doors-1.pro @@ -0,0 +1,34 @@ +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). + + +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)). diff --git a/Task/100-doors/Prolog/100-doors-2.pro b/Task/100-doors/Prolog/100-doors-2.pro new file mode 100644 index 0000000000..04252bdc72 --- /dev/null +++ b/Task/100-doors/Prolog/100-doors-2.pro @@ -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]))). diff --git a/Task/100-doors/Python/100-doors-1.py b/Task/100-doors/Python/100-doors-1.py new file mode 100644 index 0000000000..55ad725caf --- /dev/null +++ b/Task/100-doors/Python/100-doors-1.py @@ -0,0 +1,5 @@ +doors = [False] * 100 +for i in xrange(100): + for j in xrange(i, 100, i+1): + doors[j] = not doors[j] + print "Door %d:" % (i+1), 'open' if doors[i] else 'close' diff --git a/Task/100-doors/Python/100-doors-2.py b/Task/100-doors/Python/100-doors-2.py new file mode 100644 index 0000000000..1ca226e3ad --- /dev/null +++ b/Task/100-doors/Python/100-doors-2.py @@ -0,0 +1,3 @@ +for i in xrange(1, 101): + root = i ** 0.5 + print "Door %d:" % i, 'open' if root == int(root) else 'close' diff --git a/Task/100-doors/Python/100-doors-3.py b/Task/100-doors/Python/100-doors-3.py new file mode 100644 index 0000000000..257a4eb51b --- /dev/null +++ b/Task/100-doors/Python/100-doors-3.py @@ -0,0 +1 @@ +print '\n'.join(['Door %s is %s' % (i, ('closed', 'open')[(i**0.5).is_integer()]) for i in xrange(1, 101)]) diff --git a/Task/100-doors/Python/100-doors-4.py b/Task/100-doors/Python/100-doors-4.py new file mode 100644 index 0000000000..d0b56a5a90 --- /dev/null +++ b/Task/100-doors/Python/100-doors-4.py @@ -0,0 +1 @@ +print '\n'.join('Door %s is %s' % (i, 'closed' if i**0.5 % 1 else 'open') for i in range(1, 101)) diff --git a/Task/100-doors/Python/100-doors-5.py b/Task/100-doors/Python/100-doors-5.py new file mode 100644 index 0000000000..f54fda161e --- /dev/null +++ b/Task/100-doors/Python/100-doors-5.py @@ -0,0 +1,4 @@ +for i in list(range(1, 101)): + if i**0.5 % 1: state='open' + else: state='close' + print ("Door {}:{}".format(i, state)) diff --git a/Task/100-doors/R/100-doors-1.r b/Task/100-doors/R/100-doors-1.r new file mode 100644 index 0000000000..9881a681ec --- /dev/null +++ b/Task/100-doors/R/100-doors-1.r @@ -0,0 +1,10 @@ +doors_puzzle <- function(ndoors=100,passes=100) { + doors <- rep(FALSE,ndoors) + for (ii in seq(1,passes)) { + mask <- seq(0,ndoors,ii) + doors[mask] <- !doors[mask] + } + return (which(doors == TRUE)) +} + +doors_puzzle() diff --git a/Task/100-doors/R/100-doors-2.r b/Task/100-doors/R/100-doors-2.r new file mode 100644 index 0000000000..0f8d6a99d8 --- /dev/null +++ b/Task/100-doors/R/100-doors-2.r @@ -0,0 +1,5 @@ +x <- rep(1, 100) +for (i in 1:100-1) { + x <- xor(x, rep(c(rep(0,i),1), length.out=100)) +} +which(!x) diff --git a/Task/100-doors/R/100-doors-3.r b/Task/100-doors/R/100-doors-3.r new file mode 100644 index 0000000000..0f7f75b33b --- /dev/null +++ b/Task/100-doors/R/100-doors-3.r @@ -0,0 +1,5 @@ +doors_puzzle <- function(ndoors=100,passes=100) { +names(which(table(unlist(sapply(1:passes, function(X) seq(0, ndoors, by=X)))) %% 2 == 1)) +} + +doors_puzzle() diff --git a/Task/100-doors/REXX/100-doors-1.rexx b/Task/100-doors/REXX/100-doors-1.rexx new file mode 100644 index 0000000000..f81469ac5e --- /dev/null +++ b/Task/100-doors/REXX/100-doors-1.rexx @@ -0,0 +1,11 @@ +/*rexx*/ +door. = 0 +do inc = 1 to 100 + do d = inc to 100 by inc + door.d = \door.d + end +end +say "The open doors after 100 passes:" +do i = 1 to 100 + if door.i = 1 then say i +end diff --git a/Task/100-doors/REXX/100-doors-2.rexx b/Task/100-doors/REXX/100-doors-2.rexx new file mode 100644 index 0000000000..88580a4ef5 --- /dev/null +++ b/Task/100-doors/REXX/100-doors-2.rexx @@ -0,0 +1,18 @@ +/*REXX program to solve the 100 door puzzle, the hard-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.*/ + + do j=1 for doors /*process a pass-through for all doors.*/ + do k=j by j to doors /* ... every Jth door from this point. */ + door.k=\door.k /*toggle the "openness" of the door. */ + end /*k*/ + end /*j*/ +say +say 'After' doors "passes, the following doors are open:" +say + do n=1 for doors + if door.n then say right(n,20) + end /*n*/ diff --git a/Task/100-doors/REXX/100-doors-3.rexx b/Task/100-doors/REXX/100-doors-3.rexx new file mode 100644 index 0000000000..2fccfc835e --- /dev/null +++ b/Task/100-doors/REXX/100-doors-3.rexx @@ -0,0 +1,14 @@ +/*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*/ diff --git a/Task/100-doors/REXX/100-doors-4.rexx b/Task/100-doors/REXX/100-doors-4.rexx new file mode 100644 index 0000000000..e4c9141b9a --- /dev/null +++ b/Task/100-doors/REXX/100-doors-4.rexx @@ -0,0 +1,12 @@ +/*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*/ diff --git a/Task/100-doors/Racket/100-doors-1.rkt b/Task/100-doors/Racket/100-doors-1.rkt new file mode 100644 index 0000000000..c2795cf52f --- /dev/null +++ b/Task/100-doors/Racket/100-doors-1.rkt @@ -0,0 +1,28 @@ +#lang racket + +;; Like "map", but the proc must take an index as well as the element. +(define (map-index proc seq) + (for/list ([(elt i) (in-indexed seq)]) + (proc elt i))) + +;; Applies PROC to every STEPth element of SEQ, leaving the others +;; unchanged. +(define (map-step proc step seq) + (map-index + (lambda (elt i) + ((if (zero? (remainder i step) ) + proc + values) elt)) + seq)) + +(define (toggle-nth n seq) + (map-step not n seq)) + +(define (solve seq) + (for/fold ([result seq]) + ([(_ pass) (in-indexed seq)]) + (toggle-nth (add1 pass) result))) + +(for ([(door index) (in-indexed (solve (make-vector 100 #f)))]) + (when door + (printf "~a is open~%" index))) diff --git a/Task/100-doors/Racket/100-doors-2.rkt b/Task/100-doors/Racket/100-doors-2.rkt new file mode 100644 index 0000000000..8440ef4002 --- /dev/null +++ b/Task/100-doors/Racket/100-doors-2.rkt @@ -0,0 +1,6 @@ +#lang racket + +(for-each (lambda (x) (printf "~a is open\n" x)) + (filter (lambda (x) + (exact-integer? (sqrt x))) + (sequence->list (in-range 1 101)))) diff --git a/Task/100-doors/Racket/100-doors-3.rkt b/Task/100-doors/Racket/100-doors-3.rkt new file mode 100644 index 0000000000..bb232f0c33 --- /dev/null +++ b/Task/100-doors/Racket/100-doors-3.rkt @@ -0,0 +1,20 @@ +#lang slideshow +(define-syntax-rule (vector-neg-set! vec pos) + (vector-set! vec pos (not (vector-ref vec pos)))) + +(define (make-doors) + (define doors (make-vector 100 #f)) + (for ([i (in-range 100)]) + (for ([j (in-range i 100 (add1 i))]) + (vector-neg-set! doors j))) + doors) + +(displayln (list->string (for/list ([d (make-doors)]) + (if d #\o #\-)))) + +(define (closed-door) (inset (filled-rectangle 4 20) 2)) +(define (open-door) (inset (rectangle 4 20) 2)) + +(for/fold ([doors (rectangle 0 0)]) + ([open? (make-doors)]) + (hc-append doors (if open? (open-door) (closed-door)))) diff --git a/Task/100-doors/Ruby/100-doors-1.rb b/Task/100-doors/Ruby/100-doors-1.rb new file mode 100644 index 0000000000..cbfbab6894 --- /dev/null +++ b/Task/100-doors/Ruby/100-doors-1.rb @@ -0,0 +1,31 @@ +class Door + attr_reader :state + def initialize + @state=:closed + end + + def close; @state=:closed; end + def open; @state=:open; end + + def closed?; @state==:closed; end + def open?; @state==:open; end + + def toggle + if closed? + open + else + close + end + end + + def to_s; @state.to_s; end +end + +doors=Array.new(100){Door.new} +1.upto(100) do |multiplier| + doors.each_with_index do |door, i| + door.toggle if (i+1)%multiplier==0 + end +end + +doors.each_with_index{|door, i| puts "Door #{i+1} is #{door}."} diff --git a/Task/100-doors/Ruby/100-doors-2.rb b/Task/100-doors/Ruby/100-doors-2.rb new file mode 100644 index 0000000000..92dbf4f3e3 --- /dev/null +++ b/Task/100-doors/Ruby/100-doors-2.rb @@ -0,0 +1,19 @@ +n = 100 +Open = "open" +Closed = "closed" +def Open.f + Closed +end +def Closed.f + Open +end +doors = [Closed] * (n+1) +for mul in 1..n + for x in 1..n + doors[mul*x] = (doors[mul*x] || break).f + end +end +doors.each_with_index { + |b, i| + puts "Door #{i} is #{b}" if i>0 +} diff --git a/Task/100-doors/Ruby/100-doors-3.rb b/Task/100-doors/Ruby/100-doors-3.rb new file mode 100644 index 0000000000..9c4df2ab80 --- /dev/null +++ b/Task/100-doors/Ruby/100-doors-3.rb @@ -0,0 +1,4 @@ +n = 100 +(1..n).each do |i| + puts "Door #{i} is #{i**0.5 == (i**0.5).round ? "open" : "closed"}" +end diff --git a/Task/100-doors/Ruby/100-doors-4.rb b/Task/100-doors/Ruby/100-doors-4.rb new file mode 100644 index 0000000000..703b34dd1d --- /dev/null +++ b/Task/100-doors/Ruby/100-doors-4.rb @@ -0,0 +1,7 @@ +doors = [false] * 100 +100.times do |i| + (i .. doors.length).step(i+1) do |j| + doors[j] = !doors[j] + end +end +puts doors.inspect diff --git a/Task/100-doors/Sather/100-doors.sa b/Task/100-doors/Sather/100-doors.sa new file mode 100644 index 0000000000..66e1cd5592 --- /dev/null +++ b/Task/100-doors/Sather/100-doors.sa @@ -0,0 +1,22 @@ +class MAIN is + main is + pass, door :INT; + doors :ARRAY{BOOL} := #(100); + loop + doors[0.upto!(99)] := false; + end; + pass := 0; + loop while!(pass < 100); + door := pass; + loop while! (door < 100); + doors[door] := ~doors[door]; + door := door + pass + 1 + end; + pass := pass + 1; + end; + loop + door := 0.upto!(99); + #OUT + (door+1) + " " + doors[door] + "\n"; + end; + end; +end; diff --git a/Task/100-doors/Scala/100-doors-1.scala b/Task/100-doors/Scala/100-doors-1.scala new file mode 100644 index 0000000000..05b06f0dc9 --- /dev/null +++ b/Task/100-doors/Scala/100-doors-1.scala @@ -0,0 +1,3 @@ +for { i <- 1 to 100 + r = 1 to 100 map (i % _ == 0) reduceLeft (_^_) + } println (i +" "+ (if (r) "open" else "closed")) diff --git a/Task/100-doors/Scala/100-doors-2.scala b/Task/100-doors/Scala/100-doors-2.scala new file mode 100644 index 0000000000..3fb5d85876 --- /dev/null +++ b/Task/100-doors/Scala/100-doors-2.scala @@ -0,0 +1,17 @@ +def openDoors(length : Int = 100) = { + var isDoorOpen = new Array[Boolean](length) + + for (i <- 0 until length) { + for (j <- i until length by i + 1) { + isDoorOpen(j) ^= true + } + } + isDoorOpen +} + +val doorState = scala.collection.immutable.Map(false -> "closed", true -> "open") +val isDoorOpen = openDoors() + +for (doorNo <- 0 until isDoorOpen.length) { + println("Door %d is %s".format(doorNo + 1, doorState(isDoorOpen(doorNo)))) +} diff --git a/Task/100-doors/Scala/100-doors-3.scala b/Task/100-doors/Scala/100-doors-3.scala new file mode 100644 index 0000000000..d3045a744b --- /dev/null +++ b/Task/100-doors/Scala/100-doors-3.scala @@ -0,0 +1,3 @@ +val o = 1 to 10 map (i => i * i) +println("open: " + o) +println("closed: " + (1 to 100 filterNot o.contains)) diff --git a/Task/100-doors/Scheme/100-doors-1.ss b/Task/100-doors/Scheme/100-doors-1.ss new file mode 100644 index 0000000000..33898fcf3e --- /dev/null +++ b/Task/100-doors/Scheme/100-doors-1.ss @@ -0,0 +1,26 @@ +(define *max-doors* 100) + +(define (show-doors doors) + (let door ((i 0) + (l (vector-length doors))) + (cond ((= i l) + (newline)) + (else + (printf "~nDoor ~a is ~a" + (+ i 1) + (if (vector-ref doors i) "open" "closed")) + (door (+ i 1) l))))) + +(define (flip-doors doors) + (define (flip-all i) + (cond ((> i *max-doors*) doors) + (else + (let flip ((idx (- i 1))) + (cond ((>= idx *max-doors*) + (flip-all (+ i 1))) + (else + (vector-set! doors idx (not (vector-ref doors idx))) + (flip (+ idx i)))))))) + (flip-all 1)) + +(show-doors (flip-doors (make-vector *max-doors* #f))) diff --git a/Task/100-doors/Scheme/100-doors-2.ss b/Task/100-doors/Scheme/100-doors-2.ss new file mode 100644 index 0000000000..9079431984 --- /dev/null +++ b/Task/100-doors/Scheme/100-doors-2.ss @@ -0,0 +1,9 @@ +(define (optimised-flip-doors doors) + (define (flip-all i) + (cond ((> i (floor (sqrt *max-doors*))) doors) + (else + (vector-set! doors (- (* i i) 1) #t) + (flip-all (+ i 1))))) + (flip-all 1)) + +(show-doors (optimised-flip-doors (make-vector *max-doors* #f))) diff --git a/Task/100-doors/Smalltalk/100-doors-1.st b/Task/100-doors/Smalltalk/100-doors-1.st new file mode 100644 index 0000000000..2e793944f8 --- /dev/null +++ b/Task/100-doors/Smalltalk/100-doors-1.st @@ -0,0 +1,15 @@ +|a| +a := Array new: 100 . +1 to: 100 do: [ :i | a at: i put: false ]. + +1 to: 100 do: [ :pass | + pass to: 100 by: pass do: [ :door | + a at: door put: (a at: door) not . + ] +]. + +"output" +1 to: 100 do: [ :door | + ( 'door #%1 is %2' % + { door . (a at: door) ifTrue: [ 'open' ] ifFalse: [ 'closed' ] } ) displayNl +] diff --git a/Task/100-doors/Smalltalk/100-doors-2.st b/Task/100-doors/Smalltalk/100-doors-2.st new file mode 100644 index 0000000000..cdbaaaab2a --- /dev/null +++ b/Task/100-doors/Smalltalk/100-doors-2.st @@ -0,0 +1,9 @@ +|a| +a := (1 to: 100) collect: [ :x | false ]. +1 to: 10 do: [ :i | a at: (i squared) put: true ]. +1 to: 100 do: [ :i | + ( 'door #%1 is %2' % { i . + (a at: i) ifTrue: [ 'open' ] + ifFalse: [ 'closed' ] } + ) displayNl +] diff --git a/Task/100-doors/Smalltalk/100-doors-3.st b/Task/100-doors/Smalltalk/100-doors-3.st new file mode 100644 index 0000000000..56f2eaacf5 --- /dev/null +++ b/Task/100-doors/Smalltalk/100-doors-3.st @@ -0,0 +1,29 @@ +| m w h smh smw delay closedDoor border subMorphList | + +closedDoor := Color black. +border := Color veryLightGray. +delay := Delay forMilliseconds: 50. +w := World bounds corner x. +h := (World bounds corner y) / 2. +smw := w/100. +smh := h/2. + +m := BorderedMorph new position: 0@h. +m height: smh; width: w; borderColor: border. +m color: Color veryLightGray. + +1 to: 100 do: [ :pos || sm | + sm := BorderedMorph new height: smh ; width: smw ; + borderColor: border; color: closedDoor; + position: (smw*pos)@h. + m addMorph: sm asElementNumber: pos]. + +m openInWorld. +delay wait. +subMorphList := m submorphs. +"display every step" +[1 to: 100 do: [ :step | + step to: 100 by: step do: [ :pos | | subMorph | + subMorph := subMorphList at: pos. + subMorph color: subMorph color negated. + delay wait]]] fork. diff --git a/Task/100-doors/Tcl/100-doors-1.tcl b/Task/100-doors/Tcl/100-doors-1.tcl new file mode 100644 index 0000000000..43badf3380 --- /dev/null +++ b/Task/100-doors/Tcl/100-doors-1.tcl @@ -0,0 +1,11 @@ +package require Tcl 8.5 +set n 100 +set doors [concat - [lrepeat $n 0]] +for {set step 1} {$step <= $n} {incr step} { + for {set i $step} {$i <= $n} {incr i $step} { + lset doors $i [expr { ! [lindex $doors $i]}] + } +} +for {set i 1} {$i <= $n} {incr i} { + puts [format "door %d is %s" $i [expr {[lindex $doors $i] ? "open" : "closed"}]] +} diff --git a/Task/100-doors/Tcl/100-doors-2.tcl b/Task/100-doors/Tcl/100-doors-2.tcl new file mode 100644 index 0000000000..df7078d750 --- /dev/null +++ b/Task/100-doors/Tcl/100-doors-2.tcl @@ -0,0 +1,8 @@ +package require Tcl 8.5 +set doors [lrepeat [expr {$n + 1}] closed] +for {set i 1} {$i <= sqrt($n)} {incr i} { + lset doors [expr {$i ** 2}] open +} +for {set i 1} {$i <= $n} {incr i} { + puts [format "door %d is %s" $i [lindex $doors $i]] +} diff --git a/Task/100-doors/Tcl/100-doors-3.tcl b/Task/100-doors/Tcl/100-doors-3.tcl new file mode 100644 index 0000000000..8e3db5488e --- /dev/null +++ b/Task/100-doors/Tcl/100-doors-3.tcl @@ -0,0 +1,46 @@ +package require Tcl 8.5 +package require Tk + +array set door_status {} + +# create the gui +set doors [list x] +for {set i 0} {$i < 10} {incr i} { + for {set j 0} {$j < 10} {incr j} { + set k [expr {1 + $j + 10*$i}] + lappend doors [radiobutton .d_$k -text $k -variable door_status($k) \ + -indicatoron no -offrelief flat -width 3 -value open] + grid [lindex $doors $k] -column $j -row $i + } +} + +# create the controls +button .start -command go -text Start +label .i_label -text " door:" +entry .i -textvariable i -width 4 +label .step_label -text " step:" +entry .step -textvariable step -width 4 +grid .start - .i_label - .i - .step_label - .step - -row $i +grid configure .start -sticky ew +grid configure .i_label .step_label -sticky e +grid configure .i .step -sticky w + +proc go {} { + global doors door_status i step + + # initialize the door_status (all closed) + for {set d 1} {$d <= 100} {incr d} { + set door_status($d) closed + } + + # now, begin opening and closing + for {set step 1} {$step <= 100} {incr step} { + for {set i 1} {$i <= 100} {incr i} { + if {$i % $step == 0} { + [lindex $doors $i] [expr {$door_status($i) eq "open" ? "deselect" : "select"}] + update + after 50 + } + } + } +} diff --git a/Task/24-game/0DESCRIPTION b/Task/24-game/0DESCRIPTION new file mode 100644 index 0000000000..3affbe40ed --- /dev/null +++ b/Task/24-game/0DESCRIPTION @@ -0,0 +1,17 @@ +The [[wp:24 Game|24 Game]] tests one's mental arithmetic. + +Write a program that [[task feature::Rosetta Code:randomness|randomly]] chooses and [[task feature::Rosetta Code:user output|displays]] four digits, each from one to nine, with repetitions allowed. The program should prompt for the player to enter an equation using ''just'' those, and ''all'' of those four digits. The program should ''check'' then [[task feature::Rosetta Code:parsing|evaluate the expression]]. The goal is for the player to [[task feature::Rosetta Code:user input|enter]] an expression that evaluates to '''24'''. +* Only multiplication, division, addition, and subtraction operators/functions are allowed. +* Division should use floating point or rational arithmetic, etc, to preserve remainders. +* Brackets are allowed, if using an infix expression evaluator. +* Forming multiple digit numbers from the supplied digits is ''disallowed''. (So an answer of 12+12 when given 1, 2, 2, and 1 is wrong). +* The order of the digits when given does not have to be preserved. + +Note: +* The type of expression evaluator used is not mandated. An [[wp:Reverse Polish notation|RPN]] evaluator is equally acceptable for example. +* The task is not for the program to generate the expression, or test whether an expression is even possible. + +C.f: [[24 game Player]] + +'''Reference''' +# [http://www.bbc.co.uk/dna/h2g2/A933121 The 24 Game] on h2g2. diff --git a/Task/24-game/Ada/24-game.ada b/Task/24-game/Ada/24-game.ada new file mode 100644 index 0000000000..4bad72fb67 --- /dev/null +++ b/Task/24-game/Ada/24-game.ada @@ -0,0 +1,83 @@ +with Ada.Text_IO; +with Ada.Numerics.Discrete_Random; +procedure Game_24 is + subtype Operation is Character; + type Op_Array is array (Positive range <>) of Operation; + type Digit is range 1 .. 9; + type Digit_Array is array (Positive range <>) of Digit; + package Digit_IO is new Ada.Text_IO.Integer_IO (Digit); + package Random_Digit is new Ada.Numerics.Discrete_Random (Digit); + Digit_Generator : Random_Digit.Generator; + Given_Digits : array (1 .. 4) of Digit; +begin + Ada.Text_IO.Put_Line ("24 Game"); + Ada.Text_IO.Put_Line ("Generating 4 digits..."); + Random_Digit.Reset (Digit_Generator); + for I in Given_Digits'Range loop + Given_Digits (I) := Random_Digit.Random (Digit_Generator); + end loop; + Ada.Text_IO.Put ("Your Digits:"); + for I in Given_Digits'Range loop + Digit_IO.Put (Given_Digits (I)); + end loop; + Ada.Text_IO.New_Line; + Ada.Text_IO.Put ("Enter your Expression: "); + declare + Value : Integer; + Input_Operations : Op_Array (1 .. 3); + Input_Digits : Digit_Array (1 .. 4); + Unused_Digits : array (Given_Digits'Range) of Boolean := + (others => True); + begin + -- get input + for I in 1 .. 4 loop + Digit_IO.Get (Input_Digits (I)); + exit when I = 4; + Ada.Text_IO.Get (Input_Operations (I)); + end loop; + -- check input + for I in Input_Digits'Range loop + declare + Found : Boolean := False; + begin + for J in Given_Digits'Range loop + if Unused_Digits (J) and then + Given_Digits (J) = Input_Digits (I) then + Unused_Digits (J) := False; + Found := True; + exit; + end if; + end loop; + if not Found then + Ada.Text_IO.Put_Line ("Illegal Number used:" & + Digit'Image (Input_Digits (I))); + return; + end if; + end; + end loop; + -- check value + Value := Integer (Input_Digits (Input_Digits'First)); + for I in Input_Operations'Range loop + case Input_Operations (I) is + when '+' => + Value := Value + Integer (Input_Digits (I + 1)); + when '-' => + Value := Value - Integer (Input_Digits (I + 1)); + when '*' => + Value := Value * Integer (Input_Digits (I + 1)); + when '/' => + Value := Value / Integer (Input_Digits (I + 1)); + when others => + Ada.Text_IO.Put_Line ("Illegal Op used:" & + Input_Operations (I)); + return; + end case; + end loop; + if Value /= 24 then + Ada.Text_IO.Put_Line ("Value" & Integer'Image (Value) & + " is not 24!"); + else + Ada.Text_IO.Put_Line ("You won!"); + end if; + end; +end Game_24; diff --git a/Task/24-game/Argile/24-game.argile b/Task/24-game/Argile/24-game.argile new file mode 100644 index 0000000000..eebf9696e9 --- /dev/null +++ b/Task/24-game/Argile/24-game.argile @@ -0,0 +1,110 @@ +use std, array, list + +do + generate random digits + show random digits + let result = parse expression (get input line) + if result != ERROR + if some digits are unused + print "Wrong ! (you didn't use all digits)" ; failure++ + else if result == 24.0 + print "Correct !" ; success++ + else + print "Wrong ! (you got "result")" ; failure++ + while play again ? +print "success:"success" failure:"failure" total:"(success+failure) as int + +let success = 0, failure = 0. + +.: generate random digits :. + our nat seed = 0xc6f31 (: default seed when /dev/urandom doesn't exist :) + let urandom = fopen "/dev/urandom" "r" + if urandom isn't nil + fread &seed size of seed 1 urandom + fclose urandom + Cfunc srandom seed + seed = (Cfunc random) as nat + for each (val int d) from 0 to 3 + digits[d] = '1' + (seed % 9) + seed /= 9 + +let digits be an array of 4 byte + +.: show random digits :. + print "Enter an expression that equates to 24 using only all these digits:" + printf "%c , %c , %c , %c\n"(digits[0])(digits[1])(digits[2])(digits[3]) + printf "24 = " + +.: some digits are unused :. -> bool + for each (val int d) from 0 to 3 + return true if digits[d] != '\0' + false + +.: get input line :. -> text + our array of 64 byte line + Cfunc fgets (line) (size of line) (stdin) + let int i + for (i = 0) (line[i] != 0) (i++) + line[i] = '\0' if (line[i] == '\n') + line as text + +.: play again ? :. -> bool + while true + printf "Play again ? (y/n) " ; Cfunc fflush stdout + let answer = get input line + switch answer[0] + case 'n' {return false} + case 'y' {return true } + default {continue } + false + +=: ERROR := -> real {-32202.0} + +.: parse expression :. -> real + let x = 0.0, x_is_set = false, op = ' '. + let stack be a list of State ; class State {byte op; real x} + for (stack = nil) (*expr != 0) (expr++) + switch *expr + case '+' ; case '-' ; case '*' ; case '/' + error "bad syntax" if not x_is_set + op = *expr + case '1' ; case '2' ; case '3' ; case '4' ; case '5' + case '6' ; case '7' ; case '8' ; case '9' + error "missing operator" if (x_is_set and op == ' ') + error "unavailable digit" unless consume digit expr[0] + do operation with (expr[0] - '0') as real + case (Cgen "'('") + error "missing operator" if (op == ' ' but x_is_set) + (new list (new State) (code of del State())) << stack + op = ' ' ; x_is_set = false (: start fresh state :) + case (Cgen "')'") + error "mismatched parenthesis" if stack is nil + error "wrong syntax" if not x_is_set + let y = x + x = stack.data.x ; op = stack.data.op + delete pop stack + do operation with y + default {error "disallowed character"} + + .:new State :. -> State {let s=new(State); s.x=x; s.op=op; s} + .:del State :. { free s } + .:do operation with :. + switch op + case '+' {x += y} + case '-' {x -= y} + case '*' {x *= y} + case '/' {x /= y} + default {x = y; x_is_set = true} + op = ' ' + =:error:= ->real {eprint "Error: "msg" at ["expr"]";return ERROR} + .:consume digit :. -> bool + for each (val int d) from 0 to 3 + if digits[d] == b + digits[d] = '\0' + return true + false + + if stack isn't nil + delete all stack + error "unclosed parenthesis" + return x diff --git a/Task/24-game/AutoHotkey/24-game.ahk b/Task/24-game/AutoHotkey/24-game.ahk new file mode 100644 index 0000000000..0bf0b3e2de --- /dev/null +++ b/Task/24-game/AutoHotkey/24-game.ahk @@ -0,0 +1,108 @@ +AutoExecute: + Title := "24 Game" + Gui, -MinimizeBox + Gui, Add, Text, w230 vPuzzle + Gui, Add, Edit, wp vAnswer + Gui, Add, Button, w70, &Generate + Gui, Add, Button, x+10 wp Default, &Submit + Gui, Add, Button, x+10 wp, E&xit + + +ButtonGenerate: ; new set of numbers + Loop, 4 + Random, r%A_Index%, 1, 9 + Puzzle = %r1%, %r2%, %r3%, and %r4% + GuiControl,, Puzzle, The numbers are: %Puzzle% - Good luck! + GuiControl,, Answer ; empty the edit box + ControlFocus, Edit1 + Gui, -Disabled + Gui, Show,, %Title% +Return ; end of auto execute section + + +ButtonSubmit: ; check solution + Gui, Submit, NoHide + Gui, +Disabled + + ; check numbers used + RegExMatch(Answer, "(\d)\D+(\d)\D+(\d)\D+(\d)", $) + ListPuzzle := r1 "," r2 "," r3 "," r4 + ListAnswer := $1 "," $2 "," $3 "," $4 + Sort, ListPuzzle, D, + Sort, ListAnswer, D, + If Not ListPuzzle = ListAnswer { + MsgBox, 48, Error - %Title%, Numbers used!`n%Answer% + Goto, TryAgain + } + + ; check operators used + StringReplace, $, $, +,, All + StringReplace, $, $, -,, All + StringReplace, $, $, *,, All + StringReplace, $, $, /,, All + StringReplace, $, $, (,, All + StringReplace, $, $, ),, All + Loop, 9 + StringReplace, $, $, %A_Index%,, All + If StrLen($) > 0 + Or InStr(Answer, "**") + Or InStr(Answer, "//") + Or InStr(Answer, "++") + Or InStr(Answer, "--") { + MsgBox, 48, Error - %Title%, Operators used!`n%Answer% + Goto, TryAgain + } + + ; check result + Result := Eval(Answer) + If Not Result = 24 { + MsgBox, 48, Error - %Title%, Result incorrect!`n%Result% + Goto, TryAgain + } + + ; if we are sill here + MsgBox, 4, %Title%, Correct solution! Play again? + IfMsgBox, Yes + Gosub, ButtonGenerate + Else + ExitApp +Return + + +TryAgain: ; alternative ending of routine ButtonSubmit + ControlFocus, Edit1 + Gui, -Disabled + Gui, Show +Return + + +GuiClose: +GuiEscape: +ButtonExit: + ExitApp +Return + + +;--------------------------------------------------------------------------- +Eval(Expr) { ; evaluate expression using separate AHK process +;--------------------------------------------------------------------------- + ; credit for this function goes to AutoHotkey forum member Laszlo + ; http://www.autohotkey.com/forum/topic9578.html + ;----------------------------------------------------------------------- + static File := "24$Temp.ahk" + + ; delete old temporary file, and write new + FileDelete, %File% + FileContent := "#NoTrayIcon`r`n" + . "FileDelete, " File "`r`n" + . "FileAppend, `% " Expr ", " File "`r`n" + FileAppend, %FileContent%, %File% + + ; run AHK to execute temp script, evaluate expression + RunWait, %A_AhkPath% %File% + + ; get result + FileRead, Result, %File% + FileDelete, %File% + Return, Result +} diff --git a/Task/24-game/AutoIt/24-game.autoit b/Task/24-game/AutoIt/24-game.autoit new file mode 100644 index 0000000000..c1edd1282a --- /dev/null +++ b/Task/24-game/AutoIt/24-game.autoit @@ -0,0 +1,74 @@ +;AutoIt Script Example +;by Daniel Barnes +;spam me at djbarnes at orcon dot net dot en zed +;13/08/2012 + +;Choose four random digits (1-9) with repetitions allowed: +global $digits +FOR $i = 1 TO 4 + $digits &= Random(1,9,1) +NEXT + +While 1 + main() +WEnd + +Func main() + $text = "Enter an equation (using all of, and only, the single digits "&$digits &")"&@CRLF + $text &= "which evaluates to exactly 24. Only multiplication (*) division (/)"&@CRLF + $text &= "addition (+) and subtraction (-) operations and parentheses are allowed:" + $input = InputBox ("24 Game",$text,"","",400,150) + If @error Then exit + + ;remove any spaces in input + $input = StringReplace($input," ","") + + ;check correct characters were used + For $i = 1 To StringLen($input) + $chr = StringMid($input,$i,1) + If Not StringInStr("123456789*/+-()",$chr) Then + MsgBox (0, "ERROR","Invalid character used: '"&$chr&"'") + return + endif + Next + + ;validate the equation uses all of the 4 characters, and nothing else + $test = $input + $test = StringReplace($test,"(","") + $test = StringReplace($test,")","") + + ;validate the length of the input - if its not 7 characters long then the user has done something wrong + If StringLen ($test) <> 7 Then + MsgBox (0,"ERROR","The equation "&$test&" is invalid") + return + endif + + $test = StringReplace($test,"/","") + $test = StringReplace($test,"*","") + $test = StringReplace($test,"-","") + $test = StringReplace($test,"+","") + + For $i = 1 To StringLen($digits) + $digit = StringMid($digits,$i,1) + For $ii = 1 To StringLen($test) + If StringMid($test,$ii,1) = $digit Then + $test = StringLeft($test,$ii-1) & StringRight($test,StringLen($test)-$ii) + ExitLoop + endif + Next + Next + If $test <> "" Then + MsgBox (0, "ERROR", "The equation didn't use all 4 characters, and nothing else!") + return + endif + + $try = Execute($input) + + If $try = 24 Then + MsgBox (0, "24 Game","Well done. Your equation ("&$input&") = 24!") + Exit + Else + MsgBox (0, "24 Game","Fail. Your equation ("&$input&") = "&$try&"!") + return + endif +EndFunc diff --git a/Task/24-game/C/24-game.c b/Task/24-game/C/24-game.c new file mode 100644 index 0000000000..f88ca6fc0e --- /dev/null +++ b/Task/24-game/C/24-game.c @@ -0,0 +1,280 @@ +#include +#include +#include +#include + +ucontext_t ctx; +const char *msg; + +enum { OP_NONE = 0, OP_NUM, OP_ADD, OP_SUB, OP_MUL, OP_DIV }; + +typedef struct expr_t *expr, expr_t; +struct expr_t { + int op, val, used; + expr left, right; +}; + +#define N_DIGITS 4 +expr_t digits[N_DIGITS]; + +void gen_digits() +{ + int i; + for (i = 0; i < N_DIGITS; i++) + digits[i].val = 1 + rand() % 9; +} + +#define MAX_INPUT 64 +char str[MAX_INPUT]; +int pos; + +#define POOL_SIZE 8 +expr_t pool[POOL_SIZE]; +int pool_ptr; + +void reset() +{ + int i; + msg = 0; + pool_ptr = pos = 0; + for (i = 0; i < POOL_SIZE; i++) { + pool[i].op = OP_NONE; + pool[i].left = pool[i].right = 0; + } + for (i = 0; i < N_DIGITS; i++) + digits[i].used = 0; +} + +/* longish jumpish back to input cycle */ +void bail(const char *s) +{ + msg = s; + setcontext(&ctx); +} + +expr new_expr() +{ + if (pool_ptr < POOL_SIZE) + return pool + pool_ptr++; + return 0; +} + +/* check next input char */ +int next_tok() +{ + while (isspace(str[pos])) pos++; + return str[pos]; +} + +/* move input pointer forward */ +int take() +{ + if (str[pos] != '\0') return ++pos; + return 0; +} + +/* BNF(ish) +expr = term { ("+")|("-") term } +term = fact { ("*")|("/") expr } +fact = number + | '(' expr ')' +*/ + +expr get_fact(); +expr get_term(); +expr get_expr(); + +expr get_expr() +{ + int c; + expr l, r, ret; + if (!(ret = get_term())) bail("Expected term"); + while ((c = next_tok()) == '+' || c == '-') { + if (!take()) bail("Unexpected end of input"); + if (!(r = get_term())) bail("Expected term"); + + l = ret; + ret = new_expr(); + ret->op = (c == '+') ? OP_ADD : OP_SUB; + ret->left = l; + ret->right = r; + } + return ret; +} + +expr get_term() +{ + int c; + expr l, r, ret; + ret = get_fact(); + while((c = next_tok()) == '*' || c == '/') { + if (!take()) bail("Unexpected end of input"); + + r = get_fact(); + l = ret; + ret = new_expr(); + ret->op = (c == '*') ? OP_MUL : OP_DIV; + ret->left = l; + ret->right = r; + } + return ret; +} + +expr get_digit() +{ + int i, c = next_tok(); + expr ret; + if (c >= '0' && c <= '9') { + take(); + ret = new_expr(); + ret->op = OP_NUM; + ret->val = c - '0'; + for (i = 0; i < N_DIGITS; i++) + if (digits[i].val == ret->val && !digits[i].used) { + digits[i].used = 1; + return ret; + } + bail("Invalid digit"); + } + return 0; +} + +expr get_fact() +{ + int c; + expr l = get_digit(); + if (l) return l; + if ((c = next_tok()) == '(') { + take(); + l = get_expr(); + if (next_tok() != ')') bail("Unbalanced parens"); + take(); + return l; + } + return 0; +} + +expr parse() +{ + int i; + expr ret = get_expr(); + if (next_tok() != '\0') + bail("Trailing garbage"); + for (i = 0; i < N_DIGITS; i++) + if (!digits[i].used) + bail("Not all digits are used"); + return ret; +} + +typedef struct frac_t frac_t, *frac; +struct frac_t { int denom, num; }; + +int gcd(int m, int n) +{ + int t; + while (m) { + t = m; m = n % m; n = t; + } + return n; +} + +/* evaluate expression tree. result in fraction form */ +void eval_tree(expr e, frac res) +{ + frac_t l, r; + int t; + if (e->op == OP_NUM) { + res->num = e->val; + res->denom = 1; + return; + } + + eval_tree(e->left, &l); + eval_tree(e->right, &r); + + switch(e->op) { + case OP_ADD: + res->num = l.num * r.denom + l.denom * r.num; + res->denom = l.denom * r.denom; + break; + case OP_SUB: + res->num = l.num * r.denom - l.denom * r.num; + res->denom = l.denom * r.denom; + break; + case OP_MUL: + res->num = l.num * r.num; + res->denom = l.denom * r.denom; + break; + case OP_DIV: + res->num = l.num * r.denom; + res->denom = l.denom * r.num; + break; + } + if ((t = gcd(res->denom, res->num))) { + res->denom /= t; + res->num /= t; + } +} + +void get_input() +{ + int i; +reinput: + reset(); + printf("\nAvailable digits are:"); + for (i = 0; i < N_DIGITS; i++) + printf(" %d", digits[i].val); + printf(". Type an expression and I'll check it for you, or make new numbers.\n" + "Your choice? [Expr/n/q] "); + + while (1) { + for (i = 0; i < MAX_INPUT; i++) str[i] = '\n'; + fgets(str, MAX_INPUT, stdin); + if (*str == '\0') goto reinput; + if (str[MAX_INPUT - 1] != '\n') + bail("string too long"); + + for (i = 0; i < MAX_INPUT; i++) + if (str[i] == '\n') str[i] = '\0'; + if (str[0] == 'q') { + printf("Bye\n"); + exit(0); + } + if (str[0] == 'n') { + gen_digits(); + goto reinput; + } + return; + } +} + +int main() +{ + frac_t f; + srand(time(0)); + + gen_digits(); + while(1) { + get_input(); + getcontext(&ctx); /* if parse error, jump back here with err msg set */ + if (msg) { + /* after error jump; announce, reset, redo */ + printf("%s at '%.*s'\n", msg, pos, str); + continue; + } + + eval_tree(parse(), &f); + + if (f.denom == 0) bail("Divide by zero"); + if (f.denom == 1 && f.num == 24) + printf("You got 24. Very good.\n"); + else { + if (f.denom == 1) + printf("Eval to: %d, ", f.num); + else + printf("Eval to: %d/%d, ", f.num, f.denom); + printf("no good. Try again.\n"); + } + } + return 0; +} diff --git a/Task/24-game/Clojure/24-game.clj b/Task/24-game/Clojure/24-game.clj new file mode 100644 index 0000000000..c7f0503266 --- /dev/null +++ b/Task/24-game/Clojure/24-game.clj @@ -0,0 +1,45 @@ +(ns rosettacode.24game) + +(defn gen-new-game-nums [amount] (repeatedly amount #(inc ( rand-int 9)))) + +(defn orderless-seq-eq? [seq1 seq2] (apply = (map frequencies (list seq1 seq2)))) + +(defn valid-input? + "checks whether the expression is somewhat valid prefix notation + (+ 1 2 3 4) (+ 3 (+ 4 5) 6) + this is done by making sure the only contents of the list are numbers operators and brackets + flatten gets rid of the brackets, so we just need to test for operators and integers after that" + [user-input] + (if (re-find #"^\(([\d-+/*] )+\d?\)$" (pr-str (flatten user-input))) + true + false)) + +(defn game-numbers-and-user-input-same? + "input form: (+ 1 2 (+ 3 4)) +tests to see if the numbers the user entered are the same as the ones given to them by the game" + [game-nums user-input] + (orderless-seq-eq? game-nums (filter integer? (flatten user-input)))) + +(defn win [] (println "you won the game!\n")) +(defn lose [] (println "you guessed wrong, or your input was not in prefix notation. eg: '(+ 1 2 3 4)'\n")) +(defn game-start [goal game-numbers] (do + (println "Your numbers are " game-numbers) + (println "Your goal is " goal) + (println "Use the numbers and +*-/ to reach your goal\n") + (println "'q' to Quit\n"))) + +(defn play-game + "typing in 'q' quits. + to play use (play-game) (play-game 24) or (play-game 24 '(1 2 3 4)" + ([] (play-game 24)) + ([goal] (play-game goal (gen-new-game-nums 4))) + ([goal game-numbers] + (game-start goal game-numbers) + (let [input (read-line) + input-as-code (read-string input)] + (if (and (valid-input? input-as-code) + (game-numbers-and-user-input-same? game-numbers input-as-code) + (try (= goal (eval input-as-code)) (catch Exception e (do (lose) (play-game goal game-numbers))))) + (win) + (when (not (= input "q")) + (do (lose) (recur goal game-numbers))))))) diff --git a/Task/24-game/CoffeeScript/24-game.coffee b/Task/24-game/CoffeeScript/24-game.coffee new file mode 100644 index 0000000000..4259f13d90 --- /dev/null +++ b/Task/24-game/CoffeeScript/24-game.coffee @@ -0,0 +1,53 @@ +tty = require 'tty' +tty.setRawMode true + +buffer = "" +numbers = [] + +for n in [0...4] + numbers.push Math.max 1, Math.floor(Math.random() * 9) + +console.log "You can use the numbers: #{numbers.join ' '}" + +process.stdin.on 'keypress', (char, key) -> + + # accept operator + if char and isNaN(char) and /[()*\/+-]/.test(char) and buffer.substr(-1) isnt char + buffer += char + process.stdout.write char + # accept number + else if !isNaN(+char) and (buffer == '' or isNaN(buffer.substr -1)) + buffer += char + process.stdout.write char + + # check then evaluate expression + if key?.name is 'enter' + result = calculate() + process.stdout.write '\n' + if result and result is 24 + console.log " = 24! congratulations." + else + console.log "#{result}. nope." + process.exit 0 + + # quit + if key?.name is 'escape' or (key?.name == 'c' and key.ctrl) + process.exit 0 + +calculate = () -> + + if /[^\d\s()+*\/-]/.test buffer + console.log "invalid characters" + process.exit 1 + + used = buffer.match(/\d/g) + if used?.length != 4 or used.sort().join() != numbers.sort().join() + console.log "you must use the 4 numbers provided" + process.exit 1 + + res = try eval buffer catch e + return res or 'invalid expression' + + +# begin taking input +process.stdin.resume() diff --git a/Task/24-game/Erlang/24-game.erl b/Task/24-game/Erlang/24-game.erl new file mode 100644 index 0000000000..13efc88806 --- /dev/null +++ b/Task/24-game/Erlang/24-game.erl @@ -0,0 +1,65 @@ +-module(g24). +-export([main/0]). + +main() -> + random:seed(now()), + io:format("24 Game~n"), + play(). + +play() -> + io:format("Generating 4 digits...~n"), + Digts = [random:uniform(X) || X <- [9,9,9,9]], + io:format("Your digits\t~w~n", [Digts]), + read_eval(Digts), + play(). + +read_eval(Digits) -> + Exp = string:strip(io:get_line(standard_io, "Your expression: "), both, $\n), + case {correct_nums(Exp, Digits), eval(Exp)} of + {ok, X} when X == 24 -> io:format("You Win!~n"); + {ok, X} -> io:format("You Lose with ~p!~n",[X]); + {List, _} -> io:format("The following numbers are wrong: ~p~n", [List]) + end. + +correct_nums(Exp, Digits) -> + case re:run(Exp, "([0-9]+)", [global, {capture, all_but_first, list}]) of + nomatch -> + "No number entered"; + {match, IntLs} -> + case [X || [X] <- IntLs, not lists:member(list_to_integer(X), Digits)] of + [] -> ok; + L -> L + end + end. + +eval(Exp) -> + {X, _} = eval(re:replace(Exp, "\\s", "", [{return, list},global]), + 0), + X. + +eval([], Val) -> + {Val,[]}; +eval([$(|Rest], Val) -> + {NewVal, Exp} = eval(Rest, Val), + eval(Exp, NewVal); +eval([$)|Rest], Val) -> + {Val, Rest}; +eval([$[|Rest], Val) -> + {NewVal, Exp} = eval(Rest, Val), + eval(Exp, NewVal); +eval([$]|Rest], Val) -> + {Val, Rest}; +eval([$+|Rest], Val) -> + {NewOperand, Exp} = eval(Rest, 0), + eval(Exp, Val + NewOperand); +eval([$-|Rest], Val) -> + {NewOperand, Exp} = eval(Rest, 0), + eval(Exp, Val - NewOperand); +eval([$*|Rest], Val) -> + {NewOperand, Exp} = eval(Rest, 0), + eval(Exp, Val * NewOperand); +eval([$/|Rest], Val) -> + {NewOperand, Exp} = eval(Rest, 0), + eval(Exp, Val / NewOperand); +eval([X|Rest], 0) when X >= $1, X =< $9 -> + eval(Rest, X-$0). diff --git a/Task/24-game/Fortran/24-game.f b/Task/24-game/Fortran/24-game.f new file mode 100644 index 0000000000..0ad3909e1d --- /dev/null +++ b/Task/24-game/Fortran/24-game.f @@ -0,0 +1,111 @@ +program game_24 + implicit none + real :: vector(4), reals(11), result, a, b, c, d + integer :: numbers(4), ascii(11), i + character(len=11) :: expression + character :: syntax(11) + ! patterns: + character, parameter :: one(11) = (/ '(','(','1','x','1',')','x','1',')','x','1' /) + character, parameter :: two(11) = (/ '(','1','x','(','1','x','1',')',')','x','1' /) + character, parameter :: three(11) = (/ '1','x','(','(','1','x','1',')','x','1',')' /) + character, parameter :: four(11) = (/ '1','x','(','1','x','(','1','x','1',')',')' /) + character, parameter :: five(11) = (/ '(','1','x','1',')','x','(','1','x','1',')' /) + + do + call random_number(vector) + numbers = 9 * vector + 1 + write (*,*) 'Digits: ',numbers + write (*,'(a)',advance='no') 'Your expression: ' + read (*,'(a11)') expression + + forall (i=1:11) syntax(i) = expression(i:i) + ascii = iachar(syntax) + where (syntax >= '0' .and. syntax <= '9') + syntax = '1' ! number + elsewhere (syntax == '+' .or. syntax == '-' .or. syntax == '*' .or. syntax == '/') + syntax = 'x' ! op + elsewhere (syntax /= '(' .and. syntax /= ')') + syntax = '-' ! error + end where + + reals = real(ascii-48) + if ( all(syntax == one) ) then + a = reals(3); b = reals(5); c = reals(8); d = reals(11) + call check_numbers(a,b,c,d) + result = op(op(op(a,4,b),7,c),10,d) + else if ( all(syntax == two) ) then + a = reals(2); b = reals(5); c = reals(7); d = reals(11) + call check_numbers(a,b,c,d) + result = op(op(a,3,op(b,6,c)),10,d) + else if ( all(syntax == three) ) then + a = reals(1); b = reals(5); c = reals(7); d = reals(10) + call check_numbers(a,b,c,d) + result = op(a,2,op(op(b,6,c),9,d)) + else if ( all(syntax == four) ) then + a = reals(1); b = reals(4); c = reals(7); d = reals(9) + call check_numbers(a,b,c,d) + result = op(a,2,op(b,5,op(c,8,d))) + else if ( all(syntax == five) ) then + a = reals(2); b = reals(4); c = reals(8); d = reals(10) + call check_numbers(a,b,c,d) + result = op(op(a,3,b),6,op(c,9,d)) + else + stop 'Input string: incorrect syntax.' + end if + + if ( abs(result-24.0) < epsilon(1.0) ) then + write (*,*) 'You won!' + else + write (*,*) 'Your result (',result,') is incorrect!' + end if + + write (*,'(a)',advance='no') 'Another one? [y/n] ' + read (*,'(a1)') expression + if ( expression(1:1) == 'n' .or. expression(1:1) == 'N' ) then + stop + end if + end do + +contains + + pure real function op(x,c,y) + integer, intent(in) :: c + real, intent(in) :: x,y + select case ( char(ascii(c)) ) + case ('+') + op = x+y + case ('-') + op = x-y + case ('*') + op = x*y + case ('/') + op = x/y + end select + end function op + + subroutine check_numbers(a,b,c,d) + real, intent(in) :: a,b,c,d + integer :: test(4) + test = (/ nint(a),nint(b),nint(c),nint(d) /) + call Insertion_Sort(numbers) + call Insertion_Sort(test) + if ( any(test /= numbers) ) then + stop 'You cheat ;-) (Incorrect numbers)' + end if + end subroutine check_numbers + + pure subroutine Insertion_Sort(a) + integer, intent(inout) :: a(:) + integer :: temp, i, j + do i=2,size(a) + j = i-1 + temp = a(i) + do while ( j>=1 .and. a(j)>temp ) + a(j+1) = a(j) + j = j - 1 + end do + a(j+1) = temp + end do + end subroutine Insertion_Sort + +end program game_24 diff --git a/Task/24-game/Go/24-game.go b/Task/24-game/Go/24-game.go new file mode 100644 index 0000000000..6eb6eb8c7d --- /dev/null +++ b/Task/24-game/Go/24-game.go @@ -0,0 +1,68 @@ +package main + +import ( + "fmt" + "math" + "math/rand" + "time" +) + +func main() { + rand.Seed(time.Now().Unix()) + n := make([]rune, 4) + for i := range n { + n[i] = rune(rand.Intn(9) + '1') + } + fmt.Printf("Your numbers: %c\n", n) + fmt.Print("Enter RPN: ") + var expr string + fmt.Scan(&expr) + if len(expr) != 7 { + fmt.Println("invalid. expression length must be 7." + + " (4 numbers, 3 operators, no spaces)") + return + } + stack := make([]float64, 0, 4) + for _, r := range expr { + if r >= '0' && r <= '9' { + if len(n) == 0 { + fmt.Println("too many numbers.") + return + } + i := 0 + for n[i] != r { + i++ + if i == len(n) { + fmt.Println("wrong numbers.") + return + } + } + n = append(n[:i], n[i+1:]...) + stack = append(stack, float64(r-'0')) + continue + } + if len(stack) < 2 { + fmt.Println("invalid expression syntax.") + return + } + switch r { + case '+': + stack[len(stack)-2] += stack[len(stack)-1] + case '-': + stack[len(stack)-2] -= stack[len(stack)-1] + case '*': + stack[len(stack)-2] *= stack[len(stack)-1] + case '/': + stack[len(stack)-2] /= stack[len(stack)-1] + default: + fmt.Printf("%c invalid.\n", r) + return + } + stack = stack[:len(stack)-1] + } + if math.Abs(stack[0]-24) > 1e-6 { + fmt.Println("incorrect.", stack[0], "!= 24") + } else { + fmt.Println("correct.") + } +} diff --git a/Task/24-game/Haskell/24-game.hs b/Task/24-game/Haskell/24-game.hs new file mode 100644 index 0000000000..c905ce3bd8 --- /dev/null +++ b/Task/24-game/Haskell/24-game.hs @@ -0,0 +1,44 @@ +import Char +import Control.Monad.Error +import Data.List +import IO +import Maybe +import Random + +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 + +processGuess _ [] = Right "" +processGuess digits xs | not $ matches = Left "Wrong digits used" + where matches = digits == (sort . map 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") + +-- A Reverse Polish Notation calculator with full error handling +calc = result [] + where result [n] [] = Right n + result _ [] = Left "Too few operators" + result ns (x:xs) = simplify ns x >>= flip result xs + +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 + +ops = [("+",(+)), ("-",(-)), ("*",(*)), ("/",(/))] diff --git a/Task/24-game/JavaScript/24-game.js b/Task/24-game/JavaScript/24-game.js new file mode 100644 index 0000000000..06fb37c3ff --- /dev/null +++ b/Task/24-game/JavaScript/24-game.js @@ -0,0 +1,48 @@ +String.prototype.replaceAll = function(patt,repl) { var that = this; + that = that.replace(patt,repl); + if (that.search(patt) != -1) { + that = that.replaceAll(patt,repl); + } + return that; + }; + +function validChars(input) { var regInvalidChar = /[^\d\+\*\/\s-\(\)]/; + return input.search(regInvalidChar) == -1; + } + +function validNums(str, nums) { + var arr, l; + arr = str.replaceAll(/[^\d\s]/," ").replaceAll(" "," ").trim().split(" ").sort(); + l = arr.length; + + while(l--) { arr[l] = Number(arr[l]); } + + return _.isEqual(arr,nums.sort()); +} + +function validEval(input) { try { eval(input); } catch (e) { return false; }; + return true; + } + +var input; + +while(true){ var numbers = []; + var i = 4; + while(i--) { numbers.push(Math.floor(Math.random()*8+1)); + } + + input = prompt("Your numbers are:\n" + + numbers.join(" ") + + "\nEnter expression. (use only + - * / and parens).\n" + + "'x' to exit." + ); + + if (input === 'x') break; + + !validChars(input) ? alert("Invalid chars used, try again. Use only:\n + - * / ( )") + : !validNums(input,numbers) ? alert("Wrong numbers used, try again.") + : !validEval(input) ? alert("Could not evaluate input, try again.") + : eval(input) != 24 ? alert("Wrong answer:" + eval(input) + "\nTry again.") + : alert(input + "== 24. Congrats!!") + ; + } diff --git a/Task/24-game/Lua/24-game-1.lua b/Task/24-game/Lua/24-game-1.lua new file mode 100644 index 0000000000..2d615a4910 --- /dev/null +++ b/Task/24-game/Lua/24-game-1.lua @@ -0,0 +1,99 @@ +local function help() + print [[ + The 24 Game + + Given any four digits in the range 1 to 9, which may have repetitions, + Using just the +, -, *, and / operators; and the possible use of + brackets, (), show how to make an answer of 24. + + An answer of "q" will quit the game. + An answer of "!" will generate a new set of four digits. + + Note: you cannot form multiple digit numbers from the supplied digits, + so an answer of 12+12 when given 1, 2, 2, and 1 would not be allowed. + + ]] +end + +local function generate(n) + result = {} + for i=1,n do + result[i] = math.random(1,9) + end + return result +end + +local function check(answer, digits) + local adig = {} + local ddig = {} + local index + local lastWasDigit = false + for i=1,9 do adig[i] = 0 ddig[i] = 0 end + allowed = {['(']=true,[')']=true,[' ']=true,['+']=true,['-']=true,['*']=true,['/']=true,['\t']=true,['1']=true,['2']=true,['3']=true,['4']=true,['5']=true,['6']=true,['7']=true,['8']=true,['9']=true} + for i=1,string.len(answer) do + if not allowed[string.sub(answer,i,i)] then + return false + end + index = string.byte(answer,i)-48 + if index > 0 and index < 10 then + if lastWasDigit then + return false + end + lastWasDigit = true + adig[index] = adig[index] + 1 + else + lastWasDigit = false + end + end + for i,digit in next,digits do + ddig[digit] = ddig[digit]+1 + end + for i=1,9 do + if adig[i] ~= ddig[i] then + return false + end + end + return loadstring('return '..answer)() +end + +local function game24() + help() + math.randomseed(os.time()) + math.random() + local digits = generate(4) + local trial = 0 + local answer = 0 + local ans = false + io.write 'Your four digits:' + for i,digit in next,digits do + io.write (' ' .. digit) + end + print() + while ans ~= 24 do + trial = trial + 1 + io.write("Expression "..trial..": ") + answer = io.read() + if string.lower(answer) == 'q' then + break + end + if answer == '!' then + digits = generate(4) + io.write ("New digits:") + for i,digit in next,digits do + io.write (' ' .. digit) + end + print() + else + ans = check(answer,digits) + if ans == false then + print ('The input '.. answer ..' was wonky!') + else + print (' = '.. ans) + if ans == 24 then + print ("Thats right!") + end + end + end + end +end +game24() diff --git a/Task/24-game/Lua/24-game-2.lua b/Task/24-game/Lua/24-game-2.lua new file mode 100644 index 0000000000..9e57d71ef3 --- /dev/null +++ b/Task/24-game/Lua/24-game-2.lua @@ -0,0 +1,42 @@ +function twentyfour() + print [[ + The 24 Game + + Given any four digits in the range 1 to 9, which may have repetitions, + Using just the +, -, *, and / operators; and the possible use of + brackets, (), show how to make an answer of 24. + + An answer of "q" will quit the game. + An answer of "!" will generate a new set of four digits. + + Note: you cannot form multiple digit numbers from the supplied digits, + so an answer of 12+12 when given 1, 2, 2, and 1 would not be allowed. + + ]] + expr = re.compile[[ --matches properly formatted infix expressions and returns all numerals as captures + expr <- (!.) / ( / ) ( )? + number <- {[0-9]} + ws <- " "* + oper <- [-+/*] + paren <- "(" ")" ]] + local val_t = {math.random(9), math.random(9), math.random(9), math.random(9)} + table.sort(val_t) + print("the digits are " .. table.concat(val_t, ", ")) + local ex = io.read() + a, b, c, d, e = expr:match(ex) + if a and b and c and d and not e then --if there is a fifth numeral the player is cheating + local digs = {a + 0, b + 0, c + 0, d + 0} + local flag = false -- (terrorism!) + table.sort(digs) + for i = 1, 4 do + flag = digs[i] ~= val_t[i] and not print"Wrong digits!" or flag + end + if not flag and loadstring("return " .. ex)() == 24 then + print"You win!" + else + print"You lose." + end + else print"wat" --expression could not be interpreted as arithmetic + end +end +twentyfour() diff --git a/Task/24-game/PHP/24-game.php b/Task/24-game/PHP/24-game.php new file mode 100644 index 0000000000..f965884660 --- /dev/null +++ b/Task/24-game/PHP/24-game.php @@ -0,0 +1,94 @@ +#!/usr/bin/env php +The 24 Game + +Given any four digits in the range 1 to 9, which may have repetitions, +Using just the +, -, *, and / operators; and the possible use of +brackets, (), show how to make an answer of 24. + +An answer of "q" will quit the game. +An answer of "!" will generate a new set of four digits. +Otherwise you are repeatedly asked for an expression until it evaluates to 24 + +Note: you cannot form multiple digit numbers from the supplied digits, +so an answer of 12+12 when given 1, 2, 2, and 1 would not be allowed. + + 0) { + return; + } + } + + return eval("return $expression;"); +} +?> diff --git a/Task/24-game/Perl/24-game.pl b/Task/24-game/Perl/24-game.pl new file mode 100644 index 0000000000..6358ff67ac --- /dev/null +++ b/Task/24-game/Perl/24-game.pl @@ -0,0 +1,122 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +print <<'EOF'; +The 24 Game + +Given any four digits in the range 1 to 9, which may have repetitions, +Using just the +, -, *, and / operators; and the possible use of +brackets, (), show how to make an answer of 24. + +An answer of "q" will quit the game. +An answer of "!" will generate a new set of four digits. +Otherwise you are repeatedly asked for an expression until it evaluates to 24 + +Note: you cannot form multiple digit numbers from the supplied digits, +so an answer of 12+12 when given 1, 2, 2, and 1 would not be allowed. +EOF + +while(1) +{ + my $iteration_num = 0; + + my $numbers = make_numbers(); + + TRY_SOLVING: + while(1) + { + $iteration_num++; + print "Expression ${iteration_num}: "; + + my $entry = <>; + chomp($entry); + + last TRY_SOLVING if $entry eq '!'; + + exit if $entry eq 'q'; + + my $result = play($numbers, $entry); + + if (!defined $result) + { + print "That's not valid\n"; + next TRY_SOLVING; + } + elsif ($result != 24) + { + print "Sorry, that's $result\n"; + next TRY_SOLVING; + } + else + { + print "That's right! 24!!\n"; + exit; + } + } +} + +sub make_numbers +{ + my %numbers = (); + + print "Your four digits:"; + + for(1..4) + { + my $i = 1 + int(rand(9)); + $numbers{$i}++; + print "$i "; + } + + print "\n"; + + return \%numbers; +} + +sub play +{ + my ($numbers, $expression) = @_; + + my %running_numbers = %$numbers; + + my @chars = split //, $expression; + + my $operator = 1; + + CHARS: + foreach (@chars) + { + next CHARS if $_ =~ /[()]/; + + $operator = !$operator; + + if (! $operator) + { + if (defined $running_numbers{$_} && $running_numbers{$_} > 0) + { + $running_numbers{$_}--; + next CHARS; + } + else + { + return; + } + } + else + { + return if $_ !~ m{[-+*/]}; + } + } + + foreach my $remaining (values(%running_numbers)) + { + if ($remaining > 0) + { + return; + } + } + + return eval($expression); +} diff --git a/Task/24-game/PicoLisp/24-game.l b/Task/24-game/PicoLisp/24-game.l new file mode 100644 index 0000000000..74cd051483 --- /dev/null +++ b/Task/24-game/PicoLisp/24-game.l @@ -0,0 +1,31 @@ +(de checkExpression (Lst Exe) + (make + (when (diff Lst (fish num? Exe)) + (link "Not all numbers used" ) ) + (when (diff (fish num? Exe) Lst) + (link "Using wrong number(s)") ) + (when (diff (fish sym? Exe) '(+ - * /)) + (link "Using illegal operator(s)") ) ) ) + +(loop + (setq Numbers (make (do 4 (link (rand 1 9))))) + (prinl + "Please enter a Lisp expression using (, ), +, -, *, / and " + (glue ", " Numbers) ) + (prin "Or a single dot '.' to stop: ") + (T (= "." (setq Reply (catch '(NIL) (in NIL (read))))) + (bye) ) + (cond + ((str? Reply) + (prinl "-- Input error: " Reply) ) + ((checkExpression Numbers Reply) + (prinl "-- Illegal Expression") + (for S @ + (space 3) + (prinl S) ) ) + ((str? (setq Result (catch '(NIL) (eval Reply)))) + (prinl "-- Evaluation error: " @) ) + ((= 24 Result) + (prinl "++ Congratulations! Correct result :-)") ) + (T (prinl "Sorry, this gives " Result)) ) + (prinl) ) diff --git a/Task/24-game/Python/24-game.py b/Task/24-game/Python/24-game.py new file mode 100644 index 0000000000..0d534555e9 --- /dev/null +++ b/Task/24-game/Python/24-game.py @@ -0,0 +1,67 @@ +''' + The 24 Game + + Given any four digits in the range 1 to 9, which may have repetitions, + Using just the +, -, *, and / operators; and the possible use of + brackets, (), show how to make an answer of 24. + + An answer of "q" will quit the game. + An answer of "!" will generate a new set of four digits. + Otherwise you are repeatedly asked for an expression until it evaluates to 24 + + Note: you cannot form multiple digit numbers from the supplied digits, + so an answer of 12+12 when given 1, 2, 2, and 1 would not be allowed. + +''' + +from __future__ import division, print_function +import random, ast, re +import sys + +if sys.version_info[0] < 3: input = raw_input + +def choose4(): + 'four random digits >0 as characters' + return [str(random.randint(1,9)) for i in range(4)] + +def welcome(digits): + print (__doc__) + print ("Your four digits: " + ' '.join(digits)) + +def check(answer, digits): + allowed = set('() +-*/\t'+''.join(digits)) + ok = all(ch in allowed for ch in answer) and \ + all(digits.count(dig) == answer.count(dig) for dig in set(digits)) \ + and not re.search('\d\d', answer) + if ok: + try: + ast.parse(answer) + except: + ok = False + return ok + +def main(): + digits = choose4() + welcome(digits) + trial = 0 + answer = '' + chk = ans = False + while not (chk and ans == 24): + trial +=1 + answer = input("Expression %i: " % trial) + chk = check(answer, digits) + if answer.lower() == 'q': + break + if answer == '!': + digits = choose4() + print ("New digits:", ' '.join(digits)) + continue + if not chk: + print ("The input '%s' was wonky!" % answer) + else: + ans = eval(answer) + print (" = ", ans) + if ans == 24: + print ("Thats right!") + print ("Thank you and goodbye") +main() diff --git a/Task/24-game/R/24-game-1.r b/Task/24-game/R/24-game-1.r new file mode 100644 index 0000000000..e977928bff --- /dev/null +++ b/Task/24-game/R/24-game-1.r @@ -0,0 +1,54 @@ +twenty.four <- function(operators=c("+", "-", "*", "/", "("), + selector=function() sample(1:9, 4, replace=TRUE), + arguments=selector(), + goal=24) { + newdigits <- function() { + arguments <<- selector() + cat("New digits:", paste(arguments, collapse=", "), "\n") + } + help <- function() cat("Make", goal, + "out of the numbers",paste(arguments, collapse=", "), + "and the operators",paste(operators, collapse=", "), ".", + "\nEnter 'q' to quit, '!' to select new digits,", + "or '?' to repeat this message.\n") + help() + repeat { + switch(input <- readline(prompt="> "), + q={ cat("Goodbye!\n"); break }, + `?`=help(), + `!`=newdigits(), + tryCatch({ + expr <- parse(text=input, n=1)[[1]] + check.call(expr, operators, arguments) + result <- eval(expr) + if (isTRUE(all.equal(result, goal))) { + cat("Correct!\n") + newdigits() + } else { + cat("Evaluated to", result, "( goal", goal, ")\n") + } + },error=function(e) cat(e$message, "\n"))) + } +} + +check.call <- function(expr, operators, arguments) { + unexpr <- function(x) { + if (is.call(x)) + unexpr(as.list(x)) + else if (is.list(x)) + lapply(x,unexpr) + else x + } + leaves <- unlist(unexpr(expr)) + if (any(disallowed <- + !leaves %in% c(lapply(operators, as.name), + as.list(arguments)))) { + stop("'", paste(sapply(leaves[disallowed], as.character), + collapse=", "), + "' not allowed. ") + } + numbers.used <- unlist(leaves[sapply(leaves, mode) == 'numeric']) + + if (! isTRUE(all.equal(sort(numbers.used), sort(arguments)))) + stop("Must use each number once.") +} diff --git a/Task/24-game/R/24-game-2.r b/Task/24-game/R/24-game-2.r new file mode 100644 index 0000000000..aca99074f5 --- /dev/null +++ b/Task/24-game/R/24-game-2.r @@ -0,0 +1,29 @@ +> twenty.four() + +Make 24 out of the numbers 1, 6, 7, 5 and the operators +, -, *, /, ( . +Enter 'q' to quit, '!' to select new digits, or '?' to repeat this message. +> 6*(5-1) +Must use each number once. +> 1 + 6*5 - 7 +Correct! +New digits: 7, 2, 9, 3 +> (7+9)/2*3 +Correct! +New digits: 1, 4, 1, 7 +> 4*(7-1) +Must use each number once. +> (7-1)*4*1 +Correct! +New digits: 1, 5, 2, 8 +> (5-1)^2+8 +'^' not allowed. +> ! +New digits: 2, 8, 5, 2 +> 52-28 +'52, 28' not allowed. +> (8-2)*(5-2/2) +Must use each number once. +> (8+2)*2+5 +Evaluated to 25 ( goal 24 ) +> q +Goodbye! diff --git a/Task/24-game/REXX/24-game-1.rexx b/Task/24-game/REXX/24-game-1.rexx new file mode 100644 index 0000000000..b1c8c38251 --- /dev/null +++ b/Task/24-game/REXX/24-game-1.rexx @@ -0,0 +1,212 @@ +/*REXX program which allows a user to play the game of 24 (twenty-four).*/ +/* + ╔══════════════════════════════════════════════════════════════════╗ + ║ Argument is either of three forms: (blank) ║ + ║ ssss ║ + ║ ssss-ffff ║ + ║ ║ + ║ where one or both strings must be exactly four numerals (digits) ║ + ║ comprised soley of the numerals (digits) 1 ──> 9 (no zeroes). ║ + ║ ║ + ║ SSSS is the start, ║ + ║ FFFF is the start. ║ + ║ ║ + ║ If no argument is specified, this program finds a four digit ║ + ║ number (no zeroes) which has at least one solution, and shows ║ + ║ the number to the user, requesting that they enter a solution ║ + ║ in the form of: w operator x operator y operator z ║ + ║ where w x y and z are single digit numbers (no zeroes), ║ + ║ and operator can be any one of: + - * / ║ + ║ Parentheses () may be used in the normal manner for grouping, ║ + ║ as well as brackets [] or braces {}. ║ + ╚══════════════════════════════════════════════════════════════════╝ */ +parse arg orig /*get the guess from the argument. */ +orig=space(orig,0) /*remove extraneous blanks from ORIG. */ +parse var orig start '-' finish /*get the start and finish (maybe). */ +finish=word(finish start,1) /*if no FINISH specified, use START.*/ +opers='+-*/' /*define the legal arithmetic operators*/ +ops=length(opers) /* ... and the count of them (length). */ +groupsymbols='()[]{}' /*legal grouping symbols. */ +indent=left('',30) /*used to indent display of solutions. */ +Lpar='(' /*a string to make REXX code prettier. */ +Rpar=')' /*ditto. */ +show=1 /*flag used show solutions (0 = not). */ +digs=123456789 /*numerals (digits) that can be used. */ + + do j=1 for ops /*define a version for fast execution. */ + o.j=substr(opers,j,1) + end /*j*/ + +if orig\=='' then do + sols=solve(start,finish) + if sols<0 then exit 13 + if sols==0 then sols='No' /*un-geek SOLS.*/ + say + say sols 'unique solution's(finds) "found for" orig /*pluralize.*/ + exit + end +show=0 /*stop SOLVE from blabbing solutions. */ + do forever + rrrr=random(1111,9999) + if pos(0,rrrr)\==0 then iterate + if solve(rrrr)\==0 then leave + end +show=1 /*enable SOLVE to show solutions. */ +rrrr=sort(rrrr) /*sort four elements. */ +rd.=0 + do j=1 for 9 /*digit count # for each digit in RRRR.*/ + _=substr(rrrr,j,1) + rd._=countdigs(rrrr,_) + end /*j*/ + + do guesses=1; say + say 'Using the digits', + rrrr", enter an expression that equals 24 (or QUIT):" + pull y + y=space(y,0); if y=='QUIT' then exit + _v=verify(y,digs||opers||groupsymbols) + if _v\==0 then do + call ger 'invalid character:' substr(_v,1) + iterate + end + yl=length(y) + if y='' then do + call validate y + iterate + end + + do j=1 to yl-1 + _=substr(y,j,1) + if \datatype(_,'W') then iterate + _=substr(y,j+1,1) + if datatype(_,'W') then do + call ger 'invalid use of digit abuttal' + iterate guesses + end + end /*j*/ + + yd=countdigs(y,digs) /*count of digits 123456789.*/ + if yd<4 then do + call ger 'not enough digits entered.' + iterate guesses + end + if yd>4 then do + call ger 'too many digits entered.' + iterate guesses + end + + do j=1 for 9; if rd.j==0 then iterate + _d=countdigs(y,j) + if _d==rd.j then iterate + if _d /div(yyy) */ + /*Enables to check for division by zero*/ + origE=e /*keep old version for the display. */ + if pos('/(',e)\==0 then e=changestr('/(',e,"/div(") + /*The above could be replaced by: */ + /* e=changestr('/(',e,"/div(") */ + + /*INTERPRET stresses REXX's groin, */ + /*so try to avoid repeated lifting. */ + if x.e then iterate /*was the expression already used? */ + x.e=1 /*mark this expression as unique. */ + /*have REXX do the heavy lifting. */ + interpret 'x=' e + x=x/1 /*remove trailing decimal points. */ + if x\==24 then iterate /*Not correct? Try again.*/ + finds=finds+1 /*bump number of found solutions. */ + _=translate(origE,'][',")(") /*show [], not ().*/ + if show then say indent 'a solution:' _ /*show solution*/ + end /*n*/ + end /*m*/ + end /*k*/ + end /*j*/ + end /*i*/ + end /*g*/ + +return finds +/*───────────────────────────COUNTDIGS subroutine───────────────────────*/ +countdigs: arg field,numerals /*count of digits NUMERALS.*/ +return length(field)-length(space(translate(field,,numerals),0)) +/*───────────────────────────DIV subroutine─────────────────────────────*/ +div: procedure; parse arg q /*tests if dividing by 0 (zero). */ +if q=0 then q=1e9 /*if dividing by zero, change divisor. */ +return q /*changing Q invalidates the expression*/ +/*───────────────────────────GER subroutine─────────────────────────────*/ +ger: say; say '*** error! *** for argument:' y; say arg(1); say; errCode=1; return 0 +/*───────────────────────────S subroutine───────────────────────────────*/ +s: if arg(1)==1 then return ''; return 's' /*simple pluralizer.*/ +/*───────────────────────────SORT subroutine────────────────────────────*/ +sort: procedure; arg nnnn; L=length(nnnn) + + do i=1 for L /*build an array of digits from NNNN.*/ + a.i=substr(nnnn,i,1) /*this enables SORT to sort an array. */ + end /*i*/ + + do j=1 for L; _=a.j + do k=j+1 to L + if a.k<_ then parse value a.j a.k with a.k a.j + end /*k*/ + end /*j*/ +return a.1 || a.2 || a.3 || a.4 +/*───────────────────────────SYNTAX subroutin───────────────────────────*/ +syntax: call ger 'illegal syntax in' y; exit +/*───────────────────────────validate subroutine────────────────────────*/ +validate: parse arg y; errCode=0; _v=verify(y,digs) + select + when y=='' then call ger 'no digits entered.' + when length(y)<4 then call ger 'not enough digits entered, must be 4' + when length(y)>4 then call ger 'too many digits entered, must be 4' + when pos(0,y)\==0 then call ger "can't use the digit 0 (zero)" + when _v\==0 then call ger 'illegal character:' substr(y,_v,1) + otherwise nop + end /*select*/ +return \errCode diff --git a/Task/24-game/REXX/24-game-2.rexx b/Task/24-game/REXX/24-game-2.rexx new file mode 100644 index 0000000000..79165ca303 --- /dev/null +++ b/Task/24-game/REXX/24-game-2.rexx @@ -0,0 +1,25 @@ +changestr: Procedure +/* change needle to newneedle in haystack (as often as specified */ +/* or all of them if count is omitted */ + Parse Arg needle,haystack,newneedle,count + If count>'' Then Do + If count=0 Then Do + Say 'chstr count must be > 0' + Signal Syntax + End + End + res="" + changes=0 + px=1 + do Until py=0 + py=pos(needle,haystack,px) + if py>0 then Do + res=res||substr(haystack,px,py-px)||newneedle + px=py+length(needle) + changes=changes+1 + If count>'' Then + If changes=count Then Leave + End + end + res=res||substr(haystack,px) + Return res diff --git a/Task/24-game/Racket/24-game.rkt b/Task/24-game/Racket/24-game.rkt new file mode 100644 index 0000000000..c4efb35a87 --- /dev/null +++ b/Task/24-game/Racket/24-game.rkt @@ -0,0 +1,50 @@ +#lang racket + +(define (random-4) + (sort (for/list ((i (in-range 4))) + (add1 (random 9))) + <)) + +(define (check-valid-chars lst-nums str) + (define regx (string-join (list + "^[" + (string-join (map number->string lst-nums) "") + "\\(\\)\\+\\-\\/\\*\\ ]*$") + "")) + (regexp-match? regx str)) + +(define (check-all-numbers lst-nums str) + (equal? + (sort + (map (λ (x) (string->number x)) + (regexp-match* "([0-9])" str)) <) + lst-nums)) + +(define (start-game) + (display "** 24 **\n") + (display "Input \"q\" to quit or your answer in Racket ") + (display "notation, like (- 1 (* 3 2))\n\n") + (new-question)) + +(define (new-question) + (define numbers (random-4)) + (apply printf "Your numbers: ~a - ~a - ~a - ~a\n" numbers) + (define (do-loop) + (define user-expr (read-line)) + (cond + [(equal? user-expr "q") + (exit)] + [(not (check-valid-chars numbers user-expr)) + (display "Your expression seems invalid, please retry:\n") + (do-loop)] + [(not (check-all-numbers numbers user-expr)) + (display "You didn't use all the provided numbers, please retry:\n") + (do-loop)] + [(if (equal? 24 (eval (with-input-from-string user-expr read) (make-base-namespace))) + (display "OK!!") + (begin + (display "Incorrect\n") + (do-loop)))])) + (do-loop)) + +(start-game) diff --git a/Task/24-game/Ruby/24-game.rb b/Task/24-game/Ruby/24-game.rb new file mode 100644 index 0000000000..552e4448b5 --- /dev/null +++ b/Task/24-game/Ruby/24-game.rb @@ -0,0 +1,55 @@ +require "rational" + +def play + digits = Array.new(4) {1+rand(9)} + loop do + guess = get_guess(digits) + result = evaluate(guess) + if result == 24.0 + puts "yes!" + break + else + puts "nope: #{guess} = #{result}" + puts "try again" + end + end +end + +def get_guess(digits) + loop do + print "\nEnter your guess using #{digits.inspect}: " + guess = $stdin.gets.chomp + + # ensure input is safe to eval + invalid_chars = guess.scan(%r{[^\d\s()+*/-]}) + unless invalid_chars.empty? + puts "invalid characters in input: #{invalid_chars.inspect}" + next + end + + guess_digits = guess.scan(/\d/).map {|ch| ch.to_i} + if guess_digits.sort != digits.sort + puts "you didn't use the right digits" + next + end + + if guess.match(/\d\d/) + puts "no multi-digit numbers allowed" + next + end + + return guess + end +end + +# convert expression to use rational numbers, evaluate, then return as float +def evaluate(guess) + as_rat = guess.gsub(/(\d)/, 'Rational(\1,1)') + begin + eval "(#{as_rat}).to_f" + rescue SyntaxError + "[syntax error]" + end +end + +play diff --git a/Task/24-game/Scala/24-game.scala b/Task/24-game/Scala/24-game.scala new file mode 100644 index 0000000000..c7a1c939a2 --- /dev/null +++ b/Task/24-game/Scala/24-game.scala @@ -0,0 +1,154 @@ +object TwentyFourGame { + def main(args: Array[String]) { + import Parser.TwentyFourParser + + println(welcome) + + var parser = new TwentyFourParser(problemsIterator.next) + println("Your four digits: "+parser+".") + + var finished = false + var expressionCount = 1 + do { + val line = Console.readLine("Expression "+expressionCount+": ") + line match { + case "!" => + parser = new TwentyFourParser(problemsIterator.next) + println("New digits: "+parser+".") + + case "q" => + finished = true + + case _ => + parser readExpression line match { + case Some(24) => println("That's right!"); finished = true + case Some(n) => println("Sorry, that's "+n+".") + case None => + } + } + expressionCount += 1 + } while (!finished) + + println("Thank you and goodbye!") + } + + val welcome = """|The 24 Game + | + |Given any four digits in the range 1 to 9, which may have repetitions, + |Using just the +, -, *, and / operators; and the possible use of + |brackets, (), show how to make an answer of 24. + | + |An answer of "q" will quit the game. + |An answer of "!" will generate a new set of four digits. + |Otherwise you are repeatedly asked for an expression until it evaluates to 24 + | + |Note: you cannot form multiple digit numbers from the supplied digits, + |so an answer of 12+12 when given 1, 2, 2, and 1 would not be allowed. + |""".stripMargin + + val problemsIterator = ( + Iterator + continually List.fill(4)(scala.util.Random.nextInt(9) + 1 toDouble) + filter hasSolution + ) + + def hasSolution(l: List[Double]) = permute(l) flatMap computeAllOperations exists (_ == 24) + + def computeAllOperations(l: List[Double]): List[Double] = l match { + case Nil => Nil + case x :: Nil => l + case x :: xs => + for { + y <- computeAllOperations(xs) + z <- if (y == 0) List(x*y, x+y, x-y) else List(x*y, x/y, x+y, x-y) + } yield z + } + + def permute(l: List[Double]): List[List[Double]] = l match { + case Nil => List(Nil) + case x :: xs => + for { + ys <- permute(xs) + position <- 0 to ys.length + (left, right) = ys splitAt position + } yield left ::: (x :: right) + } + + object Parser { + /* Arithmetic expression grammar production rules in EBNF form: + * + * --> ( '+' | '-' )* + * --> ( '*' | '/' )* + * --> '(' ')' | + * --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 + * + * Semantically, can only be a digit from the list of remaining digits. + */ + + class TwentyFourParser(digits: List[Double]) extends scala.util.parsing.combinator.RegexParsers { + require(digits.length == 4 && digits.forall(d => 0 <= d && d <= 9)) + override val toString = digits.map(_.toInt).mkString(", ") + + // Grammar + def exprConsumingAllDigits = expr ^? (remainingDigits.allDigitsConsumed, digitsRemainingError) // Guarantees all digits consumed + def expr : Parser[Double] = term ~ rep( "+" ~ term | "-" ~ term) ^^ solveOperationChain + def term = factor ~ rep( "*" ~ factor | "/" ~ factor) ^^ solveOperationChain + def factor = "(" ~> expr <~ ")" | digit + def digit = digitRegex ^? (remainingDigits.consumeDigit, digitNotAllowedError) + def digitRegex = "\\d".r | digitExpected + def digitExpected: Parser[String] = ".".r <~ failure(expectedDigitError) // Produces clear error messages + + // Evaluate expressions + def readExpression(input: String): Option[Double] = { + remainingDigits = new DigitList(digits) // Initialize list of digits to be consumed + parseAll(exprConsumingAllDigits, input) match { + case Success(result, _) => Some(result) + case NoSuccess(msg, next) => + println(ParsingErrorFormatter(msg, next)) + None + } + } + + // List of digits to be consumed + private var remainingDigits: DigitList = _ + + // Solve partial results from parsing + private def solveOperationChain(partialResult: ~[Double,List[~[String,Double]]]): Double = partialResult match { + case first ~ chain => chain.foldLeft(first)(doOperation) + } + private def doOperation(acc: Double, op: ~[String, Double]): Double = op match { + case "+" ~ operand => acc + operand + case "-" ~ operand => acc - operand + case "*" ~ operand => acc * operand + case "/" ~ operand => acc / operand + case x => error("Unknown operation "+x+".") + } + + // Error messages + private def digitNotAllowedError(d: String) = "Digit "+d+" is not allowed here. Available digits: "+remainingDigits+"." + private def digitsRemainingError(x: Any) = "Not all digits were consumed. Digits remaining: "+remainingDigits+"." + private def expectedDigitError = "Unexpected input. Expected a digit from the list: "+remainingDigits+"." + } + + private object ParsingErrorFormatter { + def apply[T](msg: String, next: scala.util.parsing.input.Reader[T]) = + "%s\n%s\n%s\n" format (msg, next.source.toString.trim, " "*(next.offset - 1)+"^") + } + + private class DigitList(digits: List[Double]) { + private var remainingDigits = digits + override def toString = remainingDigits.map(_.toInt).mkString(", ") + + def consumeDigit: PartialFunction[String, Double] = { + case d if remainingDigits contains d.toDouble => + val n = d.toDouble + remainingDigits = remainingDigits diff List(n) + n + } + + def allDigitsConsumed: PartialFunction[Double, Double] = { + case n if remainingDigits.isEmpty => n + } + } + } +} diff --git a/Task/24-game/Scheme/24-game.ss b/Task/24-game/Scheme/24-game.ss new file mode 100644 index 0000000000..9edf4e7110 --- /dev/null +++ b/Task/24-game/Scheme/24-game.ss @@ -0,0 +1,63 @@ +#lang scheme +(require srfi/27 srfi/1) ;; random-integer, every + +(define (play) + (let* ([numbers (build-list 4 (lambda (n) + (add1 (random-integer 9))))] + [valid? (curryr valid? numbers)]) + (printf startup-message numbers) + (let loop ([exp (read)]) + (with-handlers ([exn:fail? (lambda (err) + (printf error-message exp (exn-message err)) + (loop (read)))]) + (cond [(eq? exp '!) (play)] + + [(or (eq? exp 'q) + (eof-object? exp)) (printf quit-message)] + + [(not (valid? exp)) + (printf bad-exp-message exp) + (loop (read))] + + [(not (= (eval exp) 24)) + (printf bad-result-message exp (eval exp)) + (loop (read))] + + [else (printf winning-message)]))))) + +(define (valid? exp numbers) + ;; must contain each number exactly once and only valid symbols + (define (valid-symbol? sym) + ;; only +, -, *, and / are valid + (case sym + [(+ - * /) #t] + [else #f])) + + (let* ([ls (flatten exp)] + [numbers* (filter number? ls)] + [symbols (remove number? ls)]) + (and (equal? (sort numbers <) + (sort numbers* <)) + (every valid-symbol? symbols)))) + +(define startup-message " +Write a lisp expression that evaluates to 24 +using only (, ), +, -, *, / +and these four numbers: ~a + +or '!' to get a new set of numbers +or 'q' to quit") + +(define error-message " +Your expression ~a raised an exception: + + \"~a\" + +Please try again") + +(define bad-exp-message "Sorry, ~a is a bad expression.") +(define bad-result-message "Sorry, ~a evaluates to ~a, not 24.") +(define quit-message "Thanks for playing...") +(define winning-message "You win!") + +(provide play) diff --git a/Task/24-game/Tcl/24-game.tcl b/Task/24-game/Tcl/24-game.tcl new file mode 100644 index 0000000000..059a03bc08 --- /dev/null +++ b/Task/24-game/Tcl/24-game.tcl @@ -0,0 +1,75 @@ +# Four random non-zero digits +proc choose4 {} { + set digits {} + foreach x {1 2 3 4} {lappend digits [expr {int(1+rand()*9)}]} + return [lsort $digits] +} + +# Print out a welcome message +proc welcome digits { + puts [string trim " +The 24 Game + +Given any four digits in the range 1 to 9, which may have repetitions, +Using just the +, -, *, and / operators; and the possible use of +brackets, (), show how to make an answer of 24. + +An answer of \"q\" will quit the game. +An answer of \"!\" will generate a new set of four digits. +Otherwise you are repeatedly asked for an expression until it evaluates to 24 + +Note: you cannot form multiple digit numbers from the supplied digits, +so an answer of 12+12 when given 1, 2, 2, and 1 would not be allowed. + "] + puts "\nYour four digits: $digits" +} + +# Check whether we've got a legal answer +proc check {answer digits} { + if { + [regexp "\[^-+*/() \t[join $digits {}]\]" $answer] + || [regexp {\d\d} $answer] + } then { + return false + } + set digs [lsort [regexp -inline -all {\d} $answer]] + if {$digs ne $digits} { + return false + } + expr {![catch {expr $answer}]} +} + +# The main game loop +proc main {} { + fconfigure stdout -buffering none + + set digits [choose4] + welcome $digits + set trial 0 + while true { + puts -nonewline "Expression [incr trial]: " + gets stdin answer + + # Check for various types of non-answer + if {[eof stdin] || $answer eq "q" || $answer eq "Q"} { + break + } elseif {$answer eq "!"} { + set digits [choose4] + puts "New digits: $digits" + continue + } elseif {![check $answer $digits]} { + puts "The input '$answer' was wonky!" + continue + } + + # Check to see if it is the right answer + set ans [expr [regsub {\d} $answer {&.0}]] + puts " = [string trimright $ans .0]" + if {$ans == 24.0} { + puts "That's right!" + break + } + } + puts "Thank you and goodbye" +} +main